diff --git a/0001-curl-7.26.0-72f4b534.patch b/0001-curl-7.26.0-72f4b534.patch new file mode 100644 index 0000000..11443c0 --- /dev/null +++ b/0001-curl-7.26.0-72f4b534.patch @@ -0,0 +1,253 @@ +From 74be99357669da26900ae23b5005ddeabb91b453 Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +Date: Mon, 21 May 2012 16:31:21 +0200 +Subject: [PATCH 1/2] nss: avoid using explicit casts of code pointers + +--- + lib/nss.c | 11 ++++------- + 1 files changed, 4 insertions(+), 7 deletions(-) + +diff --git a/lib/nss.c b/lib/nss.c +index 6b93893..885a120 100644 +--- a/lib/nss.c ++++ b/lib/nss.c +@@ -670,11 +670,10 @@ static SECStatus BadCertHandler(void *arg, PRFileDesc *sock) + /** + * Inform the application that the handshake is complete. + */ +-static SECStatus HandshakeCallback(PRFileDesc *sock, void *arg) ++static void HandshakeCallback(PRFileDesc *sock, void *arg) + { + (void)sock; + (void)arg; +- return SECSuccess; + } + + static void display_cert_info(struct SessionHandle *data, +@@ -1341,12 +1340,10 @@ CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex) + goto error; + + data->set.ssl.certverifyresult=0; /* not checked yet */ +- if(SSL_BadCertHook(model, (SSLBadCertHandler) BadCertHandler, conn) +- != SECSuccess) { ++ if(SSL_BadCertHook(model, BadCertHandler, conn) != SECSuccess) + goto error; +- } +- if(SSL_HandshakeCallback(model, (SSLHandshakeCallback) HandshakeCallback, +- NULL) != SECSuccess) ++ ++ if(SSL_HandshakeCallback(model, HandshakeCallback, NULL) != SECSuccess) + goto error; + + if(data->set.ssl.verifypeer) { +-- +1.7.1 + +From 72f4b534c4f57a71c458257c4ea317d557cf59f5 Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +Date: Mon, 21 May 2012 16:19:12 +0200 +Subject: [PATCH 2/2] nss: use human-readable error messages provided by NSS + +Bug: http://lists.baseurl.org/pipermail/yum-devel/2012-January/009002.html +--- + lib/nss.c | 128 +++++++++++++++++++++++++------------------------------- + 1 files changed, 57 insertions(+), 71 deletions(-) + +diff --git a/lib/nss.c b/lib/nss.c +index 885a120..d60b184 100644 +--- a/lib/nss.c ++++ b/lib/nss.c +@@ -186,6 +186,11 @@ static const char* nss_error_to_name(PRErrorCode code) + return "unknown error"; + } + ++static void nss_print_error_message(struct SessionHandle *data, PRUint32 err) ++{ ++ failf(data, "%s", PR_ErrorToString(err, PR_LANGUAGE_I_DEFAULT)); ++} ++ + static SECStatus set_ciphers(struct SessionHandle *data, PRFileDesc * model, + char *cipher_list) + { +@@ -612,61 +617,6 @@ static SECStatus nss_auth_cert_hook(void *arg, PRFileDesc *fd, PRBool checksig, + return SSL_AuthCertificate(CERT_GetDefaultCertDB(), fd, checksig, isServer); + } + +-static SECStatus BadCertHandler(void *arg, PRFileDesc *sock) +-{ +- SECStatus result = SECFailure; +- struct connectdata *conn = (struct connectdata *)arg; +- PRErrorCode err = PR_GetError(); +- CERTCertificate *cert = NULL; +- char *subject, *subject_cn, *issuer; +- +- conn->data->set.ssl.certverifyresult=err; +- cert = SSL_PeerCertificate(sock); +- subject = CERT_NameToAscii(&cert->subject); +- subject_cn = CERT_GetCommonName(&cert->subject); +- issuer = CERT_NameToAscii(&cert->issuer); +- CERT_DestroyCertificate(cert); +- +- switch(err) { +- case SEC_ERROR_CA_CERT_INVALID: +- infof(conn->data, "Issuer certificate is invalid: '%s'\n", issuer); +- break; +- case SEC_ERROR_UNTRUSTED_ISSUER: +- infof(conn->data, "Certificate is signed by an untrusted issuer: '%s'\n", +- issuer); +- break; +- case SSL_ERROR_BAD_CERT_DOMAIN: +- if(conn->data->set.ssl.verifyhost) { +- failf(conn->data, "SSL: certificate subject name '%s' does not match " +- "target host name '%s'", subject_cn, conn->host.dispname); +- } +- else { +- result = SECSuccess; +- infof(conn->data, "warning: SSL: certificate subject name '%s' does not " +- "match target host name '%s'\n", subject_cn, conn->host.dispname); +- } +- break; +- case SEC_ERROR_EXPIRED_CERTIFICATE: +- infof(conn->data, "Remote Certificate has expired.\n"); +- break; +- case SEC_ERROR_UNKNOWN_ISSUER: +- infof(conn->data, "Peer's certificate issuer is not recognized: '%s'\n", +- issuer); +- break; +- default: +- infof(conn->data, "Bad certificate received. Subject = '%s', " +- "Issuer = '%s'\n", subject, issuer); +- break; +- } +- if(result == SECSuccess) +- infof(conn->data, "SSL certificate verify ok.\n"); +- PR_Free(subject); +- PR_Free(subject_cn); +- PR_Free(issuer); +- +- return result; +-} +- + /** + * Inform the application that the handshake is complete. + */ +@@ -728,6 +678,31 @@ static void display_conn_info(struct connectdata *conn, PRFileDesc *sock) + return; + } + ++static SECStatus BadCertHandler(void *arg, PRFileDesc *sock) ++{ ++ struct connectdata *conn = (struct connectdata *)arg; ++ struct SessionHandle *data = conn->data; ++ PRErrorCode err = PR_GetError(); ++ CERTCertificate *cert; ++ ++ /* remember the cert verification result */ ++ data->set.ssl.certverifyresult = err; ++ ++ if(err == SSL_ERROR_BAD_CERT_DOMAIN && !data->set.ssl.verifyhost) ++ /* we are asked not to verify the host name */ ++ return SECSuccess; ++ ++ /* print only info about the cert, the error is printed off the callback */ ++ cert = SSL_PeerCertificate(sock); ++ if(cert) { ++ infof(data, "Server certificate:\n"); ++ display_cert_info(data, cert); ++ CERT_DestroyCertificate(cert); ++ } ++ ++ return SECFailure; ++} ++ + /** + * + * Check that the Peer certificate's issuer certificate matches the one found +@@ -1108,20 +1083,17 @@ int Curl_nss_close_all(struct SessionHandle *data) + return 0; + } + +-/* handle client certificate related errors if any; return false otherwise */ +-static bool handle_cc_error(PRInt32 err, struct SessionHandle *data) ++/* return true if the given error code is related to a client certificate */ ++static bool is_cc_error(PRInt32 err) + { + switch(err) { + case SSL_ERROR_BAD_CERT_ALERT: +- failf(data, "SSL error: SSL_ERROR_BAD_CERT_ALERT"); + return true; + + case SSL_ERROR_REVOKED_CERT_ALERT: +- failf(data, "SSL error: SSL_ERROR_REVOKED_CERT_ALERT"); + return true; + + case SSL_ERROR_EXPIRED_CERT_ALERT: +- failf(data, "SSL error: SSL_ERROR_EXPIRED_CERT_ALERT"); + return true; + + default: +@@ -1460,10 +1432,14 @@ CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex) + data->state.ssl_connect_retry = FALSE; + + err = PR_GetError(); +- if(handle_cc_error(err, data)) ++ if(is_cc_error(err)) + curlerr = CURLE_SSL_CERTPROBLEM; +- else +- infof(data, "NSS error %d (%s)\n", err, nss_error_to_name(err)); ++ ++ /* print the error number and error string */ ++ infof(data, "NSS error %d (%s)\n", err, nss_error_to_name(err)); ++ ++ /* print a human-readable message describing the error if available */ ++ nss_print_error_message(data, err); + + if(model) + PR_Close(model); +@@ -1496,12 +1472,17 @@ static ssize_t nss_send(struct connectdata *conn, /* connection data */ + PRInt32 err = PR_GetError(); + if(err == PR_WOULD_BLOCK_ERROR) + *curlcode = CURLE_AGAIN; +- else if(handle_cc_error(err, conn->data)) +- *curlcode = CURLE_SSL_CERTPROBLEM; + else { ++ /* print the error number and error string */ + const char *err_name = nss_error_to_name(err); +- failf(conn->data, "SSL write: error %d (%s)", err, err_name); +- *curlcode = CURLE_SEND_ERROR; ++ infof(conn->data, "SSL write: error %d (%s)\n", err, err_name); ++ ++ /* print a human-readable message describing the error if available */ ++ nss_print_error_message(conn->data, err); ++ ++ *curlcode = (is_cc_error(err)) ++ ? CURLE_SSL_CERTPROBLEM ++ : CURLE_SEND_ERROR; + } + return -1; + } +@@ -1523,12 +1504,17 @@ static ssize_t nss_recv(struct connectdata * conn, /* connection data */ + + if(err == PR_WOULD_BLOCK_ERROR) + *curlcode = CURLE_AGAIN; +- else if(handle_cc_error(err, conn->data)) +- *curlcode = CURLE_SSL_CERTPROBLEM; + else { ++ /* print the error number and error string */ + const char *err_name = nss_error_to_name(err); +- failf(conn->data, "SSL read: errno %d (%s)", err, err_name); +- *curlcode = CURLE_RECV_ERROR; ++ infof(conn->data, "SSL read: errno %d (%s)\n", err, err_name); ++ ++ /* print a human-readable message describing the error if available */ ++ nss_print_error_message(conn->data, err); ++ ++ *curlcode = (is_cc_error(err)) ++ ? CURLE_SSL_CERTPROBLEM ++ : CURLE_RECV_ERROR; + } + return -1; + } +-- +1.7.1 + diff --git a/curl.spec b/curl.spec index 4f5fc7c..b1e9bc6 100644 --- a/curl.spec +++ b/curl.spec @@ -1,13 +1,16 @@ Summary: A utility for getting files from remote servers (FTP, HTTP, and others) Name: curl Version: 7.26.0 -Release: 1%{?dist} +Release: 2%{?dist} License: MIT Group: Applications/Internet Source: http://curl.haxx.se/download/%{name}-%{version}.tar.lzma Source2: curlbuild.h Source3: hide_selinux.c +# use human-readable error messages provided by NSS +Patch1: 0001-curl-7.26.0-72f4b534.patch + # patch making libcurl multilib ready Patch101: 0101-curl-7.25.0-multilib.patch @@ -103,6 +106,9 @@ documentation of the library, too. %prep %setup -q +# upstream patches +%patch1 -p1 + # Fedora patches %patch101 -p1 %patch102 -p1 @@ -221,6 +227,9 @@ rm -rf $RPM_BUILD_ROOT %{_datadir}/aclocal/libcurl.m4 %changelog +* Mon May 28 2012 Kamil Dudka 7.26.0-2 +- use human-readable error messages provided by NSS (upstream commit 72f4b534) + * Fri May 25 2012 Kamil Dudka 7.26.0-1 - new upstream release