Skip to content

Commit b917037

Browse files
committed
Fix for SIP plugin not offering SRTP in response to offerless INVITEs (#3618)
1 parent b6d9710 commit b917037

File tree

1 file changed

+52
-21
lines changed

1 file changed

+52
-21
lines changed

plugins/janus_sip.c

Lines changed: 52 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,7 @@
314314
{
315315
"request" : "progress",
316316
"srtp" : "<whether to mandate (sdes_mandatory) or offer (sdes_optional) SRTP support; optional>",
317+
"srtp_profile" : "<SRTP profile to negotiate, in case SRTP is offered; optional, and only needed in response to offerless-INVITEs>",
317318
"headers" : "<object with key/value mappings (header name/value), to specify custom headers to add to the SIP OK; optional>"
318319
"autoaccept_reinvites" : <true|false, whether we should blindly accept re-INVITEs with a 200 OK instead of relaying the SDP to the browser; optional, TRUE by default>
319320
}
@@ -334,6 +335,7 @@
334335
{
335336
"request" : "accept",
336337
"srtp" : "<whether to mandate (sdes_mandatory) or offer (sdes_optional) SRTP support; optional>",
338+
"srtp_profile" : "<SRTP profile to negotiate, in case SRTP is offered; optional, and only needed in response to offerless-INVITEs>",
337339
"headers" : "<object with key/value mappings (header name/value), to specify custom headers to add to the SIP OK; optional>"
338340
"autoaccept_reinvites" : <true|false, whether we should blindly accept re-INVITEs with a 200 OK instead of relaying the SDP to the browser; optional, TRUE by default>
339341
}
@@ -1011,11 +1013,13 @@ static struct janus_json_parameter call_parameters[] = {
10111013
};
10121014
static struct janus_json_parameter accept_parameters[] = {
10131015
{"srtp", JSON_STRING, 0},
1016+
{"srtp_profile", JSON_STRING, 0},
10141017
{"headers", JSON_OBJECT, 0},
10151018
{"autoaccept_reinvites", JANUS_JSON_BOOL, 0}
10161019
};
10171020
static struct janus_json_parameter progress_parameters[] = {
10181021
{"srtp", JSON_STRING, 0},
1022+
{"srtp_profile", JSON_STRING, 0},
10191023
{"headers", JSON_OBJECT, 0},
10201024
{"autoaccept_reinvites", JANUS_JSON_BOOL, 0}
10211025
};
@@ -4324,6 +4328,26 @@ static void *janus_sip_handler(void *data) {
43244328
}
43254329
if(error_code != 0)
43264330
goto error;
4331+
/* Any SDP to handle? if not, something's wrong */
4332+
const char *msg_sdp_type = json_string_value(json_object_get(msg->jsep, "type"));
4333+
const char *msg_sdp = json_string_value(json_object_get(msg->jsep, "sdp"));
4334+
if(!msg_sdp || !msg_sdp_type) {
4335+
JANUS_LOG(LOG_ERR, "Missing SDP\n");
4336+
error_code = JANUS_SIP_ERROR_MISSING_SDP;
4337+
g_snprintf(error_cause, 512, "Missing SDP");
4338+
goto error;
4339+
}
4340+
if(json_is_true(json_object_get(msg->jsep, "e2ee"))) {
4341+
/* Media is encrypted, but SIP endpoints will need unencrypted media frames */
4342+
JANUS_LOG(LOG_ERR, "Media encryption unsupported by this plugin\n");
4343+
error_code = JANUS_SIP_ERROR_INVALID_ELEMENT;
4344+
g_snprintf(error_cause, 512, "Media encryption unsupported by this plugin");
4345+
goto error;
4346+
}
4347+
/* This may be an SDP answer, or an SDP offer (answer to offerless INVITE) */
4348+
gboolean answer = !strcasecmp(msg_sdp_type, "answer");
4349+
/* Check if we need to involve SRTP */
4350+
janus_srtp_profile srtp_profile = JANUS_SRTP_AES128_CM_SHA1_80;
43274351
json_t *srtp = json_object_get(root, "srtp");
43284352
gboolean answer_srtp = FALSE;
43294353
if(srtp) {
@@ -4343,9 +4367,9 @@ static void *janus_sip_handler(void *data) {
43434367
}
43444368
}
43454369
gboolean has_srtp = TRUE;
4346-
if(session->media.has_audio)
4370+
if(session->media.has_audio && answer)
43474371
has_srtp = (has_srtp && session->media.has_srtp_remote_audio);
4348-
if(session->media.has_video)
4372+
if(session->media.has_video && answer)
43494373
has_srtp = (has_srtp && session->media.has_srtp_remote_video);
43504374
if(session->media.require_srtp && !has_srtp) {
43514375
JANUS_LOG(LOG_ERR, "Can't %s the call: SDES-SRTP required, but caller didn't offer it\n", progress ? "progress" : "accept");
@@ -4356,33 +4380,40 @@ static void *janus_sip_handler(void *data) {
43564380
answer_srtp = answer_srtp || session->media.has_srtp_remote_audio || session->media.has_srtp_remote_video;
43574381
json_t *aar = json_object_get(root, "autoaccept_reinvites");
43584382
session->media.autoaccept_reinvites = aar ? json_is_true(aar) : TRUE;
4359-
/* Any SDP to handle? if not, something's wrong */
4360-
const char *msg_sdp_type = json_string_value(json_object_get(msg->jsep, "type"));
4361-
const char *msg_sdp = json_string_value(json_object_get(msg->jsep, "sdp"));
4362-
if(!msg_sdp) {
4363-
JANUS_LOG(LOG_ERR, "Missing SDP\n");
4364-
error_code = JANUS_SIP_ERROR_MISSING_SDP;
4365-
g_snprintf(error_cause, 512, "Missing SDP");
4366-
goto error;
4367-
}
4368-
if(json_is_true(json_object_get(msg->jsep, "e2ee"))) {
4369-
/* Media is encrypted, but SIP endpoints will need unencrypted media frames */
4370-
JANUS_LOG(LOG_ERR, "Media encryption unsupported by this plugin\n");
4371-
error_code = JANUS_SIP_ERROR_INVALID_ELEMENT;
4372-
g_snprintf(error_cause, 512, "Media encryption unsupported by this plugin");
4373-
goto error;
4374-
}
43754383
/* Accept/Progress a call from another peer */
43764384
JANUS_LOG(LOG_VERB, "We're %s the call from %s\n", progress ? "progressing" : "accepting", session->callee);
4377-
gboolean answer = !strcasecmp(msg_sdp_type, "answer");
43784385
if(!answer) {
43794386
JANUS_LOG(LOG_VERB, "This is a response to an offerless INVITE\n");
43804387
}
43814388
JANUS_LOG(LOG_VERB, "This is involving a negotiation (%s) as well:\n%s\n", msg_sdp_type, msg_sdp);
4382-
session->media.has_srtp_local_audio = answer_srtp && session->media.has_srtp_remote_audio;
4383-
session->media.has_srtp_local_video = answer_srtp && session->media.has_srtp_remote_video;
4389+
session->media.has_srtp_local_audio = answer_srtp && (session->media.has_srtp_remote_audio || !answer);
4390+
session->media.has_srtp_local_video = answer_srtp && (session->media.has_srtp_remote_video || !answer);
43844391
if(answer_srtp) {
43854392
JANUS_LOG(LOG_VERB, "Going to negotiate SDES-SRTP (%s)...\n", session->media.require_srtp ? "mandatory" : "optional");
4393+
if(!answer && !session->media.srtp_profile) {
4394+
/* We got an offerless-INVITE, any SRTP profile different from the default? */
4395+
srtp_profile = JANUS_SRTP_AES128_CM_SHA1_80;
4396+
const char *profile = json_string_value(json_object_get(root, "srtp_profile"));
4397+
if(profile) {
4398+
if(!strcmp(profile, "AES_CM_128_HMAC_SHA1_32")) {
4399+
srtp_profile = JANUS_SRTP_AES128_CM_SHA1_32;
4400+
} else if(!strcmp(profile, "AES_CM_128_HMAC_SHA1_80")) {
4401+
srtp_profile = JANUS_SRTP_AES128_CM_SHA1_80;
4402+
#ifdef HAVE_SRTP_AESGCM
4403+
} else if(!strcmp(profile, "AEAD_AES_128_GCM")) {
4404+
srtp_profile = JANUS_SRTP_AEAD_AES_128_GCM;
4405+
} else if(!strcmp(profile, "AEAD_AES_256_GCM")) {
4406+
srtp_profile = JANUS_SRTP_AEAD_AES_256_GCM;
4407+
#endif
4408+
} else {
4409+
JANUS_LOG(LOG_ERR, "Invalid element (unsupported SRTP profile)\n");
4410+
error_code = JANUS_SIP_ERROR_INVALID_ELEMENT;
4411+
g_snprintf(error_cause, 512, "Invalid element (unsupported SRTP profile)");
4412+
goto error;
4413+
}
4414+
}
4415+
session->media.srtp_profile = srtp_profile;
4416+
}
43864417
}
43874418

43884419
/* Get video-orientation extension id from SDP we got */

0 commit comments

Comments
 (0)