From a717a39a6dc52ecc1ee7c3f136f0b61ce6ada2cb Mon Sep 17 00:00:00 2001 From: Alexey Shchepin Date: Wed, 20 Nov 2002 20:19:20 +0000 Subject: [PATCH] *** empty log message *** SVN Revision: 4 --- src/ejabberd.erl | 16 +++++++- src/ejabberd_c2s.erl | 96 ++++++++++++++++++++++++++------------------ src/expat_erl.c | 2 +- src/xml.erl | 92 ++++++++++++++++++++++++++++++++++++++++++ src/xml_stream.erl | 1 - 5 files changed, 164 insertions(+), 43 deletions(-) create mode 100644 src/xml.erl diff --git a/src/ejabberd.erl b/src/ejabberd.erl index 5f0fe02ad..0ebadc358 100644 --- a/src/ejabberd.erl +++ b/src/ejabberd.erl @@ -13,5 +13,17 @@ -export([start/0]). start() -> - {ok, _} = erl_ddll:start(), - ejabberd_listener:start(). + 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]), + ejabberd_listener:start(), + loop(Port). + + +loop(Port) -> + receive + _ -> + loop(Port) + end. diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl index 1149a64e8..251f32570 100644 --- a/src/ejabberd_c2s.erl +++ b/src/ejabberd_c2s.erl @@ -21,42 +21,10 @@ % -export([init/1, wait_for_stream/2, wait_for_auth/2, terminate/3]). --record(state, {socket, sender, receiver}). +-record(state, {socket, sender, receiver, streamid}). -include("ejabberd.hrl"). -%start_old(Socket) -> -% spawn(?MODULE, init, [Socket]). - -%init_old(Socket) -> -% SenderPid = spawn(?MODULE, sender, [Socket]), -% ReceiverPid = spawn(?MODULE, receiver, [Socket, self()]), -% loop_old(Socket, SenderPid, ReceiverPid). -% -%loop_old(Socket, SenderPid, ReceiverPid) -> -% receive -% {xmlstreamstart, Name, Attrs} -> -% ?DEBUG("Socket(~p) -> XML Stream start~n" -% " Name: ~s~n" -% " Attrs: ~p~n", [Socket, Name, Attrs]), -% loop_old(Socket, SenderPid, ReceiverPid); -% {xmlstreamend, Name} -> -% ?DEBUG("Socket(~p) -> XML Stream end~n" -% " Name: ~s~n", [Socket, Name]), -% loop_old(Socket, SenderPid, ReceiverPid); -% {xmlstreamelement, El} -> -% ?DEBUG("Socket(~p) -> XML Stream element~n" -% " Element: ~p~n", [Socket, El]), -% loop_old(Socket, SenderPid, ReceiverPid); -% {xmlstreamerror, Err} -> -% ?DEBUG("Socket(~p) -> XML Stream error~n" -% " Error: ~p~n", [Socket, Err]), -% loop_old(Socket, SenderPid, ReceiverPid) -% end. - - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -define(DBGFSM, true). -ifdef(DBGFSM). @@ -81,8 +49,6 @@ %%%---------------------------------------------------------------------- start(Socket) -> gen_fsm:start(ejabberd_c2s, [Socket], ?FSMOPTS). -%start_old(Socket) -> -% spawn(?MODULE, init, [Socket]). %%%---------------------------------------------------------------------- %%% Callback functions from gen_fsm @@ -100,7 +66,8 @@ init([Socket]) -> ReceiverPid = spawn(?MODULE, receiver, [Socket, self()]), {ok, wait_for_stream, #state{socket = Socket, receiver = ReceiverPid, - sender = SenderPid}}. + sender = SenderPid, + streamid = new_id()}}. %%---------------------------------------------------------------------- %% Func: StateName/2 @@ -113,7 +80,8 @@ state_name(Event, StateData) -> wait_for_stream({xmlstreamstart, Name, Attrs}, StateData) -> % TODO - Header = io_lib:format(?STREAM_HEADER, ["SID", "localhost"]), + Header = io_lib:format(?STREAM_HEADER, + [StateData#state.streamid, "localhost"]), send_text(StateData#state.sender, Header), case lists:keysearch("xmlns:stream", 1, Attrs) of {value, {"xmlns:stream", "http://etherx.jabber.org/streams"}} -> @@ -130,8 +98,14 @@ wait_for_stream(closed, StateData) -> wait_for_auth({xmlstreamelement, El}, StateData) -> - % TODO - {next_state, wait_for_auth, StateData}; + case is_auth_packet(El) of + {auth, {U, P, D, R}} -> + io:format("AUTH: ~p~n", [{U, P, D, R}]), + % TODO + {next_state, session_established, StateData}; + _ -> + {next_state, wait_for_auth, StateData} +end; wait_for_auth({xmlstreamend, Name}, StateData) -> % TODO @@ -228,3 +202,47 @@ sender(Socket) -> send_text(Pid, Text) -> Pid ! {text, Text}. +new_id() -> + io_lib:format("~p", [random:uniform(65536*65536)]). + + +is_auth_packet({xmlelement, Name, Attrs, Els}) when Name == "iq" -> + case xml:get_attr_s("type", Attrs) of + "set" -> + case xml:remove_cdata(Els) of + [{xmlelement, "query", Attrs2, Els2}] -> + case xml:get_attr_s("xmlns", Attrs2) of + "jabber:iq:auth" -> + {auth, get_auth_tags(Els2, "", "", "", "")}; + _ -> false + end; + _ -> + false + end; + true -> + false + end; + +is_auth_packet(_) -> + false. + +get_auth_tags([{xmlelement, Name, Attrs, Els}| L], U, P, D, R) -> + CData = xml:get_cdata(Els), + case Name of + "username" -> + get_auth_tags(L, CData, P, D, R); + "password" -> + get_auth_tags(L, U, CData, D, R); + "digest" -> + get_auth_tags(L, U, P, CData, R); + "resource" -> + get_auth_tags(L, U, P, D, CData); + _ -> + get_auth_tags(L, U, P, D, R) + end; +get_auth_tags([_ | L], U, P, D, R) -> + get_auth_tags(L, U, P, D, R); +get_auth_tags([], U, P, D, R) -> + {U, P, D, R}. + + diff --git a/src/expat_erl.c b/src/expat_erl.c index b330eca16..18eb0471c 100644 --- a/src/expat_erl.c +++ b/src/expat_erl.c @@ -94,7 +94,7 @@ static ErlDrvData expat_erl_start(ErlDrvPort port, char *buff) static void expat_erl_stop(ErlDrvData handle) { - /* TODO: free parser */ + XML_ParserFree(((expat_data *)handle)->parser); driver_free((char*)handle); } diff --git a/src/xml.erl b/src/xml.erl new file mode 100644 index 000000000..e1ae3b1ba --- /dev/null +++ b/src/xml.erl @@ -0,0 +1,92 @@ +%%%---------------------------------------------------------------------- +%%% File : xml.erl +%%% Author : Alexey Shchepin +%%% Purpose : XML utils +%%% Created : 20 Nov 2002 by Alexey Shchepin +%%% Id : $Id$ +%%%---------------------------------------------------------------------- + +-module(xml). +-author('alexey@sevcom.net'). +-vsn('$Revision$ '). + +-export([element_to_string/1, crypt/1, remove_cdata/1, get_cdata/1, + get_attr/2, get_attr_s/2]). + +element_to_string(El) -> + case El of + {xmlelement, Name, Attrs, Els} -> + if length(Els) > 0 -> + "<" ++ Name ++ attrs_to_string(Attrs) ++ ">" ++ + lists:append( + lists:map(fun(E) -> element_to_string(E) end, Els)) + ++ ""; + true -> + "<" ++ Name ++ attrs_to_string(Attrs) ++ "/>" + end; + {xmlcdata, CData} -> crypt(CData) + end. + + +attrs_to_string(Attrs) -> + lists:append(lists:map(fun(A) -> attr_to_string(A) end, Attrs)). + +attr_to_string({Name, Value}) -> + " " ++ crypt(Name) ++ "='" ++ crypt(Value) ++ "'". + +crypt(S) -> + lists:reverse(crypt(S, "")). + +crypt([$& | S], R) -> + crypt(S, [$;, $p, $m, $a, $& | R]); +crypt([$< | S], R) -> + crypt(S, [$;, $t, $l, $& | R]); +crypt([$> | S], R) -> + crypt(S, [$;, $t, $g, $& | R]); +crypt([$" | S], R) -> + crypt(S, [$;, $t, $o, $u, $q, $& | R]); +crypt([$' | S], R) -> + crypt(S, [$;, $s, $o, $p, $a, $& | R]); +crypt([C | S], R) -> + crypt(S, [C | R]); +crypt([], R) -> + R. + + +remove_cdata(L) -> + lists:reverse(remove_cdata(L, [])). + +remove_cdata([{xmlelement, Name, Attrs, Els} | L], R) -> + remove_cdata(L, [{xmlelement, Name, Attrs, Els} | R]); +remove_cdata([{xmlcdata, CData} | L], R) -> + remove_cdata(L, R); +remove_cdata([], R) -> + R. + +get_cdata(L) -> + get_cdata(L, ""). + +get_cdata([{xmlcdata, CData} | L], S) -> + get_cdata(L, S ++ CData); +get_cdata([_ | L], S) -> + get_cdata(L, S); +get_cdata([], S) -> + S. + + +get_attr(AttrName, Attrs) -> + case lists:keysearch(AttrName, 1, Attrs) of + {value, {_, Val}} -> + {value, Val}; + _ -> + false + end. + +get_attr_s(AttrName, Attrs) -> + case lists:keysearch(AttrName, 1, Attrs) of + {value, {_, Val}} -> + Val; + _ -> + "" + end. + diff --git a/src/xml_stream.erl b/src/xml_stream.erl index b21ae13c0..bb3776157 100644 --- a/src/xml_stream.erl +++ b/src/xml_stream.erl @@ -16,7 +16,6 @@ start(CallbackPid) -> spawn(?MODULE, init, [CallbackPid]). init(CallbackPid) -> - ok = erl_ddll:load_driver(".", expat_erl), Port = open_port({spawn, expat_erl}, [binary]), loop(CallbackPid, Port, []).