]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
tool_getparam: add --knownhosts
authorDaniel Stenberg <daniel@haxx.se>
Sun, 5 Oct 2025 21:19:13 +0000 (23:19 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Sun, 5 Oct 2025 21:21:30 +0000 (23:21 +0200)
To allow users to specify a known hosts file that is not the default
one: ~/.ssh/known_hosts

URL: https://github.com/curl/curl/discussions/18784

docs/cmdline-opts/Makefile.inc
docs/cmdline-opts/knownhosts.md [new file with mode: 0644]
src/config2setopts.c
src/tool_cfgable.c
src/tool_cfgable.h
src/tool_getparam.c
src/tool_getparam.h
src/tool_listhelp.c
src/tool_operate.c

index b8e88421a9a0355cd8def7b0402c12a6153ecbef..f7236af1b12707ac8242cfd30a34bcbf0e9e8b66 100644 (file)
@@ -147,6 +147,7 @@ DPAGES = \
   keepalive-time.md \
   key-type.md \
   key.md \
+  knownhosts.md \
   krb.md \
   libcurl.md \
   limit-rate.md \
diff --git a/docs/cmdline-opts/knownhosts.md b/docs/cmdline-opts/knownhosts.md
new file mode 100644 (file)
index 0000000..96cf3ea
--- /dev/null
@@ -0,0 +1,31 @@
+---
+c: Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
+SPDX-License-Identifier: curl
+Long: knownhosts
+Arg: <file>
+Protocols: SCP SFTP
+Help: Specify knownhosts path
+Category: ssh
+Added: 8.17.0
+Multi: single
+See-also:
+  - hostpubsha256
+  - hostpubmd5
+  - insecure
+  - key
+Example:
+  - --cert certificate --key here $URL
+---
+
+# `--knownhosts`
+
+When doing SCP and SFTP transfers, curl automatically checks a database
+containing identification for all hosts it has ever been used with to verify
+that the host it connects to is the same as previously. Host keys are stored
+in such a knownhosts file. By default curl uses ~/.ssh/known_hosts in the
+user's home directory.
+
+This option lets a user specify a specific file to check the host against.
+
+The known host check can be disabled with --insecure, but that makes the
+transfer insecure.
index 533fe992d34b2d89330ed39a6bdcf11cf7031683..ef08f98ed87823071c827689ac5f5fcceb4202e8 100644 (file)
@@ -192,7 +192,7 @@ static CURLcode ssh_setopts(struct OperationConfig *config, CURL *curl)
     my_setopt_long(curl, CURLOPT_SSH_COMPRESSION, 1);
 
   if(!config->insecure_ok) {
-    char *known = global->knownhosts;
+    char *known = config->knownhosts;
 
     if(!known)
       known = findfile(".ssh/known_hosts", FALSE);
@@ -200,12 +200,12 @@ static CURLcode ssh_setopts(struct OperationConfig *config, CURL *curl)
       /* new in curl 7.19.6 */
       result = my_setopt_str(curl, CURLOPT_SSH_KNOWNHOSTS, known);
       if(result) {
-        global->knownhosts = NULL;
+        config->knownhosts = NULL;
         curl_free(known);
         return result;
       }
       /* store it in global to avoid repeated checks */
-      global->knownhosts = known;
+      config->knownhosts = known;
     }
     else if(!config->hostpubmd5 && !config->hostpubsha256) {
       errorf("Couldn't find a known_hosts file");
index e2df7cf91f02d5955adf5fa7242a96b72626c4c7..48148a88ad5bce13644fb10ce2f98f3650aaaaf5 100644 (file)
@@ -189,6 +189,7 @@ static void free_config_fields(struct OperationConfig *config)
   tool_safefree(config->ech);
   tool_safefree(config->ech_config);
   tool_safefree(config->ech_public);
+  tool_safefree(config->knownhosts);
 }
 
 void config_free(struct OperationConfig *config)
index 3b2ac93a74dec1332877c17453d86fbce8d6e1a7..0f86c000a27e4a8be47e48e65b2b53ffc49fc777 100644 (file)
@@ -112,6 +112,7 @@ struct OperationConfig {
   char *proxyuserpwd;
   char *proxy;
   char *noproxy;
+  char *knownhosts;
   char *mail_from;
   struct curl_slist *mail_rcpt;
   char *mail_auth;
@@ -353,8 +354,6 @@ struct GlobalConfig {
   FILE *trace_stream;
   char *libcurl;                  /* Output libcurl code to this filename */
   char *ssl_sessions;             /* file to load/save SSL session tickets */
-  char *knownhosts;               /* known host path, if set. curl_free()
-                                     this */
   struct tool_var *variables;
   struct OperationConfig *first;
   struct OperationConfig *current;
index 0fdd6373e566c75d00a35c61b32dadaa6d978a63..7b8dec7da529c3ba2a7868f15a0fda12bcf1e8b9 100644 (file)
@@ -196,6 +196,7 @@ static const struct LongShort aliases[]= {
   {"keepalive-time",             ARG_STRG, ' ', C_KEEPALIVE_TIME},
   {"key",                        ARG_FILE, ' ', C_KEY},
   {"key-type",                   ARG_STRG|ARG_TLS, ' ', C_KEY_TYPE},
+  {"knownhosts",                 ARG_FILE, ' ', C_KNOWNHOSTS},
   {"krb",                        ARG_STRG|ARG_DEPR, ' ', C_KRB},
   {"krb4",                       ARG_STRG|ARG_DEPR, ' ', C_KRB4},
   {"libcurl",                    ARG_STRG, ' ', C_LIBCURL},
@@ -2224,6 +2225,9 @@ static ParameterError opt_file(struct OperationConfig *config,
   case C_KEY: /* --key */
     err = getstr(&config->key, nextarg, DENY_BLANK);
     break;
+  case C_KNOWNHOSTS: /* --knownhosts */
+    err = getstr(&config->knownhosts, nextarg, DENY_BLANK);
+    break;
   case C_NETRC_FILE: /* --netrc-file */
     err = getstr(&config->netrc_file, nextarg, DENY_BLANK);
     break;
index a08bbac7b640092231158901309dda18cc3273c2..6b97b9c11f45806f00d11f5d1bf48e9dd0edbcd7 100644 (file)
@@ -139,6 +139,7 @@ typedef enum {
   C_KEEPALIVE_TIME,
   C_KEY,
   C_KEY_TYPE,
+  C_KNOWNHOSTS,
   C_KRB,
   C_KRB4,
   C_LIBCURL,
index bd72dbe15c51c04976e0102e8f6ac305046ed683..c8e31e77a6aed1f6512251b61b89ba67e68b31fc 100644 (file)
@@ -341,6 +341,9 @@ const struct helptxt helptext[] = {
   {"    --key-type <type>",
    "Private key file type (DER/PEM/ENG)",
    CURLHELP_TLS},
+  {"    --knownhosts <file>",
+   "Specify knownhosts path",
+   CURLHELP_SSH},
   {"    --krb <level>",
    "Enable Kerberos with security <level>",
    CURLHELP_DEPRECATED},
index d4a6d4db42512248f85fd13d8f79a7ee24e0832b..0e96ccd85f5bcae01474177081b9b594572e2569 100644 (file)
@@ -2265,7 +2265,6 @@ CURLcode operate(int argc, argv_item_t argv[])
   }
 
   varcleanup();
-  curl_free(global->knownhosts);
 
   return result;
 }