summaryrefslogtreecommitdiff
path: root/src/ejabberd_piefxis.erl
diff options
context:
space:
mode:
authorBadlop <badlop@process-one.net>2011-08-16 00:26:49 +0200
committerBadlop <badlop@process-one.net>2011-08-16 00:26:49 +0200
commit1ee6eae684c126b486c70a3cadd58fa282f517ad (patch)
tree9e15e7960fa6d3ca0b90fcf3e23ba158bf2d6535 /src/ejabberd_piefxis.erl
parentIndicate license and copyright (thanks to Stephen Röttger)(EJAB-1196) (diff)
Fix and improve support for SCRAM auth method (EJAB-1196)
Diffstat (limited to 'src/ejabberd_piefxis.erl')
-rw-r--r--src/ejabberd_piefxis.erl53
1 files changed, 41 insertions, 12 deletions
diff --git a/src/ejabberd_piefxis.erl b/src/ejabberd_piefxis.erl
index 02697163..cf5178bb 100644
--- a/src/ejabberd_piefxis.erl
+++ b/src/ejabberd_piefxis.erl
@@ -159,13 +159,13 @@ process_element(El=#xmlel{name=user, ns=_XMLNS},
State;
process_element(H=#xmlel{name=host},State) ->
- State#parsing_state{host=?BTL(exmpp_xml:get_attribute(H,"jid",none))};
+ State#parsing_state{host=?BTL(exmpp_xml:get_attribute(H, <<"jid">>, none))};
process_element(#xmlel{name='server-data'},State) ->
State;
process_element(El=#xmlel{name=include, ns=?NS_XINCLUDE}, State=#parsing_state{dir=Dir}) ->
- case exmpp_xml:get_attribute(El, href, none) of
+ case exmpp_xml:get_attribute(El, <<"href">>, none) of
none ->
ok;
HrefB ->
@@ -194,25 +194,26 @@ process_element(El,State) ->
%%%% Add user
add_user(El, Domain) ->
- User = exmpp_xml:get_attribute(El,name,none),
- Password = exmpp_xml:get_attribute(El,password,none),
- add_user(El, Domain, User, Password).
+ User = exmpp_xml:get_attribute(El, <<"name">>, none),
+ PasswordFormat = exmpp_xml:get_attribute(El, <<"password-format">>, none),
+ Password = exmpp_xml:get_attribute(El, <<"password">>, none),
+ add_user(El, Domain, User, PasswordFormat, Password).
%% @spec (El::xmlel(), Domain::string(), User::binary(), Password::binary() | none)
%% -> ok | {error, ErrorText::string()}
%% @doc Add a new user to the database.
%% If user already exists, it will be only updated.
-add_user(El, Domain, UserBinary, none) ->
+add_user(El, Domain, UserBinary, <<"plaintext">>, none) ->
User = ?BTL(UserBinary),
io:format("Account ~s@~s will not be created, updating it...~n",
[User, Domain]),
io:format(""),
populate_user_with_elements(El, Domain, User),
ok;
-add_user(El, Domain, UserBinary, PasswordBinary) ->
+add_user(El, Domain, UserBinary, PasswordFormat, PasswordBinary) ->
User = ?BTL(UserBinary),
- Password = ?BTL(PasswordBinary),
- case create_user(User,Password,Domain) of
+ Password2 = prepare_password(PasswordFormat, PasswordBinary, El),
+ case create_user(User,Password2,Domain) of
ok ->
populate_user_with_elements(El, Domain, User),
ok;
@@ -227,6 +228,21 @@ add_user(El, Domain, UserBinary, PasswordBinary) ->
{error, Other}
end.
+prepare_password(<<"plaintext">>, PasswordBinary, _El) ->
+ ?BTL(PasswordBinary);
+prepare_password(<<"scram">>, none, El) ->
+ ScramEl = exmpp_xml:get_element(El, 'scram-hash'),
+ #scram{storedkey = base64:decode(exmpp_xml:get_attribute(
+ ScramEl, <<"stored-key">>, none)),
+ serverkey = base64:decode(exmpp_xml:get_attribute(
+ ScramEl, <<"server-key">>, none)),
+ salt = base64:decode(exmpp_xml:get_attribute(
+ ScramEl, <<"salt">>, none)),
+ iterationcount = list_to_integer(exmpp_xml:get_attribute_as_list(
+ ScramEl, <<"iteration-count">>,
+ ?SCRAM_DEFAULT_ITERATION_COUNT))
+ }.
+
populate_user_with_elements(El, Domain, User) ->
exmpp_xml:foreach(
fun (_,Child) ->
@@ -346,7 +362,7 @@ populate_user(User,Domain,El=#xmlel{name='offline-messages'}) ->
fun (_Element, {xmlcdata, _}) ->
ok;
(_Element, Child) ->
- From = exmpp_xml:get_attribute(Child,from,none),
+ From = exmpp_xml:get_attribute(Child, <<"from">>,none),
FullFrom = jid_to_old_jid(exmpp_jid:parse(From)),
FullUser = jid_to_old_jid(exmpp_jid:make(User,
Domain)),
@@ -538,10 +554,23 @@ export_user(Fd, Username, Host) ->
%% @spec (Username::string(), Host::string()) -> string()
extract_user(Username, Host) ->
- Password = ejabberd_auth:get_password_s(Username, Host),
+ Password = ejabberd_auth:get_password(Username, Host),
+ PasswordStr = build_password_string(Password),
UserInfo = [extract_user_info(InfoName, Username, Host) || InfoName <- [roster, offline, private, vcard]],
UserInfoString = lists:flatten(UserInfo),
- io_lib:format("<user name='~s' password='~s'>~s</user>", [Username, Password, UserInfoString]).
+ io_lib:format("<user name='~s' ~s ~s</user>",
+ [Username, PasswordStr, UserInfoString]).
+
+build_password_string({StoredKey, ServerKey, Salt, IterationCount}) ->
+ io_lib:format("password-format='scram'>"
+ "<scram-hash stored-key='~s' server-key='~s' "
+ "salt='~s' iteration-count='~w'/> ",
+ [base64:encode_to_string(StoredKey),
+ base64:encode_to_string(ServerKey),
+ base64:encode_to_string(Salt),
+ IterationCount]);
+build_password_string(Password) when is_list(Password) ->
+ io_lib:format("password-format='plaintext' password='~s'>", [Password]).
%% @spec (InfoName::atom(), Username::string(), Host::string()) -> string()
extract_user_info(roster, Username, Host) ->