wget: run s_client helper with -servername HOST
This is necessary for multi-hosted TLSed web sites. function old new delta spawn_https_helper_openssl 334 441 +107 Based on a patch by Jeremy Chadwick <jdc@koitsu.org> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
9d20297ba8
commit
ed72761843
@ -62,9 +62,10 @@
|
|||||||
//config: a helper program to talk over HTTPS.
|
//config: a helper program to talk over HTTPS.
|
||||||
//config:
|
//config:
|
||||||
//config: OpenSSL has a simple SSL client for debug purposes.
|
//config: OpenSSL has a simple SSL client for debug purposes.
|
||||||
//config: If you select "openssl" helper, wget will effectively call
|
//config: If you select "openssl" helper, wget will effectively run:
|
||||||
//config: "openssl s_client -quiet -connect IP:443 2>/dev/null"
|
//config: "openssl s_client -quiet -connect hostname:443
|
||||||
//config: and pipe its data through it.
|
//config: -servername hostname 2>/dev/null" and pipe its data
|
||||||
|
//config: through it. -servername is not used if hostname is numeric.
|
||||||
//config: Note inconvenient API: host resolution is done twice,
|
//config: Note inconvenient API: host resolution is done twice,
|
||||||
//config: and there is no guarantee openssl's idea of IPv6 address
|
//config: and there is no guarantee openssl's idea of IPv6 address
|
||||||
//config: format is the same as ours.
|
//config: format is the same as ours.
|
||||||
@ -349,6 +350,30 @@ static void set_alarm(void)
|
|||||||
# define clear_alarm() ((void)0)
|
# define clear_alarm() ((void)0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if ENABLE_FEATURE_WGET_OPENSSL
|
||||||
|
/*
|
||||||
|
* is_ip_address() attempts to verify whether or not a string
|
||||||
|
* contains an IPv4 or IPv6 address (vs. an FQDN). The result
|
||||||
|
* of inet_pton() can be used to determine this.
|
||||||
|
*
|
||||||
|
* TODO add proper error checking when inet_pton() returns -1
|
||||||
|
* (some form of system error has occurred, and errno is set)
|
||||||
|
*/
|
||||||
|
static int is_ip_address(const char *string)
|
||||||
|
{
|
||||||
|
struct sockaddr_in sa;
|
||||||
|
|
||||||
|
int result = inet_pton(AF_INET, string, &(sa.sin_addr));
|
||||||
|
# if ENABLE_FEATURE_IPV6
|
||||||
|
if (result == 0) {
|
||||||
|
struct sockaddr_in6 sa6;
|
||||||
|
result = inet_pton(AF_INET6, string, &(sa6.sin6_addr));
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
return (result == 1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static FILE *open_socket(len_and_sockaddr *lsa)
|
static FILE *open_socket(len_and_sockaddr *lsa)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
@ -629,6 +654,7 @@ static FILE* prepare_ftp_session(FILE **dfpp, struct host_info *target, len_and_
|
|||||||
static int spawn_https_helper_openssl(const char *host, unsigned port)
|
static int spawn_https_helper_openssl(const char *host, unsigned port)
|
||||||
{
|
{
|
||||||
char *allocated = NULL;
|
char *allocated = NULL;
|
||||||
|
char *servername;
|
||||||
int sp[2];
|
int sp[2];
|
||||||
int pid;
|
int pid;
|
||||||
IF_FEATURE_WGET_SSL_HELPER(volatile int child_failed = 0;)
|
IF_FEATURE_WGET_SSL_HELPER(volatile int child_failed = 0;)
|
||||||
@ -639,12 +665,14 @@ static int spawn_https_helper_openssl(const char *host, unsigned port)
|
|||||||
|
|
||||||
if (!strchr(host, ':'))
|
if (!strchr(host, ':'))
|
||||||
host = allocated = xasprintf("%s:%u", host, port);
|
host = allocated = xasprintf("%s:%u", host, port);
|
||||||
|
servername = xstrdup(host);
|
||||||
|
strrchr(servername, ':')[0] = '\0';
|
||||||
|
|
||||||
fflush_all();
|
fflush_all();
|
||||||
pid = xvfork();
|
pid = xvfork();
|
||||||
if (pid == 0) {
|
if (pid == 0) {
|
||||||
/* Child */
|
/* Child */
|
||||||
char *argv[6];
|
char *argv[8];
|
||||||
|
|
||||||
close(sp[0]);
|
close(sp[0]);
|
||||||
xmove_fd(sp[1], 0);
|
xmove_fd(sp[1], 0);
|
||||||
@ -656,12 +684,22 @@ static int spawn_https_helper_openssl(const char *host, unsigned port)
|
|||||||
*/
|
*/
|
||||||
xmove_fd(2, 3);
|
xmove_fd(2, 3);
|
||||||
xopen("/dev/null", O_RDWR);
|
xopen("/dev/null", O_RDWR);
|
||||||
|
memset(&argv, 0, sizeof(argv));
|
||||||
argv[0] = (char*)"openssl";
|
argv[0] = (char*)"openssl";
|
||||||
argv[1] = (char*)"s_client";
|
argv[1] = (char*)"s_client";
|
||||||
argv[2] = (char*)"-quiet";
|
argv[2] = (char*)"-quiet";
|
||||||
argv[3] = (char*)"-connect";
|
argv[3] = (char*)"-connect";
|
||||||
argv[4] = (char*)host;
|
argv[4] = (char*)host;
|
||||||
argv[5] = NULL;
|
/*
|
||||||
|
* Per RFC 6066 Section 3, the only permitted values in the
|
||||||
|
* TLS server_name (SNI) field are FQDNs (DNS hostnames).
|
||||||
|
* IPv4 and IPv6 addresses, port numbers are not allowed.
|
||||||
|
*/
|
||||||
|
if (!is_ip_address(servername)) {
|
||||||
|
argv[5] = (char*)"-servername";
|
||||||
|
argv[6] = (char*)servername;
|
||||||
|
}
|
||||||
|
|
||||||
BB_EXECVP(argv[0], argv);
|
BB_EXECVP(argv[0], argv);
|
||||||
xmove_fd(3, 2);
|
xmove_fd(3, 2);
|
||||||
# if ENABLE_FEATURE_WGET_SSL_HELPER
|
# if ENABLE_FEATURE_WGET_SSL_HELPER
|
||||||
@ -674,6 +712,7 @@ static int spawn_https_helper_openssl(const char *host, unsigned port)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Parent */
|
/* Parent */
|
||||||
|
free(servername);
|
||||||
free(allocated);
|
free(allocated);
|
||||||
close(sp[1]);
|
close(sp[1]);
|
||||||
# if ENABLE_FEATURE_WGET_SSL_HELPER
|
# if ENABLE_FEATURE_WGET_SSL_HELPER
|
||||||
|
Loading…
x
Reference in New Issue
Block a user