<p>Friendly Automation <strong>submitted</strong> this change.</p><p><a href="https://gerrit.asterisk.org/c/asterisk/+/18649">View Change</a></p><div style="white-space:pre-wrap">Approvals:
Joshua Colp: Looks good to me, but someone else must approve
Kevin Harwell: Looks good to me, approved
Benjamin Keith Ford: Looks good to me, but someone else must approve
Friendly Automation: Approved for Submit
</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">res_pjsip: allow TLS verification of wildcard cert-bearing servers<br><br>Rightly the use of wildcards in certificates is disallowed in accordance<br>with RFC5922. However, RFC2818 does make some allowances with regards to<br>their use when using subject alt names with DNS name types.<br><br>As such this patch creates a new setting for TLS transports called<br>'allow_wildcard_certs', which when it and 'verify_server' are both enabled<br>allows DNS name types, as well as the common name that start with '*.'<br>to match as a wildcard.<br><br>For instance: *.example.com<br>will match for: foo.example.com<br><br>Partial matching is not allowed, e.g. f*.example.com, foo.*.com, etc...<br>And the starting wildcard only matches for a single level.<br><br>For instance: *.example.com<br>will NOT match for: foo.bar.example.com<br><br>The new setting is disabled by default.<br><br>ASTERISK-30072 #close<br><br>Change-Id: If0be3fdab2e09c2a66bb54824fca406ebaac3da4<br>---<br>M configs/samples/pjsip.conf.sample<br>A contrib/ast-db-manage/config/versions/58e440314c2a_allow_wildcard_certs.py<br>A doc/CHANGES-staging/allow_wildcard_certs.txt<br>M include/asterisk/res_pjsip.h<br>M res/res_pjsip/config_transport.c<br>M res/res_pjsip/pjsip_config.xml<br>M res/res_pjsip/pjsip_transport_events.c<br>7 files changed, 218 insertions(+), 2 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/configs/samples/pjsip.conf.sample b/configs/samples/pjsip.conf.sample</span><br><span>index a019708..9d73843 100644</span><br><span>--- a/configs/samples/pjsip.conf.sample</span><br><span>+++ b/configs/samples/pjsip.conf.sample</span><br><span>@@ -1090,6 +1090,15 @@</span><br><span> ; URI is not a hostname, the saved transport will be</span><br><span> ; used and the 'x-ast-txp' parameter stripped from the</span><br><span> ; outgoing packet.</span><br><span style="color: hsl(120, 100%, 40%);">+;allow_wildcard_certs=no ; In conjunction with verify_server, if 'yes' allow use</span><br><span style="color: hsl(120, 100%, 40%);">+ ; of wildcards, i.e. '*.' in certs for common, and</span><br><span style="color: hsl(120, 100%, 40%);">+ ; subject alt names of type DNS for TLS transport</span><br><span style="color: hsl(120, 100%, 40%);">+ ; types. Note, names must start with the wildcard.</span><br><span style="color: hsl(120, 100%, 40%);">+ ; Partial wildcards, e.g. 'f*.example.com' and</span><br><span style="color: hsl(120, 100%, 40%);">+ ; 'foo.*.com' are disallowed. As well, names only</span><br><span style="color: hsl(120, 100%, 40%);">+ ; match against a single level meaning '*.example.com'</span><br><span style="color: hsl(120, 100%, 40%);">+ ; matches 'foo.example.com', but not</span><br><span style="color: hsl(120, 100%, 40%);">+ ; 'foo.bar.example.com'. Defaults to 'no'.</span><br><span> </span><br><span> ;==========================AOR SECTION OPTIONS=========================</span><br><span> ;[aor]</span><br><span>diff --git a/contrib/ast-db-manage/config/versions/58e440314c2a_allow_wildcard_certs.py b/contrib/ast-db-manage/config/versions/58e440314c2a_allow_wildcard_certs.py</span><br><span>new file mode 100644</span><br><span>index 0000000..2e56f73</span><br><span>--- /dev/null</span><br><span>+++ b/contrib/ast-db-manage/config/versions/58e440314c2a_allow_wildcard_certs.py</span><br><span>@@ -0,0 +1,29 @@</span><br><span style="color: hsl(120, 100%, 40%);">+"""allow_wildcard_certs</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+Revision ID: 58e440314c2a</span><br><span style="color: hsl(120, 100%, 40%);">+Revises: 18e0805d367f</span><br><span style="color: hsl(120, 100%, 40%);">+Create Date: 2022-05-12 12:15:55.343743</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+"""</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+# revision identifiers, used by Alembic.</span><br><span style="color: hsl(120, 100%, 40%);">+revision = '58e440314c2a'</span><br><span style="color: hsl(120, 100%, 40%);">+down_revision = '18e0805d367f'</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+from alembic import op</span><br><span style="color: hsl(120, 100%, 40%);">+import sqlalchemy as sa</span><br><span style="color: hsl(120, 100%, 40%);">+from sqlalchemy.dialects.postgresql import ENUM</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+YESNO_NAME = 'yesno_values'</span><br><span style="color: hsl(120, 100%, 40%);">+YESNO_VALUES = ['yes', 'no']</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+def upgrade():</span><br><span style="color: hsl(120, 100%, 40%);">+ yesno_values = ENUM(*YESNO_VALUES, name=YESNO_NAME, create_type=False)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ op.add_column('ps_transports', sa.Column('allow_wildcard_certs', type_=yesno_values))</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+def downgrade():</span><br><span style="color: hsl(120, 100%, 40%);">+ if op.get_context().bind.dialect.name == 'mssql':</span><br><span style="color: hsl(120, 100%, 40%);">+ op.drop_constraint('ck_ps_transports_allow_wildcard_certs_yesno_values', 'ps_transports')</span><br><span style="color: hsl(120, 100%, 40%);">+ op.drop_column('ps_transports', 'allow_wildcard_certs')</span><br><span>diff --git a/doc/CHANGES-staging/allow_wildcard_certs.txt b/doc/CHANGES-staging/allow_wildcard_certs.txt</span><br><span>new file mode 100644</span><br><span>index 0000000..29a53dd</span><br><span>--- /dev/null</span><br><span>+++ b/doc/CHANGES-staging/allow_wildcard_certs.txt</span><br><span>@@ -0,0 +1,9 @@</span><br><span style="color: hsl(120, 100%, 40%);">+Subject: res_pjsip</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+A new transport option 'allow_wildcard_certs' has been added that when it</span><br><span style="color: hsl(120, 100%, 40%);">+and 'verify_server' are both set to 'yes', enables verification against</span><br><span style="color: hsl(120, 100%, 40%);">+wildcards, i.e. '*.' in certs for common, and subject alt names of type DNS</span><br><span style="color: hsl(120, 100%, 40%);">+for TLS transport types. Names must start with the wildcard. Partial wildcards,</span><br><span style="color: hsl(120, 100%, 40%);">+e.g. 'f*.example.com' and 'foo.*.com' are not allowed. As well, names only</span><br><span style="color: hsl(120, 100%, 40%);">+match against a single level meaning '*.example.com' matches 'foo.example.com',</span><br><span style="color: hsl(120, 100%, 40%);">+but not 'foo.bar.example.com'.</span><br><span>diff --git a/include/asterisk/res_pjsip.h b/include/asterisk/res_pjsip.h</span><br><span>index ba95c27..b5b5a72 100644</span><br><span>--- a/include/asterisk/res_pjsip.h</span><br><span>+++ b/include/asterisk/res_pjsip.h</span><br><span>@@ -173,6 +173,14 @@</span><br><span> * \since 17.0.0</span><br><span> */</span><br><span> struct ast_sip_service_route_vector *service_routes;</span><br><span style="color: hsl(120, 100%, 40%);">+ /*!</span><br><span style="color: hsl(120, 100%, 40%);">+ * Disregard RFC5922 7.2, and allow wildcard certs (TLS only)</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+ int allow_wildcard_certs;</span><br><span style="color: hsl(120, 100%, 40%);">+ /*!</span><br><span style="color: hsl(120, 100%, 40%);">+ * If true, fail if server certificate cannot verify (TLS only)</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+ int verify_server;</span><br><span> };</span><br><span> </span><br><span> #define ast_sip_transport_is_nonlocal(transport_state, addr) \</span><br><span>diff --git a/res/res_pjsip/config_transport.c b/res/res_pjsip/config_transport.c</span><br><span>index 6319ecf..38bbecb 100644</span><br><span>--- a/res/res_pjsip/config_transport.c</span><br><span>+++ b/res/res_pjsip/config_transport.c</span><br><span>@@ -839,6 +839,16 @@</span><br><span> &temp_state->state->host, NULL, transport->async_operations,</span><br><span> &temp_state->state->factory);</span><br><span> }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (res == PJ_SUCCESS) {</span><br><span style="color: hsl(120, 100%, 40%);">+ temp_state->state->factory->info = pj_pool_alloc(</span><br><span style="color: hsl(120, 100%, 40%);">+ temp_state->state->factory->pool, (strlen(transport_id) + 1));</span><br><span style="color: hsl(120, 100%, 40%);">+ /*</span><br><span style="color: hsl(120, 100%, 40%);">+ * Store transport id on the factory instance so it can be used</span><br><span style="color: hsl(120, 100%, 40%);">+ * later to look up the transport state.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+ sprintf(temp_state->state->factory->info, "%s", transport_id);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span> #else</span><br><span> ast_log(LOG_ERROR, "Transport: %s: PJSIP has not been compiled with TLS transport support, ensure OpenSSL development packages are installed\n",</span><br><span> ast_sorcery_object_get_id(obj));</span><br><span>@@ -1063,11 +1073,13 @@</span><br><span> }</span><br><span> </span><br><span> if (!strcasecmp(var->name, "verify_server")) {</span><br><span style="color: hsl(0, 100%, 40%);">- state->tls.verify_server = ast_true(var->value) ? PJ_TRUE : PJ_FALSE;</span><br><span style="color: hsl(120, 100%, 40%);">+ state->verify_server = ast_true(var->value);</span><br><span> } else if (!strcasecmp(var->name, "verify_client")) {</span><br><span> state->tls.verify_client = ast_true(var->value) ? PJ_TRUE : PJ_FALSE;</span><br><span> } else if (!strcasecmp(var->name, "require_client_cert")) {</span><br><span> state->tls.require_client_cert = ast_true(var->value) ? PJ_TRUE : PJ_FALSE;</span><br><span style="color: hsl(120, 100%, 40%);">+ } else if (!strcasecmp(var->name, "allow_wildcard_certs")) {</span><br><span style="color: hsl(120, 100%, 40%);">+ state->allow_wildcard_certs = ast_true(var->value);</span><br><span> } else {</span><br><span> return -1;</span><br><span> }</span><br><span>@@ -1084,7 +1096,7 @@</span><br><span> return -1;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- *buf = ast_strdup(AST_YESNO(state->tls.verify_server));</span><br><span style="color: hsl(120, 100%, 40%);">+ *buf = ast_strdup(AST_YESNO(state->verify_server));</span><br><span> </span><br><span> return 0;</span><br><span> }</span><br><span>@@ -1117,6 +1129,20 @@</span><br><span> return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static int allow_wildcard_certs_to_str(const void *obj, const intptr_t *args, char **buf)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct ast_sip_transport_state *state = find_state_by_transport(obj);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!state) {</span><br><span style="color: hsl(120, 100%, 40%);">+ return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ *buf = ast_strdup(AST_YESNO(state->allow_wildcard_certs));</span><br><span style="color: hsl(120, 100%, 40%);">+ ao2_ref(state, -1);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /*! \brief Custom handler for TLS method setting */</span><br><span> static int transport_tls_method_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)</span><br><span> {</span><br><span>@@ -1659,6 +1685,7 @@</span><br><span> ast_sorcery_object_field_register_custom(sorcery, "transport", "verify_server", "", transport_tls_bool_handler, verify_server_to_str, NULL, 0, 0);</span><br><span> ast_sorcery_object_field_register_custom(sorcery, "transport", "verify_client", "", transport_tls_bool_handler, verify_client_to_str, NULL, 0, 0);</span><br><span> ast_sorcery_object_field_register_custom(sorcery, "transport", "require_client_cert", "", transport_tls_bool_handler, require_client_cert_to_str, NULL, 0, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_sorcery_object_field_register_custom(sorcery, "transport", "allow_wildcard_certs", "", transport_tls_bool_handler, allow_wildcard_certs_to_str, NULL, 0, 0);</span><br><span> ast_sorcery_object_field_register_custom(sorcery, "transport", "method", "", transport_tls_method_handler, tls_method_to_str, NULL, 0, 0);</span><br><span> #if defined(PJ_HAS_SSL_SOCK) && PJ_HAS_SSL_SOCK != 0</span><br><span> ast_sorcery_object_field_register_custom(sorcery, "transport", "cipher", "", transport_tls_cipher_handler, transport_tls_cipher_to_str, NULL, 0, 0);</span><br><span>diff --git a/res/res_pjsip/pjsip_config.xml b/res/res_pjsip/pjsip_config.xml</span><br><span>index 84736d6..e6fca2e 100644</span><br><span>--- a/res/res_pjsip/pjsip_config.xml</span><br><span>+++ b/res/res_pjsip/pjsip_config.xml</span><br><span>@@ -1763,6 +1763,18 @@</span><br><span> in-progress calls.</para></span><br><span> </description></span><br><span> </configOption></span><br><span style="color: hsl(120, 100%, 40%);">+ <configOption name="allow_wildcard_certs" default="false"></span><br><span style="color: hsl(120, 100%, 40%);">+ <synopsis>Allow use of wildcards in certificates (TLS ONLY)</synopsis></span><br><span style="color: hsl(120, 100%, 40%);">+ <description></span><br><span style="color: hsl(120, 100%, 40%);">+ <para>In combination with verify_server, when enabled allow use of wildcards,</span><br><span style="color: hsl(120, 100%, 40%);">+ i.e. '*.' in certs for common,and subject alt names of type DNS for TLS</span><br><span style="color: hsl(120, 100%, 40%);">+ transport types. Names must start with the wildcard. Partial wildcards, e.g.</span><br><span style="color: hsl(120, 100%, 40%);">+ 'f*.example.com' and 'foo.*.com' are not allowed. As well, names only match</span><br><span style="color: hsl(120, 100%, 40%);">+ against a single level meaning '*.example.com' matches 'foo.example.com',</span><br><span style="color: hsl(120, 100%, 40%);">+ but not 'foo.bar.example.com'.</span><br><span style="color: hsl(120, 100%, 40%);">+ </para></span><br><span style="color: hsl(120, 100%, 40%);">+ </description></span><br><span style="color: hsl(120, 100%, 40%);">+ </configOption></span><br><span> <configOption name="symmetric_transport" default="no"></span><br><span> <synopsis>Use the same transport for outgoing requests as incoming ones.</synopsis></span><br><span> <description></span><br><span>diff --git a/res/res_pjsip/pjsip_transport_events.c b/res/res_pjsip/pjsip_transport_events.c</span><br><span>index 4df1d5e..a816f46 100644</span><br><span>--- a/res/res_pjsip/pjsip_transport_events.c</span><br><span>+++ b/res/res_pjsip/pjsip_transport_events.c</span><br><span>@@ -142,6 +142,122 @@</span><br><span> }</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static void verify_log_result(int log_level, const pjsip_transport *transport,</span><br><span style="color: hsl(120, 100%, 40%);">+ pj_uint32_t verify_status)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ const char *status[32];</span><br><span style="color: hsl(120, 100%, 40%);">+ unsigned int count;</span><br><span style="color: hsl(120, 100%, 40%);">+ unsigned int i;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ count = ARRAY_LEN(status);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (pj_ssl_cert_get_verify_status_strings(verify_status, status, &count) != PJ_SUCCESS) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_log(LOG_ERROR, "Error retrieving certificate verification result(s)\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ return;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ for (i = 0; i < count; ++i) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_log(log_level, _A_, "Transport '%s' to remote '%.*s' - %s\n", transport->factory->info,</span><br><span style="color: hsl(120, 100%, 40%);">+ (int)pj_strlen(&transport->remote_name.host), pj_strbuf(&transport->remote_name.host),</span><br><span style="color: hsl(120, 100%, 40%);">+ status[i]);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static int verify_cert_name(const pj_str_t *local, const pj_str_t *remote)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ const char *p;</span><br><span style="color: hsl(120, 100%, 40%);">+ pj_ssize_t size;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_debug(3, "Verify certificate name: local = %.*s, remote = %.*s\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ (unsigned int)pj_strlen(local), pj_strbuf(local),</span><br><span style="color: hsl(120, 100%, 40%);">+ (unsigned int)pj_strlen(remote), pj_strbuf(remote));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!pj_stricmp(remote, local)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (pj_strnicmp2(remote, "*.", 2)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ p = pj_strchr(local, '.');</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!p) {</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ size = pj_strbuf(local) + pj_strlen(local) - ++p;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return size == pj_strlen(remote) - 2 ?</span><br><span style="color: hsl(120, 100%, 40%);">+ !pj_memcmp(pj_strbuf(remote) + 2, p, size) : 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static int verify_cert_names(const pj_str_t *host, const pj_ssl_cert_info *remote)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ unsigned int i;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ for (i = 0; i < remote->subj_alt_name.cnt; ++i) {</span><br><span style="color: hsl(120, 100%, 40%);">+ /*</span><br><span style="color: hsl(120, 100%, 40%);">+ * DNS is the only type we're matching wildcards against,</span><br><span style="color: hsl(120, 100%, 40%);">+ * so only recheck those.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (remote->subj_alt_name.entry[i].type == PJ_SSL_CERT_NAME_DNS</span><br><span style="color: hsl(120, 100%, 40%);">+ && verify_cert_name(host, &remote->subj_alt_name.entry[i].name)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return verify_cert_name(host, &remote->subject.cn);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static int transport_tls_verify(const pjsip_transport *transport,</span><br><span style="color: hsl(120, 100%, 40%);">+ const pjsip_tls_state_info *state_info)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ pj_uint32_t verify_status;</span><br><span style="color: hsl(120, 100%, 40%);">+ const struct ast_sip_transport_state *state;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (transport->dir == PJSIP_TP_DIR_INCOMING) {</span><br><span style="color: hsl(120, 100%, 40%);">+ return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* transport_id should always be in factory info (see config_transport) */</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_assert(!ast_strlen_zero(transport->factory->info));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ state = ast_sip_get_transport_state(transport->factory->info);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!state) {</span><br><span style="color: hsl(120, 100%, 40%);">+ /*</span><br><span style="color: hsl(120, 100%, 40%);">+ * There should always be an associated state, but if for some</span><br><span style="color: hsl(120, 100%, 40%);">+ * reason there is not then fail verification</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_log(LOG_ERROR, "Transport state not found for '%s'\n", transport->factory->info);</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ verify_status = state_info->ssl_sock_info->verify_status;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /*</span><br><span style="color: hsl(120, 100%, 40%);">+ * By this point pjsip has already completed its verification process. If</span><br><span style="color: hsl(120, 100%, 40%);">+ * there was a name matching error it could be because they disallow wildcards.</span><br><span style="color: hsl(120, 100%, 40%);">+ * If this transport has been configured to allow wildcards then we'll need</span><br><span style="color: hsl(120, 100%, 40%);">+ * to re-check the name(s) for such.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (state->allow_wildcard_certs &&</span><br><span style="color: hsl(120, 100%, 40%);">+ (verify_status & PJ_SSL_CERT_EIDENTITY_NOT_MATCH)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if (verify_cert_names(&transport->remote_name.host,</span><br><span style="color: hsl(120, 100%, 40%);">+ state_info->ssl_sock_info->remote_cert_info)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ /* A name matched a wildcard, so clear the error */</span><br><span style="color: hsl(120, 100%, 40%);">+ verify_status &= ~PJ_SSL_CERT_EIDENTITY_NOT_MATCH;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (state->verify_server && verify_status != PJ_SSL_CERT_ESUCCESS) {</span><br><span style="color: hsl(120, 100%, 40%);">+ verify_log_result(__LOG_ERROR, transport, verify_status);</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ verify_log_result(__LOG_NOTICE, transport, verify_status);</span><br><span style="color: hsl(120, 100%, 40%);">+ return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /*! \brief Callback invoked when transport state changes occur */</span><br><span> static void transport_state_callback(pjsip_transport *transport,</span><br><span> pjsip_transport_state state, const pjsip_transport_state_info *info)</span><br><span>@@ -157,6 +273,12 @@</span><br><span> transport->obj_name, transport_state2str(state));</span><br><span> switch (state) {</span><br><span> case PJSIP_TP_STATE_CONNECTED:</span><br><span style="color: hsl(120, 100%, 40%);">+ if (PJSIP_TRANSPORT_IS_SECURE(transport) &&</span><br><span style="color: hsl(120, 100%, 40%);">+ !transport_tls_verify(transport, info->ext_info)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ pjsip_transport_shutdown(transport);</span><br><span style="color: hsl(120, 100%, 40%);">+ return;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> monitored = ao2_alloc_options(sizeof(*monitored),</span><br><span> transport_monitor_dtor, AO2_ALLOC_OPT_LOCK_NOLOCK);</span><br><span> if (!monitored) {</span><br><span></span><br></pre><div style="white-space:pre-wrap"></div><p>To view, visit <a href="https://gerrit.asterisk.org/c/asterisk/+/18649">change 18649</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.asterisk.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.asterisk.org/c/asterisk/+/18649"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: 19 </div>
<div style="display:none"> Gerrit-Change-Id: If0be3fdab2e09c2a66bb54824fca406ebaac3da4 </div>
<div style="display:none"> Gerrit-Change-Number: 18649 </div>
<div style="display:none"> Gerrit-PatchSet: 3 </div>
<div style="display:none"> Gerrit-Owner: Kevin Harwell <kharwell@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Benjamin Keith Ford <bford@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Friendly Automation </div>
<div style="display:none"> Gerrit-Reviewer: Joshua Colp <jcolp@sangoma.com> </div>
<div style="display:none"> Gerrit-Reviewer: Kevin Harwell <kharwell@digium.com> </div>
<div style="display:none"> Gerrit-MessageType: merged </div>