gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[gnurl] 169/282: libssh: improve known hosts handling


From: gnunet
Subject: [gnurl] 169/282: libssh: improve known hosts handling
Date: Wed, 01 Apr 2020 14:30:34 +0200

This is an automated email from the git hooks/post-receive script.

ng0 pushed a commit to branch master
in repository gnurl.

commit 507cf6a13db0375eadd4655b4c64710db29e9cf2
Author: Anderson Toshiyuki Sasaki <address@hidden>
AuthorDate: Fri Feb 21 11:09:26 2020 +0100

    libssh: improve known hosts handling
    
    Previously, it was not possible to get a known hosts file entry due to
    the lack of an API.  ssh_session_get_known_hosts_entry(), introduced in
    libssh-0.9.0, allows libcurl to obtain such information and behave the
    same as when compiled with libssh2.
    
    This also tries to avoid the usage of deprecated functions when the
    replacements are available.  The behaviour will not change if versions
    older than libssh-0.8.0 are used.
    
    Signed-off-by: Anderson Toshiyuki Sasaki <address@hidden>
    
    Fixes #4953
    Closes #4962
---
 lib/vssh/libssh.c | 98 +++++++++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 92 insertions(+), 6 deletions(-)

diff --git a/lib/vssh/libssh.c b/lib/vssh/libssh.c
index f66db318d..647b4d491 100644
--- a/lib/vssh/libssh.c
+++ b/lib/vssh/libssh.c
@@ -322,14 +322,25 @@ static int myssh_is_known(struct connectdata *conn)
   ssh_key pubkey;
   size_t hlen;
   unsigned char *hash = NULL;
-  char *base64 = NULL;
+  char *found_base64 = NULL;
+  char *known_base64 = NULL;
   int vstate;
   enum curl_khmatch keymatch;
   struct curl_khkey foundkey;
+  struct curl_khkey *knownkeyp = NULL;
   curl_sshkeycallback func =
     data->set.ssh_keyfunc;
 
+#if LIBSSH_VERSION_INT >= SSH_VERSION_INT(0,9,0)
+  struct ssh_knownhosts_entry *knownhostsentry = NULL;
+  struct curl_khkey knownkey;
+#endif
+
+#if LIBSSH_VERSION_INT >= SSH_VERSION_INT(0,8,0)
+  rc = ssh_get_server_publickey(sshc->ssh_session, &pubkey);
+#else
   rc = ssh_get_publickey(sshc->ssh_session, &pubkey);
+#endif
   if(rc != SSH_OK)
     return rc;
 
@@ -354,6 +365,65 @@ static int myssh_is_known(struct connectdata *conn)
     goto cleanup;
   }
 
+#if LIBSSH_VERSION_INT >= SSH_VERSION_INT(0,9,0)
+  /* Get the known_key from the known hosts file */
+  vstate = ssh_session_get_known_hosts_entry(sshc->ssh_session,
+                                             &knownhostsentry);
+
+  /* Case an entry was found in a known hosts file */
+  if(knownhostsentry) {
+    if(knownhostsentry->publickey) {
+      rc = ssh_pki_export_pubkey_base64(knownhostsentry->publickey,
+                                        &known_base64);
+      if(rc != SSH_OK) {
+        goto cleanup;
+      }
+      knownkey.key = known_base64;
+      knownkey.len = strlen(known_base64);
+
+      switch(ssh_key_type(knownhostsentry->publickey)) {
+        case SSH_KEYTYPE_RSA:
+          knownkey.keytype = CURLKHTYPE_RSA;
+          break;
+        case SSH_KEYTYPE_RSA1:
+          knownkey.keytype = CURLKHTYPE_RSA1;
+          break;
+        case SSH_KEYTYPE_ECDSA:
+          knownkey.keytype = CURLKHTYPE_ECDSA;
+          break;
+        case SSH_KEYTYPE_ED25519:
+          knownkey.keytype = CURLKHTYPE_ED25519;
+          break;
+        case SSH_KEYTYPE_DSS:
+          knownkey.keytype = CURLKHTYPE_DSS;
+          break;
+        default:
+          rc = SSH_ERROR;
+          goto cleanup;
+      }
+      knownkeyp = &knownkey;
+    }
+  }
+
+  switch(vstate) {
+    case SSH_KNOWN_HOSTS_OK:
+      keymatch = CURLKHMATCH_OK;
+      break;
+    case SSH_KNOWN_HOSTS_OTHER:
+      /* fallthrough */
+    case SSH_KNOWN_HOSTS_NOT_FOUND:
+      /* fallthrough */
+    case SSH_KNOWN_HOSTS_UNKNOWN:
+      /* fallthrough */
+    case SSH_KNOWN_HOSTS_ERROR:
+      keymatch = CURLKHMATCH_MISSING;
+      break;
+  default:
+      keymatch = CURLKHMATCH_MISMATCH;
+      break;
+  }
+
+#else
   vstate = ssh_is_server_known(sshc->ssh_session);
   switch(vstate) {
     case SSH_SERVER_KNOWN_OK:
@@ -368,14 +438,15 @@ static int myssh_is_known(struct connectdata *conn)
       keymatch = CURLKHMATCH_MISMATCH;
       break;
   }
+#endif
 
   if(func) { /* use callback to determine action */
-    rc = ssh_pki_export_pubkey_base64(pubkey, &base64);
+    rc = ssh_pki_export_pubkey_base64(pubkey, &found_base64);
     if(rc != SSH_OK)
       goto cleanup;
 
-    foundkey.key = base64;
-    foundkey.len = strlen(base64);
+    foundkey.key = found_base64;
+    foundkey.len = strlen(found_base64);
 
     switch(ssh_key_type(pubkey)) {
       case SSH_KEYTYPE_RSA:
@@ -400,15 +471,19 @@ static int myssh_is_known(struct connectdata *conn)
         goto cleanup;
     }
 
-    /* we don't have anything equivalent to knownkey. Always NULL */
     Curl_set_in_callback(data, true);
-    rc = func(data, NULL, &foundkey, /* from the remote host */
+    rc = func(data, knownkeyp, /* from the knownhosts file */
+              &foundkey, /* from the remote host */
               keymatch, data->set.ssh_keyfunc_userp);
     Curl_set_in_callback(data, false);
 
     switch(rc) {
       case CURLKHSTAT_FINE_ADD_TO_FILE:
+#if LIBSSH_VERSION_INT >= SSH_VERSION_INT(0,8,0)
+        rc = ssh_session_update_known_hosts(sshc->ssh_session);
+#else
         rc = ssh_write_knownhost(sshc->ssh_session);
+#endif
         if(rc != SSH_OK) {
           goto cleanup;
         }
@@ -429,9 +504,20 @@ static int myssh_is_known(struct connectdata *conn)
   rc = SSH_OK;
 
 cleanup:
+  if(found_base64) {
+    free(found_base64);
+  }
+  if(known_base64) {
+    free(known_base64);
+  }
   if(hash)
     ssh_clean_pubkey_hash(&hash);
   ssh_key_free(pubkey);
+#if LIBSSH_VERSION_INT >= SSH_VERSION_INT(0,9,0)
+  if(knownhostsentry) {
+    ssh_knownhosts_entry_free(knownhostsentry);
+  }
+#endif
   return rc;
 }
 

-- 
To stop receiving notification emails like this one, please contact
address@hidden.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]