diff options
author | Thomas E. Dickey <dickey@invisible-island.net> | 2007-05-13 23:54:37 -0400 |
---|---|---|
committer | Thomas E. Dickey <dickey@invisible-island.net> | 2007-05-13 23:54:37 -0400 |
commit | cdf342faa36bbeea0fe2d8519d5b17f4b072f7f6 (patch) | |
tree | a84d747c5ffecaf8cda6424d36583905f42eda99 /WWW | |
parent | 741e82fc69b69a3bfc14f33f33766a89cea4df42 (diff) | |
download | lynx-snapshots-cdf342faa36bbeea0fe2d8519d5b17f4b072f7f6.tar.gz |
snapshot of project "lynx", label v2-8-7dev_4e
Diffstat (limited to 'WWW')
-rw-r--r-- | WWW/Library/Implementation/HTFile.c | 7 | ||||
-rw-r--r-- | WWW/Library/Implementation/HTString.c | 66 | ||||
-rw-r--r-- | WWW/Library/Implementation/HTTP.c | 142 | ||||
-rw-r--r-- | WWW/Library/Implementation/HTTelnet.c | 9 |
4 files changed, 172 insertions, 52 deletions
diff --git a/WWW/Library/Implementation/HTFile.c b/WWW/Library/Implementation/HTFile.c index b15c0448..f0fcdbc3 100644 --- a/WWW/Library/Implementation/HTFile.c +++ b/WWW/Library/Implementation/HTFile.c @@ -1,4 +1,7 @@ -/* File Access HTFile.c +/* + * $LynxId: HTFile.c,v 1.102 2007/05/13 17:29:41 tom Exp $ + * + * File Access HTFile.c * =========== * * This is unix-specific code in general, with some VMS bits. @@ -2250,7 +2253,9 @@ static int decompressAndParse(HTParentAnchor *anchor, * this is a compressed file, no need to look at the filename * again. - kw */ +#if defined(USE_ZLIB) || defined(USE_BZLIB) CompressFileType method = HTEncodingToCompressType(HTAtom_name(myEncoding)); +#endif #define isDOWNLOAD(m) (strcmp(format_out->name, "www/download") && (method == m)) #ifdef USE_ZLIB diff --git a/WWW/Library/Implementation/HTString.c b/WWW/Library/Implementation/HTString.c index e212c6f1..9728e549 100644 --- a/WWW/Library/Implementation/HTString.c +++ b/WWW/Library/Implementation/HTString.c @@ -1,4 +1,7 @@ -/* Case-independent string comparison HTString.c +/* + * $LynxId: HTString.c,v 1.48 2007/05/13 19:08:59 tom Exp $ + * + * Case-independent string comparison HTString.c * * Original version came with listserv implementation. * Version TBL Oct 91 replaces one which modified the strings. @@ -129,53 +132,48 @@ int strncasecomp(const char *a, } /*NOTREACHED */ } +#endif /* VM */ + +#define end_component(p) (*(p) == '.' || *(p) == '\0') /* - * Compare strings, ignoring case. If either begins with an asterisk, treat - * that as a wildcard to match zero-or-more characters. This does not test - * for embedded wildcards. + * Compare names as described in RFC 2818: ignore case, allow wildcards. + * Return zero on a match, nonzero on mismatch. + * + * From RFC 2818: + * Names may contain the wildcard character * which is considered to match any + * single domain name component or component fragment. E.g., *.a.com matches + * foo.a.com but not bar.foo.a.com. f*.com matches foo.com but not bar.com. */ int strcasecomp_asterisk(const char *a, const char *b) { - unsigned const char *us1 = (unsigned const char *) a; - unsigned const char *us2 = (unsigned const char *) b; + const char *p; int result = 0; - if ((*a != '*') && (*b != '*')) { - result = strcasecomp(a, b); - } else { - int dir = 1; - - if (*b == '*') { - us1 = us2; - us2 = (unsigned const char *) a; - dir = -1; - } - - if (strlen((const char *) us2) < (strlen((const char *) us1) - 1)) { - result = 1; - } else { - while (*++us1 != '\0') ; - while (*++us2 != '\0') ; - - while (1) { - unsigned char a1 = TOLOWER(*us1); - unsigned char b1 = TOLOWER(*us2); - - if (a1 != b1) { - result = (a1 > b1) ? dir : -dir; - break; - } else if ((*--us1) == '*') { - result = 0; + while (!result && *a != '\0' && *b != '\0') { + if (*a == '*') { + p = b; + ++a; + for (;;) { + if (strcasecomp_asterisk(a, p) && !end_component(p)) { + ++p; + result = 1; /* could not match */ + } else { + b = p; + result = 0; /* found a match starting here */ break; } - --us2; } + } else if (*b == '*') { + result = strcasecomp_asterisk(b, a); + } else if (TOLOWER(UCH(*a)) != TOLOWER(UCH(*b))) { + result = 1; } + ++a; + ++b; } return result; } -#endif /* VM */ #ifdef NOT_ASCII diff --git a/WWW/Library/Implementation/HTTP.c b/WWW/Library/Implementation/HTTP.c index a4f490f4..c0cd6e76 100644 --- a/WWW/Library/Implementation/HTTP.c +++ b/WWW/Library/Implementation/HTTP.c @@ -1,5 +1,8 @@ -/* HyperText Tranfer Protocol - Client implementation HTTP.c - * ========================== +/* + * $LynxId: HTTP.c,v 1.85 2007/05/13 21:08:19 tom Exp $ + * + * HyperText Tranfer Protocol - Client implementation HTTP.c + * ========================== * Modified: * 27 Jan 1994 PDM Added Ari Luotonen's Fix for Reload when using proxy * servers. @@ -42,6 +45,15 @@ #include <LYrcFile.h> #include <LYLeaks.h> +#ifdef USE_SSL +#ifdef USE_OPENSSL_INCL +#include <openssl/x509v3.h> +#endif +#ifdef USE_GNUTLS_INCL +#include <gnutls/x509.h> +#endif +#endif + struct _HTStream { HTStreamClass *isa; }; @@ -419,6 +431,23 @@ static BOOL acceptEncoding(int code) return result; } +#ifdef USE_SSL +static void show_cert_issuer(X509 * peer_cert) +{ +#if defined(USE_OPENSSL_INCL) + char ssl_dn[1024]; + char *msg = NULL; + + X509_NAME_oneline(X509_get_issuer_name(peer_cert), ssl_dn, sizeof(ssl_dn)); + HTSprintf0(&msg, gettext("Certificate issued by: %s"), ssl_dn); + _HTProgress(msg); + FREE(msg); +#elif defined(USE_GNUTLS_INCL) + /* the OpenSSL code compiles but dumps core with GNU TLS */ +#endif +} +#endif + /* Load Document from HTTP Server HTLoadHTTP() * ============================== * @@ -479,6 +508,7 @@ static int HTLoadHTTP(const char *arg, const char *connect_url = NULL; /* The URL being proxied */ char *connect_host = NULL; /* The host being proxied */ SSL *handle = NULL; /* The SSL handle */ + X509 *peer_cert; /* The peer certificate */ char ssl_dn[1024]; char *cert_host; char *ssl_host; @@ -486,7 +516,7 @@ static int HTLoadHTTP(const char *arg, char *msg = NULL; int status_sslcertcheck; char *ssl_dn_start; - char *ssl_all_cns; + char *ssl_all_cns = NULL; #ifdef USE_GNUTLS_INCL int ret; @@ -689,7 +719,8 @@ static int HTLoadHTTP(const char *arg, } #endif - X509_NAME_oneline(X509_get_subject_name(SSL_get_peer_certificate(handle)), + peer_cert = SSL_get_peer_certificate(handle); + X509_NAME_oneline(X509_get_subject_name(peer_cert), #ifndef USE_GNUTLS_INCL ssl_dn, sizeof(ssl_dn)); #else @@ -719,13 +750,16 @@ static int HTLoadHTTP(const char *arg, /* initialise status information */ status_sslcertcheck = 0; /* 0 = no CN found in DN */ ssl_dn_start = ssl_dn; - ssl_all_cns = NULL; /* get host we're connecting to */ ssl_host = HTParse(url, "", PARSE_HOST); - /* strip port number */ - if ((p = strchr(ssl_host, ':')) != NULL) + /* strip port number or extract hostname component */ + if ((p = strchr(ssl_host, (ssl_host[0] == '[') ? ']' : ':')) != NULL) *p = '\0'; + if (ssl_host[0] == '[') + ssl_host++; + /* validate all CNs found in DN */ + CTRACE((tfp, "Validating CNs in '%s'\n", ssl_dn_start)); while ((cert_host = strstr(ssl_dn_start, "/CN=")) != NULL) { status_sslcertcheck = 1; /* 1 = could not verify CN */ /* start of CommonName */ @@ -736,28 +770,36 @@ static int HTLoadHTTP(const char *arg, ssl_dn_start = p; /* yes this points to the NUL byte */ } else ssl_dn_start = NULL; - /* strip port number */ - if ((p = strchr(cert_host, ':')) != NULL) + /* strip port number (XXX [ip]:port encap here too? -TG) */ + if ((p = strchr(cert_host, + (cert_host[0] == '[') ? ']' : ':')) != NULL) *p = '\0'; + if (cert_host[0] == '[') + cert_host++; + /* verify this CN */ + CTRACE((tfp, "Matching\n\tssl_host '%s'\n\tcert_host '%s'\n", + ssl_host, cert_host)); if (!strcasecomp_asterisk(ssl_host, cert_host)) { status_sslcertcheck = 2; /* 2 = verified peer */ - /* I think this is cool to have in the logs --mirabilos */ + /* I think this is cool to have in the logs -TG */ HTSprintf0(&msg, gettext("Verified connection to %s (cert=%s)"), ssl_host, cert_host); _HTProgress(msg); FREE(msg); + show_cert_issuer(SSL_get_peer_certificate(handle)); /* no need to continue the verification loop */ break; } + /* add this CN to list of failed CNs */ - if (ssl_all_cns == NULL) { - StrAllocCopy(ssl_all_cns, cert_host); - } else { - StrAllocCat(ssl_all_cns, ":"); - StrAllocCat(ssl_all_cns, cert_host); - } + if (ssl_all_cns == NULL) + StrAllocCopy(ssl_all_cns, "CN<"); + else + StrAllocCat(ssl_all_cns, ":CN<"); + StrAllocCat(ssl_all_cns, cert_host); + StrAllocCat(ssl_all_cns, ">"); /* if we cannot retry, don't try it */ if (ssl_dn_start == NULL) break; @@ -765,6 +807,67 @@ static int HTLoadHTTP(const char *arg, *ssl_dn_start = '/'; /* formerly NUL byte */ } + /* check the X.509v3 Subject Alternative Name */ +#ifdef USE_OPENSSL_INCL + if (status_sslcertcheck < 2) { + STACK_OF(GENERAL_NAME) * gens; + int i, numalts; + const GENERAL_NAME *gn; + + if ((gens = X509_get_ext_d2i(peer_cert, NID_subject_alt_name, + NULL, NULL)) != NULL) { + numalts = sk_GENERAL_NAME_num(gens); + for (i = 0; i < numalts; ++i) { + gn = sk_GENERAL_NAME_value(gens, i); + if (gn->type == GEN_DNS) + cert_host = (char *) ASN1_STRING_data(gn->d.ia5); + else if (gn->type == GEN_IPADD) { + /* XXX untested -TG */ + size_t j = ASN1_STRING_length(gn->d.ia5); + + cert_host = malloc(j + 1); + memcpy(cert_host, ASN1_STRING_data(gn->d.ia5), j); + cert_host[j] = '\0'; + } else + continue; + status_sslcertcheck = 1; /* got at least one */ + /* verify this SubjectAltName (see above) */ + if ((p = strchr(cert_host, + (cert_host[0] == '[') ? ']' : ':')) != NULL) + *p = '\0'; + if (cert_host[0] == '[') + cert_host++; + if (!(gn->type == GEN_IPADD ? strcasecomp : + strcasecomp_asterisk) (ssl_host, cert_host)) { + status_sslcertcheck = 2; + HTSprintf0(&msg, + gettext("Verified connection to %s (subj=%s)"), + ssl_host, cert_host); + _HTProgress(msg); + FREE(msg); + if (gn->type == GEN_IPADD) + free(cert_host); + break; + } + /* add to list of failed CNs */ + if (ssl_all_cns == NULL) + StrAllocCopy(ssl_all_cns, "SAN<"); + else + StrAllocCat(ssl_all_cns, ":SAN<"); + if (gn->type == GEN_DNS) + StrAllocCat(ssl_all_cns, "DNS="); + else if (gn->type == GEN_IPADD) + StrAllocCat(ssl_all_cns, "IP="); + StrAllocCat(ssl_all_cns, cert_host); + StrAllocCat(ssl_all_cns, ">"); + if (gn->type == GEN_IPADD) + free(cert_host); + } + sk_GENERAL_NAME_free(gens); + } + } +#endif /* USE_OPENSSL_INCL */ + /* if an error occurred, format the appropriate message */ if (status_sslcertcheck == 0) { HTSprintf0(&msg, SSL_FORCED_PROMPT, @@ -783,8 +886,15 @@ static int HTLoadHTTP(const char *arg, FREE(ssl_all_cns); goto done; } + HTSprintf0(&msg, + gettext("UNVERIFIED connection to %s (cert=%s)"), + ssl_host, ssl_all_cns ? ssl_all_cns : "NONE"); + _HTProgress(msg); + FREE(msg); } + show_cert_issuer(peer_cert); + HTSprintf0(&msg, gettext("Secure %d-bit %s (%s) HTTP connection"), SSL_get_cipher_bits(handle, NULL), diff --git a/WWW/Library/Implementation/HTTelnet.c b/WWW/Library/Implementation/HTTelnet.c index 2260f6c0..c1ac3150 100644 --- a/WWW/Library/Implementation/HTTelnet.c +++ b/WWW/Library/Implementation/HTTelnet.c @@ -1,4 +1,7 @@ -/* Telnet Acees, Roligin, etc HTTelnet.c +/* + * $LynxId: HTTelnet.c,v 1.37 2007/05/13 16:27:23 tom Exp $ + * + * Telnet Access, Rlogin, etc HTTelnet.c * ========================== * * Authors @@ -35,6 +38,10 @@ #include <LYClean.h> #include <LYLeaks.h> +#ifdef __GNUC__ +static void do_system(char *) GCC_UNUSED; +#endif + static void do_system(char *command) { if (!isEmpty(command)) { |