From: hno <> Date: Sat, 14 Apr 2001 06:03:19 +0000 (+0000) Subject: SSL->HTTP gatewaying support by Benno Rice X-Git-Tag: SQUID_3_0_PRE1~1546 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=1f7c91781409b84450e439b6dc08bf71db970943;p=thirdparty%2Fsquid.git SSL->HTTP gatewaying support by Benno Rice Allows Squid in accelerator mode to listen for https requests as well as http requests. --- diff --git a/configure.in b/configure.in index 83805aa1fa..d9b2da2db1 100644 --- a/configure.in +++ b/configure.in @@ -3,13 +3,13 @@ dnl Configuration input file for Squid dnl dnl Duane Wessels, wessels@nlanr.net, February 1996 (autoconf v2.9) dnl -dnl $Id: configure.in,v 1.222 2001/03/10 00:55:35 hno Exp $ +dnl $Id: configure.in,v 1.223 2001/04/14 00:03:19 hno Exp $ dnl dnl dnl AC_INIT(src/main.c) AC_CONFIG_HEADER(include/autoconf.h) -AC_REVISION($Revision: 1.222 $)dnl +AC_REVISION($Revision: 1.223 $)dnl AC_PREFIX_DEFAULT(/usr/local/squid) AC_CONFIG_AUX_DIR(cfgaux) @@ -501,6 +501,53 @@ AC_ARG_ENABLE(htcp, ]) 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 @@ AC_CHECK_HEADERS( \ 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 \ diff --git a/helpers/digest_auth/password/Makefile.in b/helpers/digest_auth/password/Makefile.in index ec9b4b868f..66b83d6aa7 100644 --- a/helpers/digest_auth/password/Makefile.in +++ b/helpers/digest_auth/password/Makefile.in @@ -1,7 +1,7 @@ # # Makefile for the Squid Object Cache server # -# $Id: Makefile.in,v 1.1 2001/01/31 22:16:42 hno Exp $ +# $Id: Makefile.in,v 1.2 2001/04/14 00:03:25 hno Exp $ # # Uncomment and customize the following to suit your needs: # @@ -45,11 +45,11 @@ XTRA_OBJS = @XTRA_OBJS@ 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 diff --git a/include/md5.h b/include/md5.h index e8e323dde3..ab8d072e61 100644 --- a/include/md5.h +++ b/include/md5.h @@ -1,9 +1,27 @@ /* - * $Id: md5.h,v 1.8 2001/03/11 21:55:20 hno Exp $ + * $Id: md5.h,v 1.9 2001/04/14 00:03:20 hno Exp $ */ #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 @@ void MD5Final(unsigned char[16], MD5_CTX *); #define MD5_DIGEST_CHARS 16 +#endif /* USE_OPENSSL */ #endif /* MD5_H */ diff --git a/include/rfc2617.h b/include/rfc2617.h index 189ec88a02..bdeac3faa2 100644 --- a/include/rfc2617.h +++ b/include/rfc2617.h @@ -14,7 +14,7 @@ /* - * $Id: rfc2617.h,v 1.1 2001/01/31 22:16:36 hno Exp $ + * $Id: rfc2617.h,v 1.2 2001/04/14 00:03:20 hno Exp $ * * DEBUG: * AUTHOR: RFC 2617 & Robert Collins @@ -49,7 +49,6 @@ #ifndef RFC2617_H #define RFC2617_H -#include "md5.h" #define HASHLEN 16 typedef char HASH[HASHLEN]; diff --git a/lib/md5.c b/lib/md5.c index 4aa10a1e6d..2ae9756698 100644 --- a/lib/md5.c +++ b/lib/md5.c @@ -1,5 +1,5 @@ /* - * $Id: md5.c,v 1.11 2001/03/11 21:55:20 hno Exp $ + * $Id: md5.c,v 1.12 2001/04/14 00:03:20 hno Exp $ */ /* taken from RFC-1321/Appendix A.3 */ @@ -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 @@ MD5_memset(char *output, int value, unsigned int len) } #endif + +#endif /* USE_OPENSSL */ diff --git a/lib/rfc2617.c b/lib/rfc2617.c index 7bf15833e0..bb93686d19 100644 --- a/lib/rfc2617.c +++ b/lib/rfc2617.c @@ -13,7 +13,7 @@ /* - * $Id: rfc2617.c,v 1.2 2001/02/01 18:49:06 hno Exp $ + * $Id: rfc2617.c,v 1.3 2001/04/14 00:03:20 hno Exp $ * * DEBUG: * AUTHOR: RFC 2617 & Robert Collins @@ -49,6 +49,7 @@ #include "config.h" #include #include "rfc2617.h" +#include "md5.h" void CvtHex(const HASH Bin, HASHHEX Hex) diff --git a/src/Makefile.in b/src/Makefile.in index ac0f50a2fc..8d9b372b5b 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -1,7 +1,7 @@ # # Makefile for the Squid Object Cache server # -# $Id: Makefile.in,v 1.200 2001/04/03 20:22:10 adrian Exp $ +# $Id: Makefile.in,v 1.201 2001/04/14 00:03:21 hno Exp $ # # Uncomment and customize the following to suit your needs: # @@ -65,6 +65,7 @@ REGEXLIB = @REGEXLIB@ PTHREADLIB = @PTHREADLIB@ SNMPLIB = @SNMPLIB@ MALLOCLIB = @LIB_MALLOC@ +SSLLIB = @SSLLIB@ AC_CFLAGS = @CFLAGS@ LDFLAGS = @LDFLAGS@ XTRA_LIBS = @XTRA_LIBS@ @@ -80,7 +81,7 @@ SHELL = /bin/sh 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 @@ OBJS = \ send-announce.o \ @SNMP_OBJS@ \ ssl.o \ + @SSL_OBJS@ \ stat.o \ StatHist.o \ String.o \ @@ -198,6 +200,8 @@ DELAY_OBJS = delay_pools.o LEAKFINDER_OBJS = \ leakfinder.o +SSL_OBJS = ssl_support.o + DEFAULTS = \ -DDEFAULT_CONFIG_FILE=\"$(DEFAULT_CONFIG_FILE)\" diff --git a/src/cf.data.pre b/src/cf.data.pre index 32badc31ed..5d8357e7e2 100644 --- a/src/cf.data.pre +++ b/src/cf.data.pre @@ -1,6 +1,6 @@ # -# $Id: cf.data.pre,v 1.216 2001/04/03 20:22:10 adrian Exp $ +# $Id: cf.data.pre,v 1.217 2001/04/14 00:03:21 hno Exp $ # # # SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -84,6 +84,57 @@ DOC_START 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 @@ DOC_START 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 ? @@ -685,6 +735,8 @@ DOC_START 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. diff --git a/src/client_side.cc b/src/client_side.cc index fa10dcc280..b3caf3a94b 100644 --- a/src/client_side.cc +++ b/src/client_side.cc @@ -1,6 +1,6 @@ /* - * $Id: client_side.cc,v 1.533 2001/04/13 14:59:11 hno Exp $ + * $Id: client_side.cc,v 1.534 2001/04/14 00:03:21 hno Exp $ * * DEBUG: section 33 Client-side Routines * AUTHOR: Duane Wessels @@ -831,7 +831,7 @@ connStateFree(int fd, void *data) /* 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 @@ parseHttpRequest(ConnStateData * conn, method_t * method_p, int *status, 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 @@ parseHttpRequest(ConnStateData * conn, method_t * method_p, int *status, 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 @@ clientReadRequest(int fd, void *data) 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 @@ httpAccept(int sock, void *data) } } +#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 @@ clientHttpConnectionsOpen(void) 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"); } diff --git a/src/comm.cc b/src/comm.cc index 76a092da58..fd8f1cf28f 100644 --- a/src/comm.cc +++ b/src/comm.cc @@ -1,6 +1,6 @@ /* - * $Id: comm.cc,v 1.317 2001/03/03 10:39:31 hno Exp $ + * $Id: comm.cc,v 1.318 2001/04/14 00:03:22 hno Exp $ * * DEBUG: section 5 Socket Functions * AUTHOR: Harvest Derived @@ -537,7 +537,7 @@ commLingerClose(int fd, void *unused) { 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 @@ void 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 @@ commHandleWrite(int fd, void *data) 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++; diff --git a/src/disk.cc b/src/disk.cc index 27a23f45d9..9ddf0821a3 100644 --- a/src/disk.cc +++ b/src/disk.cc @@ -1,6 +1,6 @@ /* - * $Id: disk.cc,v 1.154 2001/01/12 00:37:17 wessels Exp $ + * $Id: disk.cc,v 1.155 2001/04/14 00:03:22 hno Exp $ * * DEBUG: section 6 Disk I/O Routines * AUTHOR: Harvest Derived @@ -192,7 +192,7 @@ diskHandleWrite(int fd, void *notused) 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 @@ diskHandleRead(int fd, void *data) 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++; diff --git a/src/errorpage.cc b/src/errorpage.cc index 2c64294997..43511f77fc 100644 --- a/src/errorpage.cc +++ b/src/errorpage.cc @@ -1,6 +1,6 @@ /* - * $Id: errorpage.cc,v 1.163 2001/03/03 10:39:31 hno Exp $ + * $Id: errorpage.cc,v 1.164 2001/04/14 00:03:22 hno Exp $ * * DEBUG: section 4 Error Generation * AUTHOR: Duane Wessels @@ -177,7 +177,7 @@ errorTryLoadText(const char *page_name, const char *dir) 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); diff --git a/src/fd.cc b/src/fd.cc index 22b1c307da..99225b6378 100644 --- a/src/fd.cc +++ b/src/fd.cc @@ -1,6 +1,6 @@ /* - * $Id: fd.cc,v 1.41 2001/01/12 00:37:17 wessels Exp $ + * $Id: fd.cc,v 1.42 2001/04/14 00:03:22 hno Exp $ * * DEBUG: section 51 Filedescriptor Functions * AUTHOR: Duane Wessels @@ -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 @@ fd_close(int fd) 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 @@ fd_close(int fd) 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 @@ fd_open(int fd, unsigned int type, const char *desc) 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); diff --git a/src/ftp.cc b/src/ftp.cc index 60717dc378..f75e519ab5 100644 --- a/src/ftp.cc +++ b/src/ftp.cc @@ -1,6 +1,6 @@ /* - * $Id: ftp.cc,v 1.308 2001/03/03 10:39:32 hno Exp $ + * $Id: ftp.cc,v 1.309 2001/04/14 00:03:22 hno Exp $ * * DEBUG: section 9 File Transfer Protocol (FTP) * AUTHOR: Harvest Derived @@ -883,7 +883,7 @@ ftpDataRead(int fd, void *data) #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 @@ ftpReadControlReply(int fd, void *data) } 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) { diff --git a/src/gopher.cc b/src/gopher.cc index 76d3c8f6f5..7bfe50a615 100644 --- a/src/gopher.cc +++ b/src/gopher.cc @@ -1,6 +1,6 @@ /* - * $Id: gopher.cc,v 1.160 2001/03/03 10:39:32 hno Exp $ + * $Id: gopher.cc,v 1.161 2001/04/14 00:03:22 hno Exp $ * * DEBUG: section 10 Gopher * AUTHOR: Harvest Derived @@ -612,7 +612,7 @@ gopherReadReply(int fd, void *data) #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 diff --git a/src/helper.cc b/src/helper.cc index ccb5528a15..2a858c6871 100644 --- a/src/helper.cc +++ b/src/helper.cc @@ -1,6 +1,6 @@ /* - * $Id: helper.cc,v 1.26 2001/03/03 10:39:32 hno Exp $ + * $Id: helper.cc,v 1.27 2001/04/14 00:03:23 hno Exp $ * * DEBUG: section 29 Helper process maintenance * AUTHOR: Harvest Derived? @@ -659,7 +659,7 @@ helperHandleRead(int fd, void *data) 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); diff --git a/src/http.cc b/src/http.cc index ae0dabaece..a79316d871 100644 --- a/src/http.cc +++ b/src/http.cc @@ -1,6 +1,6 @@ /* - * $Id: http.cc,v 1.378 2001/03/03 10:39:32 hno Exp $ + * $Id: http.cc,v 1.379 2001/04/14 00:03:23 hno Exp $ * * DEBUG: section 11 Hypertext Transfer Protocol (HTTP) * AUTHOR: Harvest Derived @@ -482,7 +482,7 @@ httpReadReply(int fd, void *data) 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); diff --git a/src/ident.cc b/src/ident.cc index ca4e335e82..086f217ea5 100644 --- a/src/ident.cc +++ b/src/ident.cc @@ -1,6 +1,6 @@ /* - * $Id: ident.cc,v 1.57 2001/03/03 10:39:32 hno Exp $ + * $Id: ident.cc,v 1.58 2001/04/14 00:03:23 hno Exp $ * * DEBUG: section 30 Ident (RFC 931) * AUTHOR: Duane Wessels @@ -139,7 +139,7 @@ identReadReply(int fd, void *data) 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); diff --git a/src/main.cc b/src/main.cc index 9f6a1208bb..1e664e3b38 100644 --- a/src/main.cc +++ b/src/main.cc @@ -1,6 +1,6 @@ /* - * $Id: main.cc,v 1.334 2001/03/28 23:24:18 wessels Exp $ + * $Id: main.cc,v 1.335 2001/04/14 00:03:23 hno Exp $ * * DEBUG: section 1 Startup and Main Loop * AUTHOR: Harvest Derived @@ -518,6 +518,10 @@ mainInitialize(void) } #if USE_WCCP wccpInit(); +#endif +#if USE_SSL + if (Config.Sockaddr.https) + sslInit(Config.SSL.certificate, Config.SSL.key); #endif serverConnectionsOpen(); if (theOutIcpConnection >= 0) { diff --git a/src/mime.cc b/src/mime.cc index 26376f2e99..73570f866c 100644 --- a/src/mime.cc +++ b/src/mime.cc @@ -1,6 +1,6 @@ /* - * $Id: mime.cc,v 1.99 2001/01/12 00:37:19 wessels Exp $ + * $Id: mime.cc,v 1.100 2001/04/14 00:03:23 hno Exp $ * * DEBUG: section 25 MIME Parsing * AUTHOR: Harvest Derived @@ -439,7 +439,7 @@ mimeLoadIconFile(const char *icon) 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); diff --git a/src/pconn.cc b/src/pconn.cc index dcb749f310..11a52e6712 100644 --- a/src/pconn.cc +++ b/src/pconn.cc @@ -1,6 +1,6 @@ /* - * $Id: pconn.cc,v 1.30 2001/01/12 00:37:20 wessels Exp $ + * $Id: pconn.cc,v 1.31 2001/04/14 00:03:23 hno Exp $ * * DEBUG: section 48 Persistent Connections * AUTHOR: Duane Wessels @@ -125,7 +125,7 @@ pconnRead(int fd, void *data) 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); diff --git a/src/send-announce.cc b/src/send-announce.cc index 96a635c7d0..7fda259b75 100644 --- a/src/send-announce.cc +++ b/src/send-announce.cc @@ -1,6 +1,6 @@ /* - * $Id: send-announce.cc,v 1.61 2001/01/12 00:37:20 wessels Exp $ + * $Id: send-announce.cc,v 1.62 2001/04/14 00:03:23 hno Exp $ * * DEBUG: section 27 Cache Announcer * AUTHOR: Duane Wessels @@ -86,7 +86,7 @@ send_announce(const ipcache_addrs * ia, void *junk) 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'; diff --git a/src/squid.h b/src/squid.h index d72250d6c5..12edf75517 100644 --- a/src/squid.h +++ b/src/squid.h @@ -1,6 +1,6 @@ /* - * $Id: squid.h,v 1.214 2001/03/11 21:55:20 hno Exp $ + * $Id: squid.h,v 1.215 2001/04/14 00:03:23 hno Exp $ * * AUTHOR: Duane Wessels * @@ -368,6 +368,20 @@ struct rusage { #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 @@ struct rusage { /* * 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 */ diff --git a/src/ssl.cc b/src/ssl.cc index 8c155f0834..8614625f3f 100644 --- a/src/ssl.cc +++ b/src/ssl.cc @@ -1,6 +1,6 @@ /* - * $Id: ssl.cc,v 1.112 2001/03/03 10:39:33 hno Exp $ + * $Id: ssl.cc,v 1.113 2001/04/14 00:03:23 hno Exp $ * * DEBUG: section 26 Secure Sockets Layer Proxy * AUTHOR: Duane Wessels @@ -200,7 +200,7 @@ sslReadServer(int fd, void *data) 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 @@ sslReadClient(int fd, void *data) 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 @@ sslWriteServer(int fd, void *data) 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 @@ sslWriteClient(int fd, void *data) 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); diff --git a/src/structs.h b/src/structs.h index aba260fa49..eac05625e4 100644 --- a/src/structs.h +++ b/src/structs.h @@ -1,6 +1,6 @@ /* - * $Id: structs.h,v 1.385 2001/04/03 20:22:10 adrian Exp $ + * $Id: structs.h,v 1.386 2001/04/14 00:03:23 hno Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -381,6 +381,9 @@ struct _SquidConfig { } Port; struct { sockaddr_in_list *http; +#if USE_SSL + sockaddr_in_list *https; +#endif } Sockaddr; #if SQUID_SNMP struct { @@ -620,6 +623,13 @@ struct _SquidConfig { size_t swapout_chunk_size; int rebuild_chunk_percentage; } digest; +#endif +#if USE_SSL + struct { + char *certificate; + char *key; + int version; + } SSL; #endif wordlist *ext_methods; struct { @@ -734,6 +744,11 @@ struct _fde { 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 { diff --git a/src/tools.cc b/src/tools.cc index 3901a0dfc9..c9303a850e 100644 --- a/src/tools.cc +++ b/src/tools.cc @@ -1,6 +1,6 @@ /* - * $Id: tools.cc,v 1.205 2001/02/15 11:11:54 adrian Exp $ + * $Id: tools.cc,v 1.206 2001/04/14 00:03:24 hno Exp $ * * DEBUG: section 21 Misc Functions * AUTHOR: Harvest Derived @@ -589,7 +589,7 @@ writePidFile(void) return; } snprintf(buf, 32, "%d\n", (int) getpid()); - write(fd, buf, strlen(buf)); + FD_WRITE_METHOD(fd, buf, strlen(buf)); file_close(fd); } diff --git a/src/tunnel.cc b/src/tunnel.cc index 54e54c5411..eb04b78bbc 100644 --- a/src/tunnel.cc +++ b/src/tunnel.cc @@ -1,6 +1,6 @@ /* - * $Id: tunnel.cc,v 1.112 2001/03/03 10:39:33 hno Exp $ + * $Id: tunnel.cc,v 1.113 2001/04/14 00:03:23 hno Exp $ * * DEBUG: section 26 Secure Sockets Layer Proxy * AUTHOR: Duane Wessels @@ -200,7 +200,7 @@ sslReadServer(int fd, void *data) 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 @@ sslReadClient(int fd, void *data) 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 @@ sslWriteServer(int fd, void *data) 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 @@ sslWriteClient(int fd, void *data) 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); diff --git a/src/typedefs.h b/src/typedefs.h index 77d7b1cd07..e22d11d597 100644 --- a/src/typedefs.h +++ b/src/typedefs.h @@ -1,6 +1,6 @@ /* - * $Id: typedefs.h,v 1.124 2001/03/01 03:27:54 hno Exp $ + * $Id: typedefs.h,v 1.125 2001/04/14 00:03:24 hno Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -227,6 +227,8 @@ typedef void PSC(FwdServer *, void *); 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 *); diff --git a/src/url.cc b/src/url.cc index b5fb1a8d7a..d5645d4a17 100644 --- a/src/url.cc +++ b/src/url.cc @@ -1,6 +1,6 @@ /* - * $Id: url.cc,v 1.129 2001/01/12 00:37:23 wessels Exp $ + * $Id: url.cc,v 1.130 2001/04/14 00:03:24 hno Exp $ * * DEBUG: section 23 URL Parsing * AUTHOR: Duane Wessels @@ -550,12 +550,17 @@ urlCheckRequest(const request_t * r) 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; } diff --git a/src/wais.cc b/src/wais.cc index c3b429a825..72b7aa5a16 100644 --- a/src/wais.cc +++ b/src/wais.cc @@ -1,6 +1,6 @@ /* - * $Id: wais.cc,v 1.136 2001/03/03 10:39:34 hno Exp $ + * $Id: wais.cc,v 1.137 2001/04/14 00:03:24 hno Exp $ * * DEBUG: section 24 WAIS Relay * AUTHOR: Harvest Derived @@ -103,7 +103,7 @@ waisReadReply(int fd, void *data) 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 diff --git a/src/whois.cc b/src/whois.cc index 9797c627b9..fdd9588582 100644 --- a/src/whois.cc +++ b/src/whois.cc @@ -1,6 +1,6 @@ /* - * $Id: whois.cc,v 1.15 2001/03/03 10:39:34 hno Exp $ + * $Id: whois.cc,v 1.16 2001/04/14 00:03:24 hno Exp $ * * DEBUG: section 75 WHOIS protocol * AUTHOR: Duane Wessels, Kostas Anagnostakis @@ -92,7 +92,7 @@ whoisReadReply(int fd, void *data) 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);