]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: config: add the 'ssl' keyword on 'bind' lines
authorEmeric Brun <ebrun@exceliance.fr>
Fri, 18 May 2012 14:32:13 +0000 (16:32 +0200)
committerWilly Tarreau <w@1wt.eu>
Mon, 3 Sep 2012 18:49:14 +0000 (20:49 +0200)
"bind" now supports "ssl" followed by a PEM cert+key file name.

include/types/protocols.h
src/cfgparse.c
src/haproxy.c

index c6073b4d21d14cc6b6fc416e2f77416dfc024ebe..5c1356901b3347c9efe9ab1a9a6ac83a3fd9903f 100644 (file)
@@ -131,6 +131,7 @@ struct listener {
        int maxseg;                     /* for TCP, advertised MSS */
 
 #ifdef USE_OPENSSL
+       char *ssl_cert;                 /* ssl certificate */
        struct {
                SSL_CTX *ctx;
        } ssl_ctx;
index 28a9751e91c2876ed8c1803c1af9042bfaeaab32..d8b7e6dbe382f2d2bae393220fab391b4a1586af 100644 (file)
@@ -63,6 +63,9 @@
 #include <proto/server.h>
 #include <proto/session.h>
 #include <proto/raw_sock.h>
+#ifdef USE_OPENSSL
+#include <proto/ssl_sock.h>
+#endif /*USE_OPENSSL */
 #include <proto/task.h>
 #include <proto/stick_table.h>
 
@@ -1793,6 +1796,30 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
 #endif
                        }
 
+                       if (!strcmp(args[cur_arg], "ssl")) { /* use ssl certificate */
+#ifdef USE_OPENSSL
+                               struct listener *l;
+
+                               if (!*args[cur_arg + 1]) {
+                                       Alert("parsing [%s:%d] : '%s' : missing certificate.\n",
+                                             file, linenum, args[0]);
+                                       err_code |= ERR_ALERT | ERR_FATAL;
+                                       goto out;
+                               }
+
+                               for (l = curproxy->listen; l != last_listen; l = l->next)
+                                       l->ssl_cert = strdup(args[cur_arg + 1]);
+
+                               cur_arg += 2;
+                               continue;
+#else
+                               Alert("parsing [%s:%d] : '%s' : '%s' option not implemented.\n",
+                                     file, linenum, args[0], args[cur_arg]);
+                               err_code |= ERR_ALERT | ERR_FATAL;
+                               goto out;
+#endif
+                       }
+
                        if (!strcmp(args[cur_arg], "accept-proxy")) { /* expect a 'PROXY' line first */
                                struct listener *l;
 
@@ -6590,6 +6617,57 @@ out_uri_auth_compat:
                                }
                        }
 
+#ifdef USE_OPENSSL
+#ifndef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION  /* needs OpenSSL >= 0.9.7 */
+#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0
+#endif
+#ifndef SSL_OP_NO_COMPRESSION                           /* needs OpenSSL >= 0.9.9 */
+#define SSL_OP_NO_COMPRESSION 0
+#endif
+#ifndef SSL_MODE_RELEASE_BUFFERS                        /* needs OpenSSL >= 1.0.0 */
+#define SSL_MODE_RELEASE_BUFFERS 0
+#endif
+                       /* Initialize SSL */
+                       if (listener->ssl_cert) {
+                               int ssloptions =
+                                       SSL_OP_ALL | /* all known workarounds for bugs */
+                                       SSL_OP_NO_SSLv2 |
+                                       SSL_OP_NO_COMPRESSION |
+                                       SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION;
+                               int sslmode =
+                                       SSL_MODE_ENABLE_PARTIAL_WRITE |
+                                       SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
+                                       SSL_MODE_RELEASE_BUFFERS;
+
+                               listener->data = &ssl_sock; /* data layer */
+                               listener->ssl_ctx.ctx = SSL_CTX_new(SSLv23_server_method());
+                               if (!listener->ssl_ctx.ctx) {
+                                       Alert("Proxy '%s': unable to allocate SSL context to bind listener %d (%s:%d) using cert '%s'.\n",
+                                             curproxy->id, listener->luid, listener->conf.file, listener->conf.line, listener->ssl_cert);
+                                       cfgerr++;
+                                       goto skip_ssl;
+                               }
+                               SSL_CTX_set_options(listener->ssl_ctx.ctx, ssloptions);
+                               SSL_CTX_set_mode(listener->ssl_ctx.ctx, sslmode);
+                               SSL_CTX_set_verify(listener->ssl_ctx.ctx, SSL_VERIFY_NONE, NULL);
+                               SSL_CTX_set_session_cache_mode(listener->ssl_ctx.ctx, SSL_SESS_CACHE_SERVER);
+
+                               if (SSL_CTX_use_PrivateKey_file(listener->ssl_ctx.ctx, listener->ssl_cert, SSL_FILETYPE_PEM) <= 0) {
+                                       Alert("Proxy '%s': unable to load SSL private key from file '%s' in listener %d (%s:%d).\n",
+                                             curproxy->id, listener->ssl_cert, listener->luid, listener->conf.file, listener->conf.line);
+                                       cfgerr++;
+                                       goto skip_ssl;
+                               }
+
+                               if (SSL_CTX_use_certificate_chain_file(listener->ssl_ctx.ctx, listener->ssl_cert) <= 0) {
+                                       Alert("Proxy '%s': unable to load SSL certificate from file '%s' in listener %d (%s:%d).\n",
+                                             curproxy->id, listener->ssl_cert, listener->luid, listener->conf.file, listener->conf.line);
+                                       cfgerr++;
+                                       goto skip_ssl;
+                               }
+                       }
+               skip_ssl:
+#endif /* USE_OPENSSL */
                        if (curproxy->options & PR_O_TCP_NOLING)
                                listener->options |= LI_O_NOLINGER;
                        listener->maxconn = curproxy->maxconn;
index 5d537df4559a267f85608f27f89ef6bd4ebe0999..764e30f4078c429e290544806229d2d03af1b4cc 100644 (file)
@@ -993,6 +993,9 @@ void deinit(void)
                        l_next = l->next;
                        unbind_listener(l);
                        delete_listener(l);
+#ifdef USE_OPENSSL
+                       free(l->ssl_cert);
+#endif
                        free(l->name);
                        free(l->counters);
                        free(l);