Browse code

Support for server name TLS extension

This patch adds support fot the server name TLS extension, the server
name string can be retrieved with the following two selects:
@tls.serverName or @tls.server_name

Jan Janak authored on 27/03/2009 15:24:58
Showing 1 changed files
... ...
@@ -59,7 +59,8 @@ enum {
59 59
 	COMP_HOST,        /* hostname from subject/alternative */
60 60
 	COMP_URI,         /* URI from subject/alternative */
61 61
 	COMP_E,           /* Email address */
62
-	COMP_IP           /* IP from subject/alternative */
62
+	COMP_IP,          /* IP from subject/alternative */
63
+	TLSEXT_SN         /* Server name of the peer */
63 64
 };
64 65
 
65 66
 
... ...
@@ -691,6 +692,75 @@ static int sel_cert(str* res, select_t* s, struct sip_msg* msg)
691 692
 }
692 693
 
693 694
 
695
+#ifdef OPENSSL_NO_TLSEXT
696
+static int get_tlsext_sn(str* res, int type, sip_msg_t* msg)
697
+{
698
+	ERR("TLS extension 'server name' is not available! "
699
+		"please install openssl with TLS extension support and recompile "
700
+		"the server\n");
701
+	return -1;
702
+}
703
+#else
704
+static int get_tlsext_sn(str* res, sip_msg_t* msg)
705
+{
706
+	static char buf[1024];
707
+	struct tcp_connection* c;
708
+	str server_name;	
709
+	SSL* ssl;
710
+
711
+	c = get_cur_connection(msg);
712
+	if (!c) {
713
+		INFO("TLS connection not found in select_desc\n");
714
+		goto error;
715
+	}
716
+	ssl = get_ssl(c);
717
+	if (!ssl) goto error;
718
+
719
+	buf[0] = '\0';
720
+
721
+	server_name.s = (char*)SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
722
+	if (server_name.s) {
723
+		DBG("received server_name (TLS extension): '%.*s'\n", 
724
+			STR_FMT(&server_name));
725
+		server_name.len = strlen(server_name.s);
726
+	} else {
727
+		DBG("SSL_get_servername returned NULL\n");
728
+		goto error;
729
+	}
730
+	
731
+	/* copy server_name into the buffer. If the buffer is too small copy only
732
+	 * the last bytes as these are the more important ones and prefix with
733
+	 * '+' */
734
+	if (server_name.len > sizeof(buf)) {
735
+		ERR("server_name to big for buffer\n");
736
+		buf[0] = '+';
737
+		memcpy(buf + 1, server_name.s + 1 + server_name.len - sizeof(buf), 
738
+			   sizeof(buf) - 1);
739
+		res->len = sizeof(buf);
740
+	} else {
741
+		memcpy(buf, server_name.s, server_name.len);
742
+		res->len = server_name.len;
743
+	}
744
+	res->s = buf;
745
+	
746
+	tcpconn_put(c);
747
+	return 0;
748
+	
749
+error:
750
+	if (c) tcpconn_put(c);
751
+	return -1;
752
+}
753
+#endif
754
+
755
+
756
+static int sel_tlsext_sn(str* res, select_t* s, sip_msg_t* msg)
757
+{
758
+	return get_tlsext_sn(res, msg);
759
+}
760
+
761
+
762
+
763
+
694 764
 select_row_t tls_sel[] = {
695 765
 	/* Current cipher parameters */
696 766
 	{ NULL, SEL_PARAM_STR, STR_STATIC_INIT("tls"), sel_tls, 0},
... ...
@@ -699,6 +769,10 @@ select_row_t tls_sel[] = {
699 769
 	{ sel_tls, SEL_PARAM_STR, STR_STATIC_INIT("desc"),        sel_desc,    0},
700 770
 	{ sel_tls, SEL_PARAM_STR, STR_STATIC_INIT("description"), sel_desc,    0},
701 771
 	{ sel_tls, SEL_PARAM_STR, STR_STATIC_INIT("cipher"),      sel_cipher,  0},
772
+
773
+	{ sel_tls, SEL_PARAM_STR, STR_STATIC_INIT("serverName"), sel_tlsext_sn,  0},
774
+	{ sel_tls, SEL_PARAM_STR, STR_STATIC_INIT("server_name"), sel_tlsext_sn,  0},
775
+
702 776
 	{ sel_tls, SEL_PARAM_STR, STR_STATIC_INIT("peer"),        sel_cert,    DIVERSION | CERT_PEER},
703 777
 	{ sel_tls, SEL_PARAM_STR, STR_STATIC_INIT("my"),          sel_cert,    DIVERSION | CERT_LOCAL},
704 778
 	{ sel_tls, SEL_PARAM_STR, STR_STATIC_INIT("me"),          sel_cert,    DIVERSION | CERT_LOCAL},