--------------------- PatchSet 6342 Date: 2004/10/22 13:52:33 Author: hno Branch: ssl-2_5 Tag: (none) Log: Merged latest SSL changes from MARA Systems eMARA product Members: src/cf.data.pre:1.49.2.27.2.20->1.49.2.27.2.21 src/client_side.c:1.47.2.21.2.18->1.47.2.21.2.19 src/comm.c:1.18.6.2.8.3->1.18.6.2.8.4 src/external_acl.c:1.2.4.11.2.9->1.2.4.11.2.10 src/ssl_support.c:1.6.6.1.2.11->1.6.6.1.2.12 src/ssl_support.h:1.5.44.4->1.5.44.5 Index: squid/src/cf.data.pre =================================================================== RCS file: /cvsroot/squid-sf//squid/src/cf.data.pre,v retrieving revision 1.49.2.27.2.20 retrieving revision 1.49.2.27.2.21 diff -u -r1.49.2.27.2.20 -r1.49.2.27.2.21 --- squid/src/cf.data.pre 22 Oct 2004 13:45:28 -0000 1.49.2.27.2.20 +++ squid/src/cf.data.pre 22 Oct 2004 13:52:33 -0000 1.49.2.27.2.21 @@ -1,6 +1,6 @@ # -# $Id: cf.data.pre,v 1.49.2.27.2.20 2004/10/22 13:45:28 hno Exp $ +# $Id: cf.data.pre,v 1.49.2.27.2.21 2004/10/22 13:52:33 hno Exp $ # # # SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -155,6 +155,9 @@ NO_DEFAULT_CA Don't use the default CA list built in to OpenSSL. + NO_SESSION_REUSE + Don't allow for session reuse. Each connection + will result in a new SSL session. sslcontext= SSL session ID context identifier. @@ -1743,8 +1746,9 @@ %PROTO Requested protocol %PORT Requested port %METHOD Request method - %USER_CERT_xx SSL User certificate attribute xx - %USER_CA_xx SSL User certificate CA attribute xx + %USER_CERT SSL User certificate in PEM format + %USER_CERT_xx SSL User certificate subject attribute xx + %USER_CA_xx SSL User certificate issuer attribute xx %{Header} HTTP request header %{Hdr:member} HTTP request header list member %{Hdr:;member} Index: squid/src/client_side.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/client_side.c,v retrieving revision 1.47.2.21.2.18 retrieving revision 1.47.2.21.2.19 diff -u -r1.47.2.21.2.18 -r1.47.2.21.2.19 --- squid/src/client_side.c 22 Oct 2004 13:45:28 -0000 1.47.2.21.2.18 +++ squid/src/client_side.c 22 Oct 2004 13:52:33 -0000 1.47.2.21.2.19 @@ -1,6 +1,6 @@ /* - * $Id: client_side.c,v 1.47.2.21.2.18 2004/10/22 13:45:28 hno Exp $ + * $Id: client_side.c,v 1.47.2.21.2.19 2004/10/22 13:52:33 hno Exp $ * * DEBUG: section 33 Client-side Routines * AUTHOR: Duane Wessels @@ -3534,8 +3534,7 @@ } else { debug(83, 5) ("clientNegotiateSSL: FD %d has no certificate.\n", fd); } - - commSetSelect(fd, COMM_SELECT_READ, clientReadRequest, conn, 0); + clientReadRequest(fd, conn); } struct _https_port_data { Index: squid/src/comm.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/comm.c,v retrieving revision 1.18.6.2.8.3 retrieving revision 1.18.6.2.8.4 diff -u -r1.18.6.2.8.3 -r1.18.6.2.8.4 --- squid/src/comm.c 22 Oct 2004 13:45:28 -0000 1.18.6.2.8.3 +++ squid/src/comm.c 22 Oct 2004 13:52:35 -0000 1.18.6.2.8.4 @@ -1,6 +1,6 @@ /* - * $Id: comm.c,v 1.18.6.2.8.3 2004/10/22 13:45:28 hno Exp $ + * $Id: comm.c,v 1.18.6.2.8.4 2004/10/22 13:52:35 hno Exp $ * * DEBUG: section 5 Socket Functions * AUTHOR: Harvest Derived @@ -584,22 +584,39 @@ { LOCAL_ARRAY(char, buf, 1024); int n; -#if USE_SSL - if (fd_table[fd].read_pending != COMM_PENDING_NORMAL) { - fd_table[fd].read_pending = COMM_PENDING_NORMAL; - ssl_shutdown_method(fd); - if (fd_table[fd].read_pending != COMM_PENDING_NORMAL) { - commSetSelect(fd, COMM_SELECT_READ, commLingerClose, NULL, 0); - return; - } - } -#endif n = FD_READ_METHOD(fd, buf, 1024); if (n < 0) debug(5, 3) ("commLingerClose: FD %d read: %s\n", fd, xstrerror()); comm_close(fd); } +#if USE_SSL +static void +commLingerSSLClose(int fd, void *unused) +{ + int ret; + LOCAL_ARRAY(char, buf, 1024); + + ret = FD_READ_METHOD(fd, buf, 1024); + if (n < 0 && errno != EAGAIN) { + debug(5, 3) ("commLingerSSLClose: FD %d read: %s\n", fd, xstrerror()); + comm_close(fd); + return; + } + + ret = ssl_shutdown_method(fd); + if (ret == -1 && errno == EAGAIN) { + commSetSelect(fd, COMM_SELECT_WRITE, commLingerSSLClose, NULL, 0); + return; + } + if (shutdown(fd, 1) < 0) { + comm_close(fd); + return; + } + commSetSelect(fd, COMM_SELECT_READ, commLingerClose, NULL, 0); +} +#endif + static void commLingerTimeout(int fd, void *unused) { @@ -613,16 +630,20 @@ void comm_lingering_close(int fd) { + fd_note(fd, "lingering close"); + commSetSelect(fd, COMM_SELECT_READ, NULL, NULL, 0); + commSetSelect(fd, COMM_SELECT_WRITE, NULL, NULL, 0); + commSetTimeout(fd, 10, commLingerTimeout, NULL); #if USE_SSL - if (fd_table[fd].ssl) - ssl_shutdown_method(fd); + if (fd_table[fd].ssl) { + commLingerSSLClose(fd, NULL); + return; + } #endif if (shutdown(fd, 1) < 0) { comm_close(fd); return; } - fd_note(fd, "lingering close"); - commSetTimeout(fd, 10, commLingerTimeout, NULL); commSetSelect(fd, COMM_SELECT_READ, commLingerClose, NULL, 0); } #endif @@ -639,6 +660,7 @@ L.l_linger = 0; if (setsockopt(fd, SOL_SOCKET, SO_LINGER, (char *) &L, sizeof(L)) < 0) debug(50, 0) ("commResetTCPClose: FD %d: %s\n", fd, xstrerror()); + fd_table[fd].flags.close_request = 1; comm_close(fd); } @@ -652,6 +674,9 @@ assert(fd < Squid_MaxFD); F = &fd_table[fd]; + /* XXX This needs to be split and also called once on lingering close. + * In addition the ssl_shutdown may need to wait + */ if (F->flags.closing) return; if (shutting_down && (!F->flags.open || F->type == FD_FILE)) Index: squid/src/external_acl.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/external_acl.c,v retrieving revision 1.2.4.11.2.9 retrieving revision 1.2.4.11.2.10 diff -u -r1.2.4.11.2.9 -r1.2.4.11.2.10 --- squid/src/external_acl.c 22 Oct 2004 13:45:28 -0000 1.2.4.11.2.9 +++ squid/src/external_acl.c 22 Oct 2004 13:52:35 -0000 1.2.4.11.2.10 @@ -1,6 +1,6 @@ /* - * $Id: external_acl.c,v 1.2.4.11.2.9 2004/10/22 13:45:28 hno Exp $ + * $Id: external_acl.c,v 1.2.4.11.2.10 2004/10/22 13:52:35 hno Exp $ * * DEBUG: section 82 External ACL * AUTHOR: Henrik Nordstrom, MARA Systems AB @@ -114,6 +114,7 @@ #if USE_SSL EXT_ACL_USER_CERT, EXT_ACL_CA_CERT, + EXT_ACL_USER_CERT_RAW, #endif EXT_ACL_END } type; @@ -273,12 +274,14 @@ else if (strcmp(token, "%METHOD") == 0) format->type = EXT_ACL_METHOD; #if USE_SSL + else if (strcmp(token, "%USER_CERT") == 0) + format->type = EXT_ACL_USER_CERT_RAW; else if (strncmp(token, "%USER_CERT_", 11)) { format->type = EXT_ACL_USER_CERT; format->header = xstrdup(token + 11); - } else if (strncmp(token, "%CA_CERT_", 11)) { + } else if (strncmp(token, "%CA_CERT_", 9)) { format->type = EXT_ACL_USER_CERT; - format->header = xstrdup(token + 11); + format->header = xstrdup(token + 9); } #endif else { @@ -344,11 +347,14 @@ DUMP_EXT_ACL_TYPE(PORT); DUMP_EXT_ACL_TYPE(METHOD); #if USE_SSL + case EXT_ACL_USER_CERT_RAW: + storeAppendPrintf(sentry, " %%USER_CERT"); + break; case EXT_ACL_USER_CERT: storeAppendPrintf(sentry, " %%USER_CERT_%s", format->header); break; case EXT_ACL_CA_CERT: - storeAppendPrintf(sentry, " %%USER_CERT_%s", format->header); + storeAppendPrintf(sentry, " %%CA_CERT_%s", format->header); break; #endif case EXT_ACL_UNKNOWN: @@ -591,6 +597,13 @@ str = strBuf(sb); break; #if USE_SSL + case EXT_ACL_USER_CERT_RAW: + if (cbdataValid(ch->conn)) { + SSL *ssl = fd_table[ch->conn->fd].ssl; + if (ssl) + str = sslGetUserCertificatePEM(ssl); + } + break; case EXT_ACL_USER_CERT: if (cbdataValid(ch->conn)) { SSL *ssl = fd_table[ch->conn->fd].ssl; Index: squid/src/ssl_support.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/ssl_support.c,v retrieving revision 1.6.6.1.2.11 retrieving revision 1.6.6.1.2.12 diff -u -r1.6.6.1.2.11 -r1.6.6.1.2.12 --- squid/src/ssl_support.c 6 Sep 2004 15:59:21 -0000 1.6.6.1.2.11 +++ squid/src/ssl_support.c 22 Oct 2004 13:52:35 -0000 1.6.6.1.2.12 @@ -361,6 +361,7 @@ #define SSL_FLAG_DELAYED_AUTH (1<<1) #define SSL_FLAG_DONT_VERIFY_PEER (1<<2) #define SSL_FLAG_DONT_VERIFY_DOMAIN (1<<3) +#define SSL_FLAG_NO_SESSION_REUSE (1<<4) static long ssl_parse_flags(const char *flags) @@ -383,6 +384,8 @@ fl |= SSL_FLAG_DONT_VERIFY_PEER; else if (strcmp(flag, "DONT_VERIFY_DOMAIN") == 0) fl |= SSL_FLAG_DONT_VERIFY_DOMAIN; + else if (strcmp(flag, "NO_SESSION_REUSE") == 0) + fl |= SSL_FLAG_NO_SESSION_REUSE; else fatalf("Unknown ssl flag '%s'", flag); flag = strtok(NULL, ":,"); @@ -399,7 +402,7 @@ if (!ssl_initialized) { ssl_initialized = 1; SSL_load_error_strings(); - SSLeay_add_ssl_algorithms(); + SSL_library_init(); #ifdef HAVE_OPENSSL_ENGINE_H if (Config.SSL.ssl_engine) { ENGINE *e; @@ -473,6 +476,10 @@ SSL_CTX_set_session_id_context(sslContext, context, strlen(context)); } + if (fl & SSL_FLAG_NO_SESSION_REUSE) { + SSL_CTX_set_session_cache_mode(sslContext, SSL_SESS_CACHE_OFF); + } + if (Config.SSL.unclean_shutdown) { debug(83, 5) ("Enabling quiet SSL shutdowns (RFC violation).\n"); SSL_CTX_set_quiet_shutdown(sslContext, 1); @@ -778,7 +785,7 @@ if (!SSL_is_init_finished(ssl)) { errno = ENOTCONN; - return -1; + return 0; } ret = SSL_shutdown(ssl); @@ -787,21 +794,26 @@ switch (err) { case SSL_ERROR_NONE: case SSL_ERROR_ZERO_RETURN: - ret = 1; + return 1; break; case SSL_ERROR_WANT_READ: - fd_table[fd].read_pending = COMM_PENDING_WANTS_READ; - ret = -1; + fd_table[fd].write_pending = COMM_PENDING_WANTS_READ; errno = EAGAIN; + return -1; break; case SSL_ERROR_WANT_WRITE: - /* Should CommSetSelect for write, but the Squid API does not allow this.. */ - fd_table[fd].read_pending = COMM_PENDING_WANTS_WRITE; - ret = -1; + fd_table[fd].write_pending = COMM_PENDING_WANTS_WRITE; errno = EAGAIN; + return -1; break; + case SSL_ERROR_SYSCALL: + if (errno == EAGAIN || errno == 0) { + errno = EAGAIN; + return -1; + } default: - ret = -1; + debug(83, 2) ("WARNING: Unexpected error on SSL_shutdown '%d' (%d)\n", err, errno); + return -1; break; } } @@ -843,6 +855,8 @@ if (!cert) return NULL; + X509_free(cert); + name = X509_get_subject_name(cert); return ssl_get_attribute(name, attribute_name); @@ -861,6 +875,8 @@ if (!cert) return NULL; + X509_free(cert); + name = X509_get_issuer_name(cert); return ssl_get_attribute(name, attribute_name); @@ -895,3 +911,39 @@ { return sslGetUserAttribute(ssl, "Email"); } + +const char * +sslGetUserCertificatePEM(SSL *ssl) +{ + X509 *cert; + BIO *mem; + static char *str = NULL; + char *ptr; + long len; + + safe_free(str); + + if (!ssl) + return NULL; + + cert = SSL_get_peer_certificate(ssl); + + if (!cert) + return NULL; + + mem = BIO_new(BIO_s_mem()); + + PEM_write_bio_X509(mem, cert); + + + len = BIO_get_mem_data(mem, &ptr); + + str = (char *)xmalloc(len + 1); + memcpy(str, ptr, len); + str[len] = '\0'; + + X509_free(cert); + BIO_free(mem); + + return str; +} Index: squid/src/ssl_support.h =================================================================== RCS file: /cvsroot/squid-sf//squid/src/ssl_support.h,v retrieving revision 1.5.44.4 retrieving revision 1.5.44.5 diff -u -r1.5.44.4 -r1.5.44.5 --- squid/src/ssl_support.h 18 Apr 2004 00:09:08 -0000 1.5.44.4 +++ squid/src/ssl_support.h 22 Oct 2004 13:52:35 -0000 1.5.44.5 @@ -55,5 +55,6 @@ const char *sslGetUserEmail(SSL *ssl); const char *sslGetUserAttribute(SSL *ssl, const char *attribute); const char *sslGetCAAttribute(SSL *ssl, const char *attribute); +const char *sslGetUserCertificatePEM(SSL *ssl); #endif /* SQUID_SSL_SUPPORT_H */