I realized I never commited the ticket support in httpd that I added in
Brisbane. Anyone want to give me an OK on it?

Cheers
-- 
:wq Claudio

Index: config.c
===================================================================
RCS file: /cvs/src/usr.sbin/httpd/config.c,v
retrieving revision 1.50
diff -u -p -r1.50 config.c
--- config.c    6 Nov 2016 10:49:38 -0000       1.50
+++ config.c    24 Jan 2017 11:21:35 -0000
@@ -146,6 +146,7 @@ config_getcfg(struct httpd *env, struct 
        memcpy(&cf, imsg->data, sizeof(cf));
        env->sc_opts = cf.cf_opts;
        env->sc_flags = cf.cf_flags;
+       memcpy(env->sc_tls_sid, cf.cf_tls_sid, sizeof(env->sc_tls_sid));
 
        what = ps->ps_what[privsep_process];
 
@@ -238,6 +239,9 @@ config_setserver(struct httpd *env, stru
                close(srv->srv_s);
                srv->srv_s = -1;
        }
+
+       explicit_bzero(&srv->srv_conf.tls_ticket_key,
+           sizeof(srv->srv_conf.tls_ticket_key));
 
        return (0);
 }
Index: httpd.c
===================================================================
RCS file: /cvs/src/usr.sbin/httpd/httpd.c,v
retrieving revision 1.64
diff -u -p -r1.64 httpd.c
--- httpd.c     23 Jan 2017 04:25:05 -0000      1.64
+++ httpd.c     25 Jan 2017 04:22:34 -0000
@@ -57,6 +57,8 @@ int            parent_dispatch_server(int, struct
                    struct imsg *);
 int             parent_dispatch_logger(int, struct privsep_proc *,
                    struct imsg *);
+void            parent_tls_ticket_rekey_start(struct server *);
+void            parent_tls_ticket_rekey(int, short, void *);
 
 struct httpd                   *httpd_env;
 
@@ -252,6 +254,9 @@ main(int argc, char *argv[])
                exit(0);
        }
 
+       /* initialize the TLS session id to a random key for all procs */
+       arc4random_buf(env->sc_tls_sid, sizeof(env->sc_tls_sid));
+
        if (parent_configure(env) == -1)
                fatalx("configuration failed");
 
@@ -287,6 +292,10 @@ parent_configure(struct httpd *env)
        TAILQ_FOREACH(srv, env->sc_servers, srv_entry) {
                if (srv->srv_conf.flags & SRVFLAG_LOCATION)
                        continue;
+               /* start the rekey of the tls ticket keys */
+               if (srv->srv_conf.flags & SRVFLAG_TLS &&
+                   srv->srv_conf.tls_ticket_lifetime)
+                       parent_tls_ticket_rekey_start(srv);
                if (config_setserver(env, srv) == -1)
                        fatal("send server");
        }
@@ -306,6 +315,7 @@ parent_configure(struct httpd *env)
                        continue;
                cf.cf_opts = env->sc_opts;
                cf.cf_flags = env->sc_flags;
+               memcpy(cf.cf_tls_sid, env->sc_tls_sid, sizeof(cf.cf_tls_sid));
 
                proc_compose(env->sc_ps, id, IMSG_CFG_DONE, &cf, sizeof(cf));
        }
@@ -449,6 +459,38 @@ parent_dispatch_logger(int fd, struct pr
        }
 
        return (0);
