This patch is generated from the ssl-20010414 branch of HEAD-20010414 in squid Tue Sep 9 11:57:40 2003 GMT See http://devel.squid-cache.org/ Index: squid/acconfig.h diff -u squid/acconfig.h:1.6 squid/acconfig.h:1.1.1.4.4.8 --- squid/acconfig.h:1.6 Fri Mar 9 16:58:29 2001 +++ squid/acconfig.h Fri Apr 13 17:13:48 2001 @@ -22,7 +22,7 @@ #ifndef __CONFIGURE_H__ #define __CONFIGURE_H__ -@TOP@ +@ TOP @ /* $Id: squid-ssl-20010414-HEAD-20010414,v 1.1 2004/08/17 20:55:13 hno Exp $ */ /********************************* @@ -280,6 +280,18 @@ */ #undef mtyp_t +/* + * Define this to include code for SSL encryption. + */ +#undef USE_SSL + +/* + * Define this to make use of the OpenSSL libraries for + * MD5 calculation rather than Squid's own MD5 implementation + * or if building with SSL encryption (USE_SSL) + */ +#undef USE_OPENSSL + /* Define if you want to set the COSS membuf size */ #undef COSS_MEMBUF_SZ @@ -315,6 +327,6 @@ -@BOTTOM@ +@BOTTOM @ #endif /* __CONFIGURE_H__ */ Index: squid/configure.in diff -u squid/configure.in:1.19 squid/configure.in:1.1.1.4.2.1.2.14 --- squid/configure.in:1.19 Fri Mar 9 16:58:29 2001 +++ squid/configure.in Sun Mar 11 23:31:15 2001 @@ -501,6 +501,53 @@ ]) AC_SUBST(HTCP_OBJS) +AC_ARG_ENABLE(ssl, +[ --enable-ssl Enable ssl gatewaying support using OpenSSL], +[ if test "$enableval" != "no"; then + echo "SSL gatewaying enabled" + AC_DEFINE(USE_SSL) + SSL_OBJS='$(SSL_OBJS)' + SSLLIB='-lssl -lcrypto' + USE_OPENSSL=1 + fi +]) + +AC_ARG_WITH(openssl, +[ --with-openssl[=prefix] + Compile with the OpenSSL libraries. The path to + the OpenSSL development libraries and headers + installation can be specified if outside of the + system standard directories], +[ + case "$with_ssl" in + yes) + USE_OPENSSL=1 + ;; + no) + USE_OPENSSL= + ;; + *) + SSLLIBDIR="$with_ssl/lib" + SSLINC="-I$with_ssl/include" + USE_OPENSSL=1 + esac +]) + +if test -n "$USE_OPENSSL"; then + AC_DEFINE(USE_OPENSSL) + if test -z "$SSLLIB"; then + SSLLIB="-lcrypto" # for MD5 routines + fi +fi +if test -n "$SSLLIBDIR"; then + SSLLIB="-L$SSLLIBDIR $SSLLIB" +fi +if test -n "$SSLINC"; then + CFLAGS="$CFLAGS $SSLINC" +fi +AC_SUBST(SSL_OBJS) +AC_SUBST(SSLLIB) + AC_ARG_ENABLE(forw-via-db, [ --enable-forw-via-db Enable Forw/Via database], [ if test "$enableval" = "yes" ; then @@ -952,6 +999,9 @@ netinet/ip_fil_compat.h \ netinet/ip_fil.h \ netinet/ip_nat.h \ + openssl/err.h \ + openssl/md5.h \ + openssl/ssl.h \ poll.h \ pwd.h \ regex.h \ Index: squid/include/md5.h diff -u squid/include/md5.h:1.4 squid/include/md5.h:1.1.1.1.22.4 --- squid/include/md5.h:1.4 Sun Mar 11 14:11:08 2001 +++ squid/include/md5.h Sun Mar 11 23:31:15 2001 @@ -4,6 +4,24 @@ #ifndef MD5_H #define MD5_H + +#if USE_OPENSSL + +#if HAVE_OPENSSL_MD5_H +#include +#else +#error Cannot find OpenSSL headers +#endif + +/* Hack to adopt Squid to the OpenSSL syntax */ +#define MD5_DIGEST_CHARS MD5_DIGEST_LENGTH + +#define MD5Init MD5_Init +#define MD5Update MD5_Update +#define MD5Final MD5_Final + +#else /* USE_OPENSSL */ + /* MD5.H - header file for MD5C.C */ @@ -44,4 +62,5 @@ #define MD5_DIGEST_CHARS 16 +#endif /* USE_OPENSSL */ #endif /* MD5_H */ Index: squid/include/rfc2617.h diff -u squid/include/rfc2617.h:1.2 squid/include/rfc2617.h:1.2.8.2 --- squid/include/rfc2617.h:1.2 Wed Jan 31 14:20:26 2001 +++ squid/include/rfc2617.h Thu Feb 8 15:15:27 2001 @@ -49,7 +49,6 @@ #ifndef RFC2617_H #define RFC2617_H -#include "md5.h" #define HASHLEN 16 typedef char HASH[HASHLEN]; Index: squid/lib/md5.c diff -u squid/lib/md5.c:1.4 squid/lib/md5.c:1.1.1.2.18.4 --- squid/lib/md5.c:1.4 Sun Mar 11 14:11:09 2001 +++ squid/lib/md5.c Sun Mar 11 23:31:15 2001 @@ -32,6 +32,7 @@ #include "config.h" +#if !USE_OPENSSL /* * Only compile md5.c if we need it. Its needed for MD5 store keys * and by the SNMP routines. @@ -360,3 +361,5 @@ } #endif + +#endif /* USE_OPENSSL */ Index: squid/lib/rfc2617.c diff -u squid/lib/rfc2617.c:1.5 squid/lib/rfc2617.c:1.3.8.3 --- squid/lib/rfc2617.c:1.5 Sat Feb 10 09:31:46 2001 +++ squid/lib/rfc2617.c Fri Apr 13 17:13:48 2001 @@ -49,8 +49,9 @@ #include "config.h" #include #include "rfc2617.h" +#include "md5.h" -void +void CvtHex(const HASH Bin, HASHHEX Hex) { unsigned short i; @@ -71,7 +72,7 @@ Hex[HASHHEXLEN] = '\0'; }; -void +void CvtBin(const HASHHEX Hex, HASH Bin) { unsigned short i; @@ -89,7 +90,7 @@ /* calculate H(A1) as per spec */ -void +void DigestCalcHA1( const char *pszAlg, const char *pszUserName, @@ -125,7 +126,7 @@ }; /* calculate request-digest/response-digest as per HTTP Digest spec */ -void +void DigestCalcResponse( const HASHHEX HA1, /* H(A1) */ const char *pszNonce, /* nonce from server */ Index: squid/src/Makefile.in diff -u squid/src/Makefile.in:1.8 squid/src/Makefile.in:1.1.1.4.2.1.2.11 --- squid/src/Makefile.in:1.8 Tue Apr 3 23:45:08 2001 +++ squid/src/Makefile.in Tue Apr 10 06:21:38 2001 @@ -65,6 +65,7 @@ PTHREADLIB = @PTHREADLIB@ SNMPLIB = @SNMPLIB@ MALLOCLIB = @LIB_MALLOC@ +SSLLIB = @SSLLIB@ AC_CFLAGS = @CFLAGS@ LDFLAGS = @LDFLAGS@ XTRA_LIBS = @XTRA_LIBS@ @@ -80,7 +81,7 @@ INCLUDE = -I. -I../include -I$(top_srcdir)/include CFLAGS = $(AC_CFLAGS) $(INCLUDE) $(DEFINES) SQUID_LIBS = -L../lib $(CRYPTLIB) $(REGEXLIB) @SQUID_PTHREAD_LIB@ \ - $(SNMPLIB) $(MALLOCLIB) -lmiscutil $(XTRA_LIBS) + $(SNMPLIB) $(MALLOCLIB) $(SSLLIB) -lmiscutil $(XTRA_LIBS) CLIENT_LIBS = -L../lib -lmiscutil $(XTRA_LIBS) DNSSERVER_LIBS = -L../lib -lmiscutil $(XTRA_LIBS) PINGER_LIBS = -L../lib -lmiscutil $(XTRA_LIBS) @@ -160,6 +161,7 @@ send-announce.o \ @SNMP_OBJS@ \ ssl.o \ + @SSL_OBJS@ \ stat.o \ StatHist.o \ String.o \ @@ -197,6 +199,8 @@ LEAKFINDER_OBJS = \ leakfinder.o + +SSL_OBJS = ssl_support.o DEFAULTS = \ -DDEFAULT_CONFIG_FILE=\"$(DEFAULT_CONFIG_FILE)\" Index: squid/src/cf.data.pre diff -u squid/src/cf.data.pre:1.25 squid/src/cf.data.pre:1.1.1.4.2.1.2.16 --- squid/src/cf.data.pre:1.25 Tue Apr 3 23:45:08 2001 +++ squid/src/cf.data.pre Tue Apr 10 06:21:38 2001 @@ -84,6 +84,57 @@ You may specify multiple socket addresses on multiple lines. DOC_END +NAME: https_port +IFDEF: USE_SSL +TYPE: sockaddr_in_list +DEFAULT: none +LOC: Config.Sockaddr.https +DOC_START + Usage: port + hostname:port + 1.2.3.4:port + + The socket addresses where Squid will listen for HTTPS client + requests. You may specify multiple socket addresses. + + This is really only useful for situations where you are running + squid in accelerator mode and you want to do the SSL work at the + accelerator level. +DOC_END + +NAME: ssl_certificate +IFDEF: USE_SSL +TYPE: string +DEFAULT: none +LOC: Config.SSL.certificate +COMMENT: /path/to/certificate +DOC_START + Certificate for use with SSL acceleration. +DOC_END + +NAME: ssl_key +IFDEF: USE_SSL +TYPE: string +DEFAULT: none +LOC: Config.SSL.key +COMMENT: /path/to/key +DOC_START + Key for SSL certificate defined in ssl_certificate. +DOC_END + +NAME: ssl_version +IFDEF: USE_SSL +TYPE: int +DEFAULT: 1 +LOC: Config.SSL.version +DOC_START + Determines the version of SSL/TLS used. + 1: SSLv2/SSLv3 + 2: SSLv2 only + 3: SSLv3 only + 4: TLSv1 +DOC_END + NAME: icp_port udp_port TYPE: ushort @@ -447,7 +498,6 @@ be handled directly by this cache. In other words, use this to not query neighbor caches for certain objects. You may list this option multiple times. - NOCOMMENT_START #We recommend you to use at least the following line. hierarchy_stoplist cgi-bin ? @@ -684,6 +734,8 @@ Usage: cache_dir Type Directory-Name Fs-specific-data [options] + + cache_dir diskd Maxobjsize Directory-Name MB L1 L2 Q1 Q2 You can specify multiple cache_dir lines to spread the cache among different disk partitions. Index: squid/src/client_side.c diff -u squid/src/client_side.c:1.25 squid/src/client_side.c:1.1.1.4.2.2.2.28 --- squid/src/client_side.c:1.25 Fri Apr 13 11:12:37 2001 +++ squid/src/client_side.c Fri Apr 13 17:13:48 2001 @@ -831,7 +831,7 @@ /* prevent those nasty RST packets */ { char buf[SQUID_TCP_SO_RCVBUF]; - while (read(fd, buf, SQUID_TCP_SO_RCVBUF) > 0); + while (FD_READ_METHOD(fd, buf, SQUID_TCP_SO_RCVBUF) > 0); } #endif } @@ -2472,6 +2472,7 @@ if (opt_accel_uses_host && (t = mime_get_header(req_hdr, "Host"))) { int vport; char *q; + char *protocol_name = "http"; if (vport_mode) vport = (int) ntohs(http->conn->me.sin_port); else @@ -2494,8 +2495,15 @@ url_sz = strlen(url) + 32 + Config.appendDomainLen + strlen(t); http->uri = xcalloc(url_sz, 1); - snprintf(http->uri, url_sz, "http://%s:%d%s", - t, vport, url); + +#if SSL_FORWARDING_NOT_YET_DONE + if (Config.Sockaddr.https->s.sin_port == http->conn->me.sin_port) { + protocol_name = "https"; + vport = ntohs(http->conn->me.sin_port); + } +#endif + snprintf(http->uri, url_sz, "%s://%s:%d%s", + protocol_name, t, vport, url); } else if (vhost_mode) { int vport; /* Put the local socket IP address as the hostname */ @@ -2611,7 +2619,7 @@ int len = conn->in.size - conn->in.offset - 1; debug(33, 4) ("clientReadRequest: FD %d: reading request...\n", fd); statCounter.syscalls.sock.reads++; - size = read(fd, conn->in.buf + conn->in.offset, len); + size = FD_READ_METHOD(fd, conn->in.buf + conn->in.offset, len); if (size > 0) { fd_bytes(fd, size, FD_READ); kb_incr(&statCounter.client_http.kbytes_in, size); @@ -3105,6 +3113,112 @@ } } +#if USE_SSL + +/* negotiate an SSL connection */ +static void +clientNegotiateSSL(int fd, void *data) +{ + ConnStateData *conn = data; + X509 *client_cert; + int ret; + + if ((ret = SSL_accept(fd_table[fd].ssl)) <= 0) { + if (BIO_sock_should_retry(ret)) { + commSetSelect(fd, COMM_SELECT_READ, clientNegotiateSSL, conn, 0); + return; + } + ret = ERR_get_error(); + debug(81, 1) ("clientNegotiateSSL: Error negotiating SSL connection on FD %d: %s\n", + fd, ERR_error_string(ret, NULL)); + comm_close(fd); + return; + } + debug(81, 5) ("clientNegotiateSSL: FD %d negotiated cipher %s\n", fd, + SSL_get_cipher(fd_table[fd].ssl)); + + client_cert = SSL_get_peer_certificate(fd_table[fd].ssl); + if (client_cert != NULL) { + debug(81, 5) ("clientNegotiateSSL: FD %d client certificate: subject: %s\n", fd, + X509_NAME_oneline(X509_get_subject_name(client_cert), 0, 0)); + + debug(81, 5) ("clientNegotiateSSL: FD %d client certificate: issuer: %s\n", fd, + X509_NAME_oneline(X509_get_issuer_name(client_cert), 0, 0)); + + X509_free(client_cert); + } else { + debug(81, 5) ("clientNegotiateSSL: FD %d has no certificate.\n", fd); + } + + commSetSelect(fd, COMM_SELECT_READ, clientReadRequest, conn, 0); +} + +/* handle a new HTTPS connection */ +static void +httpsAccept(int sock, void *data) +{ + int *N = data; + int fd = -1; + ConnStateData *connState = NULL; + struct sockaddr_in peer; + struct sockaddr_in me; + int max = INCOMING_HTTP_MAX; + SSL *ssl; + int ssl_error; +#if USE_IDENT + static aclCheck_t identChecklist; +#endif + commSetSelect(sock, COMM_SELECT_READ, httpsAccept, NULL, 0); + while (max-- && !httpAcceptDefer(sock, NULL)) { + memset(&peer, '\0', sizeof(struct sockaddr_in)); + memset(&me, '\0', sizeof(struct sockaddr_in)); + if ((fd = comm_accept(sock, &peer, &me)) < 0) { + if (!ignoreErrno(errno)) + debug(50, 1) ("httpsAccept: FD %d: accept failure: %s\n", + sock, xstrerror()); + break; + } + if ((ssl = SSL_new(sslContext)) == NULL) { + ssl_error = ERR_get_error(); + debug(81, 1) ("httpsAccept: Error allocating handle: %s\n", + ERR_error_string(ssl_error, NULL)); + break; + } + SSL_set_fd(ssl, fd); + fd_table[fd].ssl = ssl; + fd_table[fd].read_method = &ssl_read_method; + fd_table[fd].write_method = &ssl_write_method; + debug(50, 5) ("httpsAccept: FD %d accepted, starting SSL negotiation.\n", fd); + + connState = cbdataAlloc(ConnStateData); + connState->peer = peer; + connState->log_addr = peer.sin_addr; + connState->log_addr.s_addr &= Config.Addrs.client_netmask.s_addr; + connState->me = me; + connState->fd = fd; + connState->in.size = CLIENT_REQ_BUF_SZ; + connState->in.buf = memAllocate(MEM_CLIENT_REQ_BUF); + /* XXX account connState->in.buf */ + comm_add_close_handler(fd, connStateFree, connState); + if (Config.onoff.log_fqdn) + fqdncache_gethostbyaddr(peer.sin_addr, FQDN_LOOKUP_IF_MISS); + commSetTimeout(fd, Config.Timeout.request, requestTimeout, connState); +#if USE_IDENT + identChecklist.src_addr = peer.sin_addr; + identChecklist.my_addr = me.sin_addr; + identChecklist.my_port = ntohs(me.sin_port); + if (aclCheckFast(Config.accessList.identLookup, &identChecklist)) + identStart(&me, &peer, clientIdentDone, connState); +#endif + commSetSelect(fd, COMM_SELECT_READ, clientNegotiateSSL, connState, 0); + commSetDefer(fd, clientReadDefer, connState); + clientdbEstablished(peer.sin_addr, 1); + (*N)++; + } +} + +#endif /* USE_SSL */ + #define SENDING_BODY 0 #define SENDING_HDRSONLY 1 static int @@ -3263,6 +3377,28 @@ fd); HttpSockets[NHttpSockets++] = fd; } +#ifdef USE_SSL + for (s = Config.Sockaddr.https; s; s = s->next) { + enter_suid(); + fd = comm_open(SOCK_STREAM, + 0, + s->s.sin_addr, + ntohs(s->s.sin_port), + COMM_NONBLOCKING, + "HTTPS Socket"); + leave_suid(); + if (fd < 0) + continue; + comm_listen(fd); + commSetSelect(fd, COMM_SELECT_READ, httpsAccept, NULL, 0); + /*commSetDefer(fd, httpAcceptDefer, NULL); */ + debug(1, 1) ("Accepting HTTPS connections at %s, port %d, FD %d.\n", + inet_ntoa(s->s.sin_addr), + (int) ntohs(s->s.sin_port), + fd); + HttpSockets[NHttpSockets++] = fd; + } +#endif if (NHttpSockets < 1) fatal("Cannot open HTTP Port"); } Index: squid/src/comm.c diff -u squid/src/comm.c:1.11 squid/src/comm.c:1.1.1.4.2.1.2.11 --- squid/src/comm.c:1.11 Fri Mar 30 14:29:38 2001 +++ squid/src/comm.c Sun Mar 11 23:31:16 2001 @@ -537,7 +537,7 @@ { LOCAL_ARRAY(char, buf, 1024); int n; - n = read(fd, buf, 1024); + n = FD_READ_METHOD(fd, buf, 1024); if (n < 0) debug(5, 3) ("commLingerClose: FD %d read: %s\n", fd, xstrerror()); comm_close(fd); @@ -570,10 +570,12 @@ comm_close(int fd) { fde *F = NULL; + debug(5, 5) ("comm_close: FD %d\n", fd); assert(fd >= 0); assert(fd < Squid_MaxFD); F = &fd_table[fd]; + if (F->flags.closing) return; if (shutting_down && (!F->flags.open || F->type == FD_FILE)) @@ -807,7 +809,7 @@ fd, (int) state->offset, state->size); nleft = state->size - state->offset; - len = write(fd, state->buf + state->offset, nleft); + len = FD_WRITE_METHOD(fd, state->buf + state->offset, nleft); debug(5, 5) ("commHandleWrite: write() returns %d\n", len); fd_bytes(fd, len, FD_WRITE); statCounter.syscalls.sock.writes++; Index: squid/src/disk.c diff -u squid/src/disk.c:1.5 squid/src/disk.c:1.1.1.3.12.1.2.7 --- squid/src/disk.c:1.5 Fri Jan 12 00:20:32 2001 +++ squid/src/disk.c Thu Feb 8 14:27:18 2001 @@ -192,7 +192,7 @@ errno = 0; if (fdd->write_q->file_offset != -1) lseek(fd, fdd->write_q->file_offset, SEEK_SET); - len = write(fd, + len = FD_WRITE_METHOD(fd, fdd->write_q->buf + fdd->write_q->buf_offset, fdd->write_q->len - fdd->write_q->buf_offset); debug(6, 3) ("diskHandleWrite: FD %d len = %d\n", fd, len); @@ -361,7 +361,7 @@ F->disk.offset = ctrl_dat->offset; } errno = 0; - len = read(fd, ctrl_dat->buf, ctrl_dat->req_len); + len = FD_READ_METHOD(fd, ctrl_dat->buf, ctrl_dat->req_len); if (len > 0) F->disk.offset += len; statCounter.syscalls.disk.reads++; Index: squid/src/errorpage.c diff -u squid/src/errorpage.c:1.11 squid/src/errorpage.c:1.1.1.4.2.1.2.7 --- squid/src/errorpage.c:1.11 Sat Mar 3 02:44:32 2001 +++ squid/src/errorpage.c Sun Mar 11 23:31:16 2001 @@ -177,7 +177,7 @@ return NULL; } text = xcalloc(sb.st_size + 2 + 1, 1); /* 2 == space for %S */ - if (read(fd, text, sb.st_size) != sb.st_size) { + if (FD_READ_METHOD(fd, text, sb.st_size) != sb.st_size) { debug(4, 0) ("errorTryLoadText: failed to fully read: '%s': %s\n", path, xstrerror()); xfree(text); Index: squid/src/fd.c diff -u squid/src/fd.c:1.5 squid/src/fd.c:1.1.1.3.14.1.2.5 --- squid/src/fd.c:1.5 Fri Jan 12 00:20:32 2001 +++ squid/src/fd.c Fri Apr 13 17:13:49 2001 @@ -35,6 +35,9 @@ #include "squid.h" +int default_read_method(int, char *, int); +int default_write_method(int, const char *, int); + const char *fdTypeStr[] = { "None", @@ -80,6 +83,12 @@ assert(F->read_handler == NULL); assert(F->write_handler == NULL); } + F->read_method = &default_read_method; + F->write_method = &default_write_method; +#if USE_SSL + safe_free(F->ssl); + F->ssl = NULL; +#endif debug(51, 3) ("fd_close FD %d %s\n", fd, F->desc); F->flags.open = 0; fdUpdateBiggest(fd, 0); @@ -90,6 +99,18 @@ F->timeout = 0; } +int +default_read_method(int fd, char *buf, int len) +{ + return (read(fd, buf, len)); +} + +int +default_write_method(int fd, const char *buf, int len) +{ + return (write(fd, buf, len)); +} + void fd_open(int fd, unsigned int type, const char *desc) { @@ -104,6 +125,8 @@ debug(51, 3) ("fd_open FD %d %s\n", fd, desc); F->type = type; F->flags.open = 1; + F->read_method = &default_read_method; + F->write_method = &default_write_method; fdUpdateBiggest(fd, 1); if (desc) xstrncpy(F->desc, desc, FD_DESC_SZ); Index: squid/src/ftp.c diff -u squid/src/ftp.c:1.12 squid/src/ftp.c:1.1.1.4.2.1.2.7 --- squid/src/ftp.c:1.12 Sat Mar 3 02:44:32 2001 +++ squid/src/ftp.c Sun Mar 11 23:31:16 2001 @@ -883,7 +883,7 @@ #endif memset(ftpState->data.buf + ftpState->data.offset, '\0', read_sz); statCounter.syscalls.sock.reads++; - len = read(fd, ftpState->data.buf + ftpState->data.offset, read_sz); + len = FD_READ_METHOD(fd, ftpState->data.buf + ftpState->data.offset, read_sz); if (len > 0) { fd_bytes(fd, len, FD_READ); #if DELAY_POOLS @@ -1244,7 +1244,7 @@ } assert(ftpState->ctrl.offset < ftpState->ctrl.size); statCounter.syscalls.sock.reads++; - len = read(fd, + len = FD_READ_METHOD(fd, ftpState->ctrl.buf + ftpState->ctrl.offset, ftpState->ctrl.size - ftpState->ctrl.offset); if (len > 0) { Index: squid/src/gopher.c diff -u squid/src/gopher.c:1.8 squid/src/gopher.c:1.1.1.4.2.1.2.8 --- squid/src/gopher.c:1.8 Sat Mar 3 02:44:32 2001 +++ squid/src/gopher.c Sun Mar 11 23:31:16 2001 @@ -612,7 +612,7 @@ #endif /* leave one space for \0 in gopherToHTML */ statCounter.syscalls.sock.reads++; - len = read(fd, buf, read_sz); + len = FD_READ_METHOD(fd, buf, read_sz); if (len > 0) { fd_bytes(fd, len, FD_READ); #if DELAY_POOLS Index: squid/src/helper.c diff -u squid/src/helper.c:1.9 squid/src/helper.c:1.1.1.3.20.6 --- squid/src/helper.c:1.9 Sat Mar 3 02:44:32 2001 +++ squid/src/helper.c Sun Mar 11 23:31:16 2001 @@ -659,7 +659,7 @@ assert(fd == srv->rfd); assert(cbdataValid(data)); statCounter.syscalls.sock.reads++; - len = read(fd, srv->buf + srv->offset, srv->buf_sz - srv->offset); + len = FD_READ_METHOD(fd, srv->buf + srv->offset, srv->buf_sz - srv->offset); fd_bytes(fd, len, FD_READ); debug(29, 5) ("helperHandleRead: %d bytes from %s #%d.\n", len, hlp->id_name, srv->index + 1); Index: squid/src/http.c diff -u squid/src/http.c:1.12 squid/src/http.c:1.1.1.4.2.1.2.11 --- squid/src/http.c:1.12 Sat Mar 3 02:44:32 2001 +++ squid/src/http.c Sun Mar 11 23:31:16 2001 @@ -482,7 +482,7 @@ read_sz = delayBytesWanted(delay_id, 1, read_sz); #endif statCounter.syscalls.sock.reads++; - len = read(fd, buf, read_sz); + len = FD_READ_METHOD(fd, buf, read_sz); debug(11, 5) ("httpReadReply: FD %d: len %d.\n", fd, len); if (len > 0) { fd_bytes(fd, len, FD_READ); Index: squid/src/ident.c diff -u squid/src/ident.c:1.7 squid/src/ident.c:1.1.1.3.12.1.2.6 --- squid/src/ident.c:1.7 Sat Mar 3 02:44:32 2001 +++ squid/src/ident.c Sun Mar 11 23:31:16 2001 @@ -139,7 +139,7 @@ int len = -1; buf[0] = '\0'; statCounter.syscalls.sock.reads++; - len = read(fd, buf, BUFSIZ - 1); + len = FD_READ_METHOD(fd, buf, BUFSIZ - 1); fd_bytes(fd, len, FD_READ); if (len <= 0) { comm_close(fd); Index: squid/src/main.c diff -u squid/src/main.c:1.20 squid/src/main.c:1.1.1.4.2.1.2.12 --- squid/src/main.c:1.20 Thu Mar 29 01:41:31 2001 +++ squid/src/main.c Thu Mar 29 04:20:53 2001 @@ -519,6 +519,10 @@ #if USE_WCCP wccpInit(); #endif +#if USE_SSL + if (Config.Sockaddr.https) + sslInit(Config.SSL.certificate, Config.SSL.key); +#endif serverConnectionsOpen(); if (theOutIcpConnection >= 0) { if (!Config2.Accel.on || Config.onoff.accel_with_proxy) Index: squid/src/mime.c diff -u squid/src/mime.c:1.8 squid/src/mime.c:1.1.1.4.2.1.2.5 --- squid/src/mime.c:1.8 Fri Jan 12 00:20:33 2001 +++ squid/src/mime.c Thu Feb 8 14:27:19 2001 @@ -439,7 +439,7 @@ reply->hdr_sz = e->mem_obj->inmem_hi; /* yuk */ /* read the file into the buffer and append it to store */ buf = memAllocate(MEM_4K_BUF); - while ((n = read(fd, buf, 4096)) > 0) + while ((n = FD_READ_METHOD(fd, buf, 4096)) > 0) storeAppend(e, buf, n); file_close(fd); EBIT_SET(e->flags, ENTRY_SPECIAL); Index: squid/src/pconn.c diff -u squid/src/pconn.c:1.5 squid/src/pconn.c:1.1.1.2.16.1.2.5 --- squid/src/pconn.c:1.5 Fri Jan 12 00:20:33 2001 +++ squid/src/pconn.c Thu Feb 8 14:27:19 2001 @@ -125,7 +125,7 @@ int n; assert(table != NULL); statCounter.syscalls.sock.reads++; - n = read(fd, buf, 256); + n = FD_READ_METHOD(fd, buf, 256); debug(48, 3) ("pconnRead: %d bytes from FD %d, %s\n", n, fd, hashKeyStr(&p->hash)); pconnRemoveFD(p, fd); Index: squid/src/send-announce.c diff -u squid/src/send-announce.c:1.6 squid/src/send-announce.c:1.1.1.4.2.1.2.3 --- squid/src/send-announce.c:1.6 Fri Jan 12 00:20:33 2001 +++ squid/src/send-announce.c Thu Feb 8 14:27:19 2001 @@ -86,7 +86,7 @@ l = strlen(sndbuf); if ((file = Config.Announce.file) != NULL) { fd = file_open(file, O_RDONLY | O_TEXT); - if (fd > -1 && (n = read(fd, sndbuf + l, BUFSIZ - l - 1)) > 0) { + if (fd > -1 && (n = FD_READ_METHOD(fd, sndbuf + l, BUFSIZ - l - 1)) > 0) { fd_bytes(fd, n, FD_READ); l += n; sndbuf[l] = '\0'; Index: squid/src/squid.h diff -u squid/src/squid.h:1.11 squid/src/squid.h:1.1.1.4.2.1.2.9 --- squid/src/squid.h:1.11 Sun Mar 11 14:11:09 2001 +++ squid/src/squid.h Sun Mar 11 23:31:17 2001 @@ -368,6 +368,20 @@ #endif #include "md5.h" + +#if USE_SSL +#include "ssl_support.h" +/* This is an ugly hack, but necessary. + * + * Squid's md5 conflicts with OpenSSL's md5, but they're more or less + * interchangable. + * Free is defined in include/radix.h and also in OpenSSL, but we don't need + * OpenSSL's, so it can be undef'd and then appear from radix.h later. + * It's dangerous and ugly, but I can't see any other way to get around it. + */ +#undef Free +#endif + #include "Stack.h" /* Needed for poll() on Linux at least */ @@ -464,7 +478,9 @@ /* * I'm sick of having to keep doing this .. */ - #define INDEXSD(i) (&Config.cacheSwap.swapDirs[(i)]) + +#define FD_READ_METHOD(fd, buf, len) (*fd_table[fd].read_method)(fd, buf, len) +#define FD_WRITE_METHOD(fd, buf, len) (*fd_table[fd].write_method)(fd, buf, len) #endif /* SQUID_H */ Index: squid/src/ssl.c diff -u squid/src/ssl.c:1.7 squid/src/ssl.c:1.1.1.4.2.1.2.6 --- squid/src/ssl.c:1.7 Sat Mar 3 02:44:32 2001 +++ squid/src/ssl.c Sun Mar 11 23:31:17 2001 @@ -200,7 +200,7 @@ read_sz = delayBytesWanted(sslState->delay_id, 1, read_sz); #endif statCounter.syscalls.sock.reads++; - len = read(fd, sslState->server.buf + sslState->server.len, read_sz); + len = FD_READ_METHOD(fd, sslState->server.buf + sslState->server.len, read_sz); debug(26, 3) ("sslReadServer: FD %d, read %d bytes\n", fd, len); if (len > 0) { fd_bytes(fd, len, FD_READ); @@ -236,7 +236,7 @@ fd, SQUID_TCP_SO_RCVBUF - sslState->client.len, sslState->client.len); statCounter.syscalls.sock.reads++; - len = read(fd, + len = FD_READ_METHOD(fd, sslState->client.buf + sslState->client.len, SQUID_TCP_SO_RCVBUF - sslState->client.len); debug(26, 3) ("sslReadClient: FD %d, read %d bytes\n", fd, len); @@ -276,7 +276,7 @@ debug(26, 3) ("sslWriteServer: FD %d, %d bytes to write\n", fd, sslState->client.len); statCounter.syscalls.sock.writes++; - len = write(fd, + len = FD_WRITE_METHOD(fd, sslState->client.buf, sslState->client.len); debug(26, 3) ("sslWriteServer: FD %d, %d bytes written\n", fd, len); @@ -315,7 +315,7 @@ debug(26, 3) ("sslWriteClient: FD %d, %d bytes to write\n", fd, sslState->server.len); statCounter.syscalls.sock.writes++; - len = write(fd, + len = FD_WRITE_METHOD(fd, sslState->server.buf, sslState->server.len); debug(26, 3) ("sslWriteClient: FD %d, %d bytes written\n", fd, len); Index: squid/src/ssl_support.c diff -u /dev/null squid/src/ssl_support.c:1.1.2.3 --- /dev/null Tue Sep 9 04:57:44 2003 +++ squid/src/ssl_support.c Fri Apr 13 17:13:49 2001 @@ -0,0 +1,186 @@ + +/* + * $Id: squid-ssl-20010414-HEAD-20010414,v 1.1 2004/08/17 20:55:13 hno Exp $ + * + * AUTHOR: Benno Rice + * DEBUG: section 81 SSL accelerator support + * + * SQUID Internet Object Cache http://squid.nlanr.net/Squid/ + * ---------------------------------------------------------- + * + * Squid is the result of efforts by numerous individuals from the + * Internet community. Development is led by Duane Wessels of the + * National Laboratory for Applied Network Research and funded by the + * National Science Foundation. Squid is Copyrighted (C) 1998 by + * Duane Wessels and the University of California San Diego. Please + * see the COPYRIGHT file for full details. Squid incorporates + * software developed and/or copyrighted by other sources. Please see + * the CREDITS file for full details. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. + * + */ + +#include "squid.h" + +extern int commUnsetNonBlocking(int fd); +extern int commSetNonBlocking(int fd); + +void clientNegotiateSSL(int fd, void *data); +void clientReadSSLRequest(int fd, void *data); +void connFreeSSL(int fd, void *data); + +SSL_CTX *sslContext = NULL; +SSL **ssl_table = NULL; + +static RSA * +ssl_temp_rsa_cb(SSL * ssl, int export, int keylen) +{ + static RSA *rsa = NULL; + + if (rsa == NULL) + rsa = RSA_generate_key(512, RSA_F4, NULL, NULL); + return rsa; +} + +static int +ssl_verify_cb(int ok, X509_STORE_CTX * ctx) +{ + char buffer[256]; + + X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert), buffer, + sizeof(buffer)); + if (ok) + debug(81, 5) ("SSL Certificate OK: %s\n", buffer); + else { + switch (ctx->error) { + case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: + debug(81, 5) ("SSL Certficate error: CA not known: %s\n", buffer); + break; + case X509_V_ERR_CERT_NOT_YET_VALID: + debug(81, 5) ("SSL Certficate not yet valid: %s\n", buffer); + break; + case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: + debug(81, 5) ("SSL Certificate has illegal \'not before\' field: %s\n", buffer); + break; + case X509_V_ERR_CERT_HAS_EXPIRED: + debug(81, 5) ("SSL Certificate expired: %s\n", buffer); + break; + case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: + debug(81, 5) ("SSL Certificate has invalid \'not after\' field: %s\n", buffer); + break; + default: + debug(81, 5) ("SSL unknown certificate error %d in %s\n", + ctx->error, buffer); + break; + } + } + return ok; +} + +void +sslInit(const char *certfile, const char *keyfile) +{ + int ssl_error; + SSL_METHOD *method; + SSL_load_error_strings(); + SSLeay_add_ssl_algorithms(); + + if (!keyfile) + keyfile = certfile; + if (!certfile) + certfile = keyfile; + + debug(81, 1) ("Initialising SSL.\n"); + switch (Config.SSL.version) { + case 2: + debug(81, 5) ("Using SSLv2.\n"); + method = SSLv2_server_method(); + break; + case 3: + debug(81, 5) ("Using SSLv3.\n"); + method = SSLv3_server_method(); + break; + case 4: + debug(81, 5) ("Using TLSv1.\n"); + method = TLSv1_server_method(); + break; + case 1: + default: + debug(81, 5) ("Using SSLv2/SSLv3.\n"); + method = SSLv23_server_method(); + break; + } + + sslContext = SSL_CTX_new(method); + if (sslContext == NULL) { + ssl_error = ERR_get_error(); + fatalf("Failed to allocate SSL context: %s\n", + ERR_error_string(ssl_error, NULL)); + } + SSL_CTX_set_options(sslContext, SSL_OP_ALL); + + debug(81, 1) ("Using certificate in %s\n", certfile); + if (!SSL_CTX_use_certificate_file(sslContext, certfile, SSL_FILETYPE_PEM)) { + ssl_error = ERR_get_error(); + fatalf("Failed to acquire SSL certificate: %s\n", + ERR_error_string(ssl_error, NULL)); + } + debug(81, 1) ("Using private key in %s\n", keyfile); + if (!SSL_CTX_use_PrivateKey_file(sslContext, keyfile, SSL_FILETYPE_PEM)) { + ssl_error = ERR_get_error(); + fatalf("Failed to acquire SSL private key: %s\n", + ERR_error_string(ssl_error, NULL)); + } + debug(81, 5) ("Comparing private and public SSL keys.\n"); + if (!SSL_CTX_check_private_key(sslContext)) + fatal("SSL private key does not match public key: %s\n"); + + debug(81, 9) ("Setting RSA key generation callback.\n"); + SSL_CTX_set_tmp_rsa_callback(sslContext, ssl_temp_rsa_cb); + + debug(81, 9) ("Setting certificate verification callback.\n"); + SSL_CTX_set_verify(sslContext, SSL_VERIFY_NONE, ssl_verify_cb); + + debug(81, 9) ("Setting default CA certificate location.\n"); + if (!SSL_CTX_set_default_verify_paths(sslContext)) { + ssl_error = ERR_get_error(); + debug(81, 1) ("Error error setting default CA certificate location: %s\n", + ERR_error_string(ssl_error, NULL)); + debug(81, 1) ("continuing anyway...\n"); + } + debug(81, 9) ("Set client certifying authority list.\n"); + SSL_CTX_set_client_CA_list(sslContext, SSL_load_client_CA_file(certfile)); + + ssl_table = xcalloc(Squid_MaxFD, sizeof(SSL *)); +} + +int +ssl_read_method(fd, buf, len) + int fd; + char *buf; + int len; +{ + return (SSL_read(fd_table[fd].ssl, buf, len)); +} + +int +ssl_write_method(fd, buf, len) + int fd; + const char *buf; + int len; +{ + return (SSL_write(fd_table[fd].ssl, buf, len)); +} Index: squid/src/ssl_support.h diff -u /dev/null squid/src/ssl_support.h:1.1.2.4 --- /dev/null Tue Sep 9 04:57:44 2003 +++ squid/src/ssl_support.h Sun Feb 11 03:36:06 2001 @@ -0,0 +1,52 @@ + +/* + * $Id: squid-ssl-20010414-HEAD-20010414,v 1.1 2004/08/17 20:55:13 hno Exp $ + * + * AUTHOR: Benno Rice + * + * SQUID Internet Object Cache http://squid.nlanr.net/Squid/ + * ---------------------------------------------------------- + * + * Squid is the result of efforts by numerous individuals from the + * Internet community. Development is led by Duane Wessels of the + * National Laboratory for Applied Network Research and funded by the + * National Science Foundation. Squid is Copyrighted (C) 1998 by + * Duane Wessels and the University of California San Diego. Please + * see the COPYRIGHT file for full details. Squid incorporates + * software developed and/or copyrighted by other sources. Please see + * the CREDITS file for full details. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. + * + */ + +#ifndef SSL_SUPPORT_H +#define SSL_SUPPORT_H + +#include "config.h" +#if HAVE_OPENSSL_SSL_H +#include +#endif +#if HAVE_OPENSSL_ERR_H +#include +#endif + +extern SSL_CTX *sslContext; + +void sslInit(const char *certfile, const char *keyfile); +int ssl_read_method(int, char *, int); +int ssl_write_method(int, const char *, int); + +#endif /* SSL_SUPPORT_H */ Index: squid/src/structs.h diff -u squid/src/structs.h:1.29 squid/src/structs.h:1.1.1.4.2.1.2.18 --- squid/src/structs.h:1.29 Tue Apr 3 23:45:08 2001 +++ squid/src/structs.h Fri Apr 13 17:13:49 2001 @@ -381,6 +381,9 @@ } Port; struct { sockaddr_in_list *http; +#if USE_SSL + sockaddr_in_list *https; +#endif } Sockaddr; #if SQUID_SNMP struct { @@ -621,6 +624,13 @@ int rebuild_chunk_percentage; } digest; #endif +#if USE_SSL + struct { + char *certificate; + char *key; + int version; + } SSL; +#endif wordlist *ext_methods; struct { int high_rptm; @@ -734,6 +744,11 @@ DEFER *defer_check; /* check if we should defer read */ void *defer_data; CommWriteStateData *rwstate; /* State data for comm_write */ + READ_HANDLER *read_method; + WRITE_HANDLER *write_method; +#if USE_SSL + SSL *ssl; +#endif }; struct _fileMap { Index: squid/src/tools.c diff -u squid/src/tools.c:1.11 squid/src/tools.c:1.1.1.4.2.2.2.10 --- squid/src/tools.c:1.11 Thu Feb 15 13:09:17 2001 +++ squid/src/tools.c Sat Feb 24 02:37:58 2001 @@ -589,7 +589,7 @@ return; } snprintf(buf, 32, "%d\n", (int) getpid()); - write(fd, buf, strlen(buf)); + FD_WRITE_METHOD(fd, buf, strlen(buf)); file_close(fd); } Index: squid/src/typedefs.h diff -u squid/src/typedefs.h:1.17 squid/src/typedefs.h:1.1.1.4.2.1.2.12 --- squid/src/typedefs.h:1.17 Wed Feb 28 20:04:19 2001 +++ squid/src/typedefs.h Sun Mar 11 23:31:17 2001 @@ -227,6 +227,8 @@ typedef void RH(void *data, char *); typedef void UH(void *data, wordlist *); typedef int DEFER(int fd, void *data); +typedef int READ_HANDLER(int, char *, int); +typedef int WRITE_HANDLER(int, const char *, int); typedef void CBCB(char *buf, size_t size, void *data); typedef void STIOCB(void *their_data, int errflag, storeIOState *); Index: squid/src/url.c diff -u squid/src/url.c:1.4 squid/src/url.c:1.1.1.4.2.1.2.6 --- squid/src/url.c:1.4 Fri Jan 12 00:20:33 2001 +++ squid/src/url.c Fri Apr 13 17:13:49 2001 @@ -550,12 +550,17 @@ rc = 1; break; case PROTO_HTTPS: +#ifdef USE_SSL + rc = 1; + break; +#else /* * Squid can't originate an SSL connection, so it should * never receive an "https:" URL. It should always be * CONNECT instead. */ rc = 0; +#endif default: break; } Index: squid/src/wais.c diff -u squid/src/wais.c:1.6 squid/src/wais.c:1.1.1.2.16.1.2.4 --- squid/src/wais.c:1.6 Sat Mar 3 02:44:32 2001 +++ squid/src/wais.c Sun Mar 11 23:31:17 2001 @@ -103,7 +103,7 @@ read_sz = delayBytesWanted(delay_id, 1, read_sz); #endif statCounter.syscalls.sock.reads++; - len = read(fd, buf, read_sz); + len = FD_READ_METHOD(fd, buf, read_sz); if (len > 0) { fd_bytes(fd, len, FD_READ); #if DELAY_POOLS Index: squid/src/whois.c diff -u squid/src/whois.c:1.6 squid/src/whois.c:1.1.1.2.16.1.2.5 --- squid/src/whois.c:1.6 Sat Mar 3 02:44:32 2001 +++ squid/src/whois.c Sun Mar 11 23:31:17 2001 @@ -92,7 +92,7 @@ MemObject *mem = entry->mem_obj; int len; statCounter.syscalls.sock.reads++; - len = read(fd, buf, 4095); + len = FD_READ_METHOD(fd, buf, 4095); buf[len] = '\0'; debug(75, 3) ("whoisReadReply: FD %d read %d bytes\n", fd, len); debug(75, 5) ("{%s}\n", buf); Index: squid/src/auth/digest/helpers/password/Makefile.in diff -u squid/src/auth/digest/helpers/password/Makefile.in:1.2 squid/src/auth/digest/helpers/password/Makefile.in:1.2.8.2 --- squid/src/auth/digest/helpers/password/Makefile.in:1.2 Wed Jan 31 14:20:28 2001 +++ squid/src/auth/digest/helpers/password/Makefile.in Tue Apr 10 06:19:02 2001 @@ -45,11 +45,11 @@ MV = @MV@ RM = @RM@ SHELL = /bin/sh - +SSLLIB = @SSLLIB@ INCLUDE = -I. -I../../../../../include -I$(top_srcdir)/include CFLAGS = $(AC_CFLAGS) $(INCLUDE) $(DEFINES) -AUTH_LIBS = -L../../../../../lib -lmiscutil $(CRYPTLIB) $(XTRA_LIBS) +AUTH_LIBS = -L../../../../../lib -lmiscutil $(CRYPTLIB) $(XTRA_LIBS) $(SSLLIB) PROGS = $(DIGEST_PW_AUTH_EXE) OBJS = digest_pw_auth.o squid-ssl-20010414-HEAD-20010414.new squid-ssl-20010414-HEAD-20010414 differ: char 80, line 2