Skip to content

Commit acf8d0e

Browse files
authored
Merge pull request #4631 from esl/sasl-channel-binding
Add support for XEP-440
2 parents 47acf05 + 2ee3e50 commit acf8d0e

10 files changed

Lines changed: 58 additions & 18 deletions

File tree

big_tests/rebar.config

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
{proper, "1.4.0"},
1414
{gun, "2.1.0"},
1515
{fusco, "0.1.1"},
16-
{escalus, "4.5.5"},
16+
{escalus, "4.5.6"},
1717
{ranch, "2.2.0"},
1818
{cowboy, "2.13.0"},
1919
{csv, "3.0.3", {pkg, csve}},

big_tests/rebar.lock

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@
1010
{<<"ct_groups_summary_hook">>,
1111
{pkg,<<"ct_groups_summary_hook">>,<<"0.1.1">>},
1212
0},
13-
{<<"escalus">>,{pkg,<<"escalus">>,<<"4.5.5">>},0},
13+
{<<"escalus">>,{pkg,<<"escalus">>,<<"4.5.6">>},0},
1414
{<<"esip">>,{pkg,<<"esip">>,<<"1.0.57">>},0},
1515
{<<"exml">>,{pkg,<<"hexml">>,<<"4.1.2">>},0},
1616
{<<"fast_pbkdf2">>,{pkg,<<"fast_pbkdf2">>,<<"2.0.0">>},2},
17-
{<<"fast_scram">>,{pkg,<<"fast_scram">>,<<"0.7.0">>},1},
17+
{<<"fast_scram">>,{pkg,<<"fast_scram">>,<<"0.7.1">>},1},
1818
{<<"fast_tls">>,{pkg,<<"fast_tls">>,<<"1.1.22">>},1},
1919
{<<"fusco">>,{pkg,<<"fusco">>,<<"0.1.1">>},0},
2020
{<<"gun">>,{pkg,<<"gun">>,<<"2.1.0">>},0},
@@ -42,11 +42,11 @@
4242
{<<"credentials_obfuscation">>, <<"61E282ADFB4439486B3994FAAEC69543C7EE6CC7E70C6340E8853FD9DEAF8219">>},
4343
{<<"csv">>, <<"69E7D9B3FDC72016644368762C6A3E6CBFEB85BCCADBF1BD99AB6C827E360E04">>},
4444
{<<"ct_groups_summary_hook">>, <<"21B94902B6CF2D345F4D790D34B49654E71CB8E570DCCC9C1C3616DAE720A7AA">>},
45-
{<<"escalus">>, <<"A4B0C297AA7633CF4380090564662F6B24C0E59A4453A8E96B22FE96AA1119F0">>},
45+
{<<"escalus">>, <<"054826CE22FA65FEB243107163487AC0A1A6742E4605216DF0C89613FF68033F">>},
4646
{<<"esip">>, <<"4B14E4832D08B9FFC10D855B5D10B3083232B1D53DEB4C046679496CE85569C4">>},
4747
{<<"exml">>, <<"4EA6B95AF18922F94FD67BBDEAA325A75CCE04487083C786E7417BA862D590E5">>},
4848
{<<"fast_pbkdf2">>, <<"72CDEE3C10C6B9B40E31194DE946A883CEEF6CF1F37D7FC9FD1A9D87502723F5">>},
49-
{<<"fast_scram">>, <<"FAD4DD185E0DEFA34B0E30654AB0CC4048E9324BCF65BB261E0A86BF3C604F9F">>},
49+
{<<"fast_scram">>, <<"4A0BB997A7836E44AC9E497D024A960FF9732A738190D1ABA4A02D0C8ABD170C">>},
5050
{<<"fast_tls">>, <<"44356B256AFAD4399C2FC5059A3066669DAFD8BD4E4E796C9C1CF8910DDD265E">>},
5151
{<<"fusco">>, <<"3DD6A90151DFEF30EA1937CC44E9A59177C0094918388D9BCAA2F2DC5E2AE4AA">>},
5252
{<<"gun">>, <<"B4E4CBBF3026D21981C447E9E7CA856766046EFF693720BA43114D7F5DE36E87">>},
@@ -73,11 +73,11 @@
7373
{<<"credentials_obfuscation">>, <<"843ADBE3246861CE0F1A0FA3222F384834EB31DEFD8D6B9CBA7AFD2977C957BC">>},
7474
{<<"csv">>, <<"741D1A55AABADAA3E0FE13051050101A73E90C4570B9F9403A939D9546813521">>},
7575
{<<"ct_groups_summary_hook">>, <<"997CDE48FEB0C398989E4091A341D4FFF43CFA06CDB8FB2E80CC4A0E0362691C">>},
76-
{<<"escalus">>, <<"C1FFC77E0B1A3FA74DBCCBA7EF66F0AC3B43979A1655AA6F6459FDA32BAC1791">>},
76+
{<<"escalus">>, <<"4818627C907ECD557D5162A6FBFE8B6FF6628AD5AC819104CB070E451928B7E0">>},
7777
{<<"esip">>, <<"19C357E1817B1E04792EF359BF900400F3E6D0E5ADE929FD72F88EA9B44AF2ED">>},
7878
{<<"exml">>, <<"03883AE3E27970E9DAC204B27CE330B54A6C2772455E43FE2319349DFF40B1DC">>},
7979
{<<"fast_pbkdf2">>, <<"74159FD09FB8BF5E97D25137C6C83C28E2CF7E97D7C127D83310DFD0904BD732">>},
80-
{<<"fast_scram">>, <<"39CB1D4C91C99E637E000A3864D274D8A9CB43D86EEC2495FE9546798DBFA015">>},
80+
{<<"fast_scram">>, <<"0022597BD143765B3884B64ABF53213DE32B4402F74BD24BFD4CEA9562E07EEF">>},
8181
{<<"fast_tls">>, <<"E65779AEFB7AB15C4755230FEF8077E687D20CC5A3984A5974F9F657E8E2485B">>},
8282
{<<"fusco">>, <<"6343551BD1E824F2A6CA85E1158C5B37C320FD449FBFEC7450A73F192AAF9022">>},
8383
{<<"gun">>, <<"52FC7FC246BFC3B00E01AEA1C2854C70A366348574AB50C57DFE796D24A0101D">>},

