From 6e8e7242dd82677d60945515bab59cfda63cf7db Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Mon, 30 Mar 2015 16:32:24 +0200 Subject: [PATCH] use OpenSSL instead of nss_compat_ossl ... which is no longer maintained --- elinks-0.12pre6-ssl-hostname.patch | 883 +++++++++++++++++++++++++++-- elinks-nss-inc.patch | 69 --- elinks-nss.patch | 265 --------- elinks.spec | 28 +- 4 files changed, 844 insertions(+), 401 deletions(-) delete mode 100644 elinks-nss-inc.patch delete mode 100644 elinks-nss.patch diff --git a/elinks-0.12pre6-ssl-hostname.patch b/elinks-0.12pre6-ssl-hostname.patch index 5a3820f..a51c6b8 100644 --- a/elinks-0.12pre6-ssl-hostname.patch +++ b/elinks-0.12pre6-ssl-hostname.patch @@ -1,70 +1,847 @@ -From cc428d37023b3f73458cf2054f19395035307045 Mon Sep 17 00:00:00 2001 -From: Kamil Dudka -Date: Wed, 18 Sep 2013 13:42:40 +0200 -Subject: [PATCH] verify server certificate hostname with nss_compat_ossl +From 30d96f81dbefffd3f1523256cc5a5328ea1c7ecb Mon Sep 17 00:00:00 2001 +From: Kalle Olavi Niemitalo +Date: Mon, 2 May 2011 14:41:40 +0300 +Subject: [PATCH 1/3] 1024: Use RFC 3546 server_name TLS extension -Bug: https://bugzilla.redhat.com/881411 +For both GnuTLS and OpenSSL. Not tested with nss-compat-openssl. + +Signed-off-by: Kamil Dudka --- - src/network/ssl/socket.c | 32 ++++++++++++++++++++++++++++++++ - 1 files changed, 32 insertions(+), 0 deletions(-) + src/network/ssl/socket.c | 19 ++++++++++++++++++- + src/network/ssl/ssl.c | 29 ++++++++++++++++++++++++----- + src/network/ssl/ssl.h | 14 ++++++++++++-- + 3 files changed, 54 insertions(+), 8 deletions(-) diff --git a/src/network/ssl/socket.c b/src/network/ssl/socket.c -index 3265107..0aeb037 100644 +index 45b4b4a..dc682d0 100644 --- a/src/network/ssl/socket.c +++ b/src/network/ssl/socket.c -@@ -9,6 +9,9 @@ - #define USE_OPENSSL - #elif defined(CONFIG_NSS_COMPAT_OSSL) - #include -+#include /* for PR_GetError() */ -+#include /* for SSL_SetURL() */ -+#include "protocol/uri.h" /* for get_uri_string() */ - #define USE_OPENSSL - #elif defined(CONFIG_GNUTLS) - #include -@@ -116,6 +119,19 @@ ssl_want_read(struct socket *socket) - } - } +@@ -22,6 +22,7 @@ + #include "network/socket.h" + #include "network/ssl/socket.h" + #include "network/ssl/ssl.h" ++#include "protocol/uri.h" + #include "util/memory.h" -+#ifdef CONFIG_NSS_COMPAT_OSSL -+/* wrap nss_compat_ossl to honour SSL_ERROR_BAD_CERT_DOMAIN */ -+SECStatus BadCertHandler(void *arg, PRFileDesc *ssl); -+static SECStatus nss_bad_cert_hook(void *arg, PRFileDesc *ssl) -+{ -+ if (SSL_ERROR_BAD_CERT_DOMAIN == PR_GetError()) -+ return SECFailure; -+ -+ /* fallback to the default hook of nss_compat_ossl */ -+ return BadCertHandler(arg, ssl); -+} -+#endif -+ - /* Return -1 on error, 0 or success. */ - int + +@@ -117,12 +118,28 @@ int ssl_connect(struct socket *socket) -@@ -127,6 +143,22 @@ ssl_connect(struct socket *socket) + { + int ret; ++ unsigned char *server_name; ++ struct connection *conn = socket->conn; + +- if (init_ssl_connection(socket) == S_SSL_ERROR) { ++ /* TODO: Recode server_name to UTF-8. */ ++ server_name = get_uri_string(conn->proxied_uri, URI_HOST); ++ if (!server_name) { ++ socket->ops->done(socket, connection_state(S_OUT_OF_MEM)); ++ return -1; ++ } ++ ++ /* RFC 3546 says literal IPv4 and IPv6 addresses are not allowed. */ ++ if (is_ip_address(server_name, strlen(server_name))) ++ mem_free_set(&server_name, NULL); ++ ++ if (init_ssl_connection(socket, server_name) == S_SSL_ERROR) { ++ mem_free_if(server_name); + socket->ops->done(socket, connection_state(S_SSL_ERROR)); return -1; } -+#ifdef CONFIG_NSS_COMPAT_OSSL -+ /* fix for https://bugzilla.redhat.com/881411 */ -+ { -+ struct connection *conn = socket->conn; -+ unsigned char *host = get_uri_string(conn->uri, URI_HOST); -+ if (!host -+ || SECSuccess != SSL_SetURL(socket->ssl, host) -+ || SECSuccess != SSL_BadCertHook(socket->ssl, -+ nss_bad_cert_hook, /* XXX */ NULL)) -+ { -+ socket->ops->done(socket, connection_state(S_SSL_ERROR)); -+ return -1; -+ } -+ } -+#endif ++ mem_free_if(server_name); + if (socket->no_tls) ssl_set_no_tls(socket); +diff --git a/src/network/ssl/ssl.c b/src/network/ssl/ssl.c +index 685c31e..7767a71 100644 +--- a/src/network/ssl/ssl.c ++++ b/src/network/ssl/ssl.c +@@ -212,13 +212,26 @@ struct module ssl_module = struct_module( + ); + + int +-init_ssl_connection(struct socket *socket) ++init_ssl_connection(struct socket *socket, ++ const unsigned char *server_name) + { + #ifdef CONFIG_OPENSSL + socket->ssl = SSL_new(context); + if (!socket->ssl) return S_SSL_ERROR; ++ ++ /* If the server name is known, pass it to OpenSSL. ++ * ++ * The return value of SSL_set_tlsext_host_name is not ++ * documented. The source shows that it returns 1 if ++ * successful; on error, it calls SSLerr and returns 0. */ ++ if (server_name ++ && !SSL_set_tlsext_host_name(socket->ssl, server_name)) { ++ SSL_free(socket->ssl); ++ socket->ssl = NULL; ++ return S_SSL_ERROR; ++ } ++ + #elif defined(CONFIG_GNUTLS) +- /* const unsigned char server_name[] = "localhost"; */ + ssl_t *state = mem_alloc(sizeof(ssl_t)); + + if (!state) return S_SSL_ERROR; +@@ -255,9 +268,15 @@ init_ssl_connection(struct socket *socket) + /* gnutls_handshake_set_private_extensions(*state, 1); */ + gnutls_cipher_set_priority(*state, cipher_priority); + gnutls_kx_set_priority(*state, kx_priority); +- /* gnutls_certificate_type_set_priority(*state, cert_type_priority); +- gnutls_server_name_set(*state, GNUTLS_NAME_DNS, server_name, +- sizeof(server_name) - 1); */ ++ /* gnutls_certificate_type_set_priority(*state, cert_type_priority); */ ++ ++ if (server_name ++ && gnutls_server_name_set(*state, GNUTLS_NAME_DNS, server_name, ++ strlen(server_name))) { ++ gnutls_deinit(*state); ++ mem_free(state); ++ return S_SSL_ERROR; ++ } + + socket->ssl = state; + #endif +diff --git a/src/network/ssl/ssl.h b/src/network/ssl/ssl.h +index 7c54a7a..bfd94e1 100644 +--- a/src/network/ssl/ssl.h ++++ b/src/network/ssl/ssl.h +@@ -11,8 +11,18 @@ struct socket; + extern struct module ssl_module; + + /* Initializes the SSL connection data. Returns S_OK on success and S_SSL_ERROR +- * on failure. */ +-int init_ssl_connection(struct socket *socket); ++ * on failure. ++ * ++ * server_name is the DNS name of the server (in UTF-8), or NULL if ++ * ELinks knows only the IP address. ELinks reports that name to the ++ * server so that the server can choose the correct certificate if it ++ * has multiple virtual hosts on the same IP address. See RFC 3546 ++ * section 3.1. ++ * ++ * server_name does not affect how ELinks verifies the certificate ++ * after the server has returned it. */ ++int init_ssl_connection(struct socket *socket, ++ const unsigned char *server_name); + + /* Releases the SSL connection data */ + void done_ssl_connection(struct socket *socket); -- -1.7.1 +2.1.0 + + +From e7484a980572b665747c28aa1376e29a12fb4b19 Mon Sep 17 00:00:00 2001 +From: Kalle Olavi Niemitalo +Date: Tue, 3 May 2011 03:52:21 +0300 +Subject: [PATCH 2/3] 1024: Verify server certificate hostname with OpenSSL + +Not tested with nss-compat-ossl. + +Signed-off-by: Kamil Dudka +--- + src/network/ssl/Makefile | 7 +- + src/network/ssl/match-hostname.c | 125 +++++++++++++++++ + src/network/ssl/match-hostname.h | 10 ++ + src/network/ssl/socket.c | 211 ++++++++++++++++++++++++++++- + src/network/ssl/ssl.c | 41 +++++- + src/network/ssl/ssl.h | 3 + + src/network/ssl/test/Makefile | 9 ++ + src/network/ssl/test/match-hostname-test.c | 123 +++++++++++++++++ + src/network/ssl/test/test-match-hostname | 3 + + 9 files changed, 529 insertions(+), 3 deletions(-) + create mode 100644 src/network/ssl/match-hostname.c + create mode 100644 src/network/ssl/match-hostname.h + create mode 100644 src/network/ssl/test/Makefile + create mode 100644 src/network/ssl/test/match-hostname-test.c + create mode 100755 src/network/ssl/test/test-match-hostname + +diff --git a/src/network/ssl/Makefile b/src/network/ssl/Makefile +index 26f02c2..6f265da 100644 +--- a/src/network/ssl/Makefile ++++ b/src/network/ssl/Makefile +@@ -3,6 +3,11 @@ include $(top_builddir)/Makefile.config + + INCLUDES += $(GNUTLS_CFLAGS) $(OPENSSL_CFLAGS) + +-OBJS = ssl.o socket.o ++SUBDIRS = test ++ ++# ELinks uses match-hostname.o only if CONFIG_OPENSSL. ++# However, match-hostname.o has test cases that always need it. ++# The test framework doesn't seem to support conditional tests. ++OBJS = match-hostname.o ssl.o socket.o + + include $(top_srcdir)/Makefile.lib +diff --git a/src/network/ssl/match-hostname.c b/src/network/ssl/match-hostname.c +new file mode 100644 +index 0000000..9a64bb4 +--- /dev/null ++++ b/src/network/ssl/match-hostname.c +@@ -0,0 +1,125 @@ ++/* Matching a host name to wildcards in SSL certificates */ ++ ++#ifdef HAVE_CONFIG_H ++#include "config.h" ++#endif ++ ++#include "elinks.h" ++ ++#include "intl/charsets.h" ++#include "network/ssl/match-hostname.h" ++#include "util/conv.h" ++#include "util/error.h" ++#include "util/string.h" ++ ++/** Checks whether a host name matches a pattern that may contain ++ * wildcards. ++ * ++ * @param[in] hostname ++ * The host name to which the user wanted to connect. ++ * Should be in UTF-8 and need not be null-terminated. ++ * @param[in] hostname_length ++ * The length of @a hostname, in bytes. ++ * @param[in] pattern ++ * A pattern that the host name might match. ++ * Should be in UTF-8 and need not be null-terminated. ++ * The pattern may contain wildcards, as specified in ++ * RFC 2818 section 3.1. ++ * @param[in] pattern_length ++ * The length of @a pattern, in bytes. ++ * ++ * @return ++ * Nonzero if the host name matches. Zero if it doesn't. ++ * ++ * According to RFC 2818 section 3.1, '*' matches any number of ++ * characters except '.'. For example, "*r*.example.org" matches ++ * "random.example.org" or "history.example.org" but not ++ * "frozen.fruit.example.org". ++ * ++ * This function does not allocate memory, and consumes at most ++ * O(@a hostname_length * @a pattern_length) time. */ ++int ++match_hostname_pattern(const unsigned char *hostname, ++ size_t hostname_length, ++ const unsigned char *pattern, ++ size_t pattern_length) ++{ ++ const unsigned char *const hostname_end = hostname + hostname_length; ++ const unsigned char *const pattern_end = pattern + pattern_length; ++ ++ assert(hostname <= hostname_end); ++ assert(pattern <= pattern_end); ++ if_assert_failed return 0; ++ ++ while (pattern < pattern_end) { ++ if (*pattern == '*') { ++ const unsigned char *next_wildcard; ++ size_t literal_length; ++ ++ ++pattern; ++ next_wildcard = memchr(pattern, '*', ++ pattern_end - pattern); ++ if (next_wildcard == NULL) ++ literal_length = pattern_end - pattern; ++ else ++ literal_length = next_wildcard - pattern; ++ ++ for (;;) { ++ size_t hostname_left = hostname_end - hostname; ++ unicode_val_T uni; ++ ++ if (hostname_left < literal_length) ++ return 0; ++ ++ /* If next_wildcard == NULL, then the ++ * literal string is at the end of the ++ * pattern, so anchor the match to the ++ * end of the hostname. The end of ++ * this function can then easily ++ * verify that the whole hostname was ++ * matched. ++ * ++ * But do not jump directly there; ++ * first verify that there are no '.' ++ * characters in between. */ ++ if ((next_wildcard != NULL ++ || hostname_left == literal_length) ++ && !c_strlcasecmp(pattern, literal_length, ++ hostname, literal_length)) ++ break; ++ ++ /* The literal string doesn't match here. ++ * Skip one character of the hostname and ++ * retry. If the skipped character is '.' ++ * or one of the equivalent characters ++ * listed in RFC 3490 section 3.1 ++ * requirement 1, then return 0, because ++ * '*' must not match such characters. ++ * Do the same if invalid UTF-8 is found. ++ * Cast away const. */ ++ uni = utf8_to_unicode((unsigned char **) hostname, ++ hostname_end); ++ if (uni == 0x002E ++ || uni == 0x3002 ++ || uni == 0xFF0E ++ || uni == 0xFF61 ++ || uni == UCS_NO_CHAR) ++ return 0; ++ } ++ ++ pattern += literal_length; ++ hostname += literal_length; ++ } else { ++ if (hostname == hostname_end) ++ return 0; ++ ++ if (c_toupper(*pattern) != c_toupper(*hostname)) ++ return 0; ++ ++ ++pattern; ++ ++hostname; ++ } ++ } ++ ++ return hostname == hostname_end; ++} +diff --git a/src/network/ssl/match-hostname.h b/src/network/ssl/match-hostname.h +new file mode 100644 +index 0000000..60d32b2 +--- /dev/null ++++ b/src/network/ssl/match-hostname.h +@@ -0,0 +1,10 @@ ++ ++#ifndef EL__NETWORK_SSL_MATCH_HOSTNAME_H ++#define EL__NETWORK_SSL_MATCH_HOSTNAME_H ++ ++int match_hostname_pattern(const unsigned char *hostname, ++ size_t hostname_length, ++ const unsigned char *pattern, ++ size_t pattern_length); ++ ++#endif +diff --git a/src/network/ssl/socket.c b/src/network/ssl/socket.c +index dc682d0..a67bbde 100644 +--- a/src/network/ssl/socket.c ++++ b/src/network/ssl/socket.c +@@ -6,13 +6,24 @@ + + #ifdef CONFIG_OPENSSL + #include ++#include ++#define USE_OPENSSL ++#elif defined(CONFIG_NSS_COMPAT_OSSL) ++#include ++#define USE_OPENSSL + #elif defined(CONFIG_GNUTLS) + #include + #else + #error "Huh?! You have SSL enabled, but not OPENSSL nor GNUTLS!! And then you want exactly *what* from me?" + #endif + ++#ifdef HAVE_ARPA_INET_H ++#include ++#endif + #include ++#ifdef HAVE_NETINET_IN_H ++#include ++#endif + + #include "elinks.h" + +@@ -20,6 +31,7 @@ + #include "main/select.h" + #include "network/connection.h" + #include "network/socket.h" ++#include "network/ssl/match-hostname.h" + #include "network/ssl/socket.h" + #include "network/ssl/ssl.h" + #include "protocol/uri.h" +@@ -83,6 +95,203 @@ ssl_set_no_tls(struct socket *socket) + #endif + } + ++#ifdef USE_OPENSSL ++ ++/** Checks whether the host component of a URI matches a host name in ++ * the server certificate. ++ * ++ * @param[in] uri_host ++ * The host name (or IP address) to which the user wanted to connect. ++ * Should be in UTF-8. ++ * @param[in] cert_host_asn1 ++ * A host name found in the server certificate: either as commonName ++ * in the subject field, or as a dNSName in the subjectAltName ++ * extension. This may contain wildcards, as specified in RFC 2818 ++ * section 3.1. ++ * ++ * @return ++ * Nonzero if the host matches. Zero if it doesn't, or on error. ++ * ++ * If @a uri_host is an IP address literal rather than a host name, ++ * then this function returns 0, meaning that the host name does not match. ++ * According to RFC 2818, if the certificate is intended to match an ++ * IP address, then it must have that IP address as an iPAddress ++ * SubjectAltName, rather than in commonName. For comparing those, ++ * match_uri_host_ip() must be used instead of this function. */ ++static int ++match_uri_host_name(const unsigned char *uri_host, ++ ASN1_STRING *cert_host_asn1) ++{ ++ const size_t uri_host_len = strlen(uri_host); ++ unsigned char *cert_host = NULL; ++ int cert_host_len; ++ int matched = 0; ++ ++ if (is_ip_address(uri_host, uri_host_len)) ++ goto mismatch; ++ ++ /* This function is used for both dNSName and commonName. ++ * Although dNSName is always an IA5 string, commonName allows ++ * many other encodings too. Normalize all to UTF-8. */ ++ cert_host_len = ASN1_STRING_to_UTF8(&cert_host, ++ cert_host_asn1); ++ if (cert_host_len < 0) ++ goto mismatch; ++ ++ matched = match_hostname_pattern(uri_host, uri_host_len, ++ cert_host, cert_host_len); ++ ++mismatch: ++ if (cert_host) ++ OPENSSL_free(cert_host); ++ return matched; ++} ++ ++/** Checks whether the host component of a URI matches an IP address ++ * in the server certificate. ++ * ++ * @param[in] uri_host ++ * The IP address (or host name) to which the user wanted to connect. ++ * Should be in UTF-8. ++ * @param[in] cert_host_asn1 ++ * An IP address found as iPAddress in the subjectAltName extension ++ * of the server certificate. According to RFC 5280 section 4.2.1.6, ++ * that is an octet string in network byte order. According to ++ * RFC 2818 section 3.1, wildcards are not allowed. ++ * ++ * @return ++ * Nonzero if the host matches. Zero if it doesn't, or on error. ++ * ++ * If @a uri_host is a host name rather than an IP address literal, ++ * then this function returns 0, meaning that the address does not match. ++ * This function does not try to resolve the host name to an IP address ++ * and compare that to @a cert_host_asn1, because such an approach would ++ * be vulnerable to DNS spoofing. ++ * ++ * This function does not support the address-and-netmask format used ++ * in the name constraints extension of a CA certificate (RFC 5280 ++ * section 4.2.1.10). */ ++static int ++match_uri_host_ip(const unsigned char *uri_host, ++ ASN1_OCTET_STRING *cert_host_asn1) ++{ ++ const unsigned char *cert_host_addr = ASN1_STRING_data(cert_host_asn1); ++ struct in_addr uri_host_in; ++#ifdef CONFIG_IPV6 ++ struct in6_addr uri_host_in6; ++#endif ++ ++ /* RFC 5280 defines the iPAddress alternative of GeneralName ++ * as an OCTET STRING. Verify that the type is indeed that. ++ * This is an assertion because, if someone puts the wrong ++ * type of data there, then it will not even be recognized as ++ * an iPAddress, and this function will not be called. ++ * ++ * (Because GeneralName is defined in an implicitly tagged ++ * ASN.1 module, the OCTET STRING tag is not part of the DER ++ * encoding. BER also allows a constructed encoding where ++ * each substring begins with the OCTET STRING tag; but ITU-T ++ * Rec. X.690 (07/2002) subclause 8.21 says those would be ++ * OCTET STRING even if the outer string were of some other ++ * type. "A Layman's Guide to a Subset of ASN.1, BER, and ++ * DER" (Kaliski, 1993) claims otherwise, though.) */ ++ assert(ASN1_STRING_type(cert_host_asn1) == V_ASN1_OCTET_STRING); ++ if_assert_failed return 0; ++ ++ /* cert_host_addr, url_host_in, and url_host_in6 are all in ++ * network byte order. */ ++ switch (ASN1_STRING_length(cert_host_asn1)) { ++ case 4: ++ return inet_aton(uri_host, &uri_host_in) != 0 ++ && memcmp(cert_host_addr, &uri_host_in.s_addr, 4) == 0; ++ ++#ifdef CONFIG_IPV6 ++ case 16: ++ return inet_pton(AF_INET6, uri_host, &uri_host_in6) == 1 ++ && memcmp(cert_host_addr, &uri_host_in6.s6_addr, 16) == 0; ++#endif ++ ++ default: ++ return 0; ++ } ++} ++ ++/** Verify one certificate in the server certificate chain. ++ * This callback is documented in SSL_set_verify(3). */ ++static int ++verify_callback(int preverify_ok, X509_STORE_CTX *ctx) ++{ ++ X509 *cert; ++ SSL *ssl; ++ struct socket *socket; ++ struct connection *conn; ++ unsigned char *host_in_uri; ++ GENERAL_NAMES *alts; ++ int saw_dns_name = 0; ++ int matched = 0; ++ ++ /* If OpenSSL already found a problem, keep that. */ ++ if (!preverify_ok) ++ return 0; ++ ++ /* Examine only the server certificate, not CA certificates. */ ++ if (X509_STORE_CTX_get_error_depth(ctx) != 0) ++ return preverify_ok; ++ ++ cert = X509_STORE_CTX_get_current_cert(ctx); ++ ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx()); ++ socket = SSL_get_ex_data(ssl, socket_SSL_ex_data_idx); ++ conn = socket->conn; ++ host_in_uri = get_uri_string(conn->uri, URI_HOST | URI_IDN); ++ if (!host_in_uri) ++ return 0; ++ ++ /* RFC 5280 section 4.2.1.6 describes the subjectAltName extension. ++ * RFC 2818 section 3.1 says Common Name must not be used ++ * if dNSName is present. */ ++ alts = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL); ++ if (alts != NULL) { ++ int alt_count; ++ int alt_pos; ++ GENERAL_NAME *alt; ++ ++ alt_count = sk_GENERAL_NAME_num(alts); ++ for (alt_pos = 0; !matched && alt_pos < alt_count; ++alt_pos) { ++ alt = sk_GENERAL_NAME_value(alts, alt_pos); ++ if (alt->type == GEN_DNS) { ++ saw_dns_name = 1; ++ matched = match_uri_host_name(host_in_uri, ++ alt->d.dNSName); ++ } else if (alt->type == GEN_IPADD) { ++ matched = match_uri_host_ip(host_in_uri, ++ alt->d.iPAddress); ++ } ++ } ++ ++ /* Free the GENERAL_NAMES list and each element. */ ++ sk_GENERAL_NAME_pop_free(alts, GENERAL_NAME_free); ++ } ++ ++ if (!matched && !saw_dns_name) { ++ X509_NAME *name; ++ int cn_index; ++ X509_NAME_ENTRY *entry = NULL; ++ ++ name = X509_get_subject_name(cert); ++ cn_index = X509_NAME_get_index_by_NID(name, NID_commonName, -1); ++ if (cn_index >= 0) ++ entry = X509_NAME_get_entry(name, cn_index); ++ if (entry != NULL) ++ matched = match_uri_host_name(host_in_uri, ++ X509_NAME_ENTRY_get_data(entry)); ++ } ++ ++ mem_free(host_in_uri); ++ return matched; ++} ++ ++#endif /* USE_OPENSSL */ ++ + static void + ssl_want_read(struct socket *socket) + { +@@ -149,7 +358,7 @@ ssl_connect(struct socket *socket) + if (get_opt_bool("connection.ssl.cert_verify")) + SSL_set_verify(socket->ssl, SSL_VERIFY_PEER + | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, +- NULL); ++ verify_callback); + + if (get_opt_bool("connection.ssl.client_cert.enable")) { + unsigned char *client_cert; +diff --git a/src/network/ssl/ssl.c b/src/network/ssl/ssl.c +index 7767a71..d1881c8 100644 +--- a/src/network/ssl/ssl.c ++++ b/src/network/ssl/ssl.c +@@ -39,7 +39,35 @@ + #define PATH_MAX 256 /* according to my /usr/include/bits/posix1_lim.h */ + #endif + +-SSL_CTX *context = NULL; ++static SSL_CTX *context = NULL; ++int socket_SSL_ex_data_idx = -1; ++ ++/** Prevent SSL_dup() if the SSL is associated with struct socket. ++ * We cannot copy struct socket and it doesn't have a reference count ++ * either. */ ++static int ++socket_SSL_ex_data_dup(CRYPTO_EX_DATA *to, CRYPTO_EX_DATA *from, ++ void *from_d, int idx, long argl, void *argp) ++{ ++ /* The documentation of from_d in RSA_get_ex_new_index(3) ++ * is a bit unclear. The caller does something like: ++ * ++ * void *data = CRYPTO_get_ex_data(from, idx); ++ * socket_SSL_dup(to, from, &data, idx, argl, argp); ++ * CRYPTO_set_ex_data(to, idx, data); ++ * ++ * i.e., from_d always points to a pointer, even though ++ * it is just a void * in the prototype. */ ++ struct socket *socket = *(void **) from_d; ++ ++ assert(idx == socket_SSL_ex_data_idx); ++ if_assert_failed return 0; ++ ++ if (socket) ++ return 0; /* prevent SSL_dup() */ ++ else ++ return 1; /* allow SSL_dup() */ ++} + + static void + init_openssl(struct module *module) +@@ -48,12 +76,17 @@ init_openssl(struct module *module) + context = SSL_CTX_new(SSLv23_client_method()); + SSL_CTX_set_options(context, SSL_OP_ALL); + SSL_CTX_set_default_verify_paths(context); ++ socket_SSL_ex_data_idx = SSL_get_ex_new_index(0, NULL, ++ NULL, ++ socket_SSL_ex_data_dup, ++ NULL); + } + + static void + done_openssl(struct module *module) + { + if (context) SSL_CTX_free(context); ++ /* There is no function that undoes SSL_get_ex_new_index. */ + } + + static union option_info openssl_options[] = { +@@ -219,6 +252,12 @@ init_ssl_connection(struct socket *socket, + socket->ssl = SSL_new(context); + if (!socket->ssl) return S_SSL_ERROR; + ++ if (!SSL_set_ex_data(socket->ssl, socket_SSL_ex_data_idx, socket)) { ++ SSL_free(socket->ssl); ++ socket->ssl = NULL; ++ return S_SSL_ERROR; ++ } ++ + /* If the server name is known, pass it to OpenSSL. + * + * The return value of SSL_set_tlsext_host_name is not +diff --git a/src/network/ssl/ssl.h b/src/network/ssl/ssl.h +index bfd94e1..480b4db 100644 +--- a/src/network/ssl/ssl.h ++++ b/src/network/ssl/ssl.h +@@ -29,6 +29,9 @@ void done_ssl_connection(struct socket *socket); + + unsigned char *get_ssl_connection_cipher(struct socket *socket); + ++#if defined(CONFIG_OPENSSL) || defined(CONFIG_NSS_COMPAT_OSSL) ++extern int socket_SSL_ex_data_idx; ++#endif + + /* Internal type used in ssl module. */ + +diff --git a/src/network/ssl/test/Makefile b/src/network/ssl/test/Makefile +new file mode 100644 +index 0000000..f2196eb +--- /dev/null ++++ b/src/network/ssl/test/Makefile +@@ -0,0 +1,9 @@ ++top_builddir=../../../.. ++include $(top_builddir)/Makefile.config ++ ++SUBDIRS = ++TEST_PROGS = match-hostname-test ++TESTDEPS += \ ++ $(top_builddir)/src/network/ssl/match-hostname.o ++ ++include $(top_srcdir)/Makefile.lib +diff --git a/src/network/ssl/test/match-hostname-test.c b/src/network/ssl/test/match-hostname-test.c +new file mode 100644 +index 0000000..fbdf6fa +--- /dev/null ++++ b/src/network/ssl/test/match-hostname-test.c +@@ -0,0 +1,123 @@ ++/* Test match_hostname_pattern() */ ++ ++#ifdef HAVE_CONFIG_H ++#include "config.h" ++#endif ++ ++#include ++#include ++ ++#include "elinks.h" ++ ++#include "network/ssl/match-hostname.h" ++#include "util/string.h" ++ ++struct match_hostname_pattern_test_case ++{ ++ const unsigned char *pattern; ++ const unsigned char *hostname; ++ int match; ++}; ++ ++static const struct match_hostname_pattern_test_case match_hostname_pattern_test_cases[] = { ++ { "*r*.example.org", "random.example.org", 1 }, ++ { "*r*.example.org", "history.example.org", 1 }, ++ { "*r*.example.org", "frozen.fruit.example.org", 0 }, ++ { "*r*.example.org", "steamed.fruit.example.org", 0 }, ++ ++ { "ABC.def.Ghi", "abc.DEF.gHI", 1 }, ++ ++ { "*", "localhost", 1 }, ++ { "*", "example.org", 0 }, ++ { "*.*", "example.org", 1 }, ++ { "*.*.*", "www.example.org", 1 }, ++ { "*.*.*", "example.org", 0 }, ++ ++ { "assign", "assignee", 0 }, ++ { "*peg", "arpeggiator", 0 }, ++ { "*peg*", "arpeggiator", 1 }, ++ { "*r*gi*", "arpeggiator", 1 }, ++ { "*r*git*", "arpeggiator", 0 }, ++ ++ { NULL, NULL, 0 } ++}; ++ ++int ++main(void) ++{ ++ const struct match_hostname_pattern_test_case *test; ++ int count_ok = 0; ++ int count_fail = 0; ++ struct string hostname_str = NULL_STRING; ++ struct string pattern_str = NULL_STRING; ++ ++ if (!init_string(&hostname_str) || !init_string(&pattern_str)) { ++ fputs("Out of memory.\n", stderr); ++ done_string(&hostname_str); ++ done_string(&pattern_str); ++ return EXIT_FAILURE; ++ } ++ ++ for (test = match_hostname_pattern_test_cases; test->pattern; test++) { ++ int match; ++ ++ match = match_hostname_pattern( ++ test->hostname, ++ strlen(test->hostname), ++ test->pattern, ++ strlen(test->pattern)); ++ if (!match == !test->match) { ++ /* Test OK */ ++ count_ok++; ++ } else { ++ fprintf(stderr, "match_hostname_pattern() test failed\n" ++ "\tHostname: %s\n" ++ "\tPattern: %s\n" ++ "\tActual result: %d\n" ++ "\tCorrect result: %d\n", ++ test->hostname, ++ test->pattern, ++ match, ++ test->match); ++ count_fail++; ++ } ++ ++ /* Try with strings that are not null-terminated. */ ++ hostname_str.length = 0; ++ add_to_string(&hostname_str, test->hostname); ++ add_to_string(&hostname_str, "ZZZ"); ++ pattern_str.length = 0; ++ add_to_string(&pattern_str, test->pattern); ++ add_to_string(&hostname_str, "______"); ++ ++ match = match_hostname_pattern( ++ hostname_str.source, ++ strlen(test->hostname), ++ pattern_str.source, ++ strlen(test->pattern)); ++ if (!match == !test->match) { ++ /* Test OK */ ++ count_ok++; ++ } else { ++ fprintf(stderr, "match_hostname_pattern() test failed\n" ++ "\tVariant: Strings were not null-terminated.\n" ++ "\tHostname: %s\n" ++ "\tPattern: %s\n" ++ "\tActual result: %d\n" ++ "\tCorrect result: %d\n", ++ test->hostname, ++ test->pattern, ++ match, ++ test->match); ++ count_fail++; ++ } ++ } ++ ++ printf("Summary of match_hostname_pattern() tests: %d OK, %d failed.\n", ++ count_ok, count_fail); ++ ++ done_string(&hostname_str); ++ done_string(&pattern_str); ++ return count_fail ? EXIT_FAILURE : EXIT_SUCCESS; ++ ++} +diff --git a/src/network/ssl/test/test-match-hostname b/src/network/ssl/test/test-match-hostname +new file mode 100755 +index 0000000..01d7173 +--- /dev/null ++++ b/src/network/ssl/test/test-match-hostname +@@ -0,0 +1,3 @@ ++#! /bin/sh -e ++ ++./match-hostname-test +-- +2.1.0 + + +From 0cb6967bb9ccabc583bbdc6ee76baf4fdf0f90cc Mon Sep 17 00:00:00 2001 +From: mancha +Date: Sun, 15 Jul 2012 23:27:53 +0200 +Subject: [PATCH 3/3] Fix hostname verification code. + +[ From bug 1123 attachment 569. --KON ] + +Signed-off-by: Kamil Dudka +--- + src/network/ssl/match-hostname.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/network/ssl/match-hostname.c b/src/network/ssl/match-hostname.c +index 9a64bb4..80d93b0 100644 +--- a/src/network/ssl/match-hostname.c ++++ b/src/network/ssl/match-hostname.c +@@ -97,7 +97,7 @@ match_hostname_pattern(const unsigned char *hostname, + * '*' must not match such characters. + * Do the same if invalid UTF-8 is found. + * Cast away const. */ +- uni = utf8_to_unicode((unsigned char **) hostname, ++ uni = utf8_to_unicode((unsigned char **) &hostname, + hostname_end); + if (uni == 0x002E + || uni == 0x3002 +-- +2.1.0 diff --git a/elinks-nss-inc.patch b/elinks-nss-inc.patch deleted file mode 100644 index 666fc6b..0000000 --- a/elinks-nss-inc.patch +++ /dev/null @@ -1,69 +0,0 @@ - src/network/ssl/ssl.c | 33 ++++++++++++++++++++++++++++++++- - 1 files changed, 32 insertions(+), 1 deletions(-) - -diff --git a/src/network/ssl/ssl.c b/src/network/ssl/ssl.c -index 73446b5..eadff7f 100644 ---- a/src/network/ssl/ssl.c -+++ b/src/network/ssl/ssl.c -@@ -48,10 +48,20 @@ SSL_CTX *context = NULL; - static void - init_openssl(struct module *module) - { -+ unsigned char *ca_file; - SSLeay_add_ssl_algorithms(); - context = SSL_CTX_new(SSLv23_client_method()); - SSL_CTX_set_options(context, SSL_OP_ALL); -+#ifdef CONFIG_NSS_COMPAT_OSSL -+ ca_file = get_opt_str("connection.ssl.trusted_ca_file"); -+ if (*ca_file) -+ SSL_CTX_load_verify_locations(context, ca_file, NULL); -+ else -+ SSL_CTX_set_default_verify_paths(context); -+#else -+ (void) ca_file; - SSL_CTX_set_default_verify_paths(context); -+#endif - } - - static void -@@ -61,10 +71,30 @@ done_openssl(struct module *module) - } - - static union option_info openssl_options[] = { -+#ifdef CONFIG_NSS_COMPAT_OSSL -+ INIT_OPT_BOOL("connection.ssl", N_("Verify certificates"), -+ "cert_verify", 0, 0, -+ N_("Verify the peer's SSL certificate.")), -+ -+ INIT_OPT_STRING("connection.ssl", N_("Trusted CA file"), -+ "trusted_ca_file", 0, "/etc/pki/tls/certs/ca-bundle.crt", -+ N_("The location of a file containing certificates of " -+ "trusted certification authorities in PEM format. " -+ "ELinks then trusts certificates issued by these CAs.\n" -+ "\n" -+ "If you set this option to an empty string, default NSS root" -+ "certificates are loaded.\n" -+ "\n" -+ "If you change this option or the file, you must " -+ "restart ELinks for the changes to take effect. " -+ "This option affects GnuTLS and nss_compat_ossl but not " -+ "OpenSSL.")), -+#else - INIT_OPT_BOOL("connection.ssl", N_("Verify certificates"), - "cert_verify", 0, 0, - N_("Verify the peer's SSL certificate. Note that this " - "needs extensive configuration of OpenSSL by the user.")), -+#endif - - INIT_OPT_TREE("connection.ssl", N_("Client Certificates"), - "client_cert", OPT_SORT, -@@ -187,7 +217,8 @@ static union option_info gnutls_options[] = { - "\n" - "If you change this option or the file, you must " - "restart ELinks for the changes to take effect. " -- "This option affects GnuTLS but not OpenSSL.")), -+ "This option affects GnuTLS and nss_compat_ossl but not " -+ "OpenSSL.")), - - NULL_OPTION_INFO, - }; diff --git a/elinks-nss.patch b/elinks-nss.patch deleted file mode 100644 index 893505c..0000000 --- a/elinks-nss.patch +++ /dev/null @@ -1,265 +0,0 @@ - configure.in | 34 +++++++++++++++++++++++++++++++++- - src/network/ssl/socket.c | 28 ++++++++++++++++++++++------ - src/network/ssl/ssl.c | 32 ++++++++++++++++++++++++++------ - src/network/ssl/ssl.h | 2 +- - 4 files changed, 82 insertions(+), 14 deletions(-) - -diff --git a/configure.in b/configure.in -index 0e534db..972a305 100644 ---- a/configure.in -+++ b/configure.in -@@ -970,6 +970,37 @@ AC_ARG_WITH(openssl, [[ --with-openssl[=DIR] enable OpenSSL support (default - *) chosen_ssl_library="OpenSSL" ;; - esac]) - -+AC_ARG_WITH(nss_compat_ossl, [[ --with-nss_compat_ossl[=DIR] -+ NSS compatibility SSL libraries/include files]]) -+ -+# nss_compat_ossl -+if test -n "$with_nss_compat_ossl" && test "$with_nss_compat_ossl" != "no"; then -+ EL_SAVE_FLAGS -+ if test "$with_nss_compat_ossl" = yes; then -+ if pkg-config nss; then -+ CFLAGS="$CFLAGS_X `pkg-config --cflags nss`" -+ LIBS="$LIBS_X `pkg-config --libs nss`" -+ else -+ with_nss_compat_ossl=no -+ fi -+ else -+ # Without pkg-config, we'll kludge in some defaults -+ CFLAGS="$CFLAGS_X -I$with_nss_compat_ossl/include -I/usr/include/nss3 -I/usr/include/nspr4" -+ LIBS="$LIBS_X -L$with_nss_compat_ossl/lib -lssl3 -lsmime3 -lnss3 -lplds4 -lplc4 -lnspr4 -lpthread -ldl" -+ fi -+ AC_CHECK_HEADERS(nss_compat_ossl/nss_compat_ossl.h,, [with_nss_compat_ossl=no], [#define NSS_COMPAT_OSSL_H]) -+ AC_CHECK_LIB(nss_compat_ossl, X509_free,, [with_nss_compat_ossl=no]) -+ -+ if test "$with_nss_compat_ossl" = "no"; then -+ EL_RESTORE_FLAGS -+ else -+ LIBS="$LIBS -lnss_compat_ossl" -+ EL_CONFIG(CONFIG_NSS_COMPAT_OSSL, [nss_compat_ossl]) -+ disable_openssl="yes" -+ disable_gnutls="yes" -+ fi -+fi -+ - # ---- OpenSSL - - AC_MSG_CHECKING([for OpenSSL]) -@@ -1092,10 +1123,11 @@ fi - - # Final SSL setup - --EL_CONFIG_DEPENDS(CONFIG_SSL, [CONFIG_OPENSSL CONFIG_GNUTLS], [SSL]) -+EL_CONFIG_DEPENDS(CONFIG_SSL, [CONFIG_OPENSSL CONFIG_GNUTLS CONFIG_NSS_COMPAT_OSSL], [SSL]) - AC_SUBST(CONFIG_GNUTLS_OPENSSL_COMPAT) - AC_SUBST(CONFIG_OPENSSL) - AC_SUBST(CONFIG_GNUTLS) -+AC_SUBST(CONFIG_NSS_COMPAT_OSSL) - - #endif - -diff --git a/src/network/ssl/socket.c b/src/network/ssl/socket.c -index 45b4b4a..3265107 100644 ---- a/src/network/ssl/socket.c -+++ b/src/network/ssl/socket.c -@@ -6,6 +6,10 @@ - - #ifdef CONFIG_OPENSSL - #include -+#define USE_OPENSSL -+#elif defined(CONFIG_NSS_COMPAT_OSSL) -+#include -+#define USE_OPENSSL - #elif defined(CONFIG_GNUTLS) - #include - #else -@@ -26,7 +30,7 @@ - - - /* SSL errors */ --#ifdef CONFIG_OPENSSL -+#ifdef USE_OPENSSL - #define SSL_ERROR_WANT_READ2 9999 /* XXX */ - #define SSL_ERROR_WANT_WRITE2 SSL_ERROR_WANT_WRITE - #define SSL_ERROR_SYSCALL2 SSL_ERROR_SYSCALL -@@ -40,7 +44,7 @@ - #define SSL_ERROR_SYSCALL2 GNUTLS_E_PULL_ERROR - #endif - --#ifdef CONFIG_OPENSSL -+#ifdef USE_OPENSSL - - #define ssl_do_connect(socket) SSL_get_error(socket->ssl, SSL_connect(socket->ssl)) - #define ssl_do_write(socket, data, len) SSL_write(socket->ssl, data, len) -@@ -126,7 +130,7 @@ ssl_connect(struct socket *socket) - if (socket->no_tls) - ssl_set_no_tls(socket); - --#ifdef CONFIG_OPENSSL -+#ifdef USE_OPENSSL - SSL_set_fd(socket->ssl, socket->fd); - - if (get_opt_bool("connection.ssl.cert_verify")) -@@ -137,7 +141,13 @@ ssl_connect(struct socket *socket) - if (get_opt_bool("connection.ssl.client_cert.enable")) { - unsigned char *client_cert; - -- client_cert = get_opt_str("connection.ssl.client_cert.file"); -+#ifdef CONFIG_NSS_COMPAT_OSSL -+ client_cert = get_opt_str( -+ "connection.ssl.client_cert.nickname"); -+#else -+ client_cert = get_opt_str( -+ "connection.ssl.client_cert.file"); -+#endif - if (!*client_cert) { - client_cert = getenv("X509_CLIENT_CERT"); - if (client_cert && !*client_cert) -@@ -145,11 +155,17 @@ ssl_connect(struct socket *socket) - } - - if (client_cert) { -+#ifdef CONFIG_NSS_COMPAT_OSSL -+ SSL_CTX_use_certificate_chain_file( -+ (SSL *) socket->ssl, -+ client_cert); -+#else - SSL_CTX *ctx = ((SSL *) socket->ssl)->ctx; - - SSL_CTX_use_certificate_chain_file(ctx, client_cert); - SSL_CTX_use_PrivateKey_file(ctx, client_cert, - SSL_FILETYPE_PEM); -+#endif - } - } - -@@ -206,7 +222,7 @@ ssl_write(struct socket *socket, unsigned char *data, int len) - ssize_t wr = ssl_do_write(socket, data, len); - - if (wr <= 0) { --#ifdef CONFIG_OPENSSL -+#ifdef USE_OPENSSL - int err = SSL_get_error(socket->ssl, wr); - #elif defined(CONFIG_GNUTLS) - int err = wr; -@@ -235,7 +251,7 @@ ssl_read(struct socket *socket, unsigned char *data, int len) - ssize_t rd = ssl_do_read(socket, data, len); - - if (rd <= 0) { --#ifdef CONFIG_OPENSSL -+#ifdef USE_OPENSSL - int err = SSL_get_error(socket->ssl, rd); - #elif defined(CONFIG_GNUTLS) - int err = rd; -diff --git a/src/network/ssl/ssl.c b/src/network/ssl/ssl.c -index 685c31e..73446b5 100644 ---- a/src/network/ssl/ssl.c -+++ b/src/network/ssl/ssl.c -@@ -7,6 +7,10 @@ - #ifdef CONFIG_OPENSSL - #include - #include -+#define USE_OPENSSL -+#elif defined(CONFIG_NSS_COMPAT_OSSL) -+#include -+#define USE_OPENSSL - #elif defined(CONFIG_GNUTLS) - #include - #include -@@ -33,7 +37,7 @@ - /* FIXME: As you can see, SSL is currently implemented in very, erm, - * decentralized manner. */ - --#ifdef CONFIG_OPENSSL -+#ifdef USE_OPENSSL - - #ifndef PATH_MAX - #define PATH_MAX 256 /* according to my /usr/include/bits/posix1_lim.h */ -@@ -71,12 +75,28 @@ static union option_info openssl_options[] = { - N_("Enable or not the sending of X509 client certificates " - "to servers which request them.")), - -+#ifdef CONFIG_NSS_COMPAT_OSSL -+ INIT_OPT_STRING("connection.ssl.client_cert", N_("Certificate nickname"), -+ "nickname", 0, "", -+ N_("The nickname of the client certificate stored in NSS " -+ "database. If this value is unset, the nickname from " -+ "the X509_CLIENT_CERT variable is used instead. If you " -+ "have a PKCS#12 file containing client certificate, you " -+ "can import it into your NSS database with:\n" -+ "\n" -+ "$ pk12util -i mycert.p12 -d /path/to/database\n" -+ "\n" -+ "The NSS database location can be changed by SSL_DIR " -+ "environment variable. The database can be also shared " -+ "with Mozilla browsers.")), -+#else - INIT_OPT_STRING("connection.ssl.client_cert", N_("Certificate File"), - "file", 0, "", - N_("The location of a file containing the client certificate " - "and unencrypted private key in PEM format. If unset, the " - "file pointed to by the X509_CLIENT_CERT variable is used " - "instead.")), -+#endif - - NULL_OPTION_INFO, - }; -@@ -182,7 +202,7 @@ static struct module gnutls_module = struct_module( - /* done: */ done_gnutls - ); - --#endif /* CONFIG_OPENSSL or CONFIG_GNUTLS */ -+#endif /* USE_OPENSSL or CONFIG_GNUTLS */ - - static union option_info ssl_options[] = { - INIT_OPT_TREE("connection", N_("SSL"), -@@ -193,7 +213,7 @@ static union option_info ssl_options[] = { - }; - - static struct module *ssl_modules[] = { --#ifdef CONFIG_OPENSSL -+#ifdef USE_OPENSSL - &openssl_module, - #elif defined(CONFIG_GNUTLS) - &gnutls_module, -@@ -214,7 +234,7 @@ struct module ssl_module = struct_module( - int - init_ssl_connection(struct socket *socket) - { --#ifdef CONFIG_OPENSSL -+#ifdef USE_OPENSSL - socket->ssl = SSL_new(context); - if (!socket->ssl) return S_SSL_ERROR; - #elif defined(CONFIG_GNUTLS) -@@ -271,7 +291,7 @@ done_ssl_connection(struct socket *socket) - ssl_t *ssl = socket->ssl; - - if (!ssl) return; --#ifdef CONFIG_OPENSSL -+#ifdef USE_OPENSSL - SSL_free(ssl); - #elif defined(CONFIG_GNUTLS) - gnutls_deinit(*ssl); -@@ -288,7 +308,7 @@ get_ssl_connection_cipher(struct socket *socket) - - if (!init_string(&str)) return NULL; - --#ifdef CONFIG_OPENSSL -+#ifdef USE_OPENSSL - add_format_to_string(&str, "%ld-bit %s %s", - SSL_get_cipher_bits(ssl, NULL), - SSL_get_cipher_version(ssl), -diff --git a/src/network/ssl/ssl.h b/src/network/ssl/ssl.h -index 7c54a7a..21ca142 100644 ---- a/src/network/ssl/ssl.h -+++ b/src/network/ssl/ssl.h -@@ -22,7 +22,7 @@ unsigned char *get_ssl_connection_cipher(struct socket *socket); - - /* Internal type used in ssl module. */ - --#ifdef CONFIG_OPENSSL -+#if defined(CONFIG_OPENSSL) || defined(CONFIG_NSS_COMPAT_OSSL) - #define ssl_t SSL - #elif defined(CONFIG_GNUTLS) - #define ssl_t gnutls_session_t diff --git a/elinks.spec b/elinks.spec index a55fe6d..650ef0c 100644 --- a/elinks.spec +++ b/elinks.spec @@ -3,7 +3,7 @@ Name: elinks Summary: A text-mode Web browser Version: 0.12 -Release: 0.43.%{prerel}%{?dist} +Release: 0.44.%{prerel}%{?dist} License: GPLv2 URL: http://elinks.or.cz Group: Applications/Internet @@ -18,7 +18,7 @@ BuildRequires: js-devel BuildRequires: krb5-devel BuildRequires: libidn2-devel BuildRequires: lua-devel -BuildRequires: nss_compat_ossl-devel +BuildRequires: openssl-devel BuildRequires: pkgconfig BuildRequires: zlib-devel Requires(preun): %{_sbindir}/alternatives @@ -37,8 +37,6 @@ Patch4: elinks-0.11.0-sysname.patch Patch5: elinks-0.10.1-xterm.patch Patch7: elinks-0.11.3-macropen.patch Patch8: elinks-scroll.patch -Patch9: elinks-nss.patch -Patch10: elinks-nss-inc.patch Patch11: elinks-0.12pre5-js185.patch Patch12: elinks-0.12pre5-ddg-search.patch Patch13: elinks-0.12pre6-autoconf.patch @@ -77,12 +75,6 @@ quickly and swiftly displays Web pages. #upstream fix for out of screen dialogs %patch8 -p1 -# Port elinks to use NSS library for cryptography (#346861) - accepted upstream -%patch9 -p1 - -# Port elinks to use NSS library for cryptography (#346861) - incremental patch -%patch10 -p1 - # backported upstream commits f31cf6f, 2844f8b, 218a225, and 12803e4 %patch11 -p1 @@ -92,7 +84,7 @@ quickly and swiftly displays Web pages. # add missing AC_LANG_PROGRAM around the first argument of AC_COMPILE_IFELSE %patch13 -p1 -# verify server certificate hostname with nss_compat_ossl (#881411) +# verify server certificate hostname with OpenSSL (#881411) %patch14 -p1 # let list_is_singleton() return false for an empty list (#1075415) @@ -114,9 +106,14 @@ autoheader %build export CFLAGS="$RPM_OPT_FLAGS $(getconf LFS_CFLAGS) -D_GNU_SOURCE" -%configure %{?rescue:--without-gpm} --without-x --with-gssapi \ - --enable-bittorrent --with-nss_compat_ossl --enable-256-colors \ - --without-openssl --without-gnutls --with-lua +%configure %{?rescue:--without-gpm} \ + --enable-256-colors \ + --enable-bittorrent \ + --with-gssapi \ + --with-lua \ + --with-openssl \ + --without-gnutls \ + --without-x # uncomment to turn off optimizations #sed -i 's/-O2/-O0/' Makefile.config @@ -172,6 +169,9 @@ exit 0 %{_mandir}/man5/* %changelog +* Mon Mar 30 2015 Kamil Dudka - 0.12-0.44.pre6 +- use OpenSSL instead of nss_compat_ossl, which is no longer maintained + * Fri Jan 16 2015 Tom Callaway - 0.12-0.43.pre6 - rebuild for lua 5.3