aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2016-07-25 21:34:57 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2016-07-25 21:34:57 +0200
commited72761843945ff7efc5a8ba3095a0f82e8f3e45 (patch)
tree32fa40efe67ab5f6f800ae29c8636d42acd52bba
parent9d20297ba803832d118bd27cd42107371123aa39 (diff)
downloadbusybox-w32-ed72761843945ff7efc5a8ba3095a0f82e8f3e45.tar.gz
busybox-w32-ed72761843945ff7efc5a8ba3095a0f82e8f3e45.tar.bz2
busybox-w32-ed72761843945ff7efc5a8ba3095a0f82e8f3e45.zip
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>
-rw-r--r--networking/wget.c49
1 files changed, 44 insertions, 5 deletions
diff --git a/networking/wget.c b/networking/wget.c
index 37950ed39..653d8076f 100644
--- a/networking/wget.c
+++ b/networking/wget.c
@@ -62,9 +62,10 @@
62//config: a helper program to talk over HTTPS. 62//config: a helper program to talk over HTTPS.
63//config: 63//config:
64//config: OpenSSL has a simple SSL client for debug purposes. 64//config: OpenSSL has a simple SSL client for debug purposes.
65//config: If you select "openssl" helper, wget will effectively call 65//config: If you select "openssl" helper, wget will effectively run:
66//config: "openssl s_client -quiet -connect IP:443 2>/dev/null" 66//config: "openssl s_client -quiet -connect hostname:443
67//config: and pipe its data through it. 67//config: -servername hostname 2>/dev/null" and pipe its data
68//config: through it. -servername is not used if hostname is numeric.
68//config: Note inconvenient API: host resolution is done twice, 69//config: Note inconvenient API: host resolution is done twice,
69//config: and there is no guarantee openssl's idea of IPv6 address 70//config: and there is no guarantee openssl's idea of IPv6 address
70//config: format is the same as ours. 71//config: format is the same as ours.
@@ -349,6 +350,30 @@ static void set_alarm(void)
349# define clear_alarm() ((void)0) 350# define clear_alarm() ((void)0)
350#endif 351#endif
351 352
353#if ENABLE_FEATURE_WGET_OPENSSL
354/*
355 * is_ip_address() attempts to verify whether or not a string
356 * contains an IPv4 or IPv6 address (vs. an FQDN). The result
357 * of inet_pton() can be used to determine this.
358 *
359 * TODO add proper error checking when inet_pton() returns -1
360 * (some form of system error has occurred, and errno is set)
361 */
362static int is_ip_address(const char *string)
363{
364 struct sockaddr_in sa;
365
366 int result = inet_pton(AF_INET, string, &(sa.sin_addr));
367# if ENABLE_FEATURE_IPV6
368 if (result == 0) {
369 struct sockaddr_in6 sa6;
370 result = inet_pton(AF_INET6, string, &(sa6.sin6_addr));
371 }
372# endif
373 return (result == 1);
374}
375#endif
376
352static FILE *open_socket(len_and_sockaddr *lsa) 377static FILE *open_socket(len_and_sockaddr *lsa)
353{ 378{
354 int fd; 379 int fd;
@@ -629,6 +654,7 @@ static FILE* prepare_ftp_session(FILE **dfpp, struct host_info *target, len_and_
629static int spawn_https_helper_openssl(const char *host, unsigned port) 654static int spawn_https_helper_openssl(const char *host, unsigned port)
630{ 655{
631 char *allocated = NULL; 656 char *allocated = NULL;
657 char *servername;
632 int sp[2]; 658 int sp[2];
633 int pid; 659 int pid;
634 IF_FEATURE_WGET_SSL_HELPER(volatile int child_failed = 0;) 660 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)
639 665
640 if (!strchr(host, ':')) 666 if (!strchr(host, ':'))
641 host = allocated = xasprintf("%s:%u", host, port); 667 host = allocated = xasprintf("%s:%u", host, port);
668 servername = xstrdup(host);
669 strrchr(servername, ':')[0] = '\0';
642 670
643 fflush_all(); 671 fflush_all();
644 pid = xvfork(); 672 pid = xvfork();
645 if (pid == 0) { 673 if (pid == 0) {
646 /* Child */ 674 /* Child */
647 char *argv[6]; 675 char *argv[8];
648 676
649 close(sp[0]); 677 close(sp[0]);
650 xmove_fd(sp[1], 0); 678 xmove_fd(sp[1], 0);
@@ -656,12 +684,22 @@ static int spawn_https_helper_openssl(const char *host, unsigned port)
656 */ 684 */
657 xmove_fd(2, 3); 685 xmove_fd(2, 3);
658 xopen("/dev/null", O_RDWR); 686 xopen("/dev/null", O_RDWR);
687 memset(&argv, 0, sizeof(argv));
659 argv[0] = (char*)"openssl"; 688 argv[0] = (char*)"openssl";
660 argv[1] = (char*)"s_client"; 689 argv[1] = (char*)"s_client";
661 argv[2] = (char*)"-quiet"; 690 argv[2] = (char*)"-quiet";
662 argv[3] = (char*)"-connect"; 691 argv[3] = (char*)"-connect";
663 argv[4] = (char*)host; 692 argv[4] = (char*)host;
664 argv[5] = NULL; 693 /*
694 * Per RFC 6066 Section 3, the only permitted values in the
695 * TLS server_name (SNI) field are FQDNs (DNS hostnames).
696 * IPv4 and IPv6 addresses, port numbers are not allowed.
697 */
698 if (!is_ip_address(servername)) {
699 argv[5] = (char*)"-servername";
700 argv[6] = (char*)servername;
701 }
702
665 BB_EXECVP(argv[0], argv); 703 BB_EXECVP(argv[0], argv);
666 xmove_fd(3, 2); 704 xmove_fd(3, 2);
667# if ENABLE_FEATURE_WGET_SSL_HELPER 705# if ENABLE_FEATURE_WGET_SSL_HELPER
@@ -674,6 +712,7 @@ static int spawn_https_helper_openssl(const char *host, unsigned port)
674 } 712 }
675 713
676 /* Parent */ 714 /* Parent */
715 free(servername);
677 free(allocated); 716 free(allocated);
678 close(sp[1]); 717 close(sp[1]);
679# if ENABLE_FEATURE_WGET_SSL_HELPER 718# if ENABLE_FEATURE_WGET_SSL_HELPER