summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2021-11-21 15:52:58 +0100
committerDaniel Stenberg <daniel@haxx.se>2021-11-21 23:12:48 +0100
commit18270893abdb19f0ca170c118f8a2847dbd304be (patch)
treec1e6f43db34a089ec7ea4a476c3635b519d5d890
parent3f8fde366f7655079ff97bd267226f3f7c091844 (diff)
downloadcurl-18270893abdb19f0ca170c118f8a2847dbd304be.tar.gz
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
-rw-r--r--src/tool_libinfo.c79
-rw-r--r--src/tool_libinfo.h3
-rw-r--r--src/tool_operate.c37
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, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2021, 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
@@ -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) {