diff --git a/src/ejabberd.erl b/src/ejabberd.erl index 4036e92e8..34cabc42d 100644 --- a/src/ejabberd.erl +++ b/src/ejabberd.erl @@ -23,6 +23,7 @@ init() -> Port = open_port({spawn, expat_erl}, [binary]), db_init(), ejabberd_auth:start(), + ejabberd_router:start(), ejabberd_sm:start(), ejabberd_listener:start(), loop(Port). diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl index 6cce2f261..0fd3b36e2 100644 --- a/src/ejabberd_c2s.erl +++ b/src/ejabberd_c2s.erl @@ -21,7 +21,8 @@ % -export([init/1, wait_for_stream/2, wait_for_auth/2, terminate/3]). --record(state, {socket, sender, receiver, streamid}). +-record(state, {socket, sender, receiver, streamid, + user = "", server = "localhost", resource = ""}). -include("ejabberd.hrl"). @@ -101,18 +102,20 @@ wait_for_auth({xmlstreamelement, El}, StateData) -> case is_auth_packet(El) of {auth, ID, {U, P, D, R}} -> io:format("AUTH: ~p~n", [{U, P, D, R}]), + % TODO: digested password case ejabberd_auth:check_password(U, P) of true -> % TODO - {next_state, session_established, StateData}; + {next_state, session_established, + StateData#state{user = U, resource = R}}; _ -> - Err = xml:make_error_iq_reply(El, "404", "Unauthorized"), + Err = jlib:make_error_iq_reply(El, "404", "Unauthorized"), send_element(StateData#state.sender, Err), {next_state, wait_for_auth, StateData} end; _ -> {next_state, wait_for_auth, StateData} -end; + end; wait_for_auth({xmlstreamend, Name}, StateData) -> % TODO @@ -121,6 +124,14 @@ wait_for_auth({xmlstreamend, Name}, StateData) -> wait_for_auth(closed, StateData) -> {stop, normal, StateData}. +session_established({xmlstreamelement, El}, StateData) -> + {xmlelement, Name, Attrs, Els} = El, + % TODO + {next_state, session_established, StateData}; + +session_established(closed, StateData) -> + % TODO + {stop, normal, StateData}. @@ -213,7 +224,7 @@ send_element(Pid, El) -> send_text(Pid, xml:element_to_string(El)). new_id() -> - io_lib:format("~p", [random:uniform(65536*65536)]). + lists:flatten(io_lib:format("~p", [random:uniform(65536*65536)])). is_auth_packet({xmlelement, Name, Attrs, Els}) when Name == "iq" -> @@ -257,3 +268,5 @@ get_auth_tags([], U, P, D, R) -> {U, P, D, R}. + + diff --git a/src/ejabberd_router.erl b/src/ejabberd_router.erl new file mode 100644 index 000000000..5ca2cf014 --- /dev/null +++ b/src/ejabberd_router.erl @@ -0,0 +1,43 @@ +%%%---------------------------------------------------------------------- +%%% File : ejabberd_router.erl +%%% Author : Alexey Shchepin +%%% Purpose : +%%% Created : 27 Nov 2002 by Alexey Shchepin +%%% Id : $Id$ +%%%---------------------------------------------------------------------- + +-module(ejabberd_router). +-author('alexey@sevcom.net'). + +%%-export([Function/Arity, ...]). + +-export([start/0, init/0]). + +-record(service, {domain, node, pid}). + + +start() -> + spawn(ejabberd_router, init, []). + +init() -> + register(ejabberd_router, self()), + mnesia:create_table(service, + [{ram_copies, [node()]}, + {attributes, + record_info(fields, service)}]), + loop(). + +loop() -> + receive + {route, From, To, Packet} -> + % TODO + loop(); + {register_service, Domain, Pid, Node} -> + % TODO + loop(); + {unregister_service, Domain} -> + % TODO + loop(); + _ -> + loop() + end. diff --git a/src/jlib.erl b/src/jlib.erl index 17a194ebe..0ee2ba74a 100644 --- a/src/jlib.erl +++ b/src/jlib.erl @@ -10,10 +10,102 @@ -author('alexey@sevcom.net'). -vsn('$Revision$ '). -%%-export([Function/Arity, ...]). +-export([make_error_iq_reply/3, make_correct_from_to_attrs/3, + replace_from_to_attrs/3, string_to_jid/1, tolower/1]). -send_iq(From, To, ID, SubTags) -> - ok. +%send_iq(From, To, ID, SubTags) -> +% ok. + +make_error_iq_reply({xmlelement, Name, Attrs, SubTags}, Code, Desc) + when Name == "iq" -> + NewAttrs = make_error_iq_reply_attrs(Attrs), + {xmlelement, Name, NewAttrs, SubTags ++ [{xmlelement, "error", + [{"code", Code}], + [{xmlcdata, Desc}]}]}. + +make_error_iq_reply_attrs(Attrs) -> + To = xml:get_attr("to", Attrs), + From = xml:get_attr("from", Attrs), + Attrs1 = lists:keydelete("to", 1, Attrs), + Attrs2 = lists:keydelete("from", 1, Attrs1), + Attrs3 = case To of + {value, ToVal} -> + [{"from", ToVal} | Attrs2]; + _ -> + Attrs2 + end, + Attrs4 = case From of + {value, FromVal} -> + [{"to", FromVal} | Attrs3]; + _ -> + Attrs3 + end, + Attrs5 = lists:keydelete("type", 1, Attrs4), + Attrs6 = [{"type", "error"} | Attrs5], + Attrs6. + +make_correct_from_to_attrs(From, To, Attrs) -> + Attrs1 = lists:keydelete("from", 1, Attrs), + Attrs2 = case xml:get_attr("to", Attrs) of + {value, _} -> + Attrs1; + _ -> + [{"to", To} | Attrs1] + end, + Attrs3 = [{"from", From} | Attrs2], + Attrs3. +replace_from_to_attrs(From,To,Attrs) -> + Attrs1 = lists:keydelete("to", 1, Attrs), + Attrs2 = lists:keydelete("from", 1, Attrs1), + Attrs3 = [{"to", To} | Attrs2], + Attrs4 = [{"from", From} | Attrs3], + Attrs4. + + +string_to_jid(J) -> + string_to_jid1(J, ""). + +string_to_jid1([$@ | J], "") -> + error; +string_to_jid1([$@ | J], N) -> + string_to_jid2(J, lists:reverse(N), ""); +string_to_jid1([$/ | J], "") -> + error; +string_to_jid1([$/ | J], N) -> + string_to_jid3(J, "", lists:reverse(N), ""); +string_to_jid1([C | J], N) -> + string_to_jid1(J, [C | N]); +string_to_jid1([], "") -> + error; +string_to_jid1([], N) -> + {"", lists:reverse(N), ""}. + +string_to_jid2([$/ | J], N, "") -> + error; +string_to_jid2([$/ | J], N, S) -> + string_to_jid3(J, N, lists:reverse(S), ""); +string_to_jid2([C | J], N, S) -> + string_to_jid2(J, N, [C | S]); +string_to_jid2([], N, "") -> + error; +string_to_jid2([], N, S) -> + {N, lists:reverse(S), ""}. + +string_to_jid3([C | J], N, S, R) -> + string_to_jid3(J, N, S, [C | R]); +string_to_jid3([], N, S, R) -> + {N, S, lists:reverse(R)}. + + +% TODO: UNICODE support +tolower_c(C) when C >= $A, C =< $Z -> + C + 32; +tolower_c(C) -> + C. + +tolower(S) -> + lists:map(fun tolower_c/1, S). + diff --git a/src/xml.erl b/src/xml.erl index 5ae3cb593..9ae4d5091 100644 --- a/src/xml.erl +++ b/src/xml.erl @@ -11,7 +11,7 @@ -vsn('$Revision$ '). -export([element_to_string/1, crypt/1, remove_cdata/1, get_cdata/1, - get_attr/2, get_attr_s/2, make_error_iq_reply/3]). + get_attr/2, get_attr_s/2]). element_to_string(El) -> case El of @@ -91,30 +91,3 @@ get_attr_s(AttrName, Attrs) -> end. -make_error_iq_reply({xmlelement, Name, Attrs, SubTags}, Code, Desc) - when Name == "iq" -> - NewAttrs = make_error_iq_reply_attrs(Attrs), - {xmlelement, Name, NewAttrs, SubTags ++ [{xmlelement, "error", - [{"code", Code}], - [{xmlcdata, Desc}]}]}. - -make_error_iq_reply_attrs(Attrs) -> - To = get_attr("to", Attrs), - From = get_attr("from", Attrs), - Attrs1 = lists:keydelete("to", 1, Attrs), - Attrs2 = lists:keydelete("from", 1, Attrs1), - Attrs3 = case To of - {value, ToVal} -> - [{"from", ToVal} | Attrs2]; - _ -> - Attrs2 - end, - Attrs4 = case From of - {value, FromVal} -> - [{"to", FromVal} | Attrs3]; - _ -> - Attrs3 - end, - Attrs5 = lists:keydelete("type", 1, Attrs4), - Attrs6 = [{"type", "error"} | Attrs5], - Attrs6.