diff --git a/src/ejabberd.erl b/src/ejabberd.erl index 0ebadc358..40d0bc448 100644 --- a/src/ejabberd.erl +++ b/src/ejabberd.erl @@ -10,14 +10,19 @@ -author('alexey@sevcom.net'). -vsn('$Revision$ '). --export([start/0]). +-export([start/0, init/0]). start() -> + spawn(?MODULE, init, []). + +init() -> register(ejabberd, self()), {A1, A2, A3} = now(), random:seed(A1,A2,A3), ok = erl_ddll:load_driver(".", expat_erl), Port = open_port({spawn, expat_erl}, [binary]), + db_init(), + ejabberd_auth:start(), ejabberd_listener:start(), loop(Port). @@ -27,3 +32,7 @@ loop(Port) -> _ -> loop(Port) end. + +db_init() -> + mnesia:create_schema([node()]), + mnesia:start(). diff --git a/src/ejabberd_auth.erl b/src/ejabberd_auth.erl new file mode 100644 index 000000000..3a579a41b --- /dev/null +++ b/src/ejabberd_auth.erl @@ -0,0 +1,122 @@ +%%%---------------------------------------------------------------------- +%%% File : ejabberd_auth.erl +%%% Author : Alexey Shchepin +%%% Purpose : +%%% Created : 23 Nov 2002 by Alexey Shchepin +%%% Id : $Id$ +%%%---------------------------------------------------------------------- + +-module(ejabberd_auth). +-author('alexey@sevcom.net'). +-vsn('$Revision$ '). + +%%-compile(export_all). +%%-export([Function/Arity, ...]). + +-behaviour(gen_server). + +%% External exports +-export([start/0, start_link/0, set_password/2, check_password/2]). + +%% gen_server callbacks +-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2]). + +-record(state, {}). + +-record(passwd, {jid, password}). + +%%%---------------------------------------------------------------------- +%%% API +%%%---------------------------------------------------------------------- +start() -> + gen_server:start({local, ejabberd_auth}, ejabberd_auth, [], []). +start_link() -> + gen_server:start_link({local, ejabberd_auth}, ejabberd_auth, [], []). + +%%%---------------------------------------------------------------------- +%%% Callback functions from gen_server +%%%---------------------------------------------------------------------- + +%%---------------------------------------------------------------------- +%% Func: init/1 +%% Returns: {ok, State} | +%% {ok, State, Timeout} | +%% ignore | +%% {stop, Reason} +%%---------------------------------------------------------------------- +init([]) -> + mnesia:create_table(passwd,[{disc_copies, [node()]}, + {attributes, record_info(fields, passwd)}]), + {ok, #state{}}. + +%%---------------------------------------------------------------------- +%% Func: handle_call/3 +%% Returns: {reply, Reply, State} | +%% {reply, Reply, State, Timeout} | +%% {noreply, State} | +%% {noreply, State, Timeout} | +%% {stop, Reason, Reply, State} | (terminate/2 is called) +%% {stop, Reason, State} (terminate/2 is called) +%%---------------------------------------------------------------------- +handle_call(Request, From, State) -> + Reply = ok, + {reply, Reply, State}. + +%%---------------------------------------------------------------------- +%% Func: handle_cast/2 +%% Returns: {noreply, State} | +%% {noreply, State, Timeout} | +%% {stop, Reason, State} (terminate/2 is called) +%%---------------------------------------------------------------------- +handle_cast(Msg, State) -> + {noreply, State}. + +%%---------------------------------------------------------------------- +%% Func: handle_info/2 +%% Returns: {noreply, State} | +%% {noreply, State, Timeout} | +%% {stop, Reason, State} (terminate/2 is called) +%%---------------------------------------------------------------------- +handle_info(Info, State) -> + {noreply, State}. + +%%---------------------------------------------------------------------- +%% Func: terminate/2 +%% Purpose: Shutdown the server +%% Returns: any (ignored by gen_server) +%%---------------------------------------------------------------------- +terminate(Reason, State) -> + ok. + +%%%---------------------------------------------------------------------- +%%% Internal functions +%%%---------------------------------------------------------------------- + +check_password(Jid, Password) -> + F = fun() -> + case mnesia:read({passwd, Jid}) of + [E] -> + E#passwd.password + end + end, + case mnesia:transaction(F) of + {atomic, Password} -> + true; + _ -> + false + end. + + +set_password(Jid, 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 + end, + mnesia:transaction(F). + diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl index 251f32570..518f5a488 100644 --- a/src/ejabberd_c2s.erl +++ b/src/ejabberd_c2s.erl @@ -99,10 +99,21 @@ wait_for_stream(closed, StateData) -> wait_for_auth({xmlstreamelement, El}, StateData) -> case is_auth_packet(El) of - {auth, {U, P, D, R}} -> + {auth, ID, {U, P, D, R}} -> io:format("AUTH: ~p~n", [{U, P, D, R}]), - % TODO - {next_state, session_established, StateData}; + case ejabberd_auth:check_password(U, P) of + true -> + {next_state, session_established, StateData}; + _ -> + {xmlelement, _, _, SubTags} = El, + Err = {xmlelement, "iq", + [{"id", "0"}, {"type", "error"}], + SubTags ++ [{xmlelement, "error", + [{"code", "404"}], + [{xmlcdata, "Unauthorized"}]}]}, + send_element(StateData#state.sender, Err), + {next_state, wait_for_auth, StateData} + end; _ -> {next_state, wait_for_auth, StateData} end; @@ -202,6 +213,9 @@ sender(Socket) -> send_text(Pid, Text) -> Pid ! {text, Text}. +send_element(Pid, El) -> + send_text(Pid, xml:element_to_string(El)). + new_id() -> io_lib:format("~p", [random:uniform(65536*65536)]). @@ -213,7 +227,9 @@ is_auth_packet({xmlelement, Name, Attrs, Els}) when Name == "iq" -> [{xmlelement, "query", Attrs2, Els2}] -> case xml:get_attr_s("xmlns", Attrs2) of "jabber:iq:auth" -> - {auth, get_auth_tags(Els2, "", "", "", "")}; + {auth, + xml:get_attr_s("id", Attrs), + get_auth_tags(Els2, "", "", "", "")}; _ -> false end; _ -> diff --git a/src/jlib.erl b/src/jlib.erl new file mode 100644 index 000000000..17a194ebe --- /dev/null +++ b/src/jlib.erl @@ -0,0 +1,19 @@ +%%%---------------------------------------------------------------------- +%%% File : jlib.erl +%%% Author : Alexey Shchepin +%%% Purpose : +%%% Created : 23 Nov 2002 by Alexey Shchepin +%%% Id : $Id$ +%%%---------------------------------------------------------------------- + +-module(jlib). +-author('alexey@sevcom.net'). +-vsn('$Revision$ '). + +%%-export([Function/Arity, ...]). + + +send_iq(From, To, ID, SubTags) -> + ok. + + diff --git a/xml_stream.beam b/xml_stream.beam new file mode 100644 index 000000000..2043d686c Binary files /dev/null and b/xml_stream.beam differ