You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@guacamole.apache.org by mj...@apache.org on 2018/06/26 00:25:35 UTC

[13/21] guacamole-server git commit: GUACAMOLE-527: Add host key and type settings.

GUACAMOLE-527: Add host key and type settings.


Project: http://git-wip-us.apache.org/repos/asf/guacamole-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/guacamole-server/commit/0d82cd1e
Tree: http://git-wip-us.apache.org/repos/asf/guacamole-server/tree/0d82cd1e
Diff: http://git-wip-us.apache.org/repos/asf/guacamole-server/diff/0d82cd1e

Branch: refs/heads/staging/1.0.0
Commit: 0d82cd1e6c78606a6b4d65b6d2441b02479fda88
Parents: 171bae1
Author: Nick Couchman <vn...@apache.org>
Authored: Thu Apr 5 07:36:37 2018 -0400
Committer: Nick Couchman <ni...@cotyinc.com>
Committed: Mon Jun 25 08:31:37 2018 -0400

----------------------------------------------------------------------
 src/common-ssh/common-ssh/ssh.h |  3 +-
 src/common-ssh/ssh.c            | 89 +++++++++++++++++++++++-------------
 src/protocols/ssh/settings.c    | 22 +++++++++
 src/protocols/ssh/settings.h    | 10 ++++
 4 files changed, 91 insertions(+), 33 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/0d82cd1e/src/common-ssh/common-ssh/ssh.h
----------------------------------------------------------------------
diff --git a/src/common-ssh/common-ssh/ssh.h b/src/common-ssh/common-ssh/ssh.h
index 8026549..e25b626 100644
--- a/src/common-ssh/common-ssh/ssh.h
+++ b/src/common-ssh/common-ssh/ssh.h
@@ -98,7 +98,8 @@ void guac_common_ssh_uninit();
  *     if the connection or authentication were not successful.
  */
 guac_common_ssh_session* guac_common_ssh_create_session(guac_client* client,
-        const char* hostname, const char* port, guac_common_ssh_user* user, int keepalive);
+        const char* hostname, const char* port, guac_common_ssh_user* user, int keepalive,
+        const char* host_key_type, const char* host_key);
 
 /**
  * Disconnects and destroys the given SSH session, freeing all associated

http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/0d82cd1e/src/common-ssh/ssh.c
----------------------------------------------------------------------
diff --git a/src/common-ssh/ssh.c b/src/common-ssh/ssh.c
index 5099de2..a1a62f6 100644
--- a/src/common-ssh/ssh.c
+++ b/src/common-ssh/ssh.c
@@ -415,7 +415,8 @@ static int guac_common_ssh_authenticate(guac_common_ssh_session* common_session)
 }
 
 guac_common_ssh_session* guac_common_ssh_create_session(guac_client* client,
-        const char* hostname, const char* port, guac_common_ssh_user* user, int keepalive) {
+        const char* hostname, const char* port, guac_common_ssh_user* user, int keepalive,
+        const char* host_key_type, const char* host_key) {
 
     int retval;
 
@@ -511,44 +512,68 @@ guac_common_ssh_session* guac_common_ssh_create_session(guac_client* client,
     }
 
     /* Check known_hosts */
-    size_t len;
-    int type;
+    /* Get known hosts file from user running guacd */
     struct passwd *pw = getpwuid(getuid());
     char *homedir = pw->pw_dir;
     char *known_hosts = strcat(homedir, "/.ssh/known_hosts");
     LIBSSH2_KNOWNHOSTS *ssh_known_hosts = libssh2_knownhost_init(session);
-
     libssh2_knownhost_readfile(ssh_known_hosts, known_hosts, LIBSSH2_KNOWNHOST_FILE_OPENSSH);
-    const char *fingerprint = libssh2_session_hostkey(session, &len, &type);
-
-    if (fingerprint) {
-        struct libssh2_knownhost *host;
-        int check = libssh2_knownhost_checkp(ssh_known_hosts, hostname, atoi(port),
-                                            fingerprint, len,
-                                            LIBSSH2_KNOWNHOST_TYPE_PLAIN|
-                                            LIBSSH2_KNOWNHOST_KEYENC_RAW,
-                                            &host);
-
-        switch (check) {
-            case LIBSSH2_KNOWNHOST_CHECK_MATCH:
-                guac_client_log(client, GUAC_LOG_DEBUG,
-                    "Host key match found.");
-                break;
-            case LIBSSH2_KNOWNHOST_CHECK_NOTFOUND:
-                guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR,
-                    "Host key not found in known hosts file.");
-                break;
-            case LIBSSH2_KNOWNHOST_CHECK_MISMATCH:
-                guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR,
-                    "Host key does not match host entry.");
-                break;
-            case LIBSSH2_KNOWNHOST_CHECK_FAILURE:
-            default:
-                guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR,
-                    "Host could not be checked against known hosts.");
-        }
 
