]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Support multiple SSL certificates. See http://squid.sourceforge.net/ssl/
authorhno <>
Fri, 4 May 2001 19:37:41 +0000 (19:37 +0000)
committerhno <>
Fri, 4 May 2001 19:37:41 +0000 (19:37 +0000)
for details.

Sourceforge tag: ssl-20010504

13 files changed:
src/cache_cf.cc
src/cf.data.pre
src/client_side.cc
src/comm_select.cc
src/dns_internal.cc
src/globals.h
src/icp_v2.cc
src/main.cc
src/protos.h
src/ssl_support.cc
src/ssl_support.h
src/structs.h
src/typedefs.h

index c36d0d6eb7f77b18ada3509e2c2616a25097781f..563d67a688d0cb9947f304b4bbc1a6a78692e0e0 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: cache_cf.cc,v 1.379 2001/04/20 12:40:25 hno Exp $
+ * $Id: cache_cf.cc,v 1.380 2001/05/04 13:37:41 hno Exp $
  *
  * DEBUG: section 3     Configuration File Parsing
  * AUTHOR: Harvest Derived
@@ -85,6 +85,14 @@ static void parse_sockaddr_in_list(sockaddr_in_list **);
 static void dump_sockaddr_in_list(StoreEntry *, const char *, const sockaddr_in_list *);
 static void free_sockaddr_in_list(sockaddr_in_list **);
 static int check_null_sockaddr_in_list(const sockaddr_in_list *);
+#if USE_SSL
+static void parse_https_port_list(https_port_list **);
+static void dump_https_port_list(StoreEntry *, const char *, const https_port_list *);
+static void free_https_port_list(https_port_list **);
+#if 0
+static int check_null_https_port_list(const https_port_list *);
+#endif
+#endif /* USE_SSL */
 
 void
 self_destruct(void)
@@ -2052,6 +2060,96 @@ check_null_sockaddr_in_list(const sockaddr_in_list * s)
     return NULL == s;
 }
 
