From 534b6925a399a2ea3ab5477078c463e4d153f1bf Mon Sep 17 00:00:00 2001 From: Alexey Shchepin Date: Sun, 8 Dec 2002 17:23:21 +0000 Subject: [PATCH] *** empty log message *** SVN Revision: 14 --- src/ejabberd_auth.erl | 36 +++++++++++------- src/ejabberd_c2s.erl | 15 +++++++- src/jlib.erl | 85 ++++++++++++++++++++++++++++++++++++++++++- src/mod_register.erl | 75 ++++++++++++++++++++++++++++++++++++++ src/xml.erl | 7 +++- 5 files changed, 201 insertions(+), 17 deletions(-) create mode 100644 src/mod_register.erl diff --git a/src/ejabberd_auth.erl b/src/ejabberd_auth.erl index 3a579a41b..6d150eae8 100644 --- a/src/ejabberd_auth.erl +++ b/src/ejabberd_auth.erl @@ -16,14 +16,17 @@ -behaviour(gen_server). %% External exports --export([start/0, start_link/0, set_password/2, check_password/2]). +-export([start/0, start_link/0, + set_password/2, + check_password/2, + try_register/2]). %% gen_server callbacks -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2]). -record(state, {}). --record(passwd, {jid, password}). +-record(passwd, {user, password}). %%%---------------------------------------------------------------------- %%% API @@ -92,9 +95,11 @@ terminate(Reason, State) -> %%% Internal functions %%%---------------------------------------------------------------------- -check_password(Jid, Password) -> +% TODO: lowercase user name + +check_password(User, Password) -> F = fun() -> - case mnesia:read({passwd, Jid}) of + case mnesia:read({passwd, User}) of [E] -> E#passwd.password end @@ -107,16 +112,21 @@ check_password(Jid, Password) -> end. -set_password(Jid, Password) -> +set_password(User, Password) -> F = fun() -> - case mnesia:read({passwd, Jid}) of - [] -> - New = #passwd{jid = Jid, password = Password}, - mnesia:write(New); - [E] -> - New = E#passwd{password = Password}, - mnesia:write(New) - end + mnesia:write(#passwd{user = User, password = Password}) end, mnesia:transaction(F). +try_register(User, Password) -> + F = fun() -> + case mnesia:read({passwd, User}) of + [] -> + mnesia:write(#passwd{user = User, password = Password}), + ok; + [E] -> + exists + end + end, + mnesia:transaction(F). + diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl index 5c32bbde0..79b30de16 100644 --- a/src/ejabberd_c2s.erl +++ b/src/ejabberd_c2s.erl @@ -118,7 +118,20 @@ wait_for_auth({xmlstreamelement, El}, StateData) -> {next_state, wait_for_auth, StateData} end; _ -> - {next_state, wait_for_auth, StateData} + case jlib:iq_query_info(El) of + {iq, ID, Type, "jabber:iq:register", SubEl} -> + ResIQ = mod_register:process_iq( + {"", "", ""}, {"", ?MYNAME, ""}, + {iq, ID, Type, "jabber:iq:register", SubEl}), + Res1 = jlib:replace_from_to({"", ?MYNAME, ""}, + {"", "", ""}, + jlib:iq_to_xml(ResIQ)), + Res = jlib:remove_attr("to", Res1), + send_element(StateData#state.sender, Res), + {next_state, wait_for_auth, StateData}; + _ -> + {next_state, wait_for_auth, StateData} + end end; wait_for_auth({xmlstreamend, Name}, StateData) -> diff --git a/src/jlib.erl b/src/jlib.erl index b1262e0ef..c4c510f4d 100644 --- a/src/jlib.erl +++ b/src/jlib.erl @@ -14,9 +14,15 @@ make_error_reply/3, make_correct_from_to_attrs/3, replace_from_to_attrs/3, + replace_from_to/3, + remove_attr/2, string_to_jid/1, jid_to_string/1, - tolower/1]). + tolower/1, + get_iq_namespace/1, + iq_query_info/1, + iq_to_xml/1, + get_subtag/2]). %send_iq(From, To, ID, SubTags) -> @@ -93,6 +99,16 @@ replace_from_to_attrs(From, To, Attrs) -> Attrs4 = [{"from", From} | Attrs3], Attrs4. +replace_from_to(From, To, {xmlelement, Name, Attrs, Els}) -> + NewAttrs = replace_from_to_attrs(jlib:jid_to_string(From), + jlib:jid_to_string(To), + Attrs), + {xmlelement, Name, NewAttrs, Els}. + + +remove_attr(Attr, {xmlelement, Name, Attrs, Els}) -> + NewAttrs = lists:keydelete(Attr, 1, Attrs), + {xmlelement, Name, NewAttrs, Els}. string_to_jid(J) -> string_to_jid1(J, ""). @@ -155,3 +171,70 @@ tolower_c(C) -> tolower(S) -> lists:map(fun tolower_c/1, S). + + +get_iq_namespace({xmlelement, Name, Attrs, Els}) when Name == "iq" -> + case xml:remove_cdata(Els) of + [{xmlelement, Name2, Attrs2, Els2}] -> + xml:get_attr_s("xmlns", Attrs2); + _ -> + "" + end; +get_iq_namespace(_) -> + "". + +iq_query_info({xmlelement, Name, Attrs, Els}) when Name == "iq" -> + ID = xml:get_attr_s("id", Attrs), + Type = xml:get_attr_s("type", Attrs), + case xml:remove_cdata(Els) of + [{xmlelement, Name2, Attrs2, Els2}] -> + XMLNS = xml:get_attr_s("xmlns", Attrs2), + Type1 = case Type of + "set" -> set; + "get" -> get; + _ -> invalid + end, + if + (Type1 /= invalid) and (XMLNS /= "") -> + {iq, ID, Type1, XMLNS, {xmlelement, Name2, Attrs2, Els2}}; + true -> + invalid + end; + _ -> + invalid + end; +iq_query_info(_) -> + not_iq. + +iq_type_to_string(set) -> "set"; +iq_type_to_string(get) -> "get"; +iq_type_to_string(result) -> "result"; +iq_type_to_string(error) -> "error"; +iq_type_to_string(_) -> invalid. + + +iq_to_xml({iq, ID, Type, _, SubEl}) -> + if + ID /= "" -> + {xmlelement, "iq", + [{"id", ID}, {"type", iq_type_to_string(Type)}], SubEl}; + true -> + {xmlelement, "iq", + [{"type", iq_type_to_string(Type)}], SubEl} + end. + + +get_subtag({xmlelement, _, _, Els}, Name) -> + get_subtag1(Els, Name). + +get_subtag1([El | Els], Name) -> + case El of + {xmlelement, Name, _, _} -> + El; + _ -> + get_subtag1(Els, Name) + end; +get_subtag1([], _) -> + false. + + diff --git a/src/mod_register.erl b/src/mod_register.erl new file mode 100644 index 000000000..ecd064b62 --- /dev/null +++ b/src/mod_register.erl @@ -0,0 +1,75 @@ +%%%---------------------------------------------------------------------- +%%% File : mod_register.erl +%%% Author : Alexey Shchepin +%%% Purpose : +%%% Created : 8 Dec 2002 by Alexey Shchepin +%%% Id : $Id$ +%%%---------------------------------------------------------------------- + +-module(mod_register). +-author('alexey@sevcom.net'). +-vsn('$Revision$ '). + +-export([process_iq/3]). + +-include("ejabberd.hrl"). + +process_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) -> + case Type of + set -> + UTag = jlib:get_subtag(SubEl, "username"), + PTag = jlib:get_subtag(SubEl, "password"), + RTag = jlib:get_subtag(SubEl, "remove"), + if + (UTag /= false) and (RTag /= false) -> + {iq, ID, error, XMLNS, + [SubEl, {xmlelement, + "error", + [{"code", "501"}], + [{xmlcdata, "Not Implemented"}]}]}; + (UTag /= false) and (PTag /= false) -> + User = xml:get_tag_cdata(UTag), + Password = xml:get_tag_cdata(PTag), + Server = ?MYNAME, + case From of + {User, Server, _} -> + ejabberd_auth:set_password(User, Password), + {iq, ID, result, XMLNS, [SubEl]}; + _ -> + case try_register(User, Password) of + ok -> + {iq, ID, result, XMLNS, [SubEl]}; + {error, Code, Reason} -> + {iq, ID, error, XMLNS, + [SubEl, {xmlelement, + "error", + [{"code", Code}], + [{xmlcdata, Reason}]}]} + end + end + end; + get -> + {iq, ID, error, XMLNS, [{xmlelement, + "query", + [{"xmlns", "jabber:iq:register"}], + [{xmlelement, "instructions", [], + {xmlcdata, + "Choose a username and password " + "to register with this server."}}, + {xmlelement, "username", [], []}, + {xmlelement, "password", [], []}]}]} + end. + + +try_register(User, Password) -> + case ejabberd_auth:try_register(User, Password) of + {atomic, ok} -> + ok; + {atomic, exists} -> + {error, "400", "Bad Request"}; + {error, Reason} -> + {error, "500", "Internal Server Error"} + end. + + + diff --git a/src/xml.erl b/src/xml.erl index 9ae4d5091..3bdcb62f7 100644 --- a/src/xml.erl +++ b/src/xml.erl @@ -10,7 +10,8 @@ -author('alexey@sevcom.net'). -vsn('$Revision$ '). --export([element_to_string/1, crypt/1, remove_cdata/1, get_cdata/1, +-export([element_to_string/1, crypt/1, remove_cdata/1, + get_cdata/1, get_tag_cdata/1, get_attr/2, get_attr_s/2]). element_to_string(El) -> @@ -72,7 +73,9 @@ get_cdata([_ | L], S) -> get_cdata(L, S); get_cdata([], S) -> S. - + +get_tag_cdata({xmlelement, Name, Attrs, Els}) -> + get_cdata(Els). get_attr(AttrName, Attrs) -> case lists:keysearch(AttrName, 1, Attrs) of