big_tests/tests/connect_SUITE.erl

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -455,7 +455,7 @@ correct_features_are_advertised_for_optional_starttls(Config) ->
455455
stream_features,
456456
{?MODULE, verify_features_with_optional_starttls},
457457
maybe_use_ssl,
458-
{?MODULE, verify_features_without_starttls},
458+
{?MODULE, verify_features_with_optional_starttls_post},
459459
authenticate],
460460
escalus_connection:start(UserSpec ++ [{ssl_opts, [{verify, verify_none}]}], Steps).
461461

@@ -465,7 +465,7 @@ correct_features_are_advertised_for_required_starttls(Config) ->
465465
stream_features,
466466
{?MODULE, verify_features_with_required_starttls},
467467
maybe_use_ssl,
468-
{?MODULE, verify_features_without_starttls},
468+
{?MODULE, verify_features_with_optional_starttls_post},
469469
authenticate],
470470
escalus_connection:start(UserSpec ++ [{ssl_opts, [{verify, verify_none}]}], Steps).
471471

@@ -479,6 +479,18 @@ verify_features_with_optional_starttls(Conn, Features) ->
479479
?assertMatch({sasl_mechanisms, [_|_]}, get_feature(sasl_mechanisms, Features)),
480480
{Conn, Features}.
481481

482+
verify_features_with_optional_starttls_post(Conn, Features) ->
483+
?assertEqual({starttls, false}, get_feature(starttls, Features)),
484+
{sasl_mechanisms, Mechanisms} = get_feature(sasl_mechanisms, Features),
485+
case lists:any(fun(M) -> re:run(M, "-PLUS$") /= nomatch end, Mechanisms) of
486+
true ->
487+
?assertEqual({sasl_channel_bindings, [<<"tls-exporter">>]},
488+
get_feature(sasl_channel_bindings, Features));
489+
false ->
490+
ok
491+
end,
492+
{Conn, Features}.
493+
482494
verify_features_with_required_starttls(Conn, Features) ->
483495
AdvertisedFeatures = lists:filter(fun is_present/1, Features),
484496
?assertEqual([{starttls, true}], AdvertisedFeatures),

include/mongoose_ns.hrl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@
8585
-define(NS_TLS, <<"urn:ietf:params:xml:ns:xmpp-tls">>).
8686
-define(NS_SASL, <<"urn:ietf:params:xml:ns:xmpp-sasl">>).
8787
-define(NS_SASL_2, <<"urn:xmpp:sasl:2">>).
88+
-define(NS_SASL_CB, <<"urn:xmpp:sasl-cb:0">>).
8889
-define(NS_SESSION, <<"urn:ietf:params:xml:ns:xmpp-session">>).
8990
-define(NS_BIND, <<"urn:ietf:params:xml:ns:xmpp-bind">>).
9091
-define(NS_BIND_2, <<"urn:xmpp:bind:0">>).

