diff options
| author | Fumitoshi UKAI <ukai@debian.or.jp> | 2002-01-12 13:33:47 +0000 | 
|---|---|---|
| committer | Fumitoshi UKAI <ukai@debian.or.jp> | 2002-01-12 13:33:47 +0000 | 
| commit | 9de0a515bc84b9e8ded317ae0d7dab0313ba633e (patch) | |
| tree | 4e86dab1f39d8ae73bd3d1593d7c6a33649fd2fb | |
| parent | [w3m-dev 02827] (diff) | |
| download | w3m-9de0a515bc84b9e8ded317ae0d7dab0313ba633e.tar.gz w3m-9de0a515bc84b9e8ded317ae0d7dab0313ba633e.zip | |
[w3m-dev 02829]
From: Fumitoshi UKAI  <ukai@debian.or.jp>
Diffstat (limited to '')
| -rw-r--r-- | ChangeLog | 18 | ||||
| -rw-r--r-- | file.c | 24 | ||||
| -rw-r--r-- | istream.c | 194 | ||||
| -rw-r--r-- | istream.h | 7 | ||||
| -rw-r--r-- | url.c | 108 | 
5 files changed, 179 insertions, 172 deletions
| @@ -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 @@ -1870,4 +1886,4 @@  	* release-0-2-1  	* import w3m-0.2.1 -$Id: ChangeLog,v 1.210 2002/01/12 11:44:09 ukai Exp $ +$Id: ChangeLog,v 1.211 2002/01/12 13:33:47 ukai Exp $ @@ -1,4 +1,4 @@ -/* $Id: file.c,v 1.41 2002/01/11 20:11:48 ukai Exp $ */ +/* $Id: file.c,v 1.42 2002/01/12 13:33:47 ukai Exp $ */  #include "fm.h"  #include <sys/types.h>  #include "myctype.h" @@ -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 @@ -1,4 +1,4 @@ -/* $Id: istream.c,v 1.10 2001/12/27 18:22:59 ukai Exp $ */ +/* $Id: istream.c,v 1.11 2002/01/12 13:33:47 ukai Exp $ */  #include "fm.h"  #include "istream.h"  #include <signal.h> @@ -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 */ @@ -1,4 +1,4 @@ -/* $Id: istream.h,v 1.7 2001/12/26 18:46:33 ukai Exp $ */ +/* $Id: istream.h,v 1.8 2002/01/12 13:33:47 ukai Exp $ */  #ifndef IO_STREAM_H  #define IO_STREAM_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 @@ -1,4 +1,4 @@ -/* $Id: url.c,v 1.30 2002/01/10 15:39:21 ukai Exp $ */ +/* $Id: url.c,v 1.31 2002/01/12 13:33:47 ukai Exp $ */  #include "fm.h"  #include <sys/types.h>  #include <sys/socket.h> @@ -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;  } | 
