/*! * \internal * \brief Set an ast_party_id structure based on data in a Remote-Party-ID header * * This makes use of \ref set_id_from_hdr for setting name and number. It uses * the privacy and screen parameters in order to set presentation information. * * \param rdata The incoming message * \param[out] id The ID to set * \retval 0 Succesfully set the party ID * \retval non-zero Could not set the party ID */ static int set_id_from_rpid(pjsip_rx_data *rdata, struct ast_party_id *id) { static const pj_str_t rpid_str = { "Remote-Party-ID", 15 }; static const pj_str_t privacy_str = { "privacy", 7 }; static const pj_str_t screen_str = { "screen", 6 }; pjsip_fromto_hdr *rpid_hdr = get_id_header(rdata, &rpid_str); pjsip_param *screen; pjsip_param *privacy; if (!rpid_hdr) { return -1; } set_id_from_hdr(rpid_hdr, id); if (!id->number.valid) { return -1; } privacy = pjsip_param_find(&rpid_hdr->other_param, &privacy_str); screen = pjsip_param_find(&rpid_hdr->other_param, &screen_str); if (privacy && !pj_stricmp2(&privacy->value, "full")) { id->number.presentation |= AST_PRES_RESTRICTED; id->name.presentation |= AST_PRES_RESTRICTED; } if (screen && !pj_stricmp2(&screen->value, "yes")) { id->number.presentation |= AST_PRES_USER_NUMBER_PASSED_SCREEN; id->name.presentation |= AST_PRES_USER_NUMBER_PASSED_SCREEN; } return 0; }
static pjsip_authorization_hdr* pjsip_authorization_hdr_clone( pj_pool_t *pool, const pjsip_authorization_hdr *rhs) { /* This function also serves Proxy-Authorization header. */ pjsip_authorization_hdr *hdr; if (rhs->type == PJSIP_H_AUTHORIZATION) hdr = pjsip_authorization_hdr_create(pool); else hdr = pjsip_proxy_authorization_hdr_create(pool); pj_strdup(pool, &hdr->scheme, &rhs->scheme); if (pj_stricmp2(&hdr->scheme, "digest") == 0) { pj_strdup(pool, &hdr->credential.digest.username, &rhs->credential.digest.username); pj_strdup(pool, &hdr->credential.digest.realm, &rhs->credential.digest.realm); pj_strdup(pool, &hdr->credential.digest.nonce, &rhs->credential.digest.nonce); pj_strdup(pool, &hdr->credential.digest.uri, &rhs->credential.digest.uri); pj_strdup(pool, &hdr->credential.digest.response, &rhs->credential.digest.response); pj_strdup(pool, &hdr->credential.digest.algorithm, &rhs->credential.digest.algorithm); pj_strdup(pool, &hdr->credential.digest.cnonce, &rhs->credential.digest.cnonce); pj_strdup(pool, &hdr->credential.digest.opaque, &rhs->credential.digest.opaque); pj_strdup(pool, &hdr->credential.digest.qop, &rhs->credential.digest.qop); pj_strdup(pool, &hdr->credential.digest.nc, &rhs->credential.digest.nc); pjsip_param_clone(pool, &hdr->credential.digest.other_param, &rhs->credential.digest.other_param); } else if (pj_stricmp2(&hdr->scheme, "pgp") == 0) { pj_assert(0); return NULL; } else { pj_assert(0); return NULL; } return hdr; }
static pjsip_www_authenticate_hdr* pjsip_www_authenticate_hdr_clone( pj_pool_t *pool, const pjsip_www_authenticate_hdr *rhs) { /* This function also serves Proxy-Authenticate header. */ pjsip_www_authenticate_hdr *hdr; if (rhs->type == PJSIP_H_WWW_AUTHENTICATE) hdr = pjsip_www_authenticate_hdr_create(pool); else hdr = pjsip_proxy_authenticate_hdr_create(pool); pj_strdup(pool, &hdr->scheme, &rhs->scheme); if (pj_stricmp2(&hdr->scheme, "digest") == 0) { pj_strdup(pool, &hdr->challenge.digest.realm, &rhs->challenge.digest.realm); pj_strdup(pool, &hdr->challenge.digest.domain, &rhs->challenge.digest.domain); pj_strdup(pool, &hdr->challenge.digest.nonce, &rhs->challenge.digest.nonce); pj_strdup(pool, &hdr->challenge.digest.opaque, &rhs->challenge.digest.opaque); hdr->challenge.digest.stale = rhs->challenge.digest.stale; pj_strdup(pool, &hdr->challenge.digest.algorithm, &rhs->challenge.digest.algorithm); pj_strdup(pool, &hdr->challenge.digest.qop, &rhs->challenge.digest.qop); pjsip_param_clone(pool, &hdr->challenge.digest.other_param, &rhs->challenge.digest.other_param); } else if (pj_stricmp2(&hdr->scheme, "pgp") == 0) { pj_assert(0); return NULL; } else { pj_assert(0); return NULL; } return hdr; }
static int pjsip_www_authenticate_hdr_print( pjsip_www_authenticate_hdr *hdr, char *buf, pj_size_t size) { int printed; char *startbuf = buf; char *endbuf = buf + size; copy_advance(buf, hdr->name); *buf++ = ':'; *buf++ = ' '; copy_advance(buf, hdr->scheme); *buf++ = ' '; if (pj_stricmp2(&hdr->scheme, "digest") == 0) printed = print_digest_challenge(&hdr->challenge.digest, buf, endbuf - buf); else if (pj_stricmp2(&hdr->scheme, "pgp") == 0) printed = print_pgp_challenge(&hdr->challenge.pgp, buf, endbuf - buf); else { pj_assert(0); return -1; } if (printed == -1) return -1; buf += printed; *buf = '\0'; return (int)(buf-startbuf); }
/* * This function is called to get the password for the specified username. * This function is also used to check whether the username is valid. */ pj_status_t pj_turn_get_password(const pj_stun_msg *msg, void *user_data, const pj_str_t *realm, const pj_str_t *username, pj_pool_t *pool, pj_stun_passwd_type *data_type, pj_str_t *data) { unsigned i; PJ_UNUSED_ARG(msg); PJ_UNUSED_ARG(user_data); PJ_UNUSED_ARG(pool); if (pj_stricmp2(realm, g_realm)) { LOG((THIS_FILE, "auth error: invalid realm '%.*s'", (int)realm->slen, realm->ptr)); return PJ_EINVAL; } for (i=0; i<PJ_ARRAY_SIZE(g_cred); ++i) { if (pj_stricmp2(username, g_cred[i].username) == 0) { *data_type = PJ_STUN_PASSWD_PLAIN; *data = pj_str(g_cred[i].passwd); return PJ_SUCCESS; } } LOG((THIS_FILE, "auth error: user '%.*s' not found", (int)username->slen, username->ptr)); return PJ_ENOTFOUND; }
pjsip_hdr* parse_hdr_p_charging_function_addresses(pjsip_parse_ctx* ctx) { // The P-Charging-Function-Addresses header has the following ABNF: // // P-Charging-Addr = "P-Charging-Function-Addresses" HCOLON // charge-addr-params // *(SEMI charge-addr-params) // charge-addr-params = ccf / ecf / generic-param // ccf = "ccf" EQUAL gen-value // ecf = "ecf" EQUAL gen-value // // Where the ccf and ecf elements may be repeated to specify backup CDFs // for redundancy. pj_pool_t* pool = ctx->pool; pj_scanner* scanner = ctx->scanner; pjsip_p_c_f_a_hdr* hdr = pjsip_p_c_f_a_hdr_create(pool); pj_str_t name; pj_str_t value; pjsip_param *param; for (;;) { pjsip_parse_param_imp(scanner, pool, &name, &value, PJSIP_PARSE_REMOVE_QUOTE); param = PJ_POOL_ALLOC_T(pool, pjsip_param); param->name = name; param->value = value; if (!pj_stricmp2(&name, "ccf")) { pj_list_insert_before(&hdr->ccf, param); } else if (!pj_stricmp2(&name, "ecf")) { pj_list_insert_before(&hdr->ecf, param); } else { pj_list_insert_before(&hdr->other_param, param); } // We might need to swallow the ';'. if (!pj_scan_is_eof(scanner) && *scanner->curptr == ';') { pj_scan_get_char(scanner); } // If we're EOF or looking at a newline, we're done. pj_scan_skip_whitespace(scanner); if (pj_scan_is_eof(scanner) || (*scanner->curptr == '\r') || (*scanner->curptr == '\n')) { break; } } // We're done parsing this header. pjsip_parse_end_hdr_imp(scanner); return (pjsip_hdr*)hdr; }
pjsip_hdr* parse_hdr_session_expires(pjsip_parse_ctx* ctx) { pj_pool_t* pool = ctx->pool; pj_scanner* scanner = ctx->scanner; pjsip_session_expires_hdr* hdr = pjsip_session_expires_hdr_create(pool); const pjsip_parser_const_t* pc = pjsip_parser_const(); // Parse the expiry number pj_str_t int_str; pj_scan_get(scanner, &pc->pjsip_DIGIT_SPEC, &int_str); hdr->expires = pj_strtoul(&int_str); pj_scan_skip_whitespace(scanner); // Parse the rest of the params, looking for the refresher param while (*scanner->curptr == ';') { // Consume the ';'. pj_scan_get_char(scanner); pj_scan_skip_whitespace(scanner); // Parse the param. pj_str_t name; pj_str_t value; pjsip_parse_param_imp(scanner, pool, &name, &value, PJSIP_PARSE_REMOVE_QUOTE); if (!pj_stricmp2(&name, "refresher")) { if (!pj_stricmp2(&value, "uac")) { hdr->refresher = SESSION_REFRESHER_UAC; } else if (!pj_stricmp2(&value, "uas")) { hdr->refresher = SESSION_REFRESHER_UAS; } else { PJ_THROW(PJSIP_SYN_ERR_EXCEPTION); // LCOV_EXCL_LINE } } else { pjsip_param* param = PJ_POOL_ALLOC_T(pool, pjsip_param); param->name = name; param->value = value; pj_list_insert_before(&hdr->other_param, param); } } // We're done parsing this header. pjsip_parse_end_hdr_imp(scanner); return (pjsip_hdr*)hdr; }
static int has_diversion_reason(pjsip_rx_data *rdata) { pjsip_param *reason; pjsip_fromto_hdr *hdr = get_diversion_header(rdata); if (!hdr) { return 0; } reason = get_diversion_reason(hdr); return reason && (!pj_stricmp2(&reason->value, SEND_TO_VM_REDIRECT_QUOTED_VALUE) || !pj_stricmp2(&reason->value, SEND_TO_VM_REDIRECT_VALUE)); }
/** * This method is to parse and add the choice type * argument values to command structure. **/ static pj_status_t add_choice_node(pj_cli_t *cli, pj_xml_node *xml_node, pj_cli_arg_spec *arg, pj_cli_get_dyn_choice get_choice) { pj_xml_node *choice_node; pj_xml_node *sub_node; pj_cli_arg_choice_val choice_values[PJ_CLI_MAX_CHOICE_VAL]; pj_status_t status = PJ_SUCCESS; sub_node = xml_node; arg->type = PJ_CLI_ARG_CHOICE; arg->get_dyn_choice = get_choice; choice_node = sub_node->node_head.next; while (choice_node != (pj_xml_node*)&sub_node->node_head) { pj_xml_attr *choice_attr; unsigned *stat_cnt = &arg->stat_choice_cnt; pj_cli_arg_choice_val *choice_val = &choice_values[*stat_cnt]; pj_bzero(choice_val, sizeof(*choice_val)); choice_attr = choice_node->attr_head.next; while (choice_attr != &choice_node->attr_head) { if (!pj_stricmp2(&choice_attr->name, "value")) { pj_strassign(&choice_val->value, &choice_attr->value); } else if (!pj_stricmp2(&choice_attr->name, "desc")) { pj_strassign(&choice_val->desc, &choice_attr->value); } choice_attr = choice_attr->next; } if (++(*stat_cnt) >= PJ_CLI_MAX_CHOICE_VAL) break; choice_node = choice_node->next; } if (arg->stat_choice_cnt > 0) { unsigned i; arg->stat_choice_val = (pj_cli_arg_choice_val *) pj_pool_zalloc(cli->pool, arg->stat_choice_cnt * sizeof(pj_cli_arg_choice_val)); for (i = 0; i < arg->stat_choice_cnt; i++) { pj_strdup(cli->pool, &arg->stat_choice_val[i].value, &choice_values[i].value); pj_strdup(cli->pool, &arg->stat_choice_val[i].desc, &choice_values[i].desc); } } return status; }
int main(int argc, char *argv[]) { int rc; int interractive = 0; boost(); init_signals(); while (argc > 1) { char *arg = argv[--argc]; if (*arg=='-' && *(arg+1)=='i') { interractive = 1; } else if (*arg=='-' && *(arg+1)=='p') { pj_str_t port = pj_str(argv[--argc]); param_echo_port = pj_strtoul(&port); } else if (*arg=='-' && *(arg+1)=='s') { param_echo_server = argv[--argc]; } else if (*arg=='-' && *(arg+1)=='t') { pj_str_t type = pj_str(argv[--argc]); if (pj_stricmp2(&type, "tcp")==0) param_echo_sock_type = pj_SOCK_STREAM(); else if (pj_stricmp2(&type, "udp")==0) param_echo_sock_type = pj_SOCK_DGRAM(); else { PJ_LOG(3,("", "error: unknown socket type %s", type.ptr)); return 1; } } } rc = test_main(); if (interractive) { char s[10]; puts(""); puts("Press <ENTER> to exit"); if (!fgets(s, sizeof(s), stdin)) return rc; } return rc; }
/// Get private ID from a received message by checking the Authorization /// header. If that uses the Digest scheme and contains a non-empty /// username, it puts that username into id and returns true; /// otherwise returns false. bool get_private_id(pjsip_rx_data* rdata, std::string& id) { bool success = false; pjsip_authorization_hdr* auth_hdr = (pjsip_authorization_hdr*) pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_AUTHORIZATION, NULL); if (auth_hdr != NULL) { if (pj_stricmp2(&auth_hdr->scheme, "digest") == 0) { id = PJUtils::pj_str_to_string(&auth_hdr->credential.digest.username); if (!id.empty()) { success = true; } } else { // LCOV_EXCL_START LOG_WARNING("Unsupported scheme \"%.*s\" in Authorization header when determining private ID - ignoring", auth_hdr->scheme.slen, auth_hdr->scheme.ptr); // LCOV_EXCL_STOP } } return success; }
void Sdp::setActiveRemoteSdpSession(const pjmedia_sdp_session *sdp) { activeRemoteSession_ = (pjmedia_sdp_session*) sdp; if (!sdp) { ERROR("Remote sdp is NULL while parsing telephone event attribute"); return; } for (unsigned i = 0; i < sdp->media_count; i++) if (pj_stricmp2(&sdp->media[i]->desc.media, "audio") == 0) { pjmedia_sdp_media *r_media = sdp->media[i]; static const pj_str_t STR_TELEPHONE_EVENT = { (char*) "telephone-event", 15}; pjmedia_sdp_attr *attribute = pjmedia_sdp_attr_find(r_media->attr_count, r_media->attr, &STR_TELEPHONE_EVENT, NULL); if (attribute != NULL) { pjmedia_sdp_rtpmap *rtpmap; pjmedia_sdp_attr_to_rtpmap(memPool_, attribute, &rtpmap); telephoneEventPayload_ = pj_strtoul(&rtpmap->pt); } return; } ERROR("Could not found dtmf event from remote sdp"); }
/*! * \internal * \brief Set an ast_party_id structure based on data in a P-Asserted-Identity header * * This makes use of \ref set_id_from_hdr for setting name and number. It uses * the contents of a Privacy header in order to set presentation information. * * \param rdata The incoming message * \param[out] id The ID to set * \retval 0 Successfully set the party ID * \retval non-zero Could not set the party ID */ static int set_id_from_pai(pjsip_rx_data *rdata, struct ast_party_id *id) { static const pj_str_t pai_str = { "P-Asserted-Identity", 19 }; static const pj_str_t privacy_str = { "Privacy", 7 }; pjsip_fromto_hdr *pai_hdr = get_id_header(rdata, &pai_str); pjsip_generic_string_hdr *privacy; if (!pai_hdr) { return -1; } set_id_from_hdr(pai_hdr, id); if (!id->number.valid) { return -1; } privacy = pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &privacy_str, NULL); if (privacy && !pj_stricmp2(&privacy->hvalue, "id")) { id->number.presentation = AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED; id->name.presentation = AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED; } else { id->number.presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED; id->name.presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED; } return 0; }
/* * Generate default attribute. */ static pj_status_t ilbc_default_attr (pjmedia_codec_factory *factory, const pjmedia_codec_info *id, pjmedia_codec_param *attr ) { PJ_UNUSED_ARG(factory); PJ_ASSERT_RETURN(factory==&ilbc_factory.base, PJ_EINVAL); PJ_UNUSED_ARG(id); PJ_ASSERT_RETURN(pj_stricmp2(&id->encoding_name, "iLBC")==0, PJ_EINVAL); pj_bzero(attr, sizeof(pjmedia_codec_param)); attr->info.clock_rate = CLOCK_RATE; attr->info.channel_cnt = 1; attr->info.avg_bps = ilbc_factory.bps; attr->info.max_bps = 15200; attr->info.pcm_bits_per_sample = 16; attr->info.frm_ptime = (short)ilbc_factory.mode; attr->info.pt = PJMEDIA_RTP_PT_ILBC; attr->setting.frm_per_pkt = 1; attr->setting.vad = 1; attr->setting.plc = 1; attr->setting.penh = 1; attr->setting.dec_fmtp.cnt = 1; attr->setting.dec_fmtp.param[0].name = STR_MODE; if (ilbc_factory.mode == 30) attr->setting.dec_fmtp.param[0].val = pj_str("30"); else attr->setting.dec_fmtp.param[0].val = pj_str("20"); return PJ_SUCCESS; }
static int has_diversion_reason(pjsip_rx_data *rdata) { pjsip_param *reason; pjsip_fromto_hdr *hdr = get_diversion_header(rdata); return hdr && (reason = get_diversion_reason(hdr)) && !pj_stricmp2(&reason->value, SEND_TO_VM_REDIRECT_VALUE); }
static int has_call_feature(pjsip_rx_data *rdata) { static const pj_str_t call_feature_str = { "X-Digium-Call-Feature", 21 }; pjsip_generic_string_hdr *hdr = pjsip_msg_find_hdr_by_name( rdata->msg_info.msg, &call_feature_str, NULL); return hdr && !pj_stricmp2(&hdr->hvalue, SEND_TO_VM_HEADER_VALUE); }
/** * This method is to parse and add the argument attribute to command structure. **/ static pj_status_t add_arg_node(pj_cli_t *cli, pj_xml_node *xml_node, pj_cli_cmd_spec *cmd, pj_cli_arg_spec *arg, pj_cli_get_dyn_choice get_choice) { pj_xml_attr *attr; pj_status_t status = PJ_SUCCESS; pj_xml_node *sub_node = xml_node; if (cmd->arg_cnt >= PJ_CLI_MAX_ARGS) return PJ_CLI_ETOOMANYARGS; pj_bzero(arg, sizeof(*arg)); attr = sub_node->attr_head.next; arg->optional = PJ_FALSE; arg->validate = PJ_TRUE; while (attr != &sub_node->attr_head) { if (!pj_stricmp2(&attr->name, "name")) { pj_strassign(&arg->name, &attr->value); } else if (!pj_stricmp2(&attr->name, "id")) { arg->id = pj_strtol(&attr->value); } else if (!pj_stricmp2(&attr->name, "type")) { if (!pj_stricmp2(&attr->value, "text")) { arg->type = PJ_CLI_ARG_TEXT; } else if (!pj_stricmp2(&attr->value, "int")) { arg->type = PJ_CLI_ARG_INT; } else if (!pj_stricmp2(&attr->value, "choice")) { /* Get choice value */ add_choice_node(cli, xml_node, arg, get_choice); } } else if (!pj_stricmp2(&attr->name, "desc")) { pj_strassign(&arg->desc, &attr->value); } else if (!pj_stricmp2(&attr->name, "optional")) { if (!pj_strcmp2(&attr->value, "1")) { arg->optional = PJ_TRUE; } } else if (!pj_stricmp2(&attr->name, "validate")) { if (!pj_strcmp2(&attr->value, "1")) { arg->validate = PJ_TRUE; } else { arg->validate = PJ_FALSE; } } attr = attr->next; } cmd->arg_cnt++; return status; }
static void on_response(pj_http_req *req, const pj_http_resp *resp) { unsigned i; PJ_UNUSED_ARG(req); PJ_LOG(3,(THIS_FILE, "%.*s %d %.*s", (int)resp->version.slen, resp->version.ptr, resp->status_code, (int)resp->reason.slen, resp->reason.ptr)); for (i=0; i<resp->headers.count; ++i) { const pj_http_header_elmt *h = &resp->headers.header[i]; if (!pj_stricmp2(&h->name, "Content-Length") || !pj_stricmp2(&h->name, "Content-Type")) { PJ_LOG(3,(THIS_FILE, "%.*s: %.*s", (int)h->name.slen, h->name.ptr, (int)h->value.slen, h->value.ptr)); } } }
static void get_opus_channels_and_clock_rate(const pjmedia_codec_fmtp *enc_fmtp, const pjmedia_codec_fmtp *dec_fmtp, unsigned *channel_cnt, unsigned *clock_rate) { unsigned i; unsigned enc_channel_cnt = 0, local_channel_cnt = 0; unsigned enc_clock_rate = 0, local_clock_rate = 0; for (i = 0; i < dec_fmtp->cnt; ++i) { if (!pj_stricmp2(&dec_fmtp->param[i].name, "sprop-maxcapturerate")) { local_clock_rate = (unsigned)pj_strtoul(&dec_fmtp->param[i].val); } else if (!pj_stricmp2(&dec_fmtp->param[i].name, "sprop-stereo")) { local_channel_cnt = (unsigned)pj_strtoul(&dec_fmtp->param[i].val); local_channel_cnt = (local_channel_cnt > 0) ? 2 : 1; } } if (!local_clock_rate) local_clock_rate = *clock_rate; if (!local_channel_cnt) local_channel_cnt = *channel_cnt; for (i = 0; i < enc_fmtp->cnt; ++i) { if (!pj_stricmp2(&enc_fmtp->param[i].name, "maxplaybackrate")) { enc_clock_rate = (unsigned)pj_strtoul(&enc_fmtp->param[i].val); } else if (!pj_stricmp2(&enc_fmtp->param[i].name, "stereo")) { enc_channel_cnt = (unsigned)pj_strtoul(&enc_fmtp->param[i].val); enc_channel_cnt = (enc_channel_cnt > 0) ? 2 : 1; } } /* The default is a standard mono session with 48000 Hz clock rate * (RFC 7587, section 7) */ if (!enc_clock_rate) enc_clock_rate = 48000; if (!enc_channel_cnt) enc_channel_cnt = 1; *clock_rate = (enc_clock_rate < local_clock_rate) ? enc_clock_rate : local_clock_rate; *channel_cnt = (enc_channel_cnt < local_channel_cnt) ? enc_channel_cnt : local_channel_cnt; }
/// Resolves the next hop target of the SIP message void PJUtils::resolve_next_hop(pjsip_tx_data* tdata, int retries, std::vector<AddrInfo>& servers, SAS::TrailId trail) { // Get the next hop URI from the message and parse out the destination, port // and transport. pjsip_sip_uri* next_hop = (pjsip_sip_uri*)PJUtils::next_hop(tdata->msg); std::string name = std::string(next_hop->host.ptr, next_hop->host.slen); int port = next_hop->port; int transport = -1; if (pj_stricmp2(&next_hop->transport_param, "TCP") == 0) { transport = IPPROTO_TCP; } else if (pj_stricmp2(&next_hop->transport_param, "UDP") == 0) { transport = IPPROTO_UDP; } if (retries == 0) { // Used default number of retries. retries = DEFAULT_RETRIES; } stack_data.sipresolver->resolve(name, stack_data.addr_family, port, transport, retries, servers, trail); LOG_INFO("Resolved destination URI %s to %d servers", PJUtils::uri_to_string(PJSIP_URI_IN_ROUTING_HDR, (pjsip_uri*)next_hop).c_str(), servers.size()); }
void Sdp::getRemoteSdpCryptoFromOffer(const pjmedia_sdp_session* remote_sdp, CryptoOffer& crypto_offer) { for (unsigned i = 0; i < remote_sdp->media_count; ++i) { pjmedia_sdp_media *media = remote_sdp->media[i]; for (unsigned j = 0; j < media->attr_count; j++) { pjmedia_sdp_attr *attribute = media->attr[j]; // @TODO our parser require the "a=crypto:" to be present if (pj_stricmp2(&attribute->name, "crypto") == 0) crypto_offer.push_back("a=crypto:" + std::string(attribute->value.ptr, attribute->value.slen)); } } }
static int parse_dtls_attrib(struct ast_sip_session_media *session_media, const struct pjmedia_sdp_media *stream) { int i; struct ast_rtp_engine_dtls *dtls = ast_rtp_instance_get_dtls(session_media->rtp); for (i = 0; i < stream->attr_count; i++) { pjmedia_sdp_attr *attr = stream->attr[i]; pj_str_t *value; if (!attr->value.ptr) { continue; } value = pj_strtrim(&attr->value); if (!pj_strcmp2(&attr->name, "setup")) { if (!pj_stricmp2(value, "active")) { dtls->set_setup(session_media->rtp, AST_RTP_DTLS_SETUP_ACTIVE); } else if (!pj_stricmp2(value, "passive")) { dtls->set_setup(session_media->rtp, AST_RTP_DTLS_SETUP_PASSIVE); } else if (!pj_stricmp2(value, "actpass")) { dtls->set_setup(session_media->rtp, AST_RTP_DTLS_SETUP_ACTPASS); } else if (!pj_stricmp2(value, "holdconn")) { dtls->set_setup(session_media->rtp, AST_RTP_DTLS_SETUP_HOLDCONN); } else { ast_log(LOG_WARNING, "Unsupported setup attribute value '%*s'\n", (int)value->slen, value->ptr); } } else if (!pj_strcmp2(&attr->name, "connection")) { if (!pj_stricmp2(value, "new")) { dtls->reset(session_media->rtp); } else if (!pj_stricmp2(value, "existing")) { /* Do nothing */ } else { ast_log(LOG_WARNING, "Unsupported connection attribute value '%*s'\n", (int)value->slen, value->ptr); } } else if (!pj_strcmp2(&attr->name, "fingerprint")) { char hash_value[256], hash[32]; char fingerprint_text[value->slen + 1]; ast_copy_pj_str(fingerprint_text, value, sizeof(fingerprint_text)); if (sscanf(fingerprint_text, "%31s %255s", hash, hash_value) == 2) { if (!strcasecmp(hash, "sha-1")) { dtls->set_fingerprint(session_media->rtp, AST_RTP_DTLS_HASH_SHA1, hash_value); } else if (!strcasecmp(hash, "sha-256")) { dtls->set_fingerprint(session_media->rtp, AST_RTP_DTLS_HASH_SHA256, hash_value); } else { ast_log(LOG_WARNING, "Unsupported fingerprint hash type '%s'\n", hash); } } } } ast_set_flag(session_media->srtp, AST_SRTP_CRYPTO_OFFER_OK); return 0; }
void Sdp::setMediaTransportInfoFromRemoteSdp() { if (!activeRemoteSession_) { ERROR("Remote sdp is NULL while parsing media"); return; } for (unsigned i = 0; i < activeRemoteSession_->media_count; ++i) if (pj_stricmp2(&activeRemoteSession_->media[i]->desc.media, "audio") == 0) { setRemoteAudioPort(activeRemoteSession_->media[i]->desc.port); setRemoteIP(std::string(activeRemoteSession_->conn->addr.ptr, activeRemoteSession_->conn->addr.slen)); return; } ERROR("No remote sdp media found in the remote offer"); }
static pjsip_authorization_hdr *get_auth_header(pjsip_rx_data *rdata, char *username, size_t username_size, char *realm, size_t realm_size, pjsip_authorization_hdr *start) { pjsip_authorization_hdr *header; header = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_AUTHORIZATION, start); if (!header || pj_stricmp2(&header->scheme, "digest")) { return NULL; } ast_copy_pj_str(username, &header->credential.digest.username, username_size); ast_copy_pj_str(realm, &header->credential.digest.realm, realm_size); return header; }
static int get_crypto_idx(const pj_str_t* crypto_name) { int i; int cs_cnt = sizeof(crypto_suites)/sizeof(crypto_suites[0]); /* treat unspecified crypto_name as crypto 'NULL' */ if (crypto_name->slen == 0) return 0; for (i=0; i<cs_cnt; ++i) { if (!pj_stricmp2(crypto_name, crypto_suites[i].name)) return i; } return -1; }
/* * Verify that valid SIP url is given. */ static pj_status_t verify_sip_url(char *url) { pjsip_uri *p; pj_pool_t *pool; int len = (url ? strlen(url) : 0); if (!len) return -1; pool = pj_pool_create(global.pf, "check%p", 1024, 0, NULL); if (!pool) return -1; p = pjsip_parse_uri(pool, url, len, 0); if (!p || pj_stricmp2(pjsip_uri_get_scheme(p), "sip") != 0) p = NULL; pj_pool_release(pool); return p ? 0 : -1; }
/* * This function will be called to verify that the NONCE given * in the message can be accepted. If this callback returns * PJ_FALSE, 438 (Stale Nonce) response will be created. */ pj_bool_t pj_turn_verify_nonce(const pj_stun_msg *msg, void *user_data, const pj_str_t *realm, const pj_str_t *username, const pj_str_t *nonce) { PJ_UNUSED_ARG(msg); PJ_UNUSED_ARG(user_data); PJ_UNUSED_ARG(realm); PJ_UNUSED_ARG(username); if (pj_stricmp2(nonce, THE_NONCE)) { LOG((THIS_FILE, "auth error: invalid nonce '%.*s'", (int)nonce->slen, nonce->ptr)); return PJ_FALSE; } return PJ_TRUE; }
/*! * \internal * \brief Search list for nth occurrence of specific header. */ static pjsip_hdr *find_header(struct hdr_list *list, const char *header_name, int header_number) { struct hdr_list_entry *le; pjsip_hdr *hdr = NULL; int i = 1; if (!list || ast_strlen_zero(header_name) || header_number < 1) { return NULL; } AST_LIST_TRAVERSE(list, le, nextptr) { if (pj_stricmp2(&le->hdr->name, header_name) == 0 && i++ == header_number) { hdr = le->hdr; break; } } return hdr; }
/*! * \internal * \brief Implements PJSIP_HEADER 'remove' by finding the specified header and removing it. * * Retrieve the header_datastore from the session. Fail if it doesn't exist. * If the header_name is exactly '*', the entire list is simply destroyed. * Otherwise search the list for the matching header name which may be a partial name. */ static int remove_header(void *obj) { struct header_data *data = obj; size_t len = strlen(data->header_name); struct hdr_list *list; struct hdr_list_entry *le; int removed_count = 0; RAII_VAR(struct ast_datastore *, datastore, ast_sip_session_get_datastore(data->channel->session, header_datastore.type), ao2_cleanup); if (!datastore || !datastore->data) { ast_log(AST_LOG_ERROR, "No headers had been previously added to this session.\n"); return -1; } list = datastore->data; AST_LIST_TRAVERSE_SAFE_BEGIN(list, le, nextptr) { if (data->header_name[len - 1] == '*') { if (pj_strnicmp2(&le->hdr->name, data->header_name, len - 1) == 0) { AST_LIST_REMOVE_CURRENT(nextptr); removed_count++; } } else { if (pj_stricmp2(&le->hdr->name, data->header_name) == 0) { AST_LIST_REMOVE_CURRENT(nextptr); removed_count++; } } } AST_LIST_TRAVERSE_SAFE_END; if (data->buf && data->len) { snprintf(data->buf, data->len, "%d", removed_count); } return 0; }
/* * Verify that valid SIP url is given. */ static pj_status_t verify_sip_url(const char *c_url) { pjsip_uri *p; pj_pool_t *pool; char *url; int len = (c_url ? pj_ansi_strlen(c_url) : 0); if (!len) return -1; pool = pj_pool_create(&app.cp.factory, "check%p", 1024, 0, NULL); if (!pool) return PJ_ENOMEM; url = pj_pool_alloc(pool, len+1); pj_ansi_strcpy(url, c_url); url[len] = '\0'; p = pjsip_parse_uri(pool, url, len, 0); if (!p || pj_stricmp2(pjsip_uri_get_scheme(p), "sip") != 0) p = NULL; pj_pool_release(pool); return p ? 0 : -1; }