rebar.config

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@
5959

6060
%%% Stateless libraries
6161
{opuntia, "1.1.2"},
62-
{fast_scram, "0.7.0"},
62+
{fast_scram, "0.7.1"},
6363
{idna, "6.1.1"},
6464
{uuid, "2.0.7", {pkg, uuid_erl}},
6565
{gen_fsm_compat, "0.3.0"},

rebar.lock

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
{ref,"f1c369becb6e57871f1c7b0e491f6c3a302a65ee"}},
4040
0},
4141
{<<"fast_pbkdf2">>,{pkg,<<"fast_pbkdf2">>,<<"2.0.0">>},1},
42-
{<<"fast_scram">>,{pkg,<<"fast_scram">>,<<"0.7.0">>},0},
42+
{<<"fast_scram">>,{pkg,<<"fast_scram">>,<<"0.7.1">>},0},
4343
{<<"flatlog">>,{pkg,<<"flatlog">>,<<"0.1.2">>},0},
4444
{<<"fusco">>,{pkg,<<"fusco">>,<<"0.1.1">>},0},
4545
{<<"gen_fsm_compat">>,{pkg,<<"gen_fsm_compat">>,<<"0.3.0">>},0},
@@ -139,7 +139,7 @@
139139
{<<"erlcloud">>, <<"66DE6C7D37C6E688C7AE198D56B9CBE07B2CB80054B88A798437C533C3C7F418">>},
140140
{<<"exml">>, <<"4EA6B95AF18922F94FD67BBDEAA325A75CCE04487083C786E7417BA862D590E5">>},
141141
{<<"fast_pbkdf2">>, <<"72CDEE3C10C6B9B40E31194DE946A883CEEF6CF1F37D7FC9FD1A9D87502723F5">>},
142-
{<<"fast_scram">>, <<"FAD4DD185E0DEFA34B0E30654AB0CC4048E9324BCF65BB261E0A86BF3C604F9F">>},
142+
{<<"fast_scram">>, <<"4A0BB997A7836E44AC9E497D024A960FF9732A738190D1ABA4A02D0C8ABD170C">>},
143143
{<<"flatlog">>, <<"8C4B81A4931A1396254DBD975B841F4A6350D6F128FF94FFE86799A4451E32B1">>},
144144
{<<"fusco">>, <<"3DD6A90151DFEF30EA1937CC44E9A59177C0094918388D9BCAA2F2DC5E2AE4AA">>},
145145
{<<"gen_fsm_compat">>, <<"5903549F67D595F58A7101154CBE0FDD46955FBFBE40813F1E53C23A970FF5F4">>},
@@ -206,7 +206,7 @@
206206
{<<"erlcloud">>, <<"6ED59CBD8816045765E3E76F22D08118766DF1BB1D24F5D90794C8505BCD6D44">>},
207207
{<<"exml">>, <<"03883AE3E27970E9DAC204B27CE330B54A6C2772455E43FE2319349DFF40B1DC">>},
208208
{<<"fast_pbkdf2">>, <<"74159FD09FB8BF5E97D25137C6C83C28E2CF7E97D7C127D83310DFD0904BD732">>},
209-
{<<"fast_scram">>, <<"39CB1D4C91C99E637E000A3864D274D8A9CB43D86EEC2495FE9546798DBFA015">>},
209+
{<<"fast_scram">>, <<"0022597BD143765B3884B64ABF53213DE32B4402F74BD24BFD4CEA9562E07EEF">>},
210210
{<<"flatlog">>, <<"FDD2A311A67F63F9D0BC194FAD6BEAF9CCCDE8FFFEE2919DF1C4D86098E49984">>},
211211
{<<"fusco">>, <<"6343551BD1E824F2A6CA85E1158C5B37C320FD449FBFEC7450A73F192AAF9022">>},
212212
{<<"gen_fsm_compat">>, <<"7153D11BAD328933D4B24E663D8CEC52874E14176C7FB392FA1FF768B17460D9">>},

src/c2s/mongoose_c2s_sasl.erl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
%% This way, we can decouple SASL from the client process core code.
1010
%% @end
1111
-module(mongoose_c2s_sasl).
12+
-xep([{xep, 440}, {version, "1.0.0"}]).
1213

