Skip to content

Commit 98f3ca9

Browse files
committed
#1580 Implemented custom SNI server name
1 parent bba7246 commit 98f3ca9

File tree

5 files changed

+52
-6
lines changed

5 files changed

+52
-6
lines changed

src/MQTTAsync.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -609,7 +609,7 @@ int MQTTAsync_connect(MQTTAsync handle, const MQTTAsync_connectOptions* options)
609609
}
610610
if (options->struct_version != 0 && options->ssl) /* check validity of SSL options structure */
611611
{
612-
if (strncmp(options->ssl->struct_id, "MQTS", 4) != 0 || options->ssl->struct_version < 0 || options->ssl->struct_version > 5)
612+
if (strncmp(options->ssl->struct_id, "MQTS", 4) != 0 || options->ssl->struct_version < 0 || options->ssl->struct_version > 6)
613613
{
614614
rc = MQTTASYNC_BAD_STRUCTURE;
615615
goto exit;
@@ -767,6 +767,11 @@ int MQTTAsync_connect(MQTTAsync handle, const MQTTAsync_connectOptions* options)
767767
if (m->c->sslopts->CApath)
768768
free((void*)m->c->sslopts->CApath);
769769
}
770+
if (m->c->sslopts->struct_version >= 6)
771+
{
772+
if (m->c->sslopts->serverName)
773+
free((void*)m->c->sslopts->serverName);
774+
}
770775
free((void*)m->c->sslopts);
771776
m->c->sslopts = NULL;
772777
}
@@ -816,6 +821,11 @@ int MQTTAsync_connect(MQTTAsync handle, const MQTTAsync_connectOptions* options)
816821
m->c->sslopts->protos = (const unsigned char*)MQTTStrdup((const char*)options->ssl->protos);
817822
m->c->sslopts->protos_len = options->ssl->protos_len;
818823
}
824+
if (m->c->sslopts->struct_version >= 6)
825+
{
826+
if (options->ssl->serverName)
827+
m->c->sslopts->serverName = MQTTStrdup(options->ssl->serverName);
828+
}
819829
}
820830
#else
821831
if (options->struct_version != 0 && options->ssl)

src/MQTTAsync.h

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1074,12 +1074,13 @@ typedef struct
10741074
/** The eyecatcher for this structure. Must be MQTS */
10751075
char struct_id[4];
10761076

1077-
/** The version number of this structure. Must be 0, 1, 2, 3, 4 or 5.
1077+
/** The version number of this structure. Must be 0, 1, 2, 3, 4, 5, or 6.
10781078
* 0 means no sslVersion
10791079
* 1 means no verify, CApath
10801080
* 2 means no ssl_error_context, ssl_error_cb
10811081
* 3 means no ssl_psk_cb, ssl_psk_context, disableDefaultTrustStore
10821082
* 4 means no protos, protos_len
1083+
* 5 means no (SNI) serverName
10831084
*/
10841085
int struct_version;
10851086

@@ -1178,9 +1179,18 @@ typedef struct
11781179
* Exists only if struct_version >= 5
11791180
*/
11801181
unsigned int protos_len;
1182+
1183+
/**
1184+
* Optional server name for the Server Name Indication (SNI) TLS
1185+
* extension. It's the name of the broker/server host, and must be a
1186+
* host name, and not an IP address. It can be used by a multi-homed
1187+
* server to choose the correct certificate to present to the client.
1188+
* Exists only if struct_version >= 6
1189+
*/
1190+
const char *serverName;
11811191
} MQTTAsync_SSLOptions;
11821192

1183-
#define MQTTAsync_SSLOptions_initializer { {'M', 'Q', 'T', 'S'}, 5, NULL, NULL, NULL, NULL, NULL, 1, MQTT_SSL_VERSION_DEFAULT, 0, NULL, NULL, NULL, NULL, NULL, 0, NULL, 0 }
1193+
#define MQTTAsync_SSLOptions_initializer { {'M', 'Q', 'T', 'S'}, 6, NULL, NULL, NULL, NULL, NULL, 1, MQTT_SSL_VERSION_DEFAULT, 0, NULL, NULL, NULL, NULL, NULL, 0, NULL, 0, NULL }
11841194

11851195
/** Utility structure where name/value pairs are needed */
11861196
typedef struct

