1: -module(sasl2_SUITE). 2: 3: -compile([export_all, nowarn_export_all]). 4: 5: -include_lib("stdlib/include/assert.hrl"). 6: -include_lib("exml/include/exml.hrl"). 7: -include_lib("escalus/include/escalus_xmlns.hrl"). 8: 9: -define(NS_SASL_2, <<"urn:xmpp:sasl:2">>). 10: 11: %%-------------------------------------------------------------------- 12: %% Suite configuration 13: %%-------------------------------------------------------------------- 14: 15: all() -> 16: [ 17: {group, all_tests} 18: ]. 19: 20: groups() -> 21: [ 22: {all_tests, [parallel], 23: [ 24: {group, basic}, 25: {group, scram}, 26: {group, stream_management} 27: ]}, 28: {basic, [parallel], 29: [ 30: server_does_not_announce_if_not_tls, 31: server_announces_sasl2_with_some_mechanism_and_inline_sm, 32: authenticate_stanza_has_invalid_mechanism, 33: user_agent_is_invalid, 34: user_agent_is_invalid_uuid_but_not_v4, 35: authenticate_with_plain, 36: authenticate_with_plain_and_user_agent_without_id, 37: authenticate_again_results_in_stream_error 38: ]}, 39: {scram, [parallel], 40: [ 41: authenticate_with_scram_abort, 42: authenticate_with_scram_bad_abort, 43: authenticate_with_scram_bad_response, 44: authenticate_with_scram 45: ]}, 46: {stream_management, [parallel], 47: [ 48: sm_failure_missing_previd_does_not_stop_sasl2, 49: sm_failure_invalid_h_does_not_stop_sasl2, 50: sm_failure_exceeding_h_does_not_stop_sasl2, 51: sm_failure_unknown_smid_does_not_stop_sasl2, 52: sm_is_bound_at_sasl2_success 53: ]} 54: ]. 55: 56: %%-------------------------------------------------------------------- 57: %% Init & teardown 58: %%-------------------------------------------------------------------- 59: 60: init_per_suite(Config) -> 61: Config1 = load_sasl_extensible(Config), 62: escalus:init_per_suite(Config1). 63: 64: end_per_suite(Config) -> 65: escalus_fresh:clean(), 66: dynamic_modules:restore_modules(Config), 67: escalus:end_per_suite(Config). 68: 69: init_per_group(scram, Config) -> 70: case mongoose_helper:supports_sasl_module(cyrsasl_scram_sha256) of 71: false -> 72: {skip, "scram password type not supported"}; 73: true -> 74: Config 75: end; 76: init_per_group(_GroupName, Config) -> 77: Config. 78: 79: end_per_group(_GroupName, Config) -> 80: Config. 81: 82: init_per_testcase(Name, Config) -> 83: escalus:init_per_testcase(Name, Config). 84: 85: end_per_testcase(Name, Config) -> 86: escalus:end_per_testcase(Name, Config). 87: 88: load_sasl_extensible(Config) -> 89: HostType = domain_helper:host_type(), 90: Config1 = dynamic_modules:save_modules(HostType, Config), 91: sasl2_helper:load_all_sasl2_modules(HostType), 92: Config1. 93: 94: %%-------------------------------------------------------------------- 95: %% tests 96: %%-------------------------------------------------------------------- 97: 98: server_does_not_announce_if_not_tls(Config) -> 99: Steps = [connect_non_tls_user, start_stream_get_features], 100: #{features := Features} = sasl2_helper:apply_steps(Steps, Config), 101: Sasl2 = exml_query:path(Features, [{element_with_ns, <<"authentication">>, ?NS_SASL_2}]), 102: ?assertEqual(undefined, Sasl2). 103: 104: server_announces_sasl2_with_some_mechanism_and_inline_sm(Config) -> 105: Steps = [create_connect_tls, start_stream_get_features], 106: #{features := Features} = sasl2_helper:apply_steps(Steps, Config), 107: Sasl2 = exml_query:path(Features, [{element_with_ns, <<"authentication">>, ?NS_SASL_2}]), 108: ?assertNotEqual(undefined, Sasl2), 109: Mechs = exml_query:paths(Sasl2, [{element, <<"mechanism">>}]), 110: ?assertNotEqual([], Mechs), 111: Sm = exml_query:path(Sasl2, [{element, <<"inline">>}, 112: {element_with_ns, <<"sm">>, ?NS_STREAM_MGNT_3}]), 113: ?assertNotEqual(undefined, Sm). 114: 115: authenticate_stanza_has_invalid_mechanism(Config) -> 116: Steps = [start_new_user, send_invalid_mech_auth_stanza], 117: #{answer := Response} = sasl2_helper:apply_steps(Steps, Config), 118: ?assertMatch(#xmlel{name = <<"failure">>, attrs = [{<<"xmlns">>, ?NS_SASL_2}]}, Response). 119: 120: user_agent_is_invalid(Config) -> 121: Steps = [start_new_user, send_bad_user_agent], 122: #{answer := Response} = sasl2_helper:apply_steps(Steps, Config), 123: escalus:assert(is_stream_error, [<<"policy-violation">>, <<>>], Response). 124: 125: user_agent_is_invalid_uuid_but_not_v4(Config) -> 126: Steps = [start_new_user, send_bad_user_agent_uuid], 127: #{answer := Response} = sasl2_helper:apply_steps(Steps, Config), 128: escalus:assert(is_stream_error, [<<"policy-violation">>, <<>>], Response). 129: 130: authenticate_with_plain(Config) -> 131: Steps = [start_new_user, plain_authentication, receive_features], 132: auth_with_plain(Steps, Config). 133: 134: authenticate_with_plain_and_user_agent_without_id(Config) -> 135: Steps = [start_new_user, plain_auth_user_agent_without_id, receive_features], 136: auth_with_plain(Steps, Config). 137: 138: auth_with_plain(Steps, Config) -> 139: #{answer := Success, features := Features} = sasl2_helper:apply_steps(Steps, Config), 140: ?assertMatch(#xmlel{name = <<"success">>, attrs = [{<<"xmlns">>, ?NS_SASL_2}]}, Success), 141: CData = exml_query:path(Success, [{element, <<"additional-data">>}, cdata], <<>>), 142: ?assert(is_binary(CData) andalso 0 =< byte_size(CData)), 143: Identifier = exml_query:path(Success, [{element, <<"authorization-identifier">>}, cdata], <<>>), 144: ?assertNotEqual(error, jid:from_binary(Identifier)), 145: ?assertMatch(#xmlel{name = <<"stream:features">>}, Features). 146: 147: authenticate_with_scram_abort(Config) -> 148: Steps = [start_new_user, scram_step_1, scram_abort], 149: #{answer := Response} = sasl2_helper:apply_steps(Steps, Config), 150: ?assertMatch(#xmlel{name = <<"failure">>, attrs = [{<<"xmlns">>, ?NS_SASL_2}]}, Response), 151: Aborted = exml_query:path(Response, [{element_with_ns, <<"aborted">>, ?NS_SASL}]), 152: ?assertNotEqual(undefined, Aborted). 153: 154: authenticate_with_scram_bad_abort(Config) -> 155: Steps = [start_new_user, scram_step_1, scram_bad_abort], 156: #{answer := Response} = sasl2_helper:apply_steps(Steps, Config), 157: escalus:assert(is_stream_error, [<<"invalid-namespace">>, <<>>], Response). 158: 159: authenticate_with_scram_bad_response(Config) -> 160: Steps = [start_new_user, scram_step_1, scram_bad_ns_response], 161: #{answer := Response} = sasl2_helper:apply_steps(Steps, Config), 162: escalus:assert(is_stream_error, [<<"invalid-namespace">>, <<>>], Response). 163: 164: authenticate_with_scram(Config) -> 165: Steps = [start_new_user, scram_step_1, scram_step_2, receive_features], 166: #{answer := Success, features := Features} = sasl2_helper:apply_steps(Steps, Config), 167: ?assertMatch(#xmlel{name = <<"success">>, attrs = [{<<"xmlns">>, ?NS_SASL_2}]}, Success), 168: CData = exml_query:path(Success, [{element, <<"additional-data">>}, cdata], <<>>), 169: ?assert(is_binary(CData) andalso 0 =< byte_size(CData)), 170: Identifier = exml_query:path(Success, [{element, <<"authorization-identifier">>}, cdata], <<>>), 171: ?assertNotEqual(error, jid:from_binary(Identifier)), 172: ?assertMatch(#xmlel{name = <<"stream:features">>}, Features). 173: 174: authenticate_again_results_in_stream_error(Config) -> 175: Steps = [start_new_user, plain_authentication, receive_features, plain_authentication], 176: #{answer := Response} = sasl2_helper:apply_steps(Steps, Config), 177: escalus:assert(is_stream_error, [<<"policy-violation">>, <<>>], Response). 178: 179: sm_failure_missing_previd_does_not_stop_sasl2(Config) -> 180: Steps = [create_user, buffer_messages_and_die, connect_tls, start_stream_get_features, 181: auth_with_resumption_missing_previd, receive_features], 182: #{answer := Success} = sasl2_helper:apply_steps(Steps, Config), 183: ?assertMatch(#xmlel{name = <<"success">>, attrs = [{<<"xmlns">>, ?NS_SASL_2}]}, Success), 184: Resumed = exml_query:path(Success, [{element_with_ns, <<"failed">>, ?NS_STREAM_MGNT_3}]), 185: escalus:assert(is_sm_failed, [<<"bad-request">>], Resumed). 186: 187: sm_failure_invalid_h_does_not_stop_sasl2(Config) -> 188: Steps = [create_user, buffer_messages_and_die, connect_tls, start_stream_get_features, 189: auth_with_resumption_invalid_h, receive_features], 190: #{answer := Success} = sasl2_helper:apply_steps(Steps, Config), 191: ?assertMatch(#xmlel{name = <<"success">>, attrs = [{<<"xmlns">>, ?NS_SASL_2}]}, Success), 192: Resumed = exml_query:path(Success, [{element_with_ns, <<"failed">>, ?NS_STREAM_MGNT_3}]), 193: escalus:assert(is_sm_failed, [<<"bad-request">>], Resumed). 194: 195: sm_failure_exceeding_h_does_not_stop_sasl2(Config) -> 196: Steps = [create_user, buffer_messages_and_die, connect_tls, start_stream_get_features, 197: auth_with_resumption_exceeding_h, receive_features], 198: #{answer := Success} = sasl2_helper:apply_steps(Steps, Config), 199: ?assertMatch(#xmlel{name = <<"success">>, attrs = [{<<"xmlns">>, ?NS_SASL_2}]}, Success), 200: Resumed = exml_query:path(Success, [{element_with_ns, <<"failed">>, ?NS_STREAM_MGNT_3}]), 201: escalus:assert(is_sm_failed, [<<"bad-request">>], Resumed). 202: 203: sm_failure_unknown_smid_does_not_stop_sasl2(Config) -> 204: Steps = [create_user, buffer_messages_and_die, connect_tls, start_stream_get_features, 205: auth_with_resumption_unknown_smid, receive_features], 206: #{answer := Success} = sasl2_helper:apply_steps(Steps, Config), 207: ?assertMatch(#xmlel{name = <<"success">>, attrs = [{<<"xmlns">>, ?NS_SASL_2}]}, Success), 208: Resumed = exml_query:path(Success, [{element_with_ns, <<"failed">>, ?NS_STREAM_MGNT_3}]), 209: escalus:assert(is_sm_failed, [<<"item-not-found">>], Resumed). 210: 211: sm_is_bound_at_sasl2_success(Config) -> 212: Steps = [create_user, buffer_messages_and_die, connect_tls, start_stream_get_features, 213: auth_with_resumption, has_no_more_stanzas, can_send_messages], 214: #{answer := Success, smid := SMID} = sasl2_helper:apply_steps(Steps, Config), 215: ?assertMatch(#xmlel{name = <<"success">>, attrs = [{<<"xmlns">>, ?NS_SASL_2}]}, Success), 216: Resumed = exml_query:path(Success, [{element_with_ns, <<"resumed">>, ?NS_STREAM_MGNT_3}]), 217: ?assert(escalus_pred:is_sm_resumed(SMID, Resumed)).