1314
-include_lib("kernel/include/logger.hrl").
1415

src/c2s/mongoose_c2s_stanzas.erl

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,19 +61,20 @@ stream_features_before_auth(StateData) ->
6161
determine_features(_, _, _, #{tls := #{mode := starttls_required}}, false) ->
6262
[starttls_stanza(required)];
6363
determine_features(StateData, HostType, LServer, #{tls := #{mode := starttls}}, false) ->
64-
InitialFeatures = [starttls_stanza(optional) | maybe_sasl_mechanisms(StateData)],
64+
InitialFeatures = [starttls_stanza(optional) | maybe_sasl_features(StateData)],
6565
StreamFeaturesParams = #{c2s_data => StateData, lserver => LServer},
6666
mongoose_hooks:c2s_stream_features(HostType, StreamFeaturesParams, InitialFeatures);
6767
determine_features(StateData, HostType, LServer, _, _) ->
68-
InitialFeatures = maybe_sasl_mechanisms(StateData),
68+
InitialFeatures = maybe_sasl_features(StateData),
6969
StreamFeaturesParams = #{c2s_data => StateData, lserver => LServer},
7070
mongoose_hooks:c2s_stream_features(HostType, StreamFeaturesParams, InitialFeatures).
7171

72-
-spec maybe_sasl_mechanisms(mongoose_c2s:data()) -> [exml:element()].
73-
maybe_sasl_mechanisms(StateData) ->
72+
-spec maybe_sasl_features(mongoose_c2s:data()) -> [exml:element()].
73+
maybe_sasl_features(StateData) ->
7474
case mongoose_c2s:get_auth_mechs_to_announce(StateData) of
7575
[] -> [];
7676
Mechanisms ->
77+
maybe_sasl_channel_bindings(Mechanisms) ++
7778
[#xmlel{name = <<"mechanisms">>,
7879
attrs = #{<<"xmlns">> => ?NS_SASL},
7980
children = [ mechanism(M) || M <- Mechanisms ]}]
@@ -83,6 +84,30 @@ maybe_sasl_mechanisms(StateData) ->
8384
mechanism(M) ->
8485
#xmlel{name = <<"mechanism">>, children = [#xmlcdata{content = M}]}.
8586

87+
-spec maybe_sasl_channel_bindings([binary()]) -> [exml:element()].
88+
maybe_sasl_channel_bindings(Mechanisms) ->
89+
case determine_channel_bindings(Mechanisms) of
90+
[] -> [];
91+
Bindings ->
92+
[#xmlel{name = <<"sasl-channel-binding">>,
93+
attrs = #{<<"xmlns">> => ?NS_SASL_CB},
94+
children = [ channel_binding(B) || B <- Bindings ]}]
95+
end.
96+
97+
determine_channel_bindings(Mechanisms) ->
98+
case lists:any(fun(<<"SCRAM-SHA-1-PLUS">>) -> true;
99+
(<<"SCRAM-SHA-", _:3/binary, "-PLUS">>) -> true;
100+
(_) -> false
101+
end, Mechanisms) of
102+
true -> [<<"tls-exporter">>];
103+
false -> []
104+
end.
105+
106+
-spec channel_binding(binary()) -> exml:element().
107+
channel_binding(B) ->
108+
#xmlel{name = <<"channel-binding">>, attrs = #{<<"type">> => B}}.
109+
110+
86111
-spec starttls_stanza(required | optional) -> exml:element().
87112
starttls_stanza(TLSRequired) when TLSRequired =:= required; TLSRequired =:= optional ->
88113
#xmlel{name = <<"starttls">>,

tools/ssl/openssl-ca.cnf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ default_ca = CA_default # The default ca section
1010

1111
[ CA_default ]
1212

13-
default_days = 1000 # how long to certify for
13+
default_days = 825 # how long to certify for
1414
default_crl_days = 30 # how long before next CRL
1515
default_md = sha256 # use public key default MD
1616
preserve = no # keep passed DN ordering

tools/ssl/openssl-mongooseim.cnf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ commonName = MongooseIM
2222
subjectKeyIdentifier = hash
2323
basicConstraints = CA:FALSE
2424
keyUsage = digitalSignature, keyEncipherment
25+
extendedKeyUsage = serverAuth
2526
subjectAltName = @alternate_names
2627
nsComment = "Fake Dev-Only Certificate"
2728

0 commit comments

Comments
 (0)