src/MQTTClient.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1630,6 +1630,11 @@ static MQTTResponse MQTTClient_connectURI(MQTTClient handle, MQTTClient_connectO
16301630
if (m->c->sslopts->CApath)
16311631
free((void*)m->c->sslopts->CApath);
16321632
}
1633+
if (m->c->sslopts->struct_version >= 6)
1634+
{
1635+
if (m->c->sslopts->serverName)
1636+
free((void*)m->c->sslopts->serverName);
1637+
}
16331638
free(m->c->sslopts);
16341639
m->c->sslopts = NULL;
16351640
}
@@ -1678,6 +1683,11 @@ static MQTTResponse MQTTClient_connectURI(MQTTClient handle, MQTTClient_connectO
16781683
m->c->sslopts->protos = options->ssl->protos;
16791684
m->c->sslopts->protos_len = options->ssl->protos_len;
16801685
}
1686+
if (m->c->sslopts->struct_version >= 6)
1687+
{
1688+
if (options->ssl->serverName)
1689+
m->c->sslopts->serverName = MQTTStrdup(options->ssl->serverName);
1690+
}
16811691
}
16821692
#endif
16831693

@@ -1830,7 +1840,7 @@ MQTTResponse MQTTClient_connectAll(MQTTClient handle, MQTTClient_connectOptions*
18301840
#if defined(OPENSSL)
18311841
if (options->struct_version != 0 && options->ssl) /* check validity of SSL options structure */
18321842
{
1833-
if (strncmp(options->ssl->struct_id, "MQTS", 4) != 0 || options->ssl->struct_version < 0 || options->ssl->struct_version > 5)
1843+
if (strncmp(options->ssl->struct_id, "MQTS", 4) != 0 || options->ssl->struct_version < 0 || options->ssl->struct_version > 6)
18341844
{
18351845
rc.reasonCode = MQTTCLIENT_BAD_STRUCTURE;
18361846
goto exit;

src/MQTTClient.h

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -679,12 +679,13 @@ typedef struct
679679
/** The eyecatcher for this structure. Must be MQTS */
680680
char struct_id[4];
681681

682-
/** The version number of this structure. Must be 0, 1, 2, 3, 4 or 5.
682+
/** The version number of this structure. Must be 0, 1, 2, 3, 4, 5, or 6.
683683
* 0 means no sslVersion
684684
* 1 means no verify, CApath
685685
* 2 means no ssl_error_context, ssl_error_cb
686686
* 3 means no ssl_psk_cb, ssl_psk_context, disableDefaultTrustStore
687687
* 4 means no protos, protos_len
688+
* 5 means no (SNI) serverName
688689
*/
689690
int struct_version;
690691

@@ -783,9 +784,18 @@ typedef struct
783784
* Exists only if struct_version >= 5
784785
*/
785786
unsigned int protos_len;
787+
788+
/**
789+
* Optional server name for the Server Name Indication (SNI) TLS
790+
* extension. It's the name of the broker/server host, and must be a
791+
* host name, and not an IP address. It can be used by a multi-homed
792+
* server to choose the correct certificate to present to the client.
793+
* Exists only if struct_version >= 6
794+
*/
795+
const char *serverName;
786796
} MQTTClient_SSLOptions;
787797

788-
#define MQTTClient_SSLOptions_initializer { {'M', 'Q', 'T', 'S'}, 5, NULL, NULL, NULL, NULL, NULL, 1, MQTT_SSL_VERSION_DEFAULT, 0, NULL, NULL, NULL, NULL, NULL, 0, NULL, 0 }
798+
#define MQTTClient_SSLOptions_initializer { {'M', 'Q', 'T', 'S'}, 6, NULL, NULL, NULL, NULL, NULL, 1, MQTT_SSL_VERSION_DEFAULT, 0, NULL, NULL, NULL, NULL, NULL, 0, NULL, 0, NULL }
789799

790800
/**
791801
* MQTTClient_libraryInfo is used to store details relating to the currently used

src/SSLSocket.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -740,10 +740,16 @@ int SSLSocket_setSocketForSSL(networkHandles* net, MQTTClient_SSLOptions* opts,
740740
else
741741
SSLSocket_error("SSL_set_fd", net->ssl, net->socket, rc, NULL, NULL);
742742
}
743+
/* If servername is set in the options, use that for the hostname */
744+
if (opts->struct_version >= 6 && opts->serverName != NULL) {
745+
hostname = opts->serverName;
746+
hostname_len = strnlen(hostname, MAXHOSTNAMELEN);
747+
}
743748
hostname_plus_null = malloc(hostname_len + 1u );
744749
if (hostname_plus_null)
745750
{
746751
MQTTStrncpy(hostname_plus_null, hostname, hostname_len + 1u);
752+
Log(TRACE_PROTOCOL, -1, "SNI server/host name is %s", hostname_plus_null);
747753
if ((rc = SSL_set_tlsext_host_name(net->ssl, hostname_plus_null)) != 1) {
748754
if (opts->struct_version >= 3)
749755
SSLSocket_error("SSL_set_tlsext_host_name", NULL, net->socket, rc, opts->ssl_error_cb, opts->ssl_error_context);

0 commit comments

Comments
 (0)