From 18270893abdb19f0ca170c118f8a2847dbd304be Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sun, 21 Nov 2021 15:52:58 +0100 Subject: tool_operate: only set SSH related libcurl options for SSH URLs For example, this avoids trying to find and set the known_hosts file (or warn for its absence) if SFTP or SCP are not used. Closes #8040 --- src/tool_libinfo.c | 79 +++++++++++++++++++++++++++++++----------------------- src/tool_libinfo.h | 3 ++- src/tool_operate.c | 37 +++++++++++++++++++++++-- 3 files changed, 83 insertions(+), 36 deletions(-) diff --git a/src/tool_libinfo.c b/src/tool_libinfo.c index 58088eab0..ef53fce34 100644 --- a/src/tool_libinfo.c +++ b/src/tool_libinfo.c @@ -36,6 +36,39 @@ curl_version_info_data *curlinfo = NULL; long built_in_protos = 0; +static struct proto_name_pattern { + const char *proto_name; + long proto_pattern; +} const possibly_built_in[] = { + { "dict", CURLPROTO_DICT }, + { "file", CURLPROTO_FILE }, + { "ftp", CURLPROTO_FTP }, + { "ftps", CURLPROTO_FTPS }, + { "gopher", CURLPROTO_GOPHER }, + { "gophers",CURLPROTO_GOPHERS}, + { "http", CURLPROTO_HTTP }, + { "https", CURLPROTO_HTTPS }, + { "imap", CURLPROTO_IMAP }, + { "imaps", CURLPROTO_IMAPS }, + { "ldap", CURLPROTO_LDAP }, + { "ldaps", CURLPROTO_LDAPS }, + { "mqtt", CURLPROTO_MQTT }, + { "pop3", CURLPROTO_POP3 }, + { "pop3s", CURLPROTO_POP3S }, + { "rtmp", CURLPROTO_RTMP }, + { "rtmps", CURLPROTO_RTMPS }, + { "rtsp", CURLPROTO_RTSP }, + { "scp", CURLPROTO_SCP }, + { "sftp", CURLPROTO_SFTP }, + { "smb", CURLPROTO_SMB }, + { "smbs", CURLPROTO_SMBS }, + { "smtp", CURLPROTO_SMTP }, + { "smtps", CURLPROTO_SMTPS }, + { "telnet", CURLPROTO_TELNET }, + { "tftp", CURLPROTO_TFTP }, + { NULL, 0 } +}; + /* * libcurl_info_init: retrieves run-time information about libcurl, * setting a global pointer 'curlinfo' to libcurl's run-time info @@ -46,39 +79,6 @@ long built_in_protos = 0; CURLcode get_libcurl_info(void) { - static struct proto_name_pattern { - const char *proto_name; - long proto_pattern; - } const possibly_built_in[] = { - { "dict", CURLPROTO_DICT }, - { "file", CURLPROTO_FILE }, - { "ftp", CURLPROTO_FTP }, - { "ftps", CURLPROTO_FTPS }, - { "gopher", CURLPROTO_GOPHER }, - { "gophers",CURLPROTO_GOPHERS}, - { "http", CURLPROTO_HTTP }, - { "https", CURLPROTO_HTTPS }, - { "imap", CURLPROTO_IMAP }, - { "imaps", CURLPROTO_IMAPS }, - { "ldap", CURLPROTO_LDAP }, - { "ldaps", CURLPROTO_LDAPS }, - { "mqtt", CURLPROTO_MQTT }, - { "pop3", CURLPROTO_POP3 }, - { "pop3s", CURLPROTO_POP3S }, - { "rtmp", CURLPROTO_RTMP }, - { "rtmps", CURLPROTO_RTMPS }, - { "rtsp", CURLPROTO_RTSP }, - { "scp", CURLPROTO_SCP }, - { "sftp", CURLPROTO_SFTP }, - { "smb", CURLPROTO_SMB }, - { "smbs", CURLPROTO_SMBS }, - { "smtp", CURLPROTO_SMTP }, - { "smtps", CURLPROTO_SMTPS }, - { "telnet", CURLPROTO_TELNET }, - { "tftp", CURLPROTO_TFTP }, - { NULL, 0 } - }; - const char *const *proto; /* Pointer to libcurl's run-time version information */ @@ -102,3 +102,16 @@ CURLcode get_libcurl_info(void) return CURLE_OK; } + +/* + * scheme2protocol() returns the protocol bit for the specified URL scheme + */ +long scheme2protocol(const char *scheme) +{ + struct proto_name_pattern const *p; + for(p = possibly_built_in; p->proto_name; p++) { + if(curl_strequal(scheme, p->proto_name)) + return p->proto_pattern; + } + return 0; +} diff --git a/src/tool_libinfo.h b/src/tool_libinfo.h index 9479e3c0d..823ced733 100644 --- a/src/tool_libinfo.h +++ b/src/tool_libinfo.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2020, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2021, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -29,5 +29,6 @@ extern curl_version_info_data *curlinfo; extern long built_in_protos; CURLcode get_libcurl_info(void); +long scheme2protocol(const char *scheme); #endif /* HEADER_CURL_TOOL_LIBINFO_H */ diff --git a/src/tool_operate.c b/src/tool_operate.c index bbf743dab..b9183c22a 100644 --- a/src/tool_operate.c +++ b/src/tool_operate.c @@ -661,6 +661,29 @@ static void single_transfer_cleanup(struct OperationConfig *config) } } +/* + * Return the proto bit for the scheme used in the given URL + */ +static long url_proto(char *url) +{ + CURLU *uh = curl_url(); + long proto = 0; + if(url) { + if(!curl_url_set(uh, CURLUPART_URL, url, + CURLU_GUESS_SCHEME | CURLU_NON_SUPPORT_SCHEME)) { + char *schemep = NULL; + if(!curl_url_get(uh, CURLUPART_SCHEME, &schemep, + CURLU_DEFAULT_SCHEME) && + schemep) { + proto = scheme2protocol(schemep); + curl_free(schemep); + } + } + curl_url_cleanup(uh); + } + return proto; +} + /* create the next (singular) transfer */ static CURLcode single_transfer(struct GlobalConfig *global, @@ -801,6 +824,7 @@ static CURLcode single_transfer(struct GlobalConfig *global, struct OutStruct *etag_save; struct HdrCbData *hdrcbdata = NULL; struct OutStruct etag_first; + long use_proto; CURL *curl; /* --etag-save */ @@ -1194,6 +1218,15 @@ static CURLcode single_transfer(struct GlobalConfig *global, if(result) break; + /* here */ + use_proto = url_proto(per->this_url); +#if 0 + if(!(use_proto & built_in_protos)) { + warnf(global, "URL is '%s' but no support for the scheme\n", + per->this_url); + } +#endif + if(!config->tcp_nodelay) my_setopt(curl, CURLOPT_TCP_NODELAY, 0L); @@ -1410,7 +1443,7 @@ static CURLcode single_transfer(struct GlobalConfig *global, my_setopt_str(curl, CURLOPT_KEYPASSWD, config->key_passwd); my_setopt_str(curl, CURLOPT_PROXY_KEYPASSWD, config->proxy_key_passwd); - if(built_in_protos & (CURLPROTO_SCP|CURLPROTO_SFTP)) { + if(use_proto & (CURLPROTO_SCP|CURLPROTO_SFTP)) { /* SSH and SSL private key uses same command-line option */ /* new in libcurl 7.16.1 */ @@ -1681,7 +1714,7 @@ static CURLcode single_transfer(struct GlobalConfig *global, if(config->path_as_is) my_setopt(curl, CURLOPT_PATH_AS_IS, 1L); - if((built_in_protos & (CURLPROTO_SCP|CURLPROTO_SFTP)) && + if((use_proto & (CURLPROTO_SCP|CURLPROTO_SFTP)) && !config->insecure_ok) { char *home = homedir(NULL); if(home) { -- cgit v1.2.1