diff options
author | Thomas E. Dickey <dickey@invisible-island.net> | 2001-01-02 01:53:43 -0500 |
---|---|---|
committer | Thomas E. Dickey <dickey@invisible-island.net> | 2001-01-02 01:53:43 -0500 |
commit | d31fb3c41be5d6e079d415087eda3c03cc34bcdb (patch) | |
tree | 76faa032cec14cb8e3500f25c1074eacc56c1c7e /WWW/Library/Implementation | |
parent | 244b955fa0312faea2e138d55330bd9a81fd92de (diff) | |
download | lynx-snapshots-d31fb3c41be5d6e079d415087eda3c03cc34bcdb.tar.gz |
snapshot of project "lynx", label v2-8-4dev_16
Diffstat (limited to 'WWW/Library/Implementation')
-rw-r--r-- | WWW/Library/Implementation/HTAAUtil.c | 11 | ||||
-rw-r--r-- | WWW/Library/Implementation/HTFormat.c | 40 | ||||
-rw-r--r-- | WWW/Library/Implementation/HTMLDTD.c | 3 | ||||
-rw-r--r-- | WWW/Library/Implementation/HTNews.c | 167 | ||||
-rw-r--r-- | WWW/Library/Implementation/HTNews.h | 14 | ||||
-rw-r--r-- | WWW/Library/Implementation/HTTP.c | 273 | ||||
-rw-r--r-- | WWW/Library/Implementation/HTUtils.h | 52 |
7 files changed, 552 insertions, 8 deletions
diff --git a/WWW/Library/Implementation/HTAAUtil.c b/WWW/Library/Implementation/HTAAUtil.c index ecfb04e1..25d24aa6 100644 --- a/WWW/Library/Implementation/HTAAUtil.c +++ b/WWW/Library/Implementation/HTAAUtil.c @@ -50,6 +50,10 @@ #include <HTTCP.h> #include <HTTP.h> +#ifdef USE_SSL +PRIVATE SSL * Handle = NULL; /* The SSL Handle */ +#endif /* USE_SSL */ + #include <LYStrings.h> #include <LYLeaks.h> @@ -555,7 +559,14 @@ PUBLIC char *HTAA_getUnfoldedLine NOARGS /* Reading from socket */ if (start_pointer >= end_pointer) {/*Read the next block and continue*/ +#ifdef USE_SSL + if (Handle) + count = SSL_read(Handle, buffer, BUFFER_SIZE); + else + count = NETREAD(in_soc, buffer, BUFFER_SIZE); +#else count = NETREAD(in_soc, buffer, BUFFER_SIZE); +#endif /* USE_SSL */ if (count <= 0) { in_soc = -1; return line; diff --git a/WWW/Library/Implementation/HTFormat.c b/WWW/Library/Implementation/HTFormat.c index c589749d..1148e308 100644 --- a/WWW/Library/Implementation/HTFormat.c +++ b/WWW/Library/Implementation/HTFormat.c @@ -259,6 +259,39 @@ PUBLIC int HTGetCharacter NOARGS return FROMASCII(UCH(ch)); } +#ifdef USE_SSL +PUBLIC char HTGetSSLCharacter ARGS1(void *, handle) +{ + char ch; + interrupted_in_htgetcharacter = 0; + if(!handle) + return (char)EOF; + do { + if (input_pointer >= input_limit) { + int status = SSL_read((SSL *)handle, + input_buffer, INPUT_BUFFER_SIZE); + if (status <= 0) { + if (status == 0) + return (char)EOF; + if (status == HT_INTERRUPTED) { + CTRACE((tfp, "HTFormat: Interrupted in HTGetSSLCharacter\n")); + interrupted_in_htgetcharacter = 1; + return (char)EOF; + } + CTRACE((tfp, "HTFormat: SSL_read error %d\n", status)); + return (char)EOF; /* -1 is returned by UCX + at end of HTTP link */ + } + input_pointer = input_buffer; + input_limit = input_buffer + status; + } + ch = *input_pointer++; + } while (ch == (char) 13); /* Ignore ASCII carriage return */ + + return FROMASCII(ch); +} +#endif /* USE_SSL */ + /* Match maintype to any MIME type starting with maintype, * for example: image/gif should match image */ @@ -641,7 +674,14 @@ PUBLIC int HTCopy ARGS4( goto finished; } +#ifdef USE_SSL + if (handle) + status = SSL_read((SSL *)handle, input_buffer, INPUT_BUFFER_SIZE); + else + status = NETREAD(file_number, input_buffer, INPUT_BUFFER_SIZE); +#else status = NETREAD(file_number, input_buffer, INPUT_BUFFER_SIZE); +#endif /* USE_SSL */ if (status <= 0) { if (status == 0) { diff --git a/WWW/Library/Implementation/HTMLDTD.c b/WWW/Library/Implementation/HTMLDTD.c index 3b9d9353..981bc989 100644 --- a/WWW/Library/Implementation/HTMLDTD.c +++ b/WWW/Library/Implementation/HTMLDTD.c @@ -1365,6 +1365,9 @@ static attr ulist_attr[] = { /* UL attributes */ ** ** Name*, Attributes, No. of attributes, content, extra info... */ +#undef P +#undef P +#undef P_ #ifdef USE_COLOR_STYLE #define P_(x) x , (sizeof x) -1 #define NULL_HTTag_ NULL, 0 diff --git a/WWW/Library/Implementation/HTNews.c b/WWW/Library/Implementation/HTNews.c index ded9af8c..b404733b 100644 --- a/WWW/Library/Implementation/HTNews.c +++ b/WWW/Library/Implementation/HTNews.c @@ -34,9 +34,21 @@ PUBLIC int HTNewsMaxChunk = 40; /* Largest number of articles in one window */ #define SERVER_FILE "/usr/local/lib/rn/server" #endif /* SERVER_FILE */ +#ifdef USE_SSL +extern SSL_CTX * ssl_ctx; +PRIVATE SSL * Handle = NULL; +PRIVATE int channel_s = 1; +#define NEWS_NETWRITE(sock, buff, size) \ + (Handle ? SSL_write(Handle, buff, size) : NETWRITE(sock, buff, size)) +#define NEWS_NETCLOSE(sock) \ + { (void)NETCLOSE(sock); if (Handle) SSL_free(Handle); Handle = NULL; } +PRIVATE char HTNewsGetCharacter NOPARAMS; +#define NEXT_CHAR HTNewsGetCharacter() +#else #define NEWS_NETWRITE NETWRITE #define NEWS_NETCLOSE NETCLOSE #define NEXT_CHAR HTGetCharacter() +#endif /* USE_SSL */ #include <HTML.h> #include <HTParse.h> @@ -2147,6 +2159,9 @@ PRIVATE int HTLoadNews ARGS4( char *ProxyHost = NULL; char *ProxyHREF = NULL; char *postfile = NULL; +#ifdef USE_SSL + char SSLprogress[256]; +#endif /* USE_SSL */ diagnostic = (format_out == WWW_SOURCE || /* set global flag */ format_out == HTAtom_for("www/download") || @@ -2195,11 +2210,13 @@ PRIVATE int HTLoadNews ARGS4( group_wanted) && strchr(arg, '@') == NULL) && (strchr(arg, '*') != NULL)); +#ifndef USE_SSL if (!strncasecomp(arg, "snewspost:", 10) || !strncasecomp(arg, "snewsreply:", 11)) { HTAlert(FAILED_CANNOT_POST_SSL); return HT_NOT_LOADED; } +#endif /* !USE_SSL */ if (post_wanted || reply_wanted || spost_wanted || sreply_wanted) { /* ** Make sure we have a non-zero path for the newsgroup(s). - FM @@ -2287,8 +2304,43 @@ PRIVATE int HTLoadNews ARGS4( StrAllocCopy(NewsHREF, command); } else if (!strncasecomp(arg, "snews:", 6)) { +#ifdef USE_SSL + if (((*(arg + 6) == '\0') || + (!strcmp((arg + 6), "/") || + !strcmp((arg + 6), "//") || + !strcmp((arg + 6), "///"))) || + ((!strncmp((arg + 6), "//", 2)) && + (!(cp = strchr((arg + 8), '/')) || *(cp + 1) == '\0'))) { + p1 = "*"; + group_wanted = FALSE; + list_wanted = TRUE; + } else if (*(arg + 6) != '/') { + p1 = (arg + 6); + } else if (*(arg + 6) == '/' && *(arg + 7) != '/') { + p1 = (arg + 7); + } else { + p1 = (cp + 1); + } + if (!(cp = HTParse(arg, "", PARSE_HOST)) || *cp == '\0') { + if (s >= 0 && NewsHost && strcasecomp(NewsHost, HTNewsHost)) { + NEWS_NETCLOSE(s); + s = -1; + } + StrAllocCopy(NewsHost, HTNewsHost); + } else { + if (s >= 0 && NewsHost && strcasecomp(NewsHost, cp)) { + NEWS_NETCLOSE(s); + s = -1; + } + StrAllocCopy(NewsHost, cp); + } + FREE(cp); + sprintf(command, "snews://%.250s/", NewsHost); + StrAllocCopy(NewsHREF, command); +#else HTAlert(gettext("This client does not contain support for SNEWS URLs.")); return HT_NOT_LOADED; +#endif /* USE_SSL */ } else if (!strncasecomp (arg, "news:/", 6)) { if (((*(arg + 6) == '\0') || @@ -2526,7 +2578,18 @@ PRIVATE int HTLoadNews ARGS4( _HTProgress(gettext("Connecting to NewsHost ...")); +#ifdef USE_SSL + if (!using_proxy && + (!strncmp(arg, "snews:", 6) || + !strncmp(arg, "snewspost:", 10) || + !strncmp(arg, "snewsreply:", 11))) + status = HTDoConnect (url, "NNTPS", SNEWS_PORT, &s); + else + status = HTDoConnect (url, "NNTP", NEWS_PORT, &s); +#else status = HTDoConnect (url, "NNTP", NEWS_PORT, &s); +#endif /* USE_SSL */ + if (status == HT_INTERRUPTED) { /* ** Interrupt cleanly. @@ -2542,6 +2605,12 @@ PRIVATE int HTLoadNews ARGS4( FREE(ProxyHost); FREE(ProxyHREF); FREE(ListArg); +#ifdef USE_SSL + if (Handle) { + SSL_free(Handle); + Handle = NULL; + } +#endif /* USE_SSL */ if (postfile) { HTSYS_remove(postfile); FREE(postfile); @@ -2572,6 +2641,54 @@ PRIVATE int HTLoadNews ARGS4( } else { CTRACE((tfp, "HTNews: Connected to news host %s.\n", NewsHost)); +#ifdef USE_SSL + /* + ** If this is an snews url, + ** then do the SSL stuff here + */ + if (!using_proxy && + (!strncmp(url, "snews", 5) || + !strncmp(url, "snewspost:", 10) || + !strncmp(url, "snewsreply:", 11))) { + Handle = HTGetSSLHandle(); + SSL_set_fd(Handle, s); + HTSSLInitPRNG(); + status = SSL_connect(Handle); + + if (status <= 0) { + unsigned long SSLerror; + CTRACE((tfp,"HTNews: Unable to complete SSL handshake for '%s', SSL_connect=%d, SSL error stack dump follows\n",url, status)); + SSL_load_error_strings(); + while((SSLerror = ERR_get_error()) != 0) { + CTRACE((tfp,"HTNews: SSL: %s\n",ERR_error_string(SSLerror,NULL))); + } + HTAlert( + "Unable to make secure connection to remote host."); + NEWS_NETCLOSE(s); + s = -1; + if (!(post_wanted || reply_wanted || + spost_wanted || sreply_wanted)) + (*targetClass._abort)(target, NULL); + FREE(NewsHost); + FREE(NewsHREF); + FREE(ProxyHost); + FREE(ProxyHREF); + FREE(ListArg); + if (postfile) { +#ifdef VMS + while (remove(postfile) == 0) + ; /* loop through all versions */ +#else + remove(postfile); +#endif /* VMS */ + FREE(postfile); + } + return HT_NOT_LOADED; + } + sprintf(SSLprogress,"Secure %d-bit %s (%s) NNTP connection",SSL_get_cipher_bits(Handle,NULL),SSL_get_cipher_version(Handle),SSL_get_cipher(Handle)); + _HTProgress(SSLprogress); + } +#endif /* USE_SSL */ HTInitInput(s); /* set up buffering */ if (proxycmd[0]) { status = NEWS_NETWRITE(s, proxycmd, strlen(proxycmd)); @@ -2922,6 +3039,56 @@ PUBLIC void HTClearNNTPAuthInfo NOARGS free_NNTP_AuthInfo(); } +#ifdef USE_SSL +PRIVATE char HTNewsGetCharacter NOARGS +{ + if (!Handle) + return HTGetCharacter(); + else + return HTGetSSLCharacter((void *)Handle); +} + +PUBLIC int HTNewsProxyConnect ARGS5 ( + int, sock, + CONST char *, url, + HTParentAnchor *, anAnchor, + HTFormat, format_out, + HTStream *, sink) +{ + int status; + CONST char * arg = url; + char SSLprogress[256]; + + s = channel_s = sock; + Handle = HTGetSSLHandle(); + SSL_set_fd(Handle, s); + HTSSLInitPRNG(); + status = SSL_connect(Handle); + + if (status <= 0) { + unsigned long SSLerror; + channel_s = -1; + CTRACE((tfp,"HTNews: Unable to complete SSL handshake for '%s', SSL_connect=%d, SSL error stack dump follows\n",url, status)); + SSL_load_error_strings(); + while((SSLerror = ERR_get_error()) != 0) { + CTRACE((tfp,"HTNews: SSL: %s\n",ERR_error_string(SSLerror,NULL))); + } + HTAlert("Unable to make secure connection to remote host."); + NEWS_NETCLOSE(s); + s = -1; + return HT_NOT_LOADED; + } + sprintf(SSLprogress,"Secure %d-bit %s (%s) NNTP connection", + SSL_get_cipher_bits(Handle,NULL), + SSL_get_cipher_version(Handle), + SSL_get_cipher(Handle)); + _HTProgress(SSLprogress); + status = HTLoadNews(arg, anAnchor, format_out, sink); + channel_s = -1; + return status; +} +#endif /* USE_SSL */ + #ifdef GLOBALDEF_IS_MACRO #define _HTNEWS_C_1_INIT { "news", HTLoadNews, NULL } GLOBALDEF (HTProtocol,HTNews,_HTNEWS_C_1_INIT); diff --git a/WWW/Library/Implementation/HTNews.h b/WWW/Library/Implementation/HTNews.h index 7cd930a4..92bf7f33 100644 --- a/WWW/Library/Implementation/HTNews.h +++ b/WWW/Library/Implementation/HTNews.h @@ -41,9 +41,13 @@ extern char * HTNewsHost; extern void HTClearNNTPAuthInfo NOPARAMS; -#endif /* HTNEWS_H */ - +#ifdef USE_SSL +extern int HTNewsProxyConnect PARAMS (( + int sock, + CONST char * url, + HTParentAnchor *anAnchor, + HTFormat format_out, + HTStream * sink)); +#endif -/* - - tbl */ +#endif /* HTNEWS_H */ diff --git a/WWW/Library/Implementation/HTTP.c b/WWW/Library/Implementation/HTTP.c index 89aa7045..7c792ef6 100644 --- a/WWW/Library/Implementation/HTTP.c +++ b/WWW/Library/Implementation/HTTP.c @@ -13,6 +13,10 @@ #include <HTTP.h> #include <LYUtils.h> +#ifdef USE_SSL +#include <HTNews.h> +#endif + #define HTTP_VERSION "HTTP/1.0" #define HTTP_PORT 80 @@ -67,9 +71,85 @@ extern char *http_error_file; /* Store HTTP status code in this file */ extern BOOL traversal; /* TRUE if we are doing a traversal */ extern BOOL dump_output_immediately; /* TRUE if no interactive user */ +#ifdef USE_SSL +PUBLIC SSL_CTX * ssl_ctx = NULL; /* SSL ctx */ + +PRIVATE void free_ssl_ctx NOARGS +{ + if (ssl_ctx != NULL) + SSL_CTX_free(ssl_ctx); +} + +PUBLIC SSL * HTGetSSLHandle NOARGS +{ + if (ssl_ctx == NULL) { + /* + * First time only. + */ +#if SSLEAY_VERSION_NUMBER < 0x0800 + ssl_ctx = SSL_CTX_new(); + X509_set_default_verify_paths(ssl_ctx->cert); +#else + SSLeay_add_ssl_algorithms(); + ssl_ctx = SSL_CTX_new(SSLv23_client_method()); + SSL_CTX_set_options(ssl_ctx, SSL_OP_ALL); + SSL_CTX_set_default_verify_paths(ssl_ctx); +#endif /* SSLEAY_VERSION_NUMBER < 0x0800 */ + atexit(free_ssl_ctx); + } + return(SSL_new(ssl_ctx)); +} + +PUBLIC void HTSSLInitPRNG NOARGS +{ +#if SSLEAY_VERSION_NUMBER >= 0x00905100 + if (RAND_status() == 0) { + char rand_file[256]; + time_t t; + pid_t pid; + long l,seed; + + t = time(NULL); + pid = getpid(); + RAND_file_name(rand_file, 256); + CTRACE((tfp,"HTTP: Seeding PRNG\n")); + if(rand_file != NULL) { + /* Seed as much as 1024 bytes from RAND_file_name */ + RAND_load_file(rand_file, 1024); + } + /* Seed in time (mod_ssl does this) */ + RAND_seed((unsigned char *)&t, sizeof(time_t)); + /* Seed in pid (mod_ssl does this) */ + RAND_seed((unsigned char *)&pid, sizeof(pid_t)); + /* Initialize system's random number generator */ + RAND_bytes((unsigned char *)&seed, sizeof(long)); + srand48(seed); + while (RAND_status() == 0) { + /* Repeatedly seed the PRNG using the system's random number generator until it has been seeded with enough data */ + l = lrand48(); + RAND_seed((unsigned char *)&l, sizeof(long)); + } + if (rand_file != NULL) { + /* Write a rand_file */ + RAND_write_file(rand_file); + } + } +#endif /* SSLEAY_VERSION_NUMBER >= 0x00905100 */ + return; +} + +#define HTTP_NETREAD(sock, buff, size, handle) \ + (handle ? SSL_read(handle, buff, size) : NETREAD(sock, buff, size)) +#define HTTP_NETWRITE(sock, buff, size, handle) \ + (handle ? SSL_write(handle, buff, size) : NETWRITE(sock, buff, size)) +#define HTTP_NETCLOSE(sock, handle) \ + { (void)NETCLOSE(sock); if (handle) SSL_free(handle); handle = NULL; } + +#else #define HTTP_NETREAD(a, b, c, d) NETREAD(a, b, c) #define HTTP_NETWRITE(a, b, c, d) NETWRITE(a, b, c) #define HTTP_NETCLOSE(a, b) (void)NETCLOSE(a) +#endif /* USE_SSL */ #ifdef _WINDOWS /* 1997/11/06 (Thu) 13:00:08 */ @@ -299,7 +379,19 @@ PRIVATE int HTLoadHTTP ARGS4 ( BOOL doing_redirect, already_retrying = FALSE; int len = 0; +#ifdef USE_SSL + BOOL do_connect = FALSE; /* ARE WE going to use a proxy tunnel ? */ + BOOL did_connect = FALSE; /* ARE WE actually using a proxy tunnel ? */ + CONST char *connect_url = NULL; /* The URL being proxied */ + char *connect_host = NULL; /* The host being proxied */ + SSL * handle = NULL; /* The SSL handle */ + char SSLprogress[256]; /* progress bar message */ +#if SSLEAY_VERSION_NUMBER >= 0x0900 + BOOL try_tls = TRUE; +#endif /* SSLEAY_VERSION_NUMBER >= 0x0900 */ +#else void * handle = NULL; +#endif /* USE_SSL */ if (anAnchor->isHEAD) do_head = TRUE; @@ -317,6 +409,30 @@ PRIVATE int HTLoadHTTP ARGS4 ( goto done; } +#ifdef USE_SSL + if (using_proxy && !strncmp(url, "http://", 7)) { + if ((connect_url = strstr((url+7), "https://"))) { + do_connect = TRUE; + connect_host = HTParse(connect_url, "https", PARSE_HOST); + if (!strchr(connect_host, ':')) { + sprintf(temp, ":%d", HTTPS_PORT); + StrAllocCat(connect_host, temp); + } + CTRACE((tfp, "HTTP: connect_url = '%s'\n", connect_url)); + CTRACE((tfp, "HTTP: connect_host = '%s'\n", connect_host)); + } else if ((connect_url = strstr((url+7), "snews://"))) { + do_connect = TRUE; + connect_host = HTParse(connect_url, "snews", PARSE_HOST); + if (!strchr(connect_host, ':')) { + sprintf(temp, ":%d", SNEWS_PORT); + StrAllocCat(connect_host, temp); + } + CTRACE((tfp, "HTTP: connect_url = '%s'\n", connect_url)); + CTRACE((tfp, "HTTP: connect_host = '%s'\n", connect_host)); + } + } +#endif /* USE_SSL */ + sprintf(crlf, "%c%c", CR, LF); /* @@ -340,12 +456,18 @@ try_again: line_kept_clean = NULL; if (!strncmp(url, "https", 5)) +#ifdef USE_SSL + status = HTDoConnect (url, "HTTPS", HTTPS_PORT, &s); + else + status = HTDoConnect (url, "HTTP", HTTP_PORT, &s); +#else { HTAlert(gettext("This client does not contain support for HTTPS URLs.")); status = HT_NOT_LOADED; goto done; } status = HTDoConnect (arg, "HTTP", HTTP_PORT, &s); +#endif /* USE_SSL */ if (status == HT_INTERRUPTED) { /* ** Interrupt cleanly. @@ -375,12 +497,91 @@ try_again: * This is a nice long function as well. *sigh* -RJP */ +#ifdef USE_SSL +use_tunnel: + /* + ** If this is an https document + ** then do the SSL stuff here + */ + if (did_connect || !strncmp(url, "https", 5)) { + handle = HTGetSSLHandle(); + SSL_set_fd(handle, s); +#if SSLEAY_VERSION_NUMBER >= 0x0900 + if (!try_tls) + handle->options|=SSL_OP_NO_TLSv1; +#endif /* SSLEAY_VERSION_NUMBER >= 0x0900 */ + HTSSLInitPRNG(); + status = SSL_connect(handle); + + if (status <= 0) { +#if SSLEAY_VERSION_NUMBER >= 0x0900 + if (try_tls) { + CTRACE((tfp, "HTTP: Retrying connection without TLS\n")); + _HTProgress("Retrying connection."); + try_tls = FALSE; + if (did_connect) + HTTP_NETCLOSE(s, handle); + goto try_again; + } else { + unsigned long SSLerror; + CTRACE((tfp, +"HTTP: Unable to complete SSL handshake for '%s', SSL_connect=%d, SSL error stack dump follows\n", + url, status)); + SSL_load_error_strings(); + while((SSLerror=ERR_get_error())!=0) { + CTRACE((tfp,"HTTP: SSL: %s\n",ERR_error_string(SSLerror,NULL))); + } + HTAlert("Unable to make secure connection to remote host."); + if (did_connect) + HTTP_NETCLOSE(s, handle); + status = HT_NOT_LOADED; + goto done; + } +#else + unsigned long SSLerror; + CTRACE((tfp, +"HTTP: Unable to complete SSL handshake for '%s', SSL_connect=%d, SSL error stack dump follows\n", + url, status)); + SSL_load_error_strings(); + while((SSLerror=ERR_get_error())!=0) { + CTRACE((tfp,"HTTP: SSL: %s\n",ERR_error_string(SSLerror,NULL))); + } + HTAlert("Unable to make secure connection to remote host."); + if (did_connect) + HTTP_NETCLOSE(s, handle); + status = HT_NOT_LOADED; + goto done; +#endif /* SSLEAY_VERSION_NUMBER >= 0x0900 */ + } + sprintf(SSLprogress,"Secure %d-bit %s (%s) HTTP connection",SSL_get_cipher_bits(handle,NULL),SSL_get_cipher_version(handle),SSL_get_cipher(handle)); + _HTProgress(SSLprogress); + +#ifdef NOTDEFINED + if (strcmp(HTParse(url, "", PARSE_HOST), + strstr(X509_NAME_oneline( + X509_get_subject_name( + handle->session->peer)),"/CN=")+4)) { + HTAlert("Certificate is for different host name"); + HTAlert(strstr(X509_NAME_oneline( + X509_get_subject_name( + handle->session->peer)),"/CN=")+4); + } +#endif /* NOTDEFINED */ + } +#endif /* USE_SSL */ + /* Ask that node for the document, ** omitting the host name & anchor */ { char * p1 = (HTParse(url, "", PARSE_PATH|PARSE_PUNCTUATION)); +#ifdef USE_SSL + if (do_connect) { + METHOD = "CONNECT"; + StrAllocCopy(command, "CONNECT "); + } else +#endif /* USE_SSL */ if (do_post) { METHOD = "POST"; StrAllocCopy(command, "POST "); @@ -397,8 +598,17 @@ try_again: ** of say: /gopher://a;lkdjfl;ajdf;lkj/;aldk/adflj ** so that just gopher://.... is sent. */ +#ifdef USE_SSL + if (using_proxy && !did_connect) { + if (do_connect) + StrAllocCat(command, connect_host); + else + StrAllocCat(command, p1+1); + } +#else if (using_proxy) StrAllocCat(command, p1+1); +#endif /* USE_SSL */ else StrAllocCat(command, p1); FREE(p1); @@ -638,6 +848,10 @@ try_again: } else { if (traversal || dump_output_immediately) HTAlert(FAILED_NEED_PASSWD); +#ifdef USE_SSL + if (did_connect) + HTTP_NETCLOSE(s, handle); +#endif /* USE_SSL */ FREE(command); FREE(hostname); FREE(docname); @@ -752,7 +966,11 @@ try_again: auth_proxy = NO; } - if (do_post) { + if ( +#ifdef USE_SSL + !do_connect && +#endif /* USE_SSL */ + do_post) { CTRACE((tfp, "HTTP: Doing post, content-type '%s'\n", anAnchor->post_content_type ? anAnchor->post_content_type : "lose")); @@ -776,11 +994,17 @@ try_again: StrAllocCat(command, anAnchor->post_data); } else - StrAllocCat(command, crlf); /* Blank line means "end" of headers */ + StrAllocCat(command, crlf); /* Blank line means "end" of headers */ +#ifdef USE_SSL + CTRACE((tfp, "Writing:\n%s%s----------------------------------\n", + command, + (anAnchor->post_data && !do_connect ? crlf : ""))); +#else CTRACE((tfp, "Writing:\n%s%s----------------------------------\n", command, (anAnchor->post_data ? crlf : ""))); +#endif /* USE_SSL */ _HTProgress (gettext("Sending HTTP request.")); @@ -1143,6 +1367,35 @@ try_again: * > 206 is unknown. * All should return something to display. */ +#ifdef USE_SSL + if (do_connect) { + CTRACE((tfp, "HTTP: Proxy tunnel to '%s' established.\n", + connect_host)); + do_connect = FALSE; + url = connect_url; + FREE(line_buffer); + FREE(line_kept_clean); + if (!strncmp(connect_url, "snews", 5)) { + CTRACE((tfp, + " Will attempt handshake and snews connection.\n")); + status = HTNewsProxyConnect(s, url, anAnchor, + format_out, sink); + goto done; + } + did_connect = TRUE; + already_retrying = TRUE; + eol = 0; + bytes_already_read = 0; + had_header = NO; + length = 0; + doing_redirect = FALSE; + permanent_redirection = FALSE; + target = NULL; + CTRACE((tfp, + " Will attempt handshake and resubmit headers.\n")); + goto use_tunnel; + } +#endif /* USE_SSL */ HTProgress(line_buffer); } /* case 2 switch */ break; @@ -1337,6 +1590,13 @@ try_again: gettext("Retrying with access authorization information.")); FREE(line_buffer); FREE(line_kept_clean); +#ifdef USE_SSL + if (using_proxy && !strncmp(url, "https://", 8)) { + url = arg; + do_connect = TRUE; + did_connect = FALSE; + } +#endif /* USE_SSL */ goto try_again; } else if (!(traversal || dump_output_immediately) && HTConfirm(gettext("Show the 401 message body?"))) { @@ -1771,6 +2031,15 @@ done: do_head = FALSE; do_post = FALSE; reloading = FALSE; +#ifdef USE_SSL + do_connect = FALSE; + did_connect = FALSE; + FREE(connect_host); + if (handle) { + SSL_free(handle); + handle = NULL; + } +#endif /* USE_SSL */ return status; } diff --git a/WWW/Library/Implementation/HTUtils.h b/WWW/Library/Implementation/HTUtils.h index 036ed2fd..ee787194 100644 --- a/WWW/Library/Implementation/HTUtils.h +++ b/WWW/Library/Implementation/HTUtils.h @@ -17,7 +17,7 @@ #include <sys/types.h> #include <stdio.h> -#else +#else /* HAVE_CONFIG_H */ #ifdef DJGPP #include <sys/config.h> /* pseudo-autoconf values for DJGPP libc/headers */ @@ -102,6 +102,14 @@ #endif /* HAVE_CONFIG_H */ +#if '0' != 48 +#define NOT_ASCII +#endif + +#if '0' == 240 +#define EBCDIC +#endif + #ifndef LY_MAXPATH #define LY_MAXPATH 256 #endif @@ -507,10 +515,52 @@ extern FILE *TraceFP NOPARAMS; #define Rgetpeername getpeername #endif +/* + * Workaround for order-of-evaluation problem with gcc and socks5 headers + * which breaks the Rxxxx names by attaching the prefix twice: + */ +#ifdef INCLUDE_PROTOTYPES +#undef Raccept +#undef Rbind +#undef Rconnect +#undef Rlisten +#undef Rselect +#undef Rgetpeername +#undef Rgetsockname +#define Raccept accept +#define Rbind bind +#define Rconnect connect +#define Rgetpeername getpeername +#define Rgetsockname getsockname +#define Rlisten listen +#define Rselect select +#endif + #endif /* USE_SOCKS5 */ #define SHORTENED_RBIND /* FIXME: do this in configure-script */ +#ifdef USE_SSL +#define free_func free__func +#ifdef USE_OPENSSL_INCL +#include <openssl/ssl.h> +#include <openssl/crypto.h> +#include <openssl/rand.h> +#include <openssl/err.h> +#else +#include <ssl.h> +#include <crypto.h> +#include <rand.h> +#include <err.h> +#endif +#undef free_func + +extern SSL * HTGetSSLHandle NOPARAMS; +extern void HTSSLInitPRNG NOPARAMS; +extern char HTGetSSLCharacter PARAMS((void * handle)); + +#endif /* USE_SSL */ + #include <userdefs.h> #endif /* HTUTILS_H */ |