+#if USE_SSL
+static void
+parse_https_port_list(https_port_list ** head)
+{
+    char *token;
+    char *t;
+    char *host;
+    const struct hostent *hp;
+    unsigned short port;
+    https_port_list *s;
+    token = strtok(NULL, w_space);
+    if (!token)
+       self_destruct();
+    host = NULL;
+    port = 0;
+    if ((t = strchr(token, ':'))) {
+       /* host:port */
+       host = token;
+       *t = '\0';
+       port = (unsigned short) atoi(t + 1);
+       if (0 == port)
+           self_destruct();
+    } else if ((port = atoi(token)) > 0) {
+       /* port */
+    } else {
+       self_destruct();
+    }
+    s = xcalloc(1, sizeof(*s));
+    s->s.sin_port = htons(port);
+    if (NULL == host)
+       s->s.sin_addr = any_addr;
+    else if (1 == safe_inet_addr(host, &s->s.sin_addr))
+       (void) 0;
+    else if ((hp = gethostbyname(host)))       /* dont use ipcache */
+       s->s.sin_addr = inaddrFromHostent(hp);
+    else
+       self_destruct();
+    /* parse options ... */
+    while ((token = strtok(NULL, w_space))) {
+       if (strncmp(token, "cert=", 5) == 0) {
+           safe_free(s->cert);
+           s->cert = xstrdup(token + 5);
+       } else if (strncmp(token, "key=", 4) == 0) {
+           safe_free(s->key);
+           s->key = xstrdup(token + 4);
+       } else {
+           self_destruct();
+       }
+    }
+    while (*head)
+       head = &(*head)->next;
+    *head = s;
+}
+
+static void
+dump_https_port_list(StoreEntry * e, const char *n, const https_port_list * s)
+{
+    while (s) {
+       storeAppendPrintf(e, "%s %s:%d cert=\"%s\" key=\"%s\"\n",
+           n,
+           inet_ntoa(s->s.sin_addr),
+           ntohs(s->s.sin_port),
+           s->cert,
+           s->key);
+       s = s->next;
+    }
+}
+
+static void
+free_https_port_list(https_port_list ** head)
+{
+    https_port_list *s;
+    while ((s = *head) != NULL) {
+       *head = s->next;
+       safe_free(s->cert);
+       safe_free(s->key);
+       safe_free(s);
+    }
+}
+
+#if 0
+static int
+check_null_https_port_list(const https_port_list * s)
+{
+    return NULL == s;
+}
+#endif
+
+#endif /* USE_SSL */
+
 void
 configFreeMemory(void)
 {
index 2f3c202ce4bd663c452233616f94e5ff95e69012..ddc679d40f0db5b250408ef8c63c413b13f27725 100644 (file)
@@ -1,6 +1,6 @@
 
 #
-# $Id: cf.data.pre,v 1.218 2001/04/14 00:25:17 hno Exp $
+# $Id: cf.data.pre,v 1.219 2001/05/04 13:37:41 hno Exp $
 #
 #
 # SQUID Web Proxy Cache          http://www.squid-cache.org/
@@ -86,40 +86,24 @@ DOC_END
 
 NAME: https_port
 IFDEF: USE_SSL
-TYPE: sockaddr_in_list
+TYPE: https_port_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.
+        Usage:  [ip:]port cert=certificate.pem [key=key.pem]
 
+        The socket address where Squid will listen for HTTPS client
+        requests.
+       
         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
+       If key is not specified then the given certificate is assumed to be a
+       combined certificate and key file.
 
-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.
+       You may specify multiple socket addresses on multiple lines,
+       each with their own SSL certificate.
 DOC_END
 
 NAME: ssl_version
index 7a3cf8df9e8c1b0614a2ac2058a45d54b0be6575..2454e06e74458082e577aaf741b4259fe6317854 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: client_side.cc,v 1.536 2001/04/17 22:43:10 hno Exp $
+ * $Id: client_side.cc,v 1.537 2001/05/04 13:37:41 hno Exp $
  *
  * DEBUG: section 33    Client-side Routines
  * AUTHOR: Duane Wessels
@@ -3155,7 +3155,7 @@ httpAcceptDefer(int fdunused, void *dataunused)
 void
 httpAccept(int sock, void *data)
 {
-    int *N = data;
+    int *N = &incoming_sockets_accepted;
     int fd = -1;
     ConnStateData *connState = NULL;
     struct sockaddr_in peer;
@@ -3243,11 +3243,19 @@ clientNegotiateSSL(int fd, void *data)
     commSetSelect(fd, COMM_SELECT_READ, clientReadRequest, conn, 0);
 }
 
+struct _https_port_data {
+    SSL_CTX *sslContext;
+};
+typedef struct _https_port_data https_port_data;
+CBDATA_TYPE(https_port_data);
+
 /* handle a new HTTPS connection */
 static void
 httpsAccept(int sock, void *data)
 {
-    int *N = data;
+    int *N = &incoming_sockets_accepted;
+    https_port_data *https_port = data;
+    SSL_CTX *sslContext = https_port->sslContext;
     int fd = -1;
     ConnStateData *connState = NULL;
     struct sockaddr_in peer;
@@ -3258,7 +3266,7 @@ httpsAccept(int sock, void *data)
 #if USE_IDENT
     static aclCheck_t identChecklist;
 #endif
-    commSetSelect(sock, COMM_SELECT_READ, httpsAccept, NULL, 0);
+    commSetSelect(sock, COMM_SELECT_READ, httpsAccept, https_port, 0);
     while (max-- && !httpAcceptDefer(sock, NULL)) {
        memset(&peer, '\0', sizeof(struct sockaddr_in));
        memset(&me, '\0', sizeof(struct sockaddr_in));
@@ -3433,7 +3441,7 @@ checkFailureRatio(err_type etype, hier_code hcode)
     request_failure_ratio = 0.8;       /* reset to something less than 1.0 */
 }
 
-void
+static void
 clientHttpConnectionsOpen(void)
 {
     sockaddr_in_list *s;
@@ -3467,7 +3475,15 @@ clientHttpConnectionsOpen(void)
            fd);
        HttpSockets[NHttpSockets++] = fd;
     }
-#ifdef USE_SSL
+}
+
+#if USE_SSL
+static void
+clientHttpsConnectionsOpen(void)
+{
+    https_port_list *s;
+    https_port_data *https_port;
+    int fd;
     for (s = Config.Sockaddr.https; s; s = s->next) {
        enter_suid();
        fd = comm_open(SOCK_STREAM,
@@ -3479,20 +3495,32 @@ clientHttpConnectionsOpen(void)
        leave_suid();
        if (fd < 0)
            continue;
+       CBDATA_INIT_TYPE(https_port_data);
+       https_port = cbdataAlloc(https_port_data);
+       https_port->sslContext = sslLoadCert(s->cert, s->key);
        comm_listen(fd);
-       commSetSelect(fd, COMM_SELECT_READ, httpsAccept, NULL, 0);
-       /*commSetDefer(fd, httpAcceptDefer, NULL); */
+       commSetSelect(fd, COMM_SELECT_READ, httpsAccept, https_port, 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
+
+void
+clientOpenListenSockets(void)
+{
+    clientHttpConnectionsOpen();
+#if USE_SSL
+    clientHttpsConnectionsOpen();
 #endif
     if (NHttpSockets < 1)
        fatal("Cannot open HTTP Port");
 }
-
 void
 clientHttpConnectionsClose(void)
 {
index fcb426840dbe4392b25db038754c82381a1d6366..50cd18e41550858f9254dad07276312597a758bc 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: comm_select.cc,v 1.49 2001/02/23 20:59:50 hno Exp $
+ * $Id: comm_select.cc,v 1.50 2001/05/04 13:37:42 hno Exp $
  *
  * DEBUG: section 5     Socket Functions
  *
@@ -201,10 +201,10 @@ comm_check_incoming_poll_handlers(int nfds, int *fds)
 {
     int i;
     int fd;
-    int incame = 0;
     PF *hdl = NULL;
     int npfds;
     struct pollfd pfds[3 + MAXHTTPPORTS];
+    incoming_sockets_accepted = 0;
     for (i = npfds = 0; i < nfds; i++) {
        int events;
        fd = fds[i];
@@ -227,7 +227,7 @@ comm_check_incoming_poll_handlers(int nfds, int *fds)
 #endif
     statCounter.syscalls.polls++;
     if (poll(pfds, npfds, 0) < 1)
-       return incame;
+       return incoming_sockets_accepted;
     for (i = 0; i < npfds; i++) {
        int revents;
        if (((revents = pfds[i].revents) == 0) || ((fd = pfds[i].fd) == -1))
@@ -235,7 +235,7 @@ comm_check_incoming_poll_handlers(int nfds, int *fds)
        if (revents & (POLLRDNORM | POLLIN | POLLHUP | POLLERR)) {
            if ((hdl = fd_table[fd].read_handler)) {
                fd_table[fd].read_handler = NULL;
-               hdl(fd, &incame);
+               hdl(fd, fd_table[fd].read_data);
            } else if (pfds[i].events & POLLRDNORM)
                debug(5, 1) ("comm_poll_incoming: FD %d NULL read handler\n",
                    fd);
@@ -243,13 +243,13 @@ comm_check_incoming_poll_handlers(int nfds, int *fds)
        if (revents & (POLLWRNORM | POLLOUT | POLLHUP | POLLERR)) {
            if ((hdl = fd_table[fd].write_handler)) {
                fd_table[fd].write_handler = NULL;
-               hdl(fd, &incame);
+               hdl(fd, fd_table[fd].write_data);
            } else if (pfds[i].events & POLLWRNORM)
                debug(5, 1) ("comm_poll_incoming: FD %d NULL write_handler\n",
                    fd);
        }
     }
-    return incame;
+    return incoming_sockets_accepted;
 }
 
 static void
@@ -521,13 +521,13 @@ comm_check_incoming_select_handlers(int nfds, int *fds)
 {
     int i;
     int fd;
-    int incame = 0;
     int maxfd = 0;
     PF *hdl = NULL;
     fd_set read_mask;
     fd_set write_mask;
     FD_ZERO(&read_mask);
     FD_ZERO(&write_mask);
+    incoming_sockets_accepted = 0;
     for (i = 0; i < nfds; i++) {
        fd = fds[i];
        if (fd_table[fd].read_handler) {
@@ -548,14 +548,14 @@ comm_check_incoming_select_handlers(int nfds, int *fds)
 #endif
     statCounter.syscalls.selects++;
     if (select(maxfd, &read_mask, &write_mask, NULL, &zero_tv) < 1)
-       return incame;
+       return incoming_sockets_accepted;
     for (i = 0; i < nfds; i++) {
        fd = fds[i];
        if (FD_ISSET(fd, &read_mask)) {
            if ((hdl = fd_table[fd].read_handler) != NULL) {
                fd_table[fd].read_handler = NULL;
                commUpdateReadBits(fd, NULL);
-               hdl(fd, &incame);
+               hdl(fd, fd_table[fd].read_data);
            } else {
                debug(5, 1) ("comm_select_incoming: FD %d NULL read handler\n",
                    fd);
@@ -565,14 +565,14 @@ comm_check_incoming_select_handlers(int nfds, int *fds)
            if ((hdl = fd_table[fd].write_handler) != NULL) {
                fd_table[fd].write_handler = NULL;
                commUpdateWriteBits(fd, NULL);
-               hdl(fd, &incame);
+               hdl(fd, fd_table[fd].write_data);
            } else {
                debug(5, 1) ("comm_select_incoming: FD %d NULL write handler\n",
                    fd);
            }
        }
     }
-    return incame;
+    return incoming_sockets_accepted;
 }
 
 static void
index 83d88aeea35575296ad5fbe580c10cc643f77076..e9f7a7505219d274fbc1cd0c68041a089ca13b0b 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: dns_internal.cc,v 1.37 2001/02/14 20:58:10 hno Exp $
+ * $Id: dns_internal.cc,v 1.38 2001/05/04 13:37:42 hno Exp $
  *
  * DEBUG: section 78    DNS lookups; interacts with lib/rfc1035.c
  * AUTHOR: Duane Wessels
@@ -338,7 +338,7 @@ idnsGrokReply(const char *buf, size_t sz)
 static void
 idnsRead(int fd, void *data)
 {
-    int *N = data;
+    int *N = &incoming_sockets_accepted;
     ssize_t len;
     struct sockaddr_in from;
     socklen_t from_len;
index f722460d9809d1a129e2a782e66b09374b8acd79..1d87899130ce46655d1d0c755bdf317b2350707f 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: globals.h,v 1.102 2001/04/20 12:40:26 hno Exp $
+ * $Id: globals.h,v 1.103 2001/05/04 13:37:42 hno Exp $
  *
  *
  * SQUID Web Proxy Cache          http://www.squid-cache.org/
@@ -153,3 +153,4 @@ extern int store_pages_max; /* 0 */
 extern ssize_t store_maxobjsize;       /* -1 */
 extern RemovalPolicy *mem_policy;
 extern hash_table *proxy_auth_username_cache;  /* NULL */
+extern int incoming_sockets_accepted;
index cdb55b1d16e0d87fd89b76c769284432d5f4cf1c..0b633945ec8844d8a89ed815aacf238436c69fe1 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: icp_v2.cc,v 1.65 2001/01/12 00:37:18 wessels Exp $
+ * $Id: icp_v2.cc,v 1.66 2001/05/04 13:37:42 hno Exp $
  *
  * DEBUG: section 12    Internet Cache Protocol
  * AUTHOR: Duane Wessels
@@ -337,7 +337,7 @@ icpPktDump(icp_common_t * pkt)
 void
 icpHandleUdp(int sock, void *data)
 {
-    int *N = data;
+    int *N = &incoming_sockets_accepted;
     struct sockaddr_in from;
     socklen_t from_len;
     LOCAL_ARRAY(char, buf, SQUID_UDP_SO_RCVBUF);
index 1e664e3b383f5469242664ca36d9b1fe38aa951d..4f45d4d4cb858bf030f703a9213b7052d6f4df05 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: main.cc,v 1.335 2001/04/14 00:03:23 hno Exp $
+ * $Id: main.cc,v 1.336 2001/05/04 13:37:42 hno Exp $
  *
  * DEBUG: section 1     Startup and Main Loop
  * AUTHOR: Harvest Derived
@@ -280,7 +280,7 @@ shut_down(int sig)
 static void
 serverConnectionsOpen(void)
 {
-    clientHttpConnectionsOpen();
+    clientOpenListenSockets();
     icpConnectionsOpen();
 #if USE_HTCP
     htcpInit();
@@ -518,10 +518,6 @@ 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) {
index 7920a5ea502df81b3f8d30331a1377a779550a1e..72dfee7f1ffa915a626460541aebc0f0d383d96c 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: protos.h,v 1.402 2001/04/14 00:25:18 hno Exp $
+ * $Id: protos.h,v 1.403 2001/05/04 13:37:42 hno Exp $
  *
  *
  * SQUID Web Proxy Cache          http://www.squid-cache.org/
@@ -129,7 +129,7 @@ extern int modifiedSince(StoreEntry *, request_t *);
 extern char *clientConstructTraceEcho(clientHttpRequest *);
 extern void clientPurgeRequest(clientHttpRequest *);
 extern int checkNegativeHit(StoreEntry *);
-extern void clientHttpConnectionsOpen(void);
+extern void clientOpenListenSockets(void);
 extern void clientHttpConnectionsClose(void);
 extern StoreEntry *clientCreateStoreEntry(clientHttpRequest *, method_t, request_flags);
 extern int isTcpHit(log_type);
index 0920ad6d55b79777c2146f46029c26f2e005c58e..7fc70cce4fa08b4e3e89a9915bdd425d463c2b72 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: ssl_support.cc,v 1.1 2001/04/14 18:23:41 hno Exp $
+ * $Id: ssl_support.cc,v 1.2 2001/05/04 13:37:42 hno Exp $
  *
  * AUTHOR: Benno Rice
  * DEBUG: section 81     SSL accelerator support
@@ -42,8 +42,6 @@ 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)
@@ -90,14 +88,18 @@ ssl_verify_cb(int ok, X509_STORE_CTX * ctx)
     return ok;
 }
 
-void 
-sslInit(const char *certfile, const char *keyfile)
+SSL_CTX *
+sslLoadCert(const char *certfile, const char *keyfile)
 {
     int ssl_error;
     SSL_METHOD *method;
-    SSL_load_error_strings();
-    SSLeay_add_ssl_algorithms();
-
+    SSL_CTX *sslContext;
+    static int ssl_initialized = 0;
+    if (!ssl_initialized) {
+       ssl_initialized = 1;
+       SSL_load_error_strings();
+       SSLeay_add_ssl_algorithms();
+    }
     if (!keyfile)
        keyfile = certfile;
     if (!certfile)
@@ -163,11 +165,10 @@ sslInit(const char *certfile, const char *keyfile)
     }
     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 *));
+    return sslContext;
 }
 
-int 
+int
 ssl_read_method(fd, buf, len)
      int fd;
      char *buf;
@@ -176,7 +177,7 @@ ssl_read_method(fd, buf, len)
     return (SSL_read(fd_table[fd].ssl, buf, len));
 }
 
-int 
+int
 ssl_write_method(fd, buf, len)
      int fd;
      const char *buf;
index dbebf373fa2e027da6ee893aa79be4be6e87c0e7..a6949d12c4f55bd548eef1902f53c58987c0435d 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: ssl_support.h,v 1.1 2001/04/14 18:23:41 hno Exp $
+ * $Id: ssl_support.h,v 1.2 2001/05/04 13:37:42 hno Exp $
  *
  * AUTHOR: Benno Rice
  *
@@ -43,9 +43,7 @@
 #include <openssl/err.h>
 #endif
 
-extern SSL_CTX *sslContext;
-
-void sslInit(const char *certfile, const char *keyfile);
+SSL_CTX *sslLoadCert(const char *certfile, const char *keyfile);
 int ssl_read_method(int, char *, int);
 int ssl_write_method(int, const char *, int);
 
index de870ad3fbf3c3792d018deab37fda58a575ff10..e7e073bb91b9e12853e6e7046795ccbd0c712190 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: structs.h,v 1.388 2001/04/20 12:40:26 hno Exp $
+ * $Id: structs.h,v 1.389 2001/05/04 13:37:42 hno Exp $
  *
  *
  * SQUID Web Proxy Cache          http://www.squid-cache.org/
@@ -292,6 +292,15 @@ struct _sockaddr_in_list {
     sockaddr_in_list *next;
 };
 
+#if USE_SSL
+struct _https_port_list {
+    https_port_list *next;
+    struct sockaddr_in s;
+    char *cert;
+    char *key;
+};
+
+#endif
 
 #if DELAY_POOLS
 struct _delaySpec {
@@ -382,7 +391,7 @@ struct _SquidConfig {
     struct {
        sockaddr_in_list *http;
 #if USE_SSL
-       sockaddr_in_list *https;
+       https_port_list *https;
 #endif
     } Sockaddr;
 #if SQUID_SNMP
index 45841a1fe73b70dde887112d876693a0c4602c36..f91598b52fdef2d4a7411f9a87ef1403ab288f6d 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: typedefs.h,v 1.126 2001/04/20 12:40:26 hno Exp $
+ * $Id: typedefs.h,v 1.127 2001/05/04 13:37:42 hno Exp $
  *
  *
  * SQUID Web Proxy Cache          http://www.squid-cache.org/
@@ -80,6 +80,7 @@ typedef struct _intrange intrange;
 typedef struct _ushortlist ushortlist;
 typedef struct _relist relist;
 typedef struct _sockaddr_in_list sockaddr_in_list;
+typedef struct _https_port_list https_port_list;
 typedef struct _SquidConfig SquidConfig;
 typedef struct _SquidConfig2 SquidConfig2;
 typedef struct _close_handler close_handler;