commit 02e06b8bb6f2ebfb68668828c706a28161b9546b
parent ff2574899da20514b58e7878c47f1c1e8eb14423
Author: Joris Vink <joris@coders.se>
Date:   Wed, 20 May 2015 16:36:13 +0200
Stop client initiated TLS renegotiations completely.
Diffstat:
5 files changed, 27 insertions(+), 1 deletion(-)
diff --git a/includes/kore.h b/includes/kore.h
@@ -55,7 +55,7 @@ extern int daemon(int, int);
 #define KORE_VERSION_MAJOR	1
 #define KORE_VERSION_MINOR	2
 #define KORE_VERSION_PATCH	3
-#define KORE_VERSION_STATE	"rc2"
+#define KORE_VERSION_STATE	"rc3"
 
 #define KORE_TLS_VERSION_1_2	0
 #define KORE_TLS_VERSION_1_0	1
@@ -181,6 +181,7 @@ struct connection {
 	void			*hdlr_extra;
 	X509			*cert;
 	void			*wscbs;
+	int			tls_reneg;
 
 	void			(*disconnect)(struct connection *);
 	int			(*read)(struct connection *, int *);
@@ -435,6 +436,7 @@ struct kore_timer	*kore_timer_add(void (*cb)(void *, u_int64_t,
 int		kore_tls_sni_cb(SSL *, int *, void *);
 int		kore_server_bind(const char *, const char *);
 int		kore_tls_npn_cb(SSL *, const u_char **, unsigned int *, void *);
+void		kore_tls_info_callback(const SSL *, int, int);
 
 void			kore_connection_init(void);
 struct connection	*kore_connection_new(void *);
diff --git a/src/connection.c b/src/connection.c
@@ -47,6 +47,7 @@ kore_connection_new(void *owner)
 	c->cert = NULL;
 	c->wscbs = NULL;
 	c->owner = owner;
+	c->tls_reneg = 0;
 	c->disconnect = NULL;
 	c->hdlr_extra = NULL;
 	c->inflate_started = 0;
@@ -162,6 +163,7 @@ kore_connection_handle(struct connection *c)
 
 			SSL_set_fd(c->ssl, c->fd);
 			SSL_set_accept_state(c->ssl);
+			SSL_set_app_data(c->ssl, c);
 		}
 
 		r = SSL_accept(c->ssl);
diff --git a/src/domain.c b/src/domain.c
@@ -168,6 +168,7 @@ kore_domain_sslstart(struct kore_domain *dom)
 	SSL_CTX_set_options(dom->ssl_ctx, SSL_OP_CIPHER_SERVER_PREFERENCE);
 	SSL_CTX_set_cipher_list(dom->ssl_ctx, kore_tls_cipher_list);
 
+	SSL_CTX_set_info_callback(dom->ssl_ctx, kore_tls_info_callback);
 	SSL_CTX_set_tlsext_servername_callback(dom->ssl_ctx, kore_tls_sni_cb);
 	SSL_CTX_set_next_protos_advertised_cb(dom->ssl_ctx,
 	    kore_tls_npn_cb, NULL);
diff --git a/src/kore.c b/src/kore.c
@@ -14,7 +14,9 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+#include <sys/types.h>
 #include <sys/socket.h>
+#include <sys/resource.h>
 
 #include <netdb.h>
 #include <signal.h>
@@ -208,6 +210,18 @@ kore_tls_sni_cb(SSL *ssl, int *ad, void *arg)
 
 	return (SSL_TLSEXT_ERR_NOACK);
 }
+
+void
+kore_tls_info_callback(const SSL *ssl, int flags, int ret)
+{
+	struct connection	*c;
+
+	if (flags & SSL_CB_HANDSHAKE_START) {
+		if ((c = SSL_get_app_data(ssl)) == NULL)
+			fatal("no SSL_get_app_data");
+		c->tls_reneg++;
+	}
+}
 #endif
 
 int
diff --git a/src/net.c b/src/net.c
@@ -308,6 +308,9 @@ net_write_ssl(struct connection *c, int len, int *written)
 	int		r;
 
 	r = SSL_write(c->ssl, (c->snb->buf + c->snb->s_off), len);
+	if (c->tls_reneg > 1)
+		return (KORE_RESULT_ERROR);
+
 	if (r <= 0) {
 		r = SSL_get_error(c->ssl, r);
 		switch (r) {
@@ -333,6 +336,10 @@ net_read_ssl(struct connection *c, int *bytes)
 
 	r = SSL_read(c->ssl, (c->rnb->buf + c->rnb->s_off),
 	    (c->rnb->b_len - c->rnb->s_off));
+
+	if (c->tls_reneg > 1)
+		return (KORE_RESULT_ERROR);
+
 	if (r <= 0) {
 		r = SSL_get_error(c->ssl, r);
 		switch (r) {