+}
+
+void
+parent_tls_ticket_rekey_start(struct server *srv)
+{
+       struct timeval           tv;
+
+       server_generate_ticket_key(&srv->srv_conf);
+
+       evtimer_set(&srv->srv_evt, parent_tls_ticket_rekey, srv);
+       timerclear(&tv);
+       tv.tv_sec = srv->srv_conf.tls_ticket_lifetime / 4;
+       evtimer_add(&srv->srv_evt, &tv);
+}
+
+void
+parent_tls_ticket_rekey(int fd, short events, void *arg)
+{
+       struct server           *srv = arg;
+       struct timeval           tv;
+
+       server_generate_ticket_key(&srv->srv_conf);
+       proc_compose_imsg(httpd_env->sc_ps, PROC_SERVER, -1,
+           IMSG_TLSTICKET_REKEY, -1, -1, &srv->srv_conf.tls_ticket_key,
+           sizeof(srv->srv_conf.tls_ticket_key));
+       explicit_bzero(&srv->srv_conf.tls_ticket_key,
+           sizeof(srv->srv_conf.tls_ticket_key));
+
+       evtimer_set(&srv->srv_evt, parent_tls_ticket_rekey, srv);
+       timerclear(&tv);
+       tv.tv_sec = srv->srv_conf.tls_ticket_lifetime / 4;
+       evtimer_add(&srv->srv_evt, &tv);
 }
 
 /*
Index: httpd.conf.5
===================================================================
RCS file: /cvs/src/usr.sbin/httpd/httpd.conf.5,v
retrieving revision 1.80
diff -u -p -r1.80 httpd.conf.5
--- httpd.conf.5        16 Mar 2017 10:18:11 -0000      1.80
+++ httpd.conf.5        24 Mar 2017 07:26:44 -0000
@@ -564,6 +564,13 @@ will be used (secure protocols; TLSv1.2-
 Refer to the
 .Xr tls_config_parse_protocols 3
 function for other valid protocol string values.
+.It Ic ticket Ic lifetime Ar seconds
+Enable TLS session tickets with a
+.Ar seconds
+session lifetime.
+It is possible to set
+.Ar seconds
+to default to use the httpd default timeout of 2 hours.
 .El
 .El
 .Sh TYPES
Index: httpd.h
===================================================================
RCS file: /cvs/src/usr.sbin/httpd/httpd.h,v
retrieving revision 1.130
diff -u -p -r1.130 httpd.h
--- httpd.h     7 Feb 2017 12:27:42 -0000       1.130
+++ httpd.h     16 Feb 2017 19:23:08 -0000
@@ -76,6 +76,9 @@
 #define SERVER_MIN_PREFETCHED  32
 #define SERVER_HSTS_DEFAULT_AGE        31536000
 #define SERVER_MAX_RANGES      4
+#define SERVER_DEF_TLS_LIFETIME        (2 * 3600)
+#define SERVER_MIN_TLS_LIFETIME        (60)
+#define SERVER_MAX_TLS_LIFETIME        (24 * 3600)
 
 #define MEDIATYPE_NAMEMAX      128     /* file name extension */
 #define MEDIATYPE_TYPEMAX      64      /* length of type/subtype */
