diff options
-rw-r--r-- | pjsip-apps/src/pjsua/pjsua_app.c | 15 | ||||
-rw-r--r-- | pjsip/include/pjsip/sip_transport_tls.h | 10 | ||||
-rw-r--r-- | pjsip/src/pjsip/sip_transport_tls_ossl.c | 21 |
3 files changed, 45 insertions, 1 deletions
diff --git a/pjsip-apps/src/pjsua/pjsua_app.c b/pjsip-apps/src/pjsua/pjsua_app.c index 96bdb250..2a21a249 100644 --- a/pjsip-apps/src/pjsua/pjsua_app.c +++ b/pjsip-apps/src/pjsua/pjsua_app.c @@ -206,6 +206,7 @@ static void usage(void) puts (" --tls-verify-server Verify server's certificate (default=no)"); puts (" --tls-verify-client Verify client's certificate (default=no)"); puts (" --tls-neg-timeout Specify TLS negotiation timeout (default=no)"); + puts (" --tls-srv-name Specify TLS server name for multi-hosting server (optional)"); puts (""); puts ("Media Options:"); @@ -460,7 +461,7 @@ static pj_status_t parse_args(int argc, char *argv[], OPT_NOREFERSUB, OPT_USE_TLS, OPT_TLS_CA_FILE, OPT_TLS_CERT_FILE, OPT_TLS_PRIV_FILE, OPT_TLS_PASSWORD, OPT_TLS_VERIFY_SERVER, OPT_TLS_VERIFY_CLIENT, - OPT_TLS_NEG_TIMEOUT, + OPT_TLS_NEG_TIMEOUT, OPT_TLS_SRV_NAME, OPT_CAPTURE_DEV, OPT_PLAYBACK_DEV, OPT_CAPTURE_LAT, OPT_PLAYBACK_LAT, OPT_NO_TONES, OPT_STDOUT_REFRESH, OPT_STDOUT_REFRESH_TEXT, @@ -551,6 +552,7 @@ static pj_status_t parse_args(int argc, char *argv[], { "tls-verify-server", 0, 0, OPT_TLS_VERIFY_SERVER}, { "tls-verify-client", 0, 0, OPT_TLS_VERIFY_CLIENT}, { "tls-neg-timeout", 1, 0, OPT_TLS_NEG_TIMEOUT}, + { "tls-srv-name", 1, 0, OPT_TLS_SRV_NAME}, { "capture-dev", 1, 0, OPT_CAPTURE_DEV}, { "playback-dev", 1, 0, OPT_PLAYBACK_DEV}, { "capture-lat", 1, 0, OPT_CAPTURE_LAT}, @@ -1136,6 +1138,10 @@ static pj_status_t parse_args(int argc, char *argv[], cfg->udp_cfg.tls_setting.timeout.sec = atoi(pj_optarg); break; + case OPT_TLS_SRV_NAME: + cfg->udp_cfg.tls_setting.server_name = pj_str(pj_optarg); + break; + case OPT_CAPTURE_DEV: cfg->capture_dev = atoi(pj_optarg); break; @@ -1471,6 +1477,13 @@ static int write_settings(const struct app_config *config, pj_strcat2(&cfg, line); } + if (config->udp_cfg.tls_setting.server_name.slen) { + pj_ansi_sprintf(line, "--tls-srv-name %.*s\n", + (int)config->udp_cfg.tls_setting.server_name.slen, + config->udp_cfg.tls_setting.server_name.ptr); + pj_strcat2(&cfg, line); + } + if (config->udp_cfg.tls_setting.verify_server) pj_strcat2(&cfg, "--tls-verify-server\n"); diff --git a/pjsip/include/pjsip/sip_transport_tls.h b/pjsip/include/pjsip/sip_transport_tls.h index d970df7b..cec869d4 100644 --- a/pjsip/include/pjsip/sip_transport_tls.h +++ b/pjsip/include/pjsip/sip_transport_tls.h @@ -109,6 +109,16 @@ typedef struct pjsip_tls_setting pj_str_t ciphers; /** + * Optionally specify the server name instance to be contacted when + * making outgoing TLS connection. This setting is useful when the + * server is hosting multiple domains for the same TLS listening + * socket. + * + * Default: empty. + */ + pj_str_t server_name; + + /** * When PJSIP is acting as a client (outgoing TLS connections), * it will always receive a certificate from the peer. * If \a verify_server is disabled (set to zero), PJSIP will not diff --git a/pjsip/src/pjsip/sip_transport_tls_ossl.c b/pjsip/src/pjsip/sip_transport_tls_ossl.c index 4ca2c2f9..3c4fc706 100644 --- a/pjsip/src/pjsip/sip_transport_tls_ossl.c +++ b/pjsip/src/pjsip/sip_transport_tls_ossl.c @@ -164,6 +164,7 @@ struct tls_transport /* TLS settings, copied from listener */ struct { + pj_str_t server_name; pj_time_val timeout; } setting; @@ -513,6 +514,24 @@ static pj_status_t ssl_connect(struct tls_transport *tls) if (!SSL_in_connect_init(ssl)) SSL_set_connect_state(ssl); +#ifdef SSL_set_tlsext_host_name + if (tls->setting.server_name.slen) { + char server_name[PJ_MAX_HOSTNAME]; + + if (tls->setting.server_name.slen >= PJ_MAX_HOSTNAME) + return PJ_ENAMETOOLONG; + + pj_memcpy(server_name, tls->setting.server_name.ptr, + tls->setting.server_name.slen); + server_name[tls->setting.server_name.slen] = '\0'; + + if (!SSL_set_tlsext_host_name(ssl, server_name)) { + PJ_LOG(4,(tls->base.obj_name, + "SSL_set_tlsext_host_name() failed")); + } + } +#endif + PJ_LOG(5,(tls->base.obj_name, "Starting SSL_connect() negotiation")); do { @@ -1231,6 +1250,8 @@ static pj_status_t tls_create( struct tls_listener *listener, pj_list_init(&tls->delayed_list); tls->base.pool = pool; tls->setting.timeout = listener->setting.timeout; + pj_strdup(pool, &tls->setting.server_name, + &listener->setting.server_name); pj_ansi_snprintf(tls->base.obj_name, PJ_MAX_OBJ_NAME, (is_server ? "tlss%p" :"tlsc%p"), tls); |