diff --git a/tester/flexisip/flexisip-generic.conf b/tester/flexisip/flexisip-generic.conf index c1b46e15d..90ac2e6b9 100644 --- a/tester/flexisip/flexisip-generic.conf +++ b/tester/flexisip/flexisip-generic.conf @@ -49,6 +49,9 @@ transports=sip:* sips:*;tls-certificates-dir=certificates/cn sips:*:5062;tls-cer tls-certificates-dir=./certificates/cn #tls-certificates-dir=/media/sf_workspaces/workspace-macosx/flexisip +# Plugins to use. +plugins=jweauth + ## ## STUN server parameters. ## @@ -108,7 +111,7 @@ no-403=user-agent contains 'tester-no-403' # in 'a.org b.org c.org', (to.uri.domain in 'a.org b.org c.org') # && (user-agent == 'Linphone v2') # Default value: -filter= from.uri.domain contains 'sip.example.org' || from.uri.domain contains 'auth.example.org' || from.uri.domain contains 'auth1.example.org' || from.uri.domain contains 'auth2.example.org' || from.uri.domain contains 'anonymous.invalid' +filter=!(user-agent contains 'JweAuth Linphone') && (from.uri.domain contains 'sip.example.org' || from.uri.domain contains 'auth.example.org' || from.uri.domain contains 'auth1.example.org' || from.uri.domain contains 'auth2.example.org' || from.uri.domain contains 'anonymous.invalid') # List of whitespace separated domain names to challenge. Others # are denied. @@ -625,3 +628,18 @@ only-list-subscription = !(user-agent contains 'full-presence-support') [presence-server] expires = 600 transports = sip:127.0.0.1:5065;transport=tcp + +# This module offers the possibility to use JSON Web Encryption tokens. +[module::JweAuth] + +# A request/response enters module if the boolean filter evaluates +# to true. Ex: from.uri.domain contains 'sip.linphone.org', from.uri.domain +# in 'a.org b.org c.org', (to.uri.domain in 'a.org b.org c.org') +# && (user-agent == 'Linphone v2') +# Default value: +filter=user-agent contains 'JweAuth Linphone' + +# Path to the directory where JSON Web Key (JWK) can be found. +# Any JWK must be put into a file with the `.jwk` suffix. +# Default value: /etc/flexisip/jwk/ +jwks-dir=./flexisip/jwks diff --git a/tester/flexisip/jwks/key.jwk b/tester/flexisip/jwks/key.jwk new file mode 100644 index 000000000..28c9a36ca --- /dev/null +++ b/tester/flexisip/jwks/key.jwk @@ -0,0 +1 @@ +{"kty":"RSA","kid":"8ZtM3TB2X7f1E0hH97w9BzSoj-_rMj_5iByOToYqim8","alg":"RSA-OAEP-256","e":"AQAB","n":"ghcKgYh_ASm3MzVDP1MA9Km_UDvcoSeQtthTJwTsC4rpJkhn5WPOC5ANIz82lHjDgt7PSvOkErzpYX1l7RUeYM1WuzGvxaNLmpD-s5L9U5kPeqHn3x5XQaWDZTVkHeJoQ02L-Skym2dNvWAmb2fPuQT5Vi_NOzy5MYnlHKDs-Fp3C_cinMdfRYALFOA2IeEk-_uOSP_1zvLGUG-Ltzs8lQCMrJR4iFlZmhHieMH2HS7ObM1xZuWeIThxTNtUsOfSIbpFruR3kH_U6_y6zMg9wMuXDPaS_-lZUNpIlDTpYu8YJE6xwJ0OWQa26_KeLPpQiMw-3UJfmHrChtxB6A91pQ","d":"L-NFdcuGXSo7Czm3KI9okagPCf0PSa-j4PsfGQUB03nuO655uIKV7cG4ZFo3wE34Qqu8iS3JHzC1hLLBm5WjmiTcoYo31zw2b46ig_4_DNASV6VUEtk7a6n_BXmzAiE_Gk9okG7u9y_--RB09Zu0ZrqDAowUM5M15RuK4JAIy58TSkqKhfOYPif-x9WsXqNZXd0bPuHBGchlZHnm06PMlawEiWElJazuVCQsW0a8nBLWBp_sE2zKLpQMojAWAQ74NNSgcc5c58Agh1f2r87O7HOUAnOslsOIe_2ajb_YLgxWHKuncsMaEVeDhbL-I6J8eItM-8NO8nTawP-DauWdPQ","p":"tuFco-MVA7l4sjyy_5p5s2SWrNNK-l0y-_bY8v0trrRSII0axnGW5Vops68huRpa_LwDzwie1j9LF89yR14fHAbaNoR1A8EnYVfLkNJz-3dzvbHRAMYg8nafNnEsXI3V2mvQsizFZGxyPOhw48VUcGuQqBU-RZP90_1aORgmIZc","q":"thpZP1wHVOVyzHqJbIQz0bfA-dLdS4tJGZ5TZuk-7ToIlc-YnJeUxaCwLl513kONXnTdmPPIK3S7v-iZXRvkPAiX8616QgJq9yUFlSfIelKR207nkX_erCZjSEMIfLm3OM65vUB5M_EgSIJfBRzymvhRcWAd4TpSXgLubOpt0iM","dp":"Er2tfK38rVEIaVuHDGKMLjIUrslIWbfLTb7SJLSFRe38rJFJOSTSzdYbh-pejlWBFX0-9qxveo0p6Nq9X0rp7TlWi1evlh7pJjSVC9ZFRHPNTJc4T9f98FrvneijHyj5zVRXIqsr30qtukgnqW_DY3HidRcYNpEf5eWEpW0wGyk","dq":"ArqGV9KzMWx2ueWkJYIdnKjaNWQZeMZPhBjBOyuHi9pwwn3n1YDX89Yija9QqNHuTloF8ALHHw-SuJ9tnN2MH_IpBLe2u0J6A9YELWX5NQwDr3uRMLbvyTiSCEUo3WWS_0Dpu5I5vrOAPlXlwpfacsQBxGciS3uqPEpi9DLXDm0","qi":"PvJcj7U20qXRO-v_YLPZEnkbIHI0xAImOhu51FHW58k32T-o9AJWXQ-Ggu093PWNaaMtg0VilECOpFOO6sVrDlwP1naHXdRyBLGu4iwBQnZG_7KMhxGkEM9otMyq2HlMZzN9fNcJss3SIHAINADHKbL9obfO2PjqmRugIVG29LM"} diff --git a/tester/flexisip_tester.c b/tester/flexisip_tester.c index bc85fd026..2244c6043 100644 --- a/tester/flexisip_tester.c +++ b/tester/flexisip_tester.c @@ -1923,6 +1923,114 @@ end: bctbx_list_free(lcs); } +static void deal_with_jwe_auth_module(const char *jwe, bool_t invalid_jwe, bool_t invalid_oid) { + if (!transport_supported(LinphoneTransportTls)) + return; + + // 1. Register Gandalf. + LinphoneCoreCbs *cbs = linphone_factory_create_core_cbs(linphone_factory_get()); + LinphoneCoreManager *gandalf = linphone_core_manager_new(NULL); + + // Do not use Authentication module. + linphone_core_set_user_agent(gandalf->lc, "JweAuth Linphone", NULL); + + linphone_core_cbs_set_authentication_requested(cbs, tls_authentication_provide_altname_cert); + linphone_core_add_callbacks(gandalf->lc, cbs); + linphone_core_cbs_unref(cbs); + + LinphoneProxyConfig *cfg = linphone_core_create_proxy_config(gandalf->lc); + + linphone_proxy_config_set_server_addr(cfg, "sip:sip2.linphone.org:5063;transport=tls"); + linphone_proxy_config_set_route(cfg, "sip:sip2.linphone.org:5063;transport=tls"); + linphone_proxy_config_enable_register(cfg, TRUE); + linphone_proxy_config_set_identity(cfg, "sip:gandalf@sip.example.org"); + linphone_core_add_proxy_config(gandalf->lc, cfg); + + BC_ASSERT_TRUE(wait_for(gandalf->lc, NULL, &gandalf->stat.number_of_LinphoneRegistrationOk, 1)); + BC_ASSERT_EQUAL(gandalf->stat.number_of_LinphoneRegistrationFailed,0, int, "%d"); + BC_ASSERT_EQUAL(gandalf->stat.number_of_auth_info_requested,1, int, "%d"); + + // 2. Invite Pauline. + LinphoneCoreManager *pauline = linphone_core_manager_new("pauline_rc"); + + bctbx_list_t *lcs = bctbx_list_append(NULL, gandalf->lc); + lcs = bctbx_list_append(lcs, pauline->lc); + + LinphoneCallParams *gandalf_params = linphone_core_create_call_params(gandalf->lc, NULL); + linphone_call_params_add_custom_header( + gandalf_params, + "X-token-oid", + invalid_oid ? "sip:invalid@sip.example.org" : "sip:gandalf@sip.example.org" + ); + linphone_call_params_add_custom_header(gandalf_params, "X-token-aud", "plic-ploc"); + linphone_call_params_add_custom_header(gandalf_params, "X-token-req_act", "DRAAAAA LES PYRAMIDES"); + linphone_call_params_add_custom_header(gandalf_params, "X-token-jwe", jwe); + + linphone_core_invite_address_with_params(gandalf->lc, pauline->identity, gandalf_params); + linphone_call_params_unref(gandalf_params); + + int n_expected_calls = invalid_jwe || invalid_oid ? 0 : 1; + BC_ASSERT_TRUE(wait_for_list(lcs, &gandalf->stat.number_of_LinphoneCallOutgoingRinging, n_expected_calls, 3000)); + BC_ASSERT_TRUE(wait_for_list(lcs, &pauline->stat.number_of_LinphoneCallIncomingReceived, n_expected_calls, 3000)); + + LinphoneCall *pauline_call = linphone_core_get_current_call(pauline->lc); + if (!n_expected_calls) + BC_ASSERT_PTR_NULL(pauline_call); + else { + if (pauline_call) + linphone_call_accept(pauline_call); + BC_ASSERT_TRUE(wait_for_list(lcs, &gandalf->stat.number_of_LinphoneCallConnected, 1, 1000)); + BC_ASSERT_TRUE(wait_for_list(lcs, &gandalf->stat.number_of_LinphoneCallStreamsRunning, 1, 1000)); + BC_ASSERT_TRUE(wait_for_list(lcs, &pauline->stat.number_of_LinphoneCallConnected, 1, 1000)); + BC_ASSERT_TRUE(wait_for_list(lcs, &pauline->stat.number_of_LinphoneCallStreamsRunning, 1, 1000)); + } + + LinphoneCall *gandalf_call = linphone_core_get_current_call(gandalf->lc); + if (n_expected_calls) { + if (gandalf_call) + linphone_call_terminate(gandalf_call); + BC_ASSERT_TRUE(wait_for_list(lcs, &gandalf->stat.number_of_LinphoneCallEnd, 1, 1000)); + BC_ASSERT_TRUE(wait_for_list(lcs, &pauline->stat.number_of_LinphoneCallEnd, 1, 1000)); + } + + linphone_core_manager_destroy(gandalf); + linphone_core_manager_destroy(pauline); + + linphone_proxy_config_unref(cfg); + + bctbx_list_free(lcs); +} + +void use_jwe_auth_module(void) { + static const char jwe[] = "eyJlbmMiOiJBMjU2R0NNIiwiYWxnIjoiUlNBLU9BRVAtMjU2Iiwia2lkIjoiOFp0TTNUQjJYN2YxRTBoSDk3dzlCelNvai1fck1qXzVpQnlPVG9ZcWltOCJ9.YIkpmyFKUJaSIBXh8ABjAeymbMN21VAGr7qXFmek0l8Oh3bEGBuf5YggQWP1G55V00WI8KESxm3LJnqzf-L3FDm3S8D-dLeR7GiJgJtJqED6KKf9U86aLo6UZPmh8xIdfVqLFDUeDQQwy3zwZw-MwY_xtDn_RR2u_W5bmWL-t1-A-xTIw6TEwdjqe8X_D0CuhcPx-virV3RBUHwjSO43vsdHMqLExDXIk95CuQOcUJufZJMu0q5KmpuvDSVesf6ZcmKBEVnkIlSbgAl_Hsv51RXPUT3rFsNy0LSEIByyF-zO6u_L6jpqlt8DxKc6aefa9-4KvyaxU1K7AApYZKh2TQ.fjXkk_TeGhfakvKQ.GP8RivXqe5g4OQhvzlvJ-l2jxuRziLWFNohmFIkZoXwL2mvnEqq71GWYr6_X0V7Z3I7nkMKDwhOfBpKbjnDKK-x1BEUmOmTwaJqeX_lJlZeZkXl597jtBXN3fH5vdccRvoxVFHT0DfZcEA.Km01D704Zl-J28hQJ05dEA"; + deal_with_jwe_auth_module(jwe, FALSE, FALSE); +} + +void use_jwe_auth_module_with_invalid_oid(void) { + static const char jwe[] = "eyJlbmMiOiJBMjU2R0NNIiwiYWxnIjoiUlNBLU9BRVAtMjU2Iiwia2lkIjoiOFp0TTNUQjJYN2YxRTBoSDk3dzlCelNvai1fck1qXzVpQnlPVG9ZcWltOCJ9.YIkpmyFKUJaSIBXh8ABjAeymbMN21VAGr7qXFmek0l8Oh3bEGBuf5YggQWP1G55V00WI8KESxm3LJnqzf-L3FDm3S8D-dLeR7GiJgJtJqED6KKf9U86aLo6UZPmh8xIdfVqLFDUeDQQwy3zwZw-MwY_xtDn_RR2u_W5bmWL-t1-A-xTIw6TEwdjqe8X_D0CuhcPx-virV3RBUHwjSO43vsdHMqLExDXIk95CuQOcUJufZJMu0q5KmpuvDSVesf6ZcmKBEVnkIlSbgAl_Hsv51RXPUT3rFsNy0LSEIByyF-zO6u_L6jpqlt8DxKc6aefa9-4KvyaxU1K7AApYZKh2TQ.fjXkk_TeGhfakvKQ.GP8RivXqe5g4OQhvzlvJ-l2jxuRziLWFNohmFIkZoXwL2mvnEqq71GWYr6_X0V7Z3I7nkMKDwhOfBpKbjnDKK-x1BEUmOmTwaJqeX_lJlZeZkXl597jtBXN3fH5vdccRvoxVFHT0DfZcEA.Km01D704Zl-J28hQJ05dEA"; + deal_with_jwe_auth_module(jwe, FALSE, TRUE); +} + +void use_jwe_auth_module_with_expired_exp(void) { + static const char jwe[] = "eyJlbmMiOiJBMjU2R0NNIiwiYWxnIjoiUlNBLU9BRVAtMjU2Iiwia2lkIjoiOFp0TTNUQjJYN2YxRTBoSDk3dzlCelNvai1fck1qXzVpQnlPVG9ZcWltOCJ9.PChRlYeTptnYoQDSxYRtqLCBgC3LTpsqWGKDXp-cHC_hF5vurvQfrj__KQb6mR65qBm68PmHp1KwykTAld3bUVA3ykcsGqKI7WBnpu3DLNaQ9kaluP2BvFsyhUBWDU6IqU_O8CIykTwiaSn3HSBH2MiL-lPeNfDY6ndcGXlEAOGosgXAlkFerkNsu8bm4Qkch1JIrxV6I0MhfLrNGIfPPazfYU8byVXScd0YkKlwOuaJZpUXew5nAsgb0L39vMuKomLi5ibH84X01akODOnucX6fU2f_e2MuUH4X3zgqmG9AZ8RV_Iy7irsk_VG4sS8VRftk7YqMVO8kByTkOkLwLA.DO2Navrjk-1vep94.V6n_kZt7gbYGDHnaa9q3DHK7ujkFv2Jd-9jK8xUpkH7PcG3WKTPwiLy40sFvGFr7iWnojK-tODYzakfM5t3uXWdq4iYDXv2tP_JDJt-muiE99C_07cBtL2ymrIzMp-6efzNl3YL_K-rQ9g.p3YUmwPAGO0H9e64MavQlg"; + deal_with_jwe_auth_module(jwe, TRUE, FALSE); +} + +void use_jwe_auth_module_with_no_exp(void) { + static const char jwe[] = "eyJlbmMiOiJBMjU2R0NNIiwiYWxnIjoiUlNBLU9BRVAtMjU2Iiwia2lkIjoiOFp0TTNUQjJYN2YxRTBoSDk3dzlCelNvai1fck1qXzVpQnlPVG9ZcWltOCJ9.Hn2oL4835Tkzqb4U3_0aDqgg-pxImCi2EbuTtWwa5uQ5cVz6p6gZ7s7PTPgkfJgtQTYzaRqsywI0cLIWkofAFWUGcL43U-w7_vm3gBpO7BpUKq81kscz6-31ni7M3prxyxw7eoqhdu8Hf9QjirHMaWAw7gYpEjcAshAA559T4a8svan0wq_WGoeXYYS0cEv8UEX6Lpz41tNkvchy9Ydm4kWYXloqnnl0ARR1bMOlxhpOD--Sm2fcTopO_E24tmDjdvgGddwGhHX4qOXs3dXWKM8SPj-PLvZSy7BJ3-Jfz5T1ErEzXlUxutgnV-9K1QZGCbVT6hiF39bcPfAj-y9Emw.xJR4Ot1XCoptlHau.dcYkLAvBJ2N0PnAJ5lr3f3b4CDVJNpi6PrprVB25k4EycdlW-IiiiC97SAyBeygvK5BAybyyjotU33_MC_1163Gk1SsRGn6yjujWgYeoLBRUL6yQcIiPZus.CCaNmMMMsIX4o-dIt7HquQ"; + deal_with_jwe_auth_module(jwe, TRUE, FALSE); +} + +void use_jwe_auth_module_with_invalid_attr(void) { + static const char jwe[] = "eyJlbmMiOiJBMjU2R0NNIiwiYWxnIjoiUlNBLU9BRVAtMjU2Iiwia2lkIjoiOFp0TTNUQjJYN2YxRTBoSDk3dzlCelNvai1fck1qXzVpQnlPVG9ZcWltOCJ9.Lj-1x8-c1BJWSvwYQtMWDV2fhGRNZ0B6auR1QgVRw2e4kxEToSSjZJAXKudAvNII0FUtPU6hf0uvuDuc9VQHRDCV3DSg0iLxVfcLJcnC0hygHnjBuVJiglqfKVfXnaLwadkRVS7Q3A52sC_YZnk0aTZKpefu1Zc_kr_llKH_pIEZDd2FL1M3XZXNiiemM1Lwq5sbRPYqxOHhVySOIUcAzUkPJpzgaIMGVwn4cwvDL58inp9tyUDak6BV6sFoSovpJ4w4HDIRLUj8BXcBZiyXlzj06YUiZVkO2JPRZR_KBPdZtKAE5KoWGe074e5q-L_f6_i3Y0psN9hI8FZfzy0nvw.FAtaQpIlLCx19mPq.TJS8q2aCeLT-oLSy24eRa2FN07AIjlymwruBvYROFeU-_UgomwIcPQhVvfE0h_QyJNVcY1iwBnCBe8KDbVHUrfHhQcCHJmOHXZ7ouzINBPk0qqr-ubCroHuV3J-prIa10qwvEzjmFBAPEw4.6cOmc0txLOCpIXa3WOkRSA"; + deal_with_jwe_auth_module(jwe, TRUE, FALSE); +} + +void use_jwe_auth_with_malformed_token(void) { + static const char jwe[] = "eyJlbmMiOiJBMjU2R0NNIiwiYWxnIjoiUlNBLU9BRVAtMjU2Iiwia2lkIjoiOFp0TTNUQjJYN2YxRTBoSDk3dzlCelNvai1fck1qXzVpQnlPVG9ZcWltOCJ9.YIkpmyFKUJaSIBXh8ABjAeymbMN21VAGr7qXFmek0l8Oh3bEGBuf5YggQWP1G55V00WI8KESxm3LJnqzf-L3FDm3S8D-dLeR7GiJgJtJqED6KKf9U86aLo6UZPmh8xIdfVqLFDUeDQQwy3zwZw-MwY_xtDn_RR2u_W5bmWL-t1-A-xTIw6TEwdjqe8X_D0CuhcPx-virV3RBUHwjSO43vsdHMqLExDXIk95CuQOcUJufZJMu0q5KmpuvDSVesf6ZcmKBEVnkIlSbgAl_Hsv51RXPUT3rFsNy0LSEIByyF-zO6u_L6jpqlt8DxKc6aefa9-4KvyaxU1K7AApYZKh2TQ.fjXkk_TeGhfakvKQ.GP8RivXqe5g4OQhvzlvJ-l2jxuRziLWFNohmFIkZoXwL2mvnEqq71GWYr6_X0V7Z3I7nkMKDwhOfBpKbjnDKK-x1BEUmOmTwaJqeX_lJlZeZkXl597jtBXN3fH5vdccRvoxVFHT0DfZcEA.Km01D704Zl-J18hQJ05dEA"; + deal_with_jwe_auth_module(jwe, TRUE, FALSE); +} + test_t flexisip_tests[] = { TEST_ONE_TAG("Subscribe forking", subscribe_forking, "LeaksMemory"), TEST_NO_TAG("Message forking", message_forking), @@ -1970,9 +2078,17 @@ test_t flexisip_tests[] = { TEST_NO_TAG("Sequential forking with no response from highest priority", sequential_forking_with_no_response_for_highest_priority), TEST_NO_TAG("Sequential forking with insertion of higher priority", sequential_forking_with_insertion_of_higher_priority), TEST_NO_TAG("Sequential forking with fallback route", sequential_forking_with_fallback_route), - TEST_NO_TAG("Registered contact does not have regid param", register_without_regid) + TEST_NO_TAG("Registered contact does not have regid param", register_without_regid), + TEST_NO_TAG("Use JweAuth module", use_jwe_auth_module), + TEST_NO_TAG("Use JweAuth module with invalid oid", use_jwe_auth_module_with_invalid_oid), + TEST_NO_TAG("Use JweAuth module with expired exp", use_jwe_auth_module_with_expired_exp), + TEST_NO_TAG("Use JweAuth module with no exp", use_jwe_auth_module_with_no_exp), + TEST_NO_TAG("Use JweAuth module with invalid attr", use_jwe_auth_module_with_invalid_attr), + TEST_NO_TAG("Use JweAuth module with malformed token", use_jwe_auth_with_malformed_token) }; - -test_suite_t flexisip_test_suite = {"Flexisip", NULL, NULL, liblinphone_tester_before_each, liblinphone_tester_after_each, - sizeof(flexisip_tests) / sizeof(flexisip_tests[0]), flexisip_tests}; +test_suite_t flexisip_test_suite = { + "Flexisip", NULL, NULL, + liblinphone_tester_before_each, liblinphone_tester_after_each, + sizeof(flexisip_tests) / sizeof(flexisip_tests[0]), flexisip_tests +};