From: Daniel Stenberg Date: Sat, 22 Feb 2025 12:05:17 +0000 (+0100) Subject: tool_operate: fail SSH transfers without server auth X-Git-Tag: curl-8_13_0~379 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=e1b3d46944890cd2c1e3eef8d75d292ab0411e35;p=thirdparty%2Fcurl.git tool_operate: fail SSH transfers without server auth This now insists on using a server auth option unless --insecure is provided. As an added bonus, it now also only checks for the knownhosts file once (if found). Ref: #16197 Closes #16205 --- diff --git a/src/tool_cfgable.h b/src/tool_cfgable.h index abc2d3f602..11f14d7715 100644 --- a/src/tool_cfgable.h +++ b/src/tool_cfgable.h @@ -324,6 +324,8 @@ struct GlobalConfig { char *libcurl; /* Output libcurl code to this filename */ char *ssl_sessions; /* file to load/save SSL session tickets */ char *help_category; /* The help category, if set */ + char *knownhosts; /* known host path, if set. curl_free() + this */ struct tool_var *variables; struct OperationConfig *first; struct OperationConfig *current; diff --git a/src/tool_operate.c b/src/tool_operate.c index 3417750531..95ce8a4234 100644 --- a/src/tool_operate.c +++ b/src/tool_operate.c @@ -1156,16 +1156,24 @@ static CURLcode config2setopts(struct GlobalConfig *global, my_setopt(curl, CURLOPT_SSH_COMPRESSION, 1L); if(!config->insecure_ok) { - char *known = findfile(".ssh/known_hosts", FALSE); + char *known = global->knownhosts; + + if(!known) + known = findfile(".ssh/known_hosts", FALSE); if(known) { /* new in curl 7.19.6 */ result = res_setopt_str(curl, CURLOPT_SSH_KNOWNHOSTS, known); - curl_free(known); - if(result == CURLE_UNKNOWN_OPTION) - /* libssh2 version older than 1.1.1 */ - result = CURLE_OK; - if(result) + if(result) { + global->knownhosts = NULL; + curl_free(known); return result; + } + /* store it in global to avoid repeated checks */ + global->knownhosts = known; + } + else if(!config->hostpubmd5 && !config->hostpubsha256) { + errorf(global, "Couldn't find a known_hosts file"); + return CURLE_FAILED_INIT; } else warnf(global, "Couldn't find a known_hosts file"); @@ -3266,6 +3274,7 @@ CURLcode operate(struct GlobalConfig *global, int argc, argv_item_t argv[]) } varcleanup(global); + curl_free(global->knownhosts); return result; } diff --git a/tests/data/test445 b/tests/data/test445 index dbdcfe6ba4..4e12367d83 100644 --- a/tests/data/test445 +++ b/tests/data/test445 @@ -46,7 +46,7 @@ http-proxy Refuse tunneling protocols through HTTP proxy --x http://%HOSTIP:%PROXYPORT/%TESTNUMBER -p gopher://127.0.0.1 dict://127.0.0.1 http://moo https://example telnet://another ftp://yes ftps://again imap://more ldap://perhaps mqtt://yes pop3://mail rtsp://harder scp://copy sftp://files smb://wird smtp://send +-x http://%HOSTIP:%PROXYPORT/%TESTNUMBER -p gopher://127.0.0.1 dict://127.0.0.1 http://moo https://example telnet://another ftp://yes ftps://again imap://more ldap://perhaps mqtt://yes pop3://mail rtsp://harder scp://copy sftp://files smb://wird smtp://send -k