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;