@@ -109,6 +112,7 @@ enum httpchunk {
 struct ctl_flags {
        uint8_t          cf_opts;
        uint32_t         cf_flags;
+       uint8_t          cf_tls_sid[TLS_MAX_SESSION_ID_LENGTH];
 };
 
 enum key_type {
@@ -219,7 +223,8 @@ enum imsg_type {
        IMSG_CFG_DONE,
        IMSG_LOG_ACCESS,
        IMSG_LOG_ERROR,
-       IMSG_LOG_OPEN
+       IMSG_LOG_OPEN,
+       IMSG_TLSTICKET_REKEY
 };
 
 enum privsep_procid {
@@ -444,6 +449,12 @@ struct auth {
 };
 TAILQ_HEAD(serverauth, auth);
 
+struct server_tls_ticket {
+       uint32_t        tt_id;
+       uint32_t        tt_keyrev;
+       unsigned char   tt_key[TLS_TICKET_KEY_SIZE];
+};
+
 struct server_config {
        uint32_t                 id;
        uint32_t                 parent_id;
@@ -477,6 +488,8 @@ struct server_config {
        uint8_t                 *tls_ocsp_staple;
        size_t                   tls_ocsp_staple_len;
        char                    *tls_ocsp_staple_file;
+       struct server_tls_ticket tls_ticket_key;
+       int                      tls_ticket_lifetime;
 
        uint32_t                 flags;
        int                      strip;
@@ -540,6 +553,8 @@ struct httpd {
        char                    *sc_chroot;
        char                    *sc_logdir;
 
+       uint8_t                  sc_tls_sid[TLS_MAX_SESSION_ID_LENGTH];
+
        struct serverlist       *sc_servers;
        struct mediatypes       *sc_mediatypes;
        struct media_type        sc_default_type;
@@ -573,6 +588,7 @@ void         server(struct privsep *, struct pr
 int     server_tls_cmp(struct server *, struct server *, int);
 int     server_tls_load_keypair(struct server *);
 int     server_tls_load_ocsp(struct server *);
+void    server_generate_ticket_key(struct server_config *);
 int     server_privinit(struct server *);
 void    server_purge(struct server *);
 void    serverconfig_free(struct server_config *);
Index: parse.y
===================================================================
RCS file: /cvs/src/usr.sbin/httpd/parse.y,v
retrieving revision 1.89
diff -u -p -r1.89 parse.y
--- parse.y     7 Feb 2017 12:27:42 -0000       1.89
+++ parse.y     16 Feb 2017 19:20:23 -0000
@@ -130,10 +130,10 @@ typedef struct {
 %}
 
 %token ACCESS ALIAS AUTO BACKLOG BODY BUFFER CERTIFICATE CHROOT CIPHERS COMMON
-%token COMBINED CONNECTION DHE DIRECTORY ECDHE ERR FCGI INDEX IP KEY LISTEN
-%token LOCATION LOG LOGDIR MATCH MAXIMUM NO NODELAY OCSP ON PORT PREFORK
-%token PROTOCOLS REQUESTS ROOT SACK SERVER SOCKET STRIP STYLE SYSLOG TCP 
TIMEOUT
-%token TLS TYPE TYPES HSTS MAXAGE SUBDOMAINS DEFAULT PRELOAD REQUEST
+%token COMBINED CONNECTION DHE DIRECTORY ECDHE ERR FCGI INDEX IP KEY LIFETIME
+%token LISTEN LOCATION LOG LOGDIR MATCH MAXIMUM NO NODELAY OCSP ON PORT PREFORK
+%token PROTOCOLS REQUESTS ROOT SACK SERVER SOCKET STRIP STYLE SYSLOG TCP TICKET
+%token TIMEOUT TLS TYPE TYPES HSTS MAXAGE SUBDOMAINS DEFAULT PRELOAD REQUEST
 %token ERROR INCLUDE AUTHENTICATE WITH BLOCK DROP RETURN PASS
 %token <v.string>      STRING
 %token  <v.number>     NUMBER
@@ -766,6 +766,23 @@ tlsopts            : CERTIFICATE STRING            {
                        }
                        free($2);
                }
+               | TICKET LIFETIME DEFAULT       {
+                       srv_conf->tls_ticket_lifetime = SERVER_DEF_TLS_LIFETIME;
+               }
+               | TICKET LIFETIME NUMBER        {
+                       if ($3 != 0 && $3 < SERVER_MIN_TLS_LIFETIME) {
+                               yyerror("ticket lifetime too small");
+                               YYERROR;
+                       }
+                       if ($3 > SERVER_MAX_TLS_LIFETIME) {
+                               yyerror("ticket lifetime too large");
+                               YYERROR;
+                       }
+                       srv_conf->tls_ticket_lifetime = $3;
+               }
+               | NO TICKET                     {
+                       srv_conf->tls_ticket_lifetime = 0;
+               }
                ;
 
 root           : ROOT rootflags
@@ -1218,6 +1235,7 @@ lookup(char *s)
                { "index",              INDEX },
                { "ip",                 IP },
                { "key",                KEY },
+               { "lifetime",           LIFETIME },
                { "listen",             LISTEN },
                { "location",           LOCATION },
                { "log",                LOG },
@@ -1246,6 +1264,7 @@ lookup(char *s)
                { "subdomains",         SUBDOMAINS },
                { "syslog",             SYSLOG },
                { "tcp",                TCP },
+               { "ticket",             TICKET },
                { "timeout",            TIMEOUT },
                { "tls",                TLS },
                { "type",               TYPE },
Index: server.c
===================================================================
RCS file: /cvs/src/usr.sbin/httpd/server.c,v
retrieving revision 1.107
diff -u -p -r1.107 server.c
--- server.c    7 Feb 2017 12:27:42 -0000       1.107
+++ server.c    16 Feb 2017 19:20:23 -0000
@@ -58,6 +58,7 @@ int            server_socket(struct sockaddr_stor
                    struct server_config *, int, int);
 int             server_socket_listen(struct sockaddr_storage *, in_port_t,
                    struct server_config *);
+struct server  *server_byid(uint32_t);
 
 int             server_tls_init(struct server *);
 void            server_tls_readcb(int, short, void *);
@@ -135,6 +136,8 @@ server_tls_cmp(struct server *s1, struct
 
        if (sc1->tls_protocols != sc2->tls_protocols)
                return (-1);
+       if (sc1->tls_ticket_lifetime != sc2->tls_ticket_lifetime)
+               return (-1);
        if (strcmp(sc1->tls_ciphers, sc2->tls_ciphers) != 0)
                return (-1);
        if (strcmp(sc1->tls_dhe_params, sc2->tls_dhe_params) != 0)
@@ -266,6 +269,31 @@ server_tls_init(struct server *srv)
                }
        }
 
+       /* set common session ID among all processes */
+       if (tls_config_set_session_id(srv->srv_tls_config,
+           httpd_env->sc_tls_sid, sizeof(httpd_env->sc_tls_sid)) == -1) {
+               log_warnx("%s: could not set the TLS session ID: %s",
+                   __func__, tls_config_error(srv->srv_tls_config));
+               return (-1);
+       }
+
+       /* ticket support */
+       if (srv->srv_conf.tls_ticket_lifetime) {
+               if (tls_config_set_session_lifetime(srv->srv_tls_config,
+                   srv->srv_conf.tls_ticket_lifetime) == -1) {
+                       log_warnx("%s: could not set the TLS session lifetime: "
+                           "%s", __func__,
+                           tls_config_error(srv->srv_tls_config));
+                       return (-1);
+               }
+               tls_config_add_ticket_key(srv->srv_tls_config,
+                   srv->srv_conf.tls_ticket_key.tt_keyrev,
+                   srv->srv_conf.tls_ticket_key.tt_key,
+                   sizeof(srv->srv_conf.tls_ticket_key.tt_key));
+               explicit_bzero(&srv->srv_conf.tls_ticket_key,
+                   sizeof(srv->srv_conf.tls_ticket_key));
+       }
+
        if (tls_configure(srv->srv_tls_ctx, srv->srv_tls_config) != 0) {
                log_warnx("%s: failed to configure tls - %s", __func__,
                    tls_error(srv->srv_tls_ctx));
@@ -287,6 +315,16 @@ server_tls_init(struct server *srv)
 }
 
 void
+server_generate_ticket_key(struct server_config *srv_conf)
+{
+       struct server_tls_ticket *key = &srv_conf->tls_ticket_key;
+
+       key->tt_id = srv_conf->id;
+       key->tt_keyrev = arc4random();
+       arc4random_buf(key->tt_key, sizeof(key->tt_key));
+}
+
+void
 server_init(struct privsep *ps, struct privsep_proc *p, void *arg)
 {
        server_http();
@@ -438,6 +476,18 @@ serverconfig_byid(uint32_t id)
        return (NULL);
 }
 
+struct server *
+server_byid(uint32_t id)
+{
+       struct server   *srv;
+
+       TAILQ_FOREACH(srv, httpd_env->sc_servers, srv_entry) {
+               if (srv->srv_conf.id == id)
+                       return (srv);
+       }
+       return (NULL);
+}
+
 int
 server_foreach(int (*srv_cb)(struct server *,
     struct server_config *, void *), void *arg)
@@ -1226,6 +1276,9 @@ server_close(struct client *clt, const c
 int
 server_dispatch_parent(int fd, struct privsep_proc *p, struct imsg *imsg)
 {
+       struct server                   *srv;
+       struct server_tls_ticket         key;
+
        switch (imsg->hdr.type) {
        case IMSG_CFG_MEDIA:
                config_getmedia(httpd_env, imsg);
@@ -1247,6 +1300,16 @@ server_dispatch_parent(int fd, struct pr
                break;
        case IMSG_CTL_RESET:
                config_getreset(httpd_env, imsg);
+               break;
+       case IMSG_TLSTICKET_REKEY:
+               IMSG_SIZE_CHECK(imsg, (&key));
+               memcpy(&key, imsg->data, sizeof(key));
+               /* apply to the right server */
+               srv = server_byid(key.tt_id);
+               if (srv) {
+                       tls_config_add_ticket_key(srv->srv_tls_config,
+                           key.tt_keyrev, key.tt_key, sizeof(key.tt_key));
+               }
                break;
        default:
                return (-1);

Reply via email to