[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[gnurl] 21/282: libssh2: add support for forcing a hostkey type
From: |
gnunet |
Subject: |
[gnurl] 21/282: libssh2: add support for forcing a hostkey type |
Date: |
Wed, 01 Apr 2020 14:28:06 +0200 |
This is an automated email from the git hooks/post-receive script.
ng0 pushed a commit to branch master
in repository gnurl.
commit 272282a05416e42d2cc4a847a31fd457bc6cc827
Author: Santino Keupp <address@hidden>
AuthorDate: Fri Dec 20 13:37:20 2019 +0100
libssh2: add support for forcing a hostkey type
- Allow forcing the host's key type found in the known_hosts file.
Currently, curl (with libssh2) does not take keys from your known_hosts
file into account when talking to a server. With this patch the
known_hosts file will be searched for an entry matching the hostname
and, if found, libssh2 will be told to claim this key type from the
server.
Closes https://github.com/curl/curl/pull/4747
---
lib/vssh/libssh2.c | 130 +++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 130 insertions(+)
diff --git a/lib/vssh/libssh2.c b/lib/vssh/libssh2.c
index 063f3d2ae..adac93047 100644
--- a/lib/vssh/libssh2.c
+++ b/lib/vssh/libssh2.c
@@ -106,6 +106,7 @@ static LIBSSH2_ALLOC_FUNC(my_libssh2_malloc);
static LIBSSH2_REALLOC_FUNC(my_libssh2_realloc);
static LIBSSH2_FREE_FUNC(my_libssh2_free);
+static CURLcode ssh_force_knownhost_key_type(struct connectdata *conn);
static CURLcode ssh_connect(struct connectdata *conn, bool *done);
static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done);
static CURLcode ssh_do(struct connectdata *conn, bool *done);
@@ -648,6 +649,129 @@ static CURLcode ssh_check_fingerprint(struct connectdata
*conn)
return ssh_knownhost(conn);
}
+/*
+ * ssh_force_knownhost_key_type() will check the known hosts file and try to
+ * force a specific public key type from the server if an entry is found.
+ */
+static CURLcode ssh_force_knownhost_key_type(struct connectdata *conn)
+{
+ CURLcode result = CURLE_OK;
+
+#ifdef HAVE_LIBSSH2_KNOWNHOST_API
+
+#ifdef LIBSSH2_KNOWNHOST_KEY_ED25519
+ static const char * const hostkey_method_ssh_ed25519
+ = "ssh-ed25519";
+#endif
+#ifdef LIBSSH2_KNOWNHOST_KEY_ECDSA_521
+ static const char * const hostkey_method_ssh_ecdsa_521
+ = "ecdsa-sha2-nistp521";
+#endif
+#ifdef LIBSSH2_KNOWNHOST_KEY_ECDSA_384
+ static const char * const hostkey_method_ssh_ecdsa_384
+ = "ecdsa-sha2-nistp384";
+#endif
+#ifdef LIBSSH2_KNOWNHOST_KEY_ECDSA_256
+ static const char * const hostkey_method_ssh_ecdsa_256
+ = "ecdsa-sha2-nistp256";
+#endif
+ static const char * const hostkey_method_ssh_rsa
+ = "ssh-rsa";
+ static const char * const hostkey_method_ssh_dss
+ = "ssh-dss";
+
+ const char *hostkey_method = NULL;
+ struct ssh_conn *sshc = &conn->proto.sshc;
+ struct Curl_easy *data = conn->data;
+ struct libssh2_knownhost* store = NULL;
+ const char *kh_name_end = NULL;
+ long unsigned int kh_name_size = 0;
+ int port = 0;
+ bool found = false;
+
+ if(sshc->kh && !data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]) {
+ /* lets try to find our host in the known hosts file */
+ while(!libssh2_knownhost_get(sshc->kh, &store, store)) {
+ /* For non-standard ports, the name will be enclosed in */
+ /* square brackets, followed by a colon and the port */
+ if(store->name[0] == '[') {
+ kh_name_end = strstr(store->name, "]:");
+ if(!kh_name_end) {
+ infof(data, "Invalid host pattern %s in %s\n",
+ store->name, data->set.str[STRING_SSH_KNOWNHOSTS]);
+ continue;
+ }
+ port = atoi(kh_name_end + 2);
+ if(kh_name_end && (port == conn->remote_port)) {
+ kh_name_size = strlen(store->name) - 1 - strlen(kh_name_end);
+ if(strncmp(store->name + 1, conn->host.name, kh_name_size) == 0) {
+ found = true;
+ break;
+ }
+ }
+ }
+ else if(strcmp(store->name, conn->host.name) == 0) {
+ found = true;
+ break;
+ }
+ }
+
+ if(found) {
+ infof(data, "Found host %s in %s\n",
+ store->name, data->set.str[STRING_SSH_KNOWNHOSTS]);
+
+ switch(store->typemask & LIBSSH2_KNOWNHOST_KEY_MASK) {
+#ifdef LIBSSH2_KNOWNHOST_KEY_ED25519
+ case LIBSSH2_KNOWNHOST_KEY_ED25519:
+ hostkey_method = hostkey_method_ssh_ed25519;
+ break;
+#endif
+#ifdef LIBSSH2_KNOWNHOST_KEY_ECDSA_521
+ case LIBSSH2_KNOWNHOST_KEY_ECDSA_521:
+ hostkey_method = hostkey_method_ssh_ecdsa_521;
+ break;
+#endif
+#ifdef LIBSSH2_KNOWNHOST_KEY_ECDSA_384
+ case LIBSSH2_KNOWNHOST_KEY_ECDSA_384:
+ hostkey_method = hostkey_method_ssh_ecdsa_384;
+ break;
+#endif
+#ifdef LIBSSH2_KNOWNHOST_KEY_ECDSA_256
+ case LIBSSH2_KNOWNHOST_KEY_ECDSA_256:
+ hostkey_method = hostkey_method_ssh_ecdsa_256;
+ break;
+#endif
+ case LIBSSH2_KNOWNHOST_KEY_SSHRSA:
+ hostkey_method = hostkey_method_ssh_rsa;
+ break;
+ case LIBSSH2_KNOWNHOST_KEY_SSHDSS:
+ hostkey_method = hostkey_method_ssh_dss;
+ break;
+ case LIBSSH2_KNOWNHOST_KEY_RSA1:
+ failf(data, "Found host key type RSA1 which is not supported\n");
+ return CURLE_SSH;
+ default:
+ failf(data, "Unknown host key type: %i\n",
+ (store->typemask & LIBSSH2_KNOWNHOST_KEY_MASK));
+ return CURLE_SSH;
+ }
+
+ infof(data, "Set \"%s\" as SSH hostkey type\n", hostkey_method);
+ result = libssh2_session_error_to_CURLE(
+ libssh2_session_method_pref(
+ sshc->ssh_session, LIBSSH2_METHOD_HOSTKEY, hostkey_method));
+ }
+ else {
+ infof(data, "Did not find host %s in %s\n",
+ conn->host.name, data->set.str[STRING_SSH_KNOWNHOSTS]);
+ }
+ }
+
+#endif /* HAVE_LIBSSH2_KNOWNHOST_API */
+
+ return result;
+}
+
/*
* ssh_statemach_act() runs the SSH state machine as far as it can without
* blocking and without reaching the end. The data the pointer 'block' points
@@ -680,6 +804,12 @@ static CURLcode ssh_statemach_act(struct connectdata
*conn, bool *block)
non-blocking */
libssh2_session_set_blocking(sshc->ssh_session, 0);
+ result = ssh_force_knownhost_key_type(conn);
+ if(result) {
+ state(conn, SSH_SESSION_FREE);
+ break;
+ }
+
state(conn, SSH_S_STARTUP);
/* FALLTHROUGH */
--
To stop receiving notification emails like this one, please contact
address@hidden.
- [gnurl] 10/282: libtest/mk-lib1521: adapt to new public header layout, (continued)
- [gnurl] 10/282: libtest/mk-lib1521: adapt to new public header layout, gnunet, 2020/04/01
- [gnurl] 06/282: bump: work towards 7.69.0 is started, gnunet, 2020/04/01
- [gnurl] 12/282: scripts/delta: adapt to new public header layout, gnunet, 2020/04/01
- [gnurl] 15/282: vtls: Refactor Curl_multissl_version to make the code clearer, gnunet, 2020/04/01
- [gnurl] 20/282: cmake: Improve libssh2 check on Windows, gnunet, 2020/04/01
- [gnurl] 17/282: multi: Change curl_multi_wait/poll to error on negative timeout, gnunet, 2020/04/01
- [gnurl] 16/282: cmake: Enable SMB for Windows builds, gnunet, 2020/04/01
- [gnurl] 14/282: fix: Copyright year out of date, should be 2020, gnunet, 2020/04/01
- [gnurl] 18/282: ngtcp2: Add an error code for QUIC connection errors, gnunet, 2020/04/01
- [gnurl] 09/282: include: remove non-curl prefixed defines, gnunet, 2020/04/01
- [gnurl] 21/282: libssh2: add support for forcing a hostkey type,
gnunet <=
- [gnurl] 22/282: misc: Copyright year out of date, should be 2020, gnunet, 2020/04/01
- [gnurl] 19/282: schannel: Make CURLOPT_CAINFO work better on Windows 7, gnunet, 2020/04/01
- [gnurl] 23/282: curl: remove 'config' field from OutStruct, gnunet, 2020/04/01
- [gnurl] 13/282: hostip: move code to resolve IP address literals to `Curl_resolv`, gnunet, 2020/04/01
- [gnurl] 11/282: test1167: verify global symbols in public headers are curl prefixed, gnunet, 2020/04/01
- [gnurl] 25/282: curl: make #0 not output the full URL, gnunet, 2020/04/01
- [gnurl] 26/282: ConnectionExists: respect the max_concurrent_streams limits, gnunet, 2020/04/01
- [gnurl] 30/282: schannel_verify: Fix alt names manual verify for UNICODE builds, gnunet, 2020/04/01
- [gnurl] 31/282: CMake: use check_symbol_exists also for inet_pton, gnunet, 2020/04/01
- [gnurl] 39/282: ROADMAP: thread-safe `curl_global_init()`, gnunet, 2020/04/01