diff --git a/CHANGES b/CHANGES index 8324aed19647cb7c28df20ff51fa618f10f59c3e..85658a4eceaae8f6ed6740810f0bf4ca3bc71b2b 100644 --- a/CHANGES +++ b/CHANGES @@ -30,6 +30,14 @@ app_voicemail * The 'Comedian Mail' prompts can now be overriden using the 'vm-login' and 'vm-newuser' configuration options in voicemail.conf. +res_pjsip_transport_websocket +------------------ + * Removed non-secure websocket support. Firefox and Chrome have not allowed + non-secure websockets for quite some time so this shouldn't be an issue + for people. Attempting to use a non-secure websocket may or may not work + when Asterisk attempts to send SIP requests to do something like initiate + call hangup. + ------------------------------------------------------------------------------ --- Functionality changes from Asterisk 13.13.0 to Asterisk 13.14.0 ---------- ------------------------------------------------------------------------------ diff --git a/res/res_pjsip/security_events.c b/res/res_pjsip/security_events.c index 5c30e1c5e7a55f2bd599291dcd79aa922bfbac80..ef3a748b2fd5424976ec21f116d18bd3c05542d4 100644 --- a/res/res_pjsip/security_events.c +++ b/res/res_pjsip/security_events.c @@ -44,9 +44,9 @@ static enum ast_transport security_event_get_transport(pjsip_rx_data *rdata) } else if (rdata->tp_info.transport->key.type == PJSIP_TRANSPORT_TLS || rdata->tp_info.transport->key.type == PJSIP_TRANSPORT_TLS6) { return AST_TRANSPORT_TLS; - } else if (!strcmp(rdata->tp_info.transport->type_name, "WS")) { + } else if (!strcasecmp(rdata->tp_info.transport->type_name, "WS")) { return AST_TRANSPORT_WS; - } else if (!strcmp(rdata->tp_info.transport->type_name, "WSS")) { + } else if (!strcasecmp(rdata->tp_info.transport->type_name, "WSS")) { return AST_TRANSPORT_WSS; } else { return 0; diff --git a/res/res_pjsip_nat.c b/res/res_pjsip_nat.c index 59ef71c5c7db3eedddde3af862820cab5aa0cd51..7404ef5f01c39732f7a5b4b613bcac9e9bf6fa82 100644 --- a/res/res_pjsip_nat.c +++ b/res/res_pjsip_nat.c @@ -35,7 +35,9 @@ static void rewrite_uri(pjsip_rx_data *rdata, pjsip_sip_uri *uri) { pj_cstr(&uri->host, rdata->pkt_info.src_name); - if (strcasecmp("udp", rdata->tp_info.transport->type_name)) { + if (!strcasecmp("WSS", rdata->tp_info.transport->type_name)) { + /* WSS is special, we don't want to overwrite the URI at all as it needs to be ws */ + } else if (strcasecmp("udp", rdata->tp_info.transport->type_name)) { uri->transport_param = pj_str(rdata->tp_info.transport->type_name); } else { uri->transport_param.slen = 0; diff --git a/res/res_pjsip_transport_websocket.c b/res/res_pjsip_transport_websocket.c index 82ade56e08603777acf7c828335185bbfcc1c7f4..ff8e346f4d956aaebe1e2b6c229f2ef0235a7e59 100644 --- a/res/res_pjsip_transport_websocket.c +++ b/res/res_pjsip_transport_websocket.c @@ -38,7 +38,6 @@ #include "asterisk/res_pjsip_session.h" #include "asterisk/taskprocessor.h" -static int transport_type_ws; static int transport_type_wss; /*! @@ -149,6 +148,7 @@ static int transport_create(void *data) pjsip_endpoint *endpt = ast_sip_get_pjsip_endpoint(); struct pjsip_tpmgr *tpmgr = pjsip_endpt_get_tpmgr(endpt); + char *ws_addr_str; pj_pool_t *pool; pj_str_t buf; pj_status_t status; @@ -183,9 +183,23 @@ static int transport_create(void *data) goto on_error; } - pj_sockaddr_parse(pj_AF_UNSPEC(), 0, pj_cstr(&buf, ast_sockaddr_stringify(ast_websocket_remote_address(newtransport->ws_session))), &newtransport->transport.key.rem_addr); + /* + * The type_name here is mostly used by log messages eihter in + * pjproject or Asterisk. Other places are reconstituting subscriptions + * after a restart (which could never work for a websocket connection anyway), + * received MESSAGE requests to set PJSIP_TRANSPORT, and most importantly + * by pjproject when generating the Via header. + */ + newtransport->transport.type_name = ast_websocket_is_secure(newtransport->ws_session) + ? "WSS" : "WS"; + + ws_addr_str = ast_sockaddr_stringify(ast_websocket_remote_address(newtransport->ws_session)); + ast_debug(4, "Creating websocket transport for %s:%s\n", + newtransport->transport.type_name, ws_addr_str); + + pj_sockaddr_parse(pj_AF_UNSPEC(), 0, pj_cstr(&buf, ws_addr_str), &newtransport->transport.key.rem_addr); newtransport->transport.key.rem_addr.addr.sa_family = pj_AF_INET(); - newtransport->transport.key.type = ast_websocket_is_secure(newtransport->ws_session) ? transport_type_wss : transport_type_ws; + newtransport->transport.key.type = transport_type_wss; newtransport->transport.addr_len = pj_sockaddr_get_len(&newtransport->transport.key.rem_addr); @@ -196,7 +210,6 @@ static int transport_create(void *data) newtransport->transport.local_name.host.slen = pj_ansi_strlen(newtransport->transport.local_name.host.ptr); newtransport->transport.local_name.port = pj_sockaddr_get_port(&newtransport->transport.key.rem_addr); - newtransport->transport.type_name = (char *)pjsip_transport_get_type_name(newtransport->transport.key.type); newtransport->transport.flag = pjsip_transport_get_flag_from_type((pjsip_transport_type_e)newtransport->transport.key.type); newtransport->transport.info = (char *)pj_pool_alloc(newtransport->transport.pool, 64); @@ -382,19 +395,27 @@ static pj_bool_t websocket_on_rx_msg(pjsip_rx_data *rdata) long type = rdata->tp_info.transport->key.type; - if (type != (long)transport_type_ws && type != (long)transport_type_wss) { + if (type != (long) transport_type_wss) { return PJ_FALSE; } - if ((contact = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT, NULL)) && !contact->star && - (PJSIP_URI_SCHEME_IS_SIP(contact->uri) || PJSIP_URI_SCHEME_IS_SIPS(contact->uri))) { + contact = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT, NULL); + if (contact + && !contact->star + && (PJSIP_URI_SCHEME_IS_SIP(contact->uri) || PJSIP_URI_SCHEME_IS_SIPS(contact->uri))) { pjsip_sip_uri *uri = pjsip_uri_get_uri(contact->uri); + const pj_str_t *txp_str = &STR_WS; + + ast_debug(4, "%s re-writing Contact URI from %.*s:%d%s%.*s to %s:%d;transport=%s\n", + pjsip_rx_data_get_info(rdata), + (int)pj_strlen(&uri->host), pj_strbuf(&uri->host), uri->port, + pj_strlen(&uri->transport_param) ? ";transport=" : "", + (int)pj_strlen(&uri->transport_param), pj_strbuf(&uri->transport_param), + rdata->pkt_info.src_name ?: "", rdata->pkt_info.src_port, pj_strbuf(txp_str)); pj_cstr(&uri->host, rdata->pkt_info.src_name); uri->port = rdata->pkt_info.src_port; - ast_debug(4, "Re-wrote Contact URI host/port to %.*s:%d\n", - (int)pj_strlen(&uri->host), pj_strbuf(&uri->host), uri->port); - pj_strdup(rdata->tp_info.pool, &uri->transport_param, &STR_WS); + pj_strdup(rdata->tp_info.pool, &uri->transport_param, txp_str); } rdata->msg_info.via->rport_param = 0; @@ -429,8 +450,16 @@ static int load_module(void) { CHECK_PJSIP_MODULE_LOADED(); - pjsip_transport_register_type(PJSIP_TRANSPORT_RELIABLE, "WS", 5060, &transport_type_ws); - pjsip_transport_register_type(PJSIP_TRANSPORT_RELIABLE | PJSIP_TRANSPORT_SECURE, "WS", 5060, &transport_type_wss); + /* + * We only need one transport type defined. Firefox and Chrome + * do not support anything other than secure websockets anymore. + * + * Also we really cannot have two transports with the same name + * because it would be ambiguous. Outgoing requests may try to + * find the transport by name and pjproject only finds the first + * one registered. + */ + pjsip_transport_register_type(PJSIP_TRANSPORT_RELIABLE | PJSIP_TRANSPORT_SECURE, "ws", 5060, &transport_type_wss); if (ast_sip_register_service(&websocket_module) != PJ_SUCCESS) { return AST_MODULE_LOAD_DECLINE;