+    /* Add host key provided from settings */
+    if (strcmp(host_key, "") > 0) {
+
+        int kh_key_type = 0;
+        if (strcmp(host_key_type, "ssh-rsa") == 0)
+            kh_key_type = LIBSSH2_KNOWNHOST_KEY_SSHRSA;
+        else if(strcmp(host_key_type, "ssh-dss") == 0)
+            kh_key_type = LIBSSH2_KNOWNHOST_KEY_SSHDSS;
+        else if(strcmp(host_key_type, "rsa1") == 0)
+            kh_key_type = LIBSSH2_KNOWNHOST_KEY_RSA1;
+        else
+            guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR,
+                    "Invalid SSH host key type %s", host_key_type);
+
+        if (libssh2_knownhost_addc(ssh_known_hosts, hostname, NULL, host_key, strlen(host_key),
+                NULL, 0, LIBSSH2_KNOWNHOST_TYPE_PLAIN|LIBSSH2_KNOWNHOST_KEYENC_BASE64|
+                         kh_key_type, NULL))
+            guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR,
+                "Failed to add host key to known hosts store for %s", hostname);
+    }
+
+    /* Get fingerprint of host we're connecting to */
+    size_t fp_len;
+    int fp_type;
+    const char *fingerprint = libssh2_session_hostkey(session, &fp_len, &fp_type);
+
+    if (!fingerprint || strcmp(fingerprint, "") == 0) {
+        guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR,
+                "Could not retrieve fingerprint of SSH server %s", hostname);
+    }
+
+    struct libssh2_knownhost *host;
+    int kh_check = libssh2_knownhost_checkp(ssh_known_hosts, hostname, atoi(port),
+                                         fingerprint, fp_len,
+                                         LIBSSH2_KNOWNHOST_TYPE_PLAIN|
+                                         LIBSSH2_KNOWNHOST_KEYENC_RAW,
+                                         &host);
 
+    switch (kh_check) {
+        case LIBSSH2_KNOWNHOST_CHECK_MATCH:
+            guac_client_log(client, GUAC_LOG_DEBUG,
+                "Host key match found.");
+            break;
+        case LIBSSH2_KNOWNHOST_CHECK_NOTFOUND:
+            guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR,
+                "Host key not found in known hosts file.");
+            break;
+        case LIBSSH2_KNOWNHOST_CHECK_MISMATCH:
+            guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR,
+                "Host key does not match host entry.");
+            break;
+        case LIBSSH2_KNOWNHOST_CHECK_FAILURE:
+        default:
+            guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR,
+                "Host could not be checked against known hosts.");
     }
 
     /* Perform handshake */

http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/0d82cd1e/src/protocols/ssh/settings.c
----------------------------------------------------------------------
diff --git a/src/protocols/ssh/settings.c b/src/protocols/ssh/settings.c
index 2ce9790..bc650e9 100644
--- a/src/protocols/ssh/settings.c
+++ b/src/protocols/ssh/settings.c
@@ -31,6 +31,8 @@
 /* Client plugin arguments */
 const char* GUAC_SSH_CLIENT_ARGS[] = {
     "hostname",
+    "host_key_type",
+    "host_key",
     "port",
     "username",
     "password",
@@ -69,6 +71,16 @@ enum SSH_ARGS_IDX {
     IDX_HOSTNAME,
 
     /**
+     * The type of public SSH host key provided.  Optional.
+     */
+    IDX_HOST_KEY_TYPE,
+
+    /**
+     * The Base64-encoded public SSH host key.  Optional.
+     */
+    IDX_HOST_KEY,
+
+    /**
      * The port to connect to. Optional.
      */
     IDX_PORT,
@@ -247,6 +259,14 @@ guac_ssh_settings* guac_ssh_parse_args(guac_user* user,
         guac_user_parse_args_string(user, GUAC_SSH_CLIENT_ARGS, argv,
                 IDX_HOSTNAME, "");
 
+    settings->host_key_type =
+        guac_user_parse_args_string(user, GUAC_SSH_CLIENT_ARGS, argv,
+                IDX_HOST_KEY_TYPE, "ssh-rsa");
+
+    settings->host_key =
+        guac_user_parse_args_string(user, GUAC_SSH_CLIENT_ARGS, argv,
+                IDX_HOST_KEY, NULL);
+
     settings->username =
         guac_user_parse_args_string(user, GUAC_SSH_CLIENT_ARGS, argv,
                 IDX_USERNAME, NULL);
@@ -384,6 +404,8 @@ void guac_ssh_settings_free(guac_ssh_settings* settings) {
 
     /* Free network connection information */
     free(settings->hostname);
+    free(settings->host_key_type);
+    free(settings->host_key);
     free(settings->port);
 
     /* Free credentials */

http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/0d82cd1e/src/protocols/ssh/settings.h
----------------------------------------------------------------------
diff --git a/src/protocols/ssh/settings.h b/src/protocols/ssh/settings.h
index 393cfc0..ac8400e 100644
--- a/src/protocols/ssh/settings.h
+++ b/src/protocols/ssh/settings.h
@@ -71,6 +71,16 @@ typedef struct guac_ssh_settings {
     char* hostname;
 
     /**
+     * The type of public SSH host key.
+     */
+    char* host_key_type;
+
+    /**
+     * The public SSH host key.
+     */
+    char* host_key;
+
+    /**
      * The port of the SSH server to connect to.
      */
     char* port;