diff --git a/README.md b/README.md index 04c5ae32f..b12596db5 100644 --- a/README.md +++ b/README.md @@ -1403,7 +1403,8 @@ Optionally included keys are: A list of strings controlling the behaviour regarding SDES. The default is to offer SDES without any session parameters when encryption is desired, and to accept it when DTLS-SRTP is unavailable. If two SDES endpoints are connected to each other, then the default is to offer SDES with the same options - as were received from the other endpoint. + as were received from the other endpoint. Additionally, all other supported SDES crypto suites are + added to the outgoing offer by default. These options can also be put into the `flags` list using a prefix of `SDES-`. All options controlling SDES session parameters can be used either in all lower case or in all upper case. @@ -1422,6 +1423,14 @@ Optionally included keys are: Negates the respective option. This is useful if one of the session parameters was offered by an SDES endpoint, but it should not be offered on the far side if this endpoint also speaks SDES. + - `no-`*SUITE* + + Exclude individual crypto suites from being included in the offer. For example, + `no-NULL_HMAC_SHA1_32` would exclude the crypto suite `NULL_HMAC_SHA1_32` from + the offer. This has two effects: if a given crypto suite was present in a received + offer, it will be removed and will be missing in the outgoing offer; and if a given crypto + suite was not present in the received offer, it will not be added to it. + * `record call` Contains one of the strings `yes`, `no`, `on` or `off`. This tells the rtpengine diff --git a/daemon/call.c b/daemon/call.c index c7714f581..a63cdf957 100644 --- a/daemon/call.c +++ b/daemon/call.c @@ -1368,6 +1368,15 @@ static void __generate_crypto(const struct sdp_ng_flags *flags, struct call_medi for (GList *l = offered_cpq->head; l; l = l->next) { struct crypto_params_sdes *offered_cps = l->data; + if (flags->sdes_no && g_hash_table_lookup(flags->sdes_no, + &offered_cps->params.crypto_suite->name_str)) + { + ilog(LOG_DEBUG, "Dropping offered crypto suite '%s' from offer " + "due to 'SDES-no' option", + offered_cps->params.crypto_suite->name); + continue; + } + struct crypto_params_sdes *cps = g_slice_alloc0(sizeof(*cps)); g_queue_push_tail(cpq, cps); @@ -1388,6 +1397,15 @@ static void __generate_crypto(const struct sdp_ng_flags *flags, struct call_medi if ((types_offered & (1 << i))) continue; + if (flags->sdes_no && g_hash_table_lookup(flags->sdes_no, + &crypto_suites[i].name_str)) + { + ilog(LOG_DEBUG, "Not offering crypto suite '%s' " + "due to 'SDES-no' option", + crypto_suites[i].name); + continue; + } + struct crypto_params_sdes *cps = g_slice_alloc0(sizeof(*cps)); g_queue_push_tail(cpq, cps); diff --git a/daemon/call_interfaces.c b/daemon/call_interfaces.c index 14018f5b9..2b28f7990 100644 --- a/daemon/call_interfaces.c +++ b/daemon/call_interfaces.c @@ -38,6 +38,11 @@ int trust_address_def; int dtls_passive_def; +INLINE int call_ng_flags_prefix(struct sdp_ng_flags *out, str *s_ori, const char *prefix, + void (*cb)(struct sdp_ng_flags *, str *, void *), void *ptr); +static void call_ng_flags_str_ht(struct sdp_ng_flags *out, str *s, void *htp); + + static int call_stream_address_gstring(GString *o, struct packet_stream *ps, enum stream_address_format format) { int len, ret; char buf[64]; /* 64 bytes ought to be enough for anybody */ @@ -500,6 +505,9 @@ INLINE char *bencode_get_alt(bencode_item_t *i, const char *one, const char *two } INLINE void ng_sdes_option(struct sdp_ng_flags *out, str *s, void *dummy) { + if (call_ng_flags_prefix(out, s, "no-", call_ng_flags_str_ht, &out->sdes_no)) + return; + switch (__csh_lookup(s)) { case CSH_LOOKUP("no"): case CSH_LOOKUP("off"): @@ -593,7 +601,7 @@ static void call_ng_flags_codec_list(struct sdp_ng_flags *out, str *s, void *qp) *s_copy = *s; g_queue_push_tail((GQueue *) qp, s_copy); } -static void call_ng_flags_codec_ht(struct sdp_ng_flags *out, str *s, void *htp) { +static void call_ng_flags_str_ht(struct sdp_ng_flags *out, str *s, void *htp) { str *s_copy; s_copy = g_slice_alloc(sizeof(*s_copy)); *s_copy = *s; @@ -677,9 +685,11 @@ static void call_ng_flags_flags(struct sdp_ng_flags *out, str *s, void *dummy) { break; default: // handle values aliases from other dictionaries + if (call_ng_flags_prefix(out, s, "SDES-no-", call_ng_flags_str_ht, &out->sdes_no)) + return; if (call_ng_flags_prefix(out, s, "SDES-", ng_sdes_option, NULL)) return; - if (call_ng_flags_prefix(out, s, "codec-strip-", call_ng_flags_codec_ht, &out->codec_strip)) + if (call_ng_flags_prefix(out, s, "codec-strip-", call_ng_flags_str_ht, &out->codec_strip)) return; if (call_ng_flags_prefix(out, s, "codec-offer-", call_ng_flags_codec_list, &out->codec_offer)) return; @@ -689,7 +699,7 @@ static void call_ng_flags_flags(struct sdp_ng_flags *out, str *s, void *dummy) { if (call_ng_flags_prefix(out, s, "codec-transcode-", call_ng_flags_codec_list, &out->codec_transcode)) return; - if (call_ng_flags_prefix(out, s, "codec-mask-", call_ng_flags_codec_ht, &out->codec_mask)) + if (call_ng_flags_prefix(out, s, "codec-mask-", call_ng_flags_str_ht, &out->codec_mask)) return; #endif @@ -781,11 +791,11 @@ static void call_ng_process_flags(struct sdp_ng_flags *out, bencode_item_t *inpu } if ((dict = bencode_dictionary_get_expect(input, "codec", BENCODE_DICTIONARY))) { - call_ng_flags_list(out, dict, "strip", call_ng_flags_codec_ht, &out->codec_strip); + call_ng_flags_list(out, dict, "strip", call_ng_flags_str_ht, &out->codec_strip); call_ng_flags_list(out, dict, "offer", call_ng_flags_codec_list, &out->codec_offer); #ifdef WITH_TRANSCODING call_ng_flags_list(out, dict, "transcode", call_ng_flags_codec_list, &out->codec_transcode); - call_ng_flags_list(out, dict, "mask", call_ng_flags_codec_ht, &out->codec_mask); + call_ng_flags_list(out, dict, "mask", call_ng_flags_str_ht, &out->codec_mask); #endif } } @@ -794,6 +804,8 @@ static void call_ng_free_flags(struct sdp_ng_flags *flags) { g_hash_table_destroy(flags->codec_strip); if (flags->codec_mask) g_hash_table_destroy(flags->codec_mask); + if (flags->sdes_no) + g_hash_table_destroy(flags->sdes_no); g_queue_clear_full(&flags->codec_offer, str_slice_free); g_queue_clear_full(&flags->codec_transcode, str_slice_free); } diff --git a/daemon/crypto.c b/daemon/crypto.c index 033469f8a..8f7ce5e9a 100644 --- a/daemon/crypto.c +++ b/daemon/crypto.c @@ -735,6 +735,7 @@ void crypto_init_main() { for (unsigned int i = 0; i < num_crypto_suites; i++) { cs = &__crypto_suites[i]; cs->idx = i; + str_init(&cs->name_str, (char *) cs->name); switch(cs->master_key_len) { case 16: cs->lib_cipher_ptr = EVP_aes_128_ecb(); diff --git a/include/call_interfaces.h b/include/call_interfaces.h index 7c3349304..dc7cc0a8a 100644 --- a/include/call_interfaces.h +++ b/include/call_interfaces.h @@ -37,6 +37,7 @@ struct sdp_ng_flags { GQueue codec_transcode; GHashTable *codec_mask; int ptime; + GHashTable *sdes_no; int asymmetric:1, no_redis_update:1, unidirectional:1, diff --git a/include/crypto.h b/include/crypto.h index 9c0e0d939..1ca5537e9 100644 --- a/include/crypto.h +++ b/include/crypto.h @@ -58,6 +58,7 @@ struct crypto_suite { //const char *dtls_profile_code; // unused const void *lib_cipher_ptr; unsigned int idx; // filled in during crypto_init_main() + str name_str; // same as `name` }; struct crypto_session_params {