Skip to content

Instantly share code, notes, and snippets.

@weitzj
Created June 1, 2015 21:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save weitzj/18b07b7402bda937ef18 to your computer and use it in GitHub Desktop.
Save weitzj/18b07b7402bda937ef18 to your computer and use it in GitHub Desktop.
diff --git a/client/client_shared.c b/client/client_shared.c
index 00f5c6c..e2c3696 100644
--- a/client/client_shared.c
+++ b/client/client_shared.c
@@ -505,6 +505,16 @@ int client_config_line_proc(struct mosq_config *cfg, int pub_or_sub, int argc, c
}else{
cfg->pub_mode = MSGMODE_STDIN_FILE;
}
+#ifdef WITH_TLS
+ }else if(!strcmp(argv[i], "--sni-hostname")){
+ if(i==argc-1){
+ fprintf(stderr, "Error: --sni-hostname argument given but no hostname specified.\n\n");
+ return 1;
+ }else{
+ cfg->sni_hostname = strdup(argv[i+1]);
+ }
+ i++;
+#endif
#ifdef WITH_SRV
}else if(!strcmp(argv[i], "-S")){
cfg->use_srv = true;
@@ -671,6 +681,11 @@ int client_opts_set(struct mosquitto *mosq, struct mosq_config *cfg)
mosquitto_lib_cleanup();
return 1;
}
+ if(cfg->sni_hostname && mosquitto_tls_sni_set(mosq, cfg->sni_hostname)){
+ if(!cfg->quiet) fprintf(stderr, "Error: Problem setting TLS SNI hostname option.\n");
+ mosquitto_lib_cleanup();
+ return 1;
+ }
# ifdef WITH_TLS_PSK
if(cfg->psk && mosquitto_tls_psk_set(mosq, cfg->psk, cfg->psk_identity, NULL)){
if(!cfg->quiet) fprintf(stderr, "Error: Problem setting TLS-PSK options.\n");
diff --git a/client/client_shared.h b/client/client_shared.h
index 0a974b1..4a63b57 100644
--- a/client/client_shared.h
+++ b/client/client_shared.h
@@ -66,6 +66,7 @@ struct mosq_config {
char *ciphers;
bool insecure;
char *tls_version;
+ char *sni_hostname;
# ifdef WITH_TLS_PSK
char *psk;
char *psk_identity;
diff --git a/client/pub_client.c b/client/pub_client.c
index d48cd71..deaeefd 100644
--- a/client/pub_client.c
+++ b/client/pub_client.c
@@ -213,7 +213,7 @@ void print_usage(void)
printf(" [--will-topic [--will-payload payload] [--will-qos qos] [--will-retain]]\n");
#ifdef WITH_TLS
printf(" [{--cafile file | --capath dir} [--cert file] [--key file]\n");
- printf(" [--ciphers ciphers] [--insecure]]\n");
+ printf(" [--ciphers ciphers] [--insecure] [--sni-hostname hostname]]\n");
#ifdef WITH_TLS_PSK
printf(" [--psk hex-key --psk-identity identity [--ciphers ciphers]]\n");
#endif
diff --git a/client/sub_client.c b/client/sub_client.c
index 3c6c225..a5458a2 100644
--- a/client/sub_client.c
+++ b/client/sub_client.c
@@ -142,7 +142,7 @@ void print_usage(void)
printf(" [--will-topic [--will-payload payload] [--will-qos qos] [--will-retain]]\n");
#ifdef WITH_TLS
printf(" [{--cafile file | --capath dir} [--cert file] [--key file]\n");
- printf(" [--ciphers ciphers] [--insecure]]\n");
+ printf(" [--ciphers ciphers] [--insecure] [--sni-hostname hostname]]\n");
#ifdef WITH_TLS_PSK
printf(" [--psk hex-key --psk-identity identity [--ciphers ciphers]]\n");
#endif
diff --git a/lib/linker.version b/lib/linker.version
index 59eed79..69c7d2e 100644
--- a/lib/linker.version
+++ b/lib/linker.version
@@ -78,3 +78,8 @@ MOSQ_1.4 {
mosquitto_sub_topic_check;
mosquitto_socks5_set;
} MOSQ_1.3;
+
+MOSQ_1.5 {
+ global:
+ mosquitto_tls_sni_set;
+} MOSQ_1.4;
diff --git a/lib/mosquitto.c b/lib/mosquitto.c
index 99af899..d794dab 100644
--- a/lib/mosquitto.c
+++ b/lib/mosquitto.c
@@ -318,6 +318,8 @@ void _mosquitto_destroy(struct mosquitto *mosq)
if(mosq->tls_ciphers) _mosquitto_free(mosq->tls_ciphers);
if(mosq->tls_psk) _mosquitto_free(mosq->tls_psk);
if(mosq->tls_psk_identity) _mosquitto_free(mosq->tls_psk_identity);
+ if(mosq->tls_sni_hostname) _mosquitto_free(mosq->tls_sni_hostname);
+
#endif
if(mosq->address){
@@ -817,6 +819,23 @@ int mosquitto_tls_psk_set(struct mosquitto *mosq, const char *psk, const char *i
}
+int mosquitto_tls_sni_set(struct mosquitto *mosq, const char *hostname)
+{
+#ifdef WITH_TLS
+ if(!mosq || !hostname) return MOSQ_ERR_INVAL;
+
+ mosq->tls_sni_hostname = _mosquitto_strdup(hostname);
+ if(!mosq->tls_sni_hostname){
+ return MOSQ_ERR_NOMEM;
+ }
+
+ return MOSQ_ERR_SUCCESS;
+#else
+ return MOSQ_ERR_NOT_SUPPORTED;
+#endif
+}
+
+
int mosquitto_loop(struct mosquitto *mosq, int timeout, int max_packets)
{
#ifdef HAVE_PSELECT
diff --git a/lib/mosquitto.h b/lib/mosquitto.h
index 88abe08..fed3521 100644
--- a/lib/mosquitto.h
+++ b/lib/mosquitto.h
@@ -1085,6 +1085,26 @@ libmosq_EXPORT int mosquitto_tls_opts_set(struct mosquitto *mosq, int cert_reqs,
*/
libmosq_EXPORT int mosquitto_tls_psk_set(struct mosquitto *mosq, const char *psk, const char *identity, const char *ciphers);
+/*
+ * Function: mosquitto_tls_sni_set
+ *
+ * Configure the client for TLS Server Name Indication support. Must be called
+ * before <mosquitto_connect>.
+ *
+ * Parameters:
+ * mosq - a valid mosquitto instance.
+ * hostname - the SNI hostname.
+ *
+ * Returns:
+ * MOSQ_ERR_SUCCESS - on success.
+ * MOSQ_ERR_INVAL - if the input parameters were invalid.
+ * MOSQ_ERR_NOMEM - if an out of memory condition occurred.
+ *
+ * See Also:
+ * <mosquitto_tls_set>
+ */
+libmosq_EXPORT int mosquitto_tls_sni_set(struct mosquitto *mosq, const char *hostname);
+
/*
* Function: mosquitto_connect_callback_set
*
diff --git a/lib/mosquitto_internal.h b/lib/mosquitto_internal.h
index 4c34116..b1b9a08 100644
--- a/lib/mosquitto_internal.h
+++ b/lib/mosquitto_internal.h
@@ -173,6 +173,7 @@ struct mosquitto {
char *tls_ciphers;
char *tls_psk;
char *tls_psk_identity;
+ char *tls_sni_hostname;
int tls_cert_reqs;
bool tls_insecure;
#endif
diff --git a/lib/net_mosq.c b/lib/net_mosq.c
index bfc1384..e1e3259 100644
--- a/lib/net_mosq.c
+++ b/lib/net_mosq.c
@@ -535,6 +535,13 @@ int _mosquitto_socket_connect(struct mosquitto *mosq, const char *host, uint16_t
COMPAT_CLOSE(sock);
return MOSQ_ERR_TLS;
}
+
+ if(mosq->tls_sni_hostname && !SSL_set_tlsext_host_name(mosq->ssl, mosq->tls_sni_hostname)) {
+ _mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Unable to set SNI hostname \"%s\".", mosq->tls_sni_hostname);
+ COMPAT_CLOSE(sock);
+ return MOSQ_ERR_TLS;
+ }
+
SSL_set_ex_data(mosq->ssl, tls_ex_index_mosq, mosq);
bio = BIO_new_socket(sock, BIO_NOCLOSE);
if(!bio){
diff --git a/man/mosquitto_pub.1.xml b/man/mosquitto_pub.1.xml
index 171415c..eb90f08 100644
--- a/man/mosquitto_pub.1.xml
+++ b/man/mosquitto_pub.1.xml
@@ -56,6 +56,7 @@
<arg><option>--ciphers</option> <replaceable>ciphers</replaceable></arg>
<arg><option>--tls-version</option> <replaceable>version</replaceable></arg>
<arg><option>--insecure</option></arg>
+ <arg><option>--sni-hostname</option> <replaceable>hostname</replaceable></arg>
</arg>
<arg>
<arg choice='plain'><option>--psk</option> <replaceable>hex-key</replaceable></arg>
@@ -347,6 +348,16 @@
</listitem>
</varlistentry>
<varlistentry>
+ <term><option>--sni-hostname</option></term>
+ <listitem>
+ <para>Set the hostname to use for TLS Server Name
+ Indication (SNI) support. This allows the client to
+ indicate the hostname that it wishes to connect as part
+ of the TLS handshake, and so allow the server to use
+ multiple certificates on a single IP address.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
<term><option>-t</option></term>
<term><option>--topic</option></term>
<listitem>
diff --git a/man/mosquitto_sub.1.xml b/man/mosquitto_sub.1.xml
index 7e6f642..5e210f8 100644
--- a/man/mosquitto_sub.1.xml
+++ b/man/mosquitto_sub.1.xml
@@ -52,6 +52,7 @@
<arg><option>--key</option> <replaceable>file</replaceable></arg>
<arg><option>--tls-version</option> <replaceable>version</replaceable></arg>
<arg><option>--insecure</option></arg>
+ <arg><option>--sni-hostname</option> <replaceable>hostname</replaceable></arg>
</arg>
<arg>
<arg choice='plain'><option>--psk</option> <replaceable>hex-key</replaceable></arg>
@@ -356,6 +357,16 @@
</listitem>
</varlistentry>
<varlistentry>
+ <term><option>--sni-hostname</option></term>
+ <listitem>
+ <para>Set the hostname to use for TLS Server Name
+ Indication (SNI) support. This allows the client to
+ indicate the hostname that it wishes to connect as part
+ of the TLS handshake, and so allow the server to use
+ multiple certificates on a single IP address.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
<term><option>-t</option></term>
<term><option>--topic</option></term>
<listitem>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment