GUACAMOLE-527: Add basic check for known hosts file for SSH connections.

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

Branch: refs/heads/master
Commit: 171bae1f5c13144f1574db11ac9a19732ec567cc
Parents: 334849e
Author: Nick Couchman <vn...@apache.org>
Authored: Sun Mar 25 17:34:29 2018 -0400
Committer: Nick Couchman <nick_couch...@cotyinc.com>
Committed: Mon Jun 25 08:31:37 2018 -0400

----------------------------------------------------------------------
 src/common-ssh/ssh.c | 42 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 42 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/171bae1f/src/common-ssh/ssh.c
----------------------------------------------------------------------
diff --git a/src/common-ssh/ssh.c b/src/common-ssh/ssh.c
index 5ea6fea..5099de2 100644
--- a/src/common-ssh/ssh.c
+++ b/src/common-ssh/ssh.c
@@ -35,6 +35,7 @@
 #include <netdb.h>
 #include <netinet/in.h>
 #include <pthread.h>
+#include <pwd.h>
 #include <stddef.h>
 #include <stdlib.h>
 #include <string.h>
@@ -509,6 +510,47 @@ guac_common_ssh_session* 
guac_common_ssh_create_session(guac_client* client,
         return NULL;
     }
 
+    /* Check known_hosts */
+    size_t len;
+    int type;
+    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.");
+        }
+
+
+    }
+
     /* Perform handshake */
     if (libssh2_session_handshake(session, fd)) {
         guac_client_abort(client, GUAC_PROTOCOL_STATUS_UPSTREAM_ERROR,

Reply via email to