diff --git a/src/cyrsasl_plain.erl b/src/cyrsasl_plain.erl index 4e69b06ba..696e303e5 100644 --- a/src/cyrsasl_plain.erl +++ b/src/cyrsasl_plain.erl @@ -44,7 +44,7 @@ mech_new(_Host, _GetPassword, CheckPassword, _CheckPasswordDigest) -> {ok, #state{check_password = CheckPassword}}. mech_step(State, ClientIn) -> - case parse(ClientIn) of + case prepare(ClientIn) of [AuthzId, User, Password] -> case (State#state.check_password)(User, Password) of {true, AuthModule} -> @@ -57,6 +57,24 @@ mech_step(State, ClientIn) -> {error, "bad-protocol"} end. +prepare(ClientIn) -> + case parse(ClientIn) of + [[], UserMaybeDomain, Password] -> + case parse_domain(UserMaybeDomain) of + %% login@domainpwd + [User, Domain] -> + [UserMaybeDomain, User, Password]; + %% loginpwd + [User] -> + ["", User, Password] + end; + %% login@domainloginpwd + [AuthzId, User, Password] -> + [AuthzId, User, Password]; + _ -> + error + end. + parse(S) -> parse1(S, "", []). @@ -71,5 +89,12 @@ parse1([], S, T) -> lists:reverse([lists:reverse(S) | T]). +parse_domain(S) -> + parse_domain1(S, "", []). - +parse_domain1([$@ | Cs], S, T) -> + parse_domain1(Cs, "", [lists:reverse(S) | T]); +parse_domain1([C | Cs], S, T) -> + parse_domain1(Cs, [C | S], T); +parse_domain1([], S, T) -> + lists:reverse([lists:reverse(S) | T]).