w3m

Unnamed repository; edit this file to name it for gitweb.
git clone https://logand.com/git/w3m.git/
Log | Files | Refs | README

commit 0edb69b049cea09e7dbb79cf331f42e1b59e4545
parent 58bfcc6f039e93807a879cfe162471ac30512abb
Author: ukai <ukai>
Date:   Sat, 12 Jan 2002 13:33:47 +0000

[w3m-dev 02829]
From: Fumitoshi UKAI  <ukai@debian.or.jp>

Diffstat:
MChangeLog | 16++++++++++++++++
Mfile.c | 22+++++++++++++---------
Mistream.c | 192++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------
Mistream.h | 5++---
Murl.c | 106+++++--------------------------------------------------------------------------
5 files changed, 174 insertions(+), 167 deletions(-)

diff --git a/ChangeLog b/ChangeLog @@ -1,5 +1,21 @@ 2002-01-12 Fumitoshi UKAI <ukai@debian.or.jp> + * [w3m-dev 02829] + * file.c (loadGeneralFile): return NO_BUFFER + * file.c (loadGeneralFile): if ssl_get_certificate() fails, + no buffer created + * istream.c (ssl_certificate_validity): deleted + * istream.c (ssl_set_certificate_validity): ditto + * istream.c (accept_this_site): added + * istream.c (ssl_accept_this_site): ditto + * istream.c (ssl_check_cert_ident): 1st arg is `X509 *' + * istream.c (ssl_get_certificate): 2nd arg is `char *hostname' + cert check code moved here from openSSLHandle() + * url.c (free_ssl_ctx): accept_this_site initialized + * url.c (openSSLHandle): remove cert check code here + +2002-01-12 Fumitoshi UKAI <ukai@debian.or.jp> + * [w3m-dev 02827] * scripts/Makefile: use sed instead of /bin/sh while read; echo loop diff --git a/file.c b/file.c @@ -1052,7 +1052,7 @@ loadGeneralFile(char *path, ParsedURL *volatile current, char *referer, { struct stat st; if (stat(pu.real_file, &st) < 0) - return NULL; + return NO_BUFFER; if (S_ISDIR(st.st_mode)) { if (UseExternalDirBuffer) { Str cmd = Strnew_charp(DirBufferCommand); @@ -1077,7 +1077,7 @@ loadGeneralFile(char *path, ParsedURL *volatile current, char *referer, } } } - return NULL; + return NO_BUFFER; } /* openURL() succeeded */ @@ -1090,7 +1090,7 @@ loadGeneralFile(char *path, ParsedURL *volatile current, char *referer, if (b) discardBuffer(b); UFclose(&f); - return NULL; + return NO_BUFFER; } b = NULL; @@ -1125,8 +1125,10 @@ loadGeneralFile(char *path, ParsedURL *volatile current, char *referer, t_buf = newBuffer(INIT_BUFFER_WIDTH); #ifdef USE_SSL if (IStype(f.stream) == IST_SSL) { - Str s = ssl_get_certificate(f.stream); - if (s != NULL) + Str s = ssl_get_certificate(f.stream, pu.host); + if (s == NULL) + return NO_BUFFER; + else t_buf->ssl_certificate = s->ptr; } #endif @@ -1185,7 +1187,7 @@ loadGeneralFile(char *path, ParsedURL *volatile current, char *referer, /* abort */ UFclose(&f); signal(SIGINT, prevtrap); - return NULL; + return NO_BUFFER; } UFclose(&f); add_auth_cookie_flag = 1; @@ -1206,7 +1208,7 @@ loadGeneralFile(char *path, ParsedURL *volatile current, char *referer, /* abort */ UFclose(&f); signal(SIGINT, prevtrap); - return NULL; + return NO_BUFFER; } UFclose(&f); status = HTST_NORMAL; @@ -1421,8 +1423,10 @@ loadGeneralFile(char *path, ParsedURL *volatile current, char *referer, } #ifdef USE_SSL if (IStype(f.stream) == IST_SSL) { - Str s = ssl_get_certificate(f.stream); - if (s != NULL) + Str s = ssl_get_certificate(f.stream, pu.host); + if (s == NULL) + return NO_BUFFER; + else t_buf->ssl_certificate = s->ptr; } #endif diff --git a/istream.c b/istream.c @@ -357,61 +357,21 @@ ISeos(InputStream stream) } #ifdef USE_SSL -static Str ssl_certificate_validity; +static Str accept_this_site; void -ssl_set_certificate_validity(Str msg) +ssl_accept_this_site(char *hostname) { - ssl_certificate_validity = msg; -} - -Str -ssl_get_certificate(InputStream stream) -{ - BIO *bp; - X509 *x; - X509_NAME *xn; - char *p; - int len; - Str s; - char buf[2048]; - - if (stream == NULL) - return NULL; - if (IStype(stream) != IST_SSL) - return NULL; - if (stream->ssl.handle == NULL) - return NULL; - x = SSL_get_peer_certificate(stream->ssl.handle->ssl); - if (x == NULL) - return Strnew_charp("no peer certificate"); - bp = BIO_new(BIO_s_mem()); - X509_print(bp, x); - len = (int)BIO_ctrl(bp, BIO_CTRL_INFO, 0, (char *)&p); - s = ssl_certificate_validity ? Strdup(ssl_certificate_validity) - : Strnew_charp("valid certificate"); - Strcat_charp(s, "\n"); - xn = X509_get_subject_name(x); - if (X509_NAME_get_text_by_NID(xn, NID_commonName, buf, sizeof(buf)) == -1) - Strcat_charp(s, " subject=<unknown>"); + if (hostname) + accept_this_site = Strnew_charp(hostname); else - Strcat_m_charp(s, " subject=", buf, NULL); - xn = X509_get_issuer_name(x); - if (X509_NAME_get_text_by_NID(xn, NID_commonName, buf, sizeof(buf)) == -1) - Strcat_charp(s, ": issuer=<unnown>"); - else - Strcat_m_charp(s, ": issuer=", buf, NULL); - Strcat_charp(s, "\n\n"); - Strcat_charp_n(s, p, len); - BIO_free_all(bp); - X509_free(x); - return s; + accept_this_site = NULL; } -Str -ssl_check_cert_ident(SSL * handle, char *hostname) + +static Str +ssl_check_cert_ident(X509 * x, char *hostname) { - X509 *x; int i; Str ret = NULL; int match_ident = FALSE; @@ -425,12 +385,6 @@ ssl_check_cert_ident(SSL * handle, char *hostname) * the use of the Common Name is existing practice, it is deprecated and * Certification Authorities are encouraged to use the dNSName instead. */ - x = SSL_get_peer_certificate(handle); - if (!x) { - ret = Strnew_charp("Unable to get peer certificate"); - return ret; - } - i = X509_get_ext_by_NID(x, NID_subject_alt_name, -1); if (i >= 0) { X509_EXTENSION *ex; @@ -493,9 +447,137 @@ ssl_check_cert_ident(SSL * handle, char *hostname) else match_ident = TRUE; } - X509_free(x); return ret; } + +Str +ssl_get_certificate(InputStream stream, char *hostname) +{ + BIO *bp; + X509 *x; + X509_NAME *xn; + char *p; + int len; + Str s; + char buf[2048]; + Str amsg = NULL; + Str emsg; + char *ans; + + if (stream == NULL) + return NULL; + if (IStype(stream) != IST_SSL) + return NULL; + if (stream->ssl.handle == NULL) + return NULL; + x = SSL_get_peer_certificate(stream->ssl.handle->ssl); + if (x == NULL) { + if (accept_this_site + && strcasecmp(accept_this_site->ptr, hostname) == 0) + ans = "y"; + else { + emsg = Strnew_charp("No SSL peer certificate: accept (y/n)?"); + term_raw(); + ans = inputChar(emsg->ptr); + } + if (tolower(*ans) == 'y') + amsg = Strnew_charp + ("Accept SSL session without any peer certificate"); + else { + char *e = "This SSL session was rejected " + "to prevent security violation: no peer certificate"; + disp_err_message(e, FALSE); + free_ssl_ctx(); + return NULL; + } + if (amsg) + disp_err_message(amsg->ptr, FALSE); + ssl_accept_this_site(hostname); + s = amsg ? amsg : Strnew_charp("valid certificate"); + return s; + } +#ifdef USE_SSL_VERIFY + /* check the cert chain. + * The chain length is automatically checked by OpenSSL when we + * set the verify depth in the ctx. + */ + if (ssl_verify_server) { + long verr; + if ((verr = SSL_get_verify_result(stream->ssl.handle->ssl)) + != X509_V_OK) { + const char *em = X509_verify_cert_error_string(verr); + if (accept_this_site + && strcasecmp(accept_this_site->ptr, hostname) == 0) + ans = "y"; + else { + emsg = Sprintf("%s: accept (y/n)?", em); + term_raw(); + ans = inputChar(emsg->ptr); + } + if (tolower(*ans) == 'y') { + amsg = Sprintf("Accept unsecure SSL session: " + "unverified: %s", em); + } + else { + char *e = + Sprintf("This SSL session was rejected: %s", em)->ptr; + disp_err_message(e, FALSE); + free_ssl_ctx(); + return NULL; + } + } + } +#endif + emsg = ssl_check_cert_ident(x, hostname); + if (emsg != NULL) { + if (accept_this_site + && strcasecmp(accept_this_site->ptr, hostname) == 0) + ans = "y"; + else { + Str ep = Strdup(emsg); + if (ep->length > COLS - 16) + Strshrink(ep, ep->length - (COLS - 16)); + term_raw(); + Strcat_charp(ep, ": accept(y/n)?"); + ans = inputChar(ep->ptr); + } + if (tolower(*ans) == 'y') { + amsg = Strnew_charp("Accept unsecure SSL session:"); + Strcat(amsg, emsg); + } + else { + char *e = "This SSL session was rejected " + "to prevent security violation"; + disp_err_message(e, FALSE); + free_ssl_ctx(); + return NULL; + } + } + if (amsg) + disp_err_message(amsg->ptr, FALSE); + ssl_accept_this_site(hostname); + s = amsg ? amsg : Strnew_charp("valid certificate"); + Strcat_charp(s, "\n"); + xn = X509_get_subject_name(x); + if (X509_NAME_get_text_by_NID(xn, NID_commonName, buf, sizeof(buf)) == -1) + Strcat_charp(s, " subject=<unknown>"); + else + Strcat_m_charp(s, " subject=", buf, NULL); + xn = X509_get_issuer_name(x); + if (X509_NAME_get_text_by_NID(xn, NID_commonName, buf, sizeof(buf)) == -1) + Strcat_charp(s, ": issuer=<unnown>"); + else + Strcat_m_charp(s, ": issuer=", buf, NULL); + Strcat_charp(s, "\n\n"); + + bp = BIO_new(BIO_s_mem()); + X509_print(bp, x); + len = (int)BIO_ctrl(bp, BIO_CTRL_INFO, 0, (char *)&p); + Strcat_charp_n(s, p, len); + BIO_free_all(bp); + X509_free(x); + return s; +} #endif /* Raw level input stream functions */ diff --git a/istream.h b/istream.h @@ -125,9 +125,8 @@ extern int ISread(InputStream stream, Str buf, int count); extern int ISfileno(InputStream stream); extern int ISeos(InputStream stream); #ifdef USE_SSL -extern void ssl_set_certificate_validity(Str msg); -extern Str ssl_get_certificate(InputStream stream); -extern Str ssl_check_cert_ident(SSL * handle, char *hostname); +extern void ssl_accept_this_site(char *hostname); +extern Str ssl_get_certificate(InputStream stream, char *hostname); #endif #define IST_BASIC 0 diff --git a/url.c b/url.c @@ -240,6 +240,7 @@ free_ssl_ctx() if (ssl_ctx != NULL) SSL_CTX_free(ssl_ctx); ssl_ctx = NULL; + ssl_accept_this_site(NULL); } #if SSLEAY_VERSION_NUMBER >= 0x00905100 @@ -276,11 +277,7 @@ static SSL * openSSLHandle(int sock, char *hostname) { SSL *handle = NULL; - Str emsg; - Str amsg = NULL; - char *ans; static char *old_ssl_forbid_method = NULL; - static Str accept_this_site = NULL; #ifdef USE_SSL_VERIFY static int old_ssl_verify_server = -1; #endif @@ -301,7 +298,6 @@ openSSLHandle(int sock, char *hostname) } if (ssl_path_modified) { free_ssl_ctx(); - accept_this_site = NULL; ssl_path_modified = 0; } #endif /* defined(USE_SSL_VERIFY) */ @@ -363,105 +359,15 @@ openSSLHandle(int sock, char *hostname) #if SSLEAY_VERSION_NUMBER >= 0x00905100 init_PRNG(); #endif /* SSLEAY_VERSION_NUMBER >= 0x00905100 */ - if (SSL_connect(handle) <= 0) - goto eend; -#ifdef USE_SSL_VERIFY - /* check the cert chain. - * The chain length is automatically checked by OpenSSL when we - * set the verify depth in the ctx. - */ - if (ssl_verify_server) { - X509 *x; - x = SSL_get_peer_certificate(handle); - if (x == NULL) { - if (accept_this_site - && strcasecmp(accept_this_site->ptr, hostname) == 0) - ans = "y"; - else { - emsg = Strnew_charp("No SSL peer certificate: accept (y/n)?"); - term_raw(); - ans = inputChar(emsg->ptr); - } - if (tolower(*ans) == 'y') - amsg = - Strnew_charp - ("Accept SSL session without any peer certificate"); - else { - char *e = "This SSL session was rejected " - "to prevent security violation: no peer certificate"; - disp_err_message(e, FALSE); - free_ssl_ctx(); - return NULL; - } - } - else { - long verr; - X509_free(x); - if ((verr = SSL_get_verify_result(handle)) != X509_V_OK) { - const char *em = X509_verify_cert_error_string(verr); - if (accept_this_site - && strcasecmp(accept_this_site->ptr, hostname) == 0) - ans = "y"; - else { - emsg = Sprintf("%s: accept (y/n)?", em); - term_raw(); - ans = inputChar(emsg->ptr); - } - if (tolower(*ans) == 'y') { - amsg = Sprintf("Accept unsecure SSL session: " - "unverified: %s", em); - } - else { - char *e = - Sprintf("This SSL session was rejected: %s", em)->ptr; - disp_err_message(e, FALSE); - free_ssl_ctx(); - return NULL; - } - } - } - } - else -#endif - amsg = Strnew_charp("Certificate is not verified"); - - emsg = ssl_check_cert_ident(handle, hostname); - if (emsg != NULL) { - if (accept_this_site - && strcasecmp(accept_this_site->ptr, hostname) == 0) - ans = "y"; - else { - Str ep = Strdup(emsg); - if (ep->length > COLS - 16) - Strshrink(ep, ep->length - (COLS - 16)); - term_raw(); - Strcat_charp(ep, ": accept(y/n)?"); - ans = inputChar(ep->ptr); - } - if (tolower(*ans) == 'y') { - amsg = Strnew_charp("Accept unsecure SSL session:"); - Strcat(amsg, emsg); - } - else { - char *e = "This SSL session was rejected " - "to prevent security violation"; - disp_err_message(e, FALSE); - free_ssl_ctx(); - return NULL; - } - } - ssl_set_certificate_validity(amsg); - if (amsg) - disp_err_message(amsg->ptr, FALSE); - accept_this_site = Strnew_charp(hostname); - return handle; + if (SSL_connect(handle) > 0) + return handle; eend: close(sock); if (handle) SSL_free(handle); - accept_this_site = NULL; - emsg = Sprintf("SSL error: %s", ERR_error_string(ERR_get_error(), NULL)); - disp_err_message(emsg->ptr, FALSE); + disp_err_message(Sprintf + ("SSL error: %s", + ERR_error_string(ERR_get_error(), NULL))->ptr, FALSE); return NULL; }