Skip to content

Commit

Permalink
Merge pull request #1224 from omenlabs/ALPN
Browse files Browse the repository at this point in the history
Bridge TLS Application-Layer Protocol Negotiation
  • Loading branch information
ralight committed Apr 11, 2019
2 parents 8b53270 + c011be6 commit 77aaec6
Show file tree
Hide file tree
Showing 9 changed files with 53 additions and 0 deletions.
1 change: 1 addition & 0 deletions lib/mosquitto.c
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,7 @@ void mosquitto__destroy(struct mosquitto *mosq)
mosquitto__free(mosq->tls_ciphers);
mosquitto__free(mosq->tls_psk);
mosquitto__free(mosq->tls_psk_identity);
mosquitto__free(mosq->tls_alpn);
#endif

mosquitto__free(mosq->address);
Expand Down
1 change: 1 addition & 0 deletions lib/mosquitto.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ enum mosq_opt_t {
MOSQ_OPT_TLS_ENGINE = 7,
MOSQ_OPT_TLS_ENGINE_KPASS_SHA1 = 8,
MOSQ_OPT_TLS_OCSP_REQUIRED = 9,
MOSQ_OPT_TLS_ALPN = 10,
};


Expand Down
1 change: 1 addition & 0 deletions lib/mosquitto_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@ struct mosquitto {
char *tls_engine;
char *tls_engine_kpass_sha1;
enum mosquitto__keyform tls_keyform;
char *tls_alpn;
#endif
bool want_write;
bool want_connect;
Expand Down
16 changes: 16 additions & 0 deletions lib/net_mosq.c
Original file line number Diff line number Diff line change
Expand Up @@ -527,6 +527,10 @@ static int net__init_ssl_ctx(struct mosquitto *mosq)
{
int ret;
ENGINE *engine = NULL;
#if OPENSSL_VERSION_NUMBER >= 0x10002000L /* ALPN was added into OpenSSL 1.0.2 */
uint8_t tls_alpn_wire[256];
uint8_t tls_alpn_len;
#endif

if(mosq->ssl_ctx){
if(!mosq->ssl_ctx_defaults){
Expand Down Expand Up @@ -582,6 +586,18 @@ static int net__init_ssl_ctx(struct mosquitto *mosq)
/* Disable compression */
SSL_CTX_set_options(mosq->ssl_ctx, SSL_OP_NO_COMPRESSION);

/* Set ALPN */
if(mosq->tls_alpn) {
#if OPENSSL_VERSION_NUMBER >= 0x10002000L /* ALPN was added into OpenSSL 1.0.2 */
tls_alpn_len = (uint8_t) strnlen(mosq->tls_alpn, 254);
tls_alpn_wire[0] = tls_alpn_len; // first byte is length of string
memcpy(tls_alpn_wire + 1, mosq->tls_alpn, tls_alpn_len);
SSL_CTX_set_alpn_protos(mosq->ssl_ctx, tls_alpn_wire, tls_alpn_len + 1);
#else
log__printf(mosq, MOSQ_LOG_ERR, "Error: TLS ALPN not supported by version of OpenSSL.");
#endif
}

#ifdef SSL_MODE_RELEASE_BUFFERS
/* Use even less memory per SSL connection. */
SSL_CTX_set_mode(mosq->ssl_ctx, SSL_MODE_RELEASE_BUFFERS);
Expand Down
12 changes: 12 additions & 0 deletions lib/options.c
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,18 @@ int mosquitto_string_option(struct mosquitto *mosq, enum mosq_opt_t option, cons
#endif
break;

case MOSQ_OPT_TLS_ALPN:
#ifdef WITH_TLS
mosq->tls_alpn = mosquitto__strdup(value);
if(!mosq->tls_alpn){
return MOSQ_ERR_NOMEM;
}
return MOSQ_ERR_SUCCESS;
#else
return MOSQ_ERR_NOT_SUPPORTED;
#endif
break;

default:
return MOSQ_ERR_INVAL;
}
Expand Down
8 changes: 8 additions & 0 deletions man/mosquitto.conf.5.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1811,6 +1811,14 @@ topic clients/total in 0 test/mosquitto/org $SYS/broker/
connection to succeed.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>bridge_alpn</option> <replaceable>alpn</replaceable></term>
<listitem>
<para>Configure the application layer protocol negotiation
option for the TLS session. Useful for brokers that support
both websockets and MQTT on the same port.</para>
</listitem>
</varlistentry>
</variablelist>
</refsect2>
</refsect1>
Expand Down
1 change: 1 addition & 0 deletions src/bridge.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ int bridge__new(struct mosquitto_db *db, struct mosquitto__bridge *bridge)
new_context->tls_ocsp_required = new_context->bridge->tls_ocsp_required;
new_context->tls_version = new_context->bridge->tls_version;
new_context->tls_insecure = new_context->bridge->tls_insecure;
new_context->tls_alpn = new_context->bridge->tls_alpn;
#ifdef FINAL_WITH_TLS_PSK
new_context->tls_psk_identity = new_context->bridge->tls_psk_identity;
new_context->tls_psk = new_context->bridge->tls_psk;
Expand Down
12 changes: 12 additions & 0 deletions src/conf.c
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,7 @@ void config__cleanup(struct mosquitto__config *config)
#ifdef WITH_TLS
mosquitto__free(config->bridges[i].tls_version);
mosquitto__free(config->bridges[i].tls_cafile);
mosquitto__free(config->bridges[i].tls_alpn);
#ifdef FINAL_WITH_TLS_PSK
mosquitto__free(config->bridges[i].tls_psk_identity);
mosquitto__free(config->bridges[i].tls_psk);
Expand Down Expand Up @@ -995,6 +996,17 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct
if(conf__parse_string(&token, "bridge_cafile", &cur_bridge->tls_cafile, saveptr)) return MOSQ_ERR_INVAL;
#else
log__printf(NULL, MOSQ_LOG_WARNING, "Warning: Bridge and/or TLS support not available.");
#endif
}else if(!strcmp(token, "bridge_alpn")){
#if defined(WITH_BRIDGE) && defined(WITH_TLS)
if(reload) continue; // FIXME
if(!cur_bridge){
log__printf(NULL, MOSQ_LOG_ERR, "Error: Invalid bridge configuration.");
return MOSQ_ERR_INVAL;
}
if(conf__parse_string(&token, "bridge_alpn", &cur_bridge->tls_alpn, saveptr)) return MOSQ_ERR_INVAL;
#else
log__printf(NULL, MOSQ_LOG_WARNING, "Warning: Bridge and/or TLS support not available.");
#endif
}else if(!strcmp(token, "bridge_capath")){
#if defined(WITH_BRIDGE) && defined(WITH_TLS)
Expand Down
1 change: 1 addition & 0 deletions src/mosquitto_broker_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -514,6 +514,7 @@ struct mosquitto__bridge{
char *tls_certfile;
char *tls_keyfile;
char *tls_version;
char *tls_alpn;
# ifdef FINAL_WITH_TLS_PSK
char *tls_psk_identity;
char *tls_psk;
Expand Down

0 comments on commit 77aaec6

Please sign in to comment.