]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
sftp: add the option CURLKHSTAT_FINE_REPLACE
authorMichael Musset <mickamusset@gmail.com>
Wed, 15 Jul 2020 14:39:40 +0000 (16:39 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Mon, 24 Aug 2020 15:26:08 +0000 (17:26 +0200)
Replace the old fingerprint of the host with a new.

Closes #5685

docs/libcurl/opts/CURLOPT_SSH_KEYFUNCTION.3
docs/libcurl/symbols-in-versions
include/curl/curl.h
lib/vssh/libssh2.c

index 895bc3687cd6c3a6c4feb08b186283df541be6dc..233221f796c77d9d14115992e9c595042e43fca1 100644 (file)
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
@@ -35,6 +35,7 @@ enum curl_khstat {
                         now so this causes a CURLE_DEFER error but
                         otherwise the connection will be left intact
                         etc */
+  CURLKHSTAT_FINE_REPLACE
 };
 
 enum curl_khmatch {
@@ -72,7 +73,13 @@ known_hosts file \fIknownkey\fP, the key from the remote site \fIfoundkey\fP,
 info from libcurl on the matching status and a custom pointer (set with
 \fICURLOPT_SSH_KEYDATA(3)\fP). It MUST return one of the following return
 codes to tell libcurl how to act:
-
+.IP CURLKHSTAT_FINE_REPLACE
+The new host+key is accepted and libcurl will replace the old host+key into
+the known_hosts file before continuing with the connection.  This will also
+add the new host+key combo to the known_host pool kept in memory if it wasn't
+already present there. The adding of data to the file is done by completely
+replacing the file with a new copy, so the permissions of the file must allow
+this. (Added in 7.73.0)
 .IP CURLKHSTAT_FINE_ADD_TO_FILE
 The host+key is accepted and libcurl will append it to the known_hosts file
 before continuing with the connection. This will also add the host+key combo
index 797e8ab3328823b006ffc7256179911a0150cca9..0e2faacec9e7cf98fdfad3a45960ffdfaa3778c1 100644 (file)
@@ -311,6 +311,7 @@ CURLKHMATCH_OK                  7.19.6
 CURLKHSTAT_DEFER                7.19.6
 CURLKHSTAT_FINE                 7.19.6
 CURLKHSTAT_FINE_ADD_TO_FILE     7.19.6
+CURLKHSTAT_FINE_REPLACE         7.73.0
 CURLKHSTAT_REJECT               7.19.6
 CURLKHTYPE_DSS                  7.19.6
 CURLKHTYPE_ECDSA                7.58.0
index f4d5bf645d1e01e8e0ea45d481d5bbfe32a065f9..2366ef3c724681fec88ddcd397ea634419211502 100644 (file)
@@ -832,6 +832,7 @@ enum curl_khstat {
   CURLKHSTAT_DEFER,  /* do not accept it, but we can't answer right now so
                         this causes a CURLE_DEFER error but otherwise the
                         connection will be left intact etc */
+  CURLKHSTAT_FINE_REPLACE, /* accept and replace the wrong key*/
   CURLKHSTAT_LAST    /* not for use, only a marker for last-in-list */
 };
 
index dc4db6f2ee3b23337a955efd16bba9bf9ffb8fdd..968bc1e20fc388590dd2793a430c3e74a4fa7e19 100644 (file)
@@ -442,6 +442,7 @@ static CURLcode ssh_knownhost(struct connectdata *conn)
   if(data->set.str[STRING_SSH_KNOWNHOSTS]) {
     /* we're asked to verify the host against a file */
     struct ssh_conn *sshc = &conn->proto.sshc;
+    struct libssh2_knownhost *host = NULL;
     int rc;
     int keytype;
     size_t keylen;
@@ -456,7 +457,6 @@ static CURLcode ssh_knownhost(struct connectdata *conn)
        * What host name does OpenSSH store in its file if an IDN name is
        * used?
        */
-      struct libssh2_knownhost *host;
       enum curl_khmatch keymatch;
       curl_sshkeycallback func =
         data->set.ssh_keyfunc?data->set.ssh_keyfunc:sshkeycallback;
@@ -568,7 +568,13 @@ static CURLcode ssh_knownhost(struct connectdata *conn)
       /* DEFER means bail out but keep the SSH_HOSTKEY state */
       result = sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
       break;
+    case CURLKHSTAT_FINE_REPLACE:
+      /* remove old host+key that doesn't match */
+      if(host)
+        libssh2_knownhost_del(sshc->kh, host);
+        /*FALLTHROUGH*/
     case CURLKHSTAT_FINE:
+        /*FALLTHROUGH*/
     case CURLKHSTAT_FINE_ADD_TO_FILE:
       /* proceed */
       if(keycheck != LIBSSH2_KNOWNHOST_CHECK_MATCH) {
@@ -583,7 +589,8 @@ static CURLcode ssh_knownhost(struct connectdata *conn)
         if(addrc)
           infof(data, "Warning adding the known host %s failed!\n",
                 conn->host.name);
-        else if(rc == CURLKHSTAT_FINE_ADD_TO_FILE) {
+        else if(rc == CURLKHSTAT_FINE_ADD_TO_FILE ||
+                rc == CURLKHSTAT_FINE_REPLACE) {
           /* now we write the entire in-memory list of known hosts to the
              known_hosts file */
           int wrc =