From a8a8e3b5a6cb872bbcf95b271515fc2aae9085d4 Mon Sep 17 00:00:00 2001 From: Alexey Shchepin Date: Thu, 6 Feb 2003 19:09:22 +0000 Subject: [PATCH] *** empty log message *** SVN Revision: 62 --- TODO | 3 +- doc/guide.html | 13 +++-- doc/guide.tex | 16 +++--- src/ejabberd.app | 2 +- src/ejabberd.cfg | 2 + src/ejabberd.erl | 2 + src/ejabberd_c2s.erl | 30 +++++------ src/ejabberd_listener.erl | 46 +++++++++++++---- src/ejabberd_s2s_in.erl | 6 +-- src/ejabberd_service.erl | 6 +-- src/mod_configure.erl | 103 ++++++++++++++++++++++++++++++++------ 11 files changed, 168 insertions(+), 61 deletions(-) diff --git a/TODO b/TODO index 6d2ba9e30..d571ae660 100644 --- a/TODO +++ b/TODO @@ -5,9 +5,10 @@ admin interface S2S timeouts rewrite S2S key validation iq:browse (?) -SRV DNS records +more correctly work with SRV DNS records (priority, weight, etc...) karma SSL +SASL JEP-62,63 (?) make roster set work in one transaction diff --git a/doc/guide.html b/doc/guide.html index e4bcb91a7..1da6a5bf5 100644 --- a/doc/guide.html +++ b/doc/guide.html @@ -178,23 +178,23 @@ Declaration of ACL in config file have following syntax:
{user_regexp, <regexp>}
Matches local user with name that mathes <regexp>. Example:
-{acl, tests, {user, "test.*"}}.
+{acl, tests, {user, "^test[0-9]*$"}}.
 
{user_regexp, <regexp>, <server>}
Matches user with name that mathes <regexp> and from server <server>. Example:
-{acl, tests, {user, "test.*", "localhost"}}.
+{acl, tests, {user, "^test", "localhost"}}.
 
{server_regexp, <regexp>}
Matches any JID from server that matches <regexp>. Example:
-{acl, icq, {server, "icq.*"}}.
+{acl, icq, {server, "^icq\\."}}.
 
{node_regexp, <user_regexp>, <server_regexp>}
Matches user with name that mathes <user_regexp> and from server that matches <server_regexp>. Example:
-{acl, aleksey, {node_regexp, "aleksey.*", "jabber.(ru|org)"}}.
+{acl, aleksey, {node_regexp, "^aleksey", "^jabber.(ru|org)$"}}.
 
{user_glob, <glob>}
@@ -357,7 +357,7 @@ correctly only after restart)

Node config/acls
-Via jabber:x:data queries to this node possible edit ACLs list. (See +Via jabber:x:data queries to this node possible to edit ACLs list. (See figure 2)

[acls editing window] @@ -369,8 +369,7 @@ figure 2)

Node config/access
-Via jabber:x:data queries to this node possible edit access rules. -Not work yet.
+Via jabber:x:data queries to this node possible to edit access rules.

diff --git a/doc/guide.tex b/doc/guide.tex index 46ecc96dc..f9a3e5eb5 100644 --- a/doc/guide.tex +++ b/doc/guide.tex @@ -218,27 +218,29 @@ Declaration of ACL in config file have following syntax: \item[\texttt{\{user\_regexp, \}}] Matches local user with name that mathes \texttt{}. Example: \begin{verbatim} -{acl, tests, {user, "test.*"}}. +{acl, tests, {user, "^test[0-9]*$"}}. \end{verbatim} +%$ \item[\texttt{\{user\_regexp, , \}}] Matches user with name that mathes \texttt{} and from server \texttt{}. Example: \begin{verbatim} -{acl, tests, {user, "test.*", "localhost"}}. +{acl, tests, {user, "^test", "localhost"}}. \end{verbatim} \item[\texttt{\{server\_regexp, \}}] Matches any JID from server that matches \texttt{}. Example: \begin{verbatim} -{acl, icq, {server, "icq.*"}}. +{acl, icq, {server, "^icq\\."}}. \end{verbatim} \item[\texttt{\{node\_regexp, , \}}] Matches user with name that mathes \texttt{} and from server that matches \texttt{}. Example: \begin{verbatim} -{acl, aleksey, {node_regexp, "aleksey.*", "jabber.(ru|org)"}}. +{acl, aleksey, {node_regexp, "^aleksey", "^jabber.(ru|org)$"}}. \end{verbatim} +%$ \item[\texttt{\{user\_glob, \}}] \item[\texttt{\{user\_glob, , \}}] @@ -400,7 +402,7 @@ correctly only after restart) \paragraph{Node \texttt{config/acls}} -Via \ns{jabber:x:data} queries to this node possible edit ACLs list. (See +Via \ns{jabber:x:data} queries to this node possible to edit ACLs list. (See figure~\ref{fig:acls}) \begin{figure}[htbp] \centering @@ -412,8 +414,8 @@ figure~\ref{fig:acls}) \paragraph{Node \texttt{config/access}} -Via \ns{jabber:x:data} queries to this node possible edit access rules. -\textbf{Not work yet}. +Via \ns{jabber:x:data} queries to this node possible to edit access rules. + \paragraph{Node \texttt{config/remusers}} diff --git a/src/ejabberd.app b/src/ejabberd.app index a90fbaeb4..894141e54 100644 --- a/src/ejabberd.app +++ b/src/ejabberd.app @@ -43,7 +43,7 @@ ejabberd_mod_roster, ejabberd_listeners ]}, - {applications, [kernel, stdlib, mnesia]}, + {applications, [kernel, stdlib, mnesia, crypto, ssl]}, {env, []}, {mod, {ejabberd_app, []}}]}. diff --git a/src/ejabberd.cfg b/src/ejabberd.cfg index 6cc428f35..c91c71139 100644 --- a/src/ejabberd.cfg +++ b/src/ejabberd.cfg @@ -29,6 +29,8 @@ override_acls. {host, "e.localhost"}. {listen, [{5522, ejabberd_c2s, start, [{access, c2s}]}, + %{5523, ejabberd_c2s, start, + % [{access, c2s}, {ssl, [{certfile, "./ssl.pem"}]}]}, {5269, ejabberd_s2s_in, start, []}, {8888, ejabberd_service, start, [{host, "asd.e.localhost", [{password, "asdqwe"}]}]} diff --git a/src/ejabberd.erl b/src/ejabberd.erl index ef3b85c15..c34430fc3 100644 --- a/src/ejabberd.erl +++ b/src/ejabberd.erl @@ -14,6 +14,8 @@ start() -> application:start(mnesia), + application:start(crypto), + application:start(ssl), application:start(ejabberd). stop() -> diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl index 2fa3e1d2e..13e7cc169 100644 --- a/src/ejabberd_c2s.erl +++ b/src/ejabberd_c2s.erl @@ -13,7 +13,7 @@ -behaviour(gen_fsm). %% External exports --export([start/2, receiver/2, sender/1, send_text/2, send_element/2]). +-export([start/2, receiver/3, sender/2, send_text/2, send_element/2]). %% gen_fsm callbacks -export([init/1, wait_for_stream/2, wait_for_auth/2, session_established/2, @@ -61,8 +61,8 @@ %%%---------------------------------------------------------------------- %%% API %%%---------------------------------------------------------------------- -start(Socket, Opts) -> - gen_fsm:start(ejabberd_c2s, [Socket, Opts], ?FSMOPTS). +start(SockData, Opts) -> + gen_fsm:start(ejabberd_c2s, [SockData, Opts], ?FSMOPTS). %%%---------------------------------------------------------------------- %%% Callback functions from gen_fsm @@ -75,9 +75,9 @@ start(Socket, Opts) -> %% ignore | %% {stop, StopReason} %%---------------------------------------------------------------------- -init([Socket, Opts]) -> - SenderPid = spawn(?MODULE, sender, [Socket]), - ReceiverPid = spawn(?MODULE, receiver, [Socket, self()]), +init([{SockMod, Socket}, Opts]) -> + SenderPid = spawn(?MODULE, sender, [Socket, SockMod]), + ReceiverPid = spawn(?MODULE, receiver, [Socket, SockMod, self()]), Access = case lists:keysearch(access, 1, Opts) of {value, {_, A}} -> A; @@ -367,28 +367,28 @@ terminate(Reason, StateName, StateData) -> %%% Internal functions %%%---------------------------------------------------------------------- -receiver(Socket, C2SPid) -> +receiver(Socket, SockMod, C2SPid) -> XMLStreamPid = xml_stream:start(C2SPid), - receiver(Socket, C2SPid, XMLStreamPid). + receiver(Socket, SockMod, C2SPid, XMLStreamPid). -receiver(Socket, C2SPid, XMLStreamPid) -> - case gen_tcp:recv(Socket, 0) of +receiver(Socket, SockMod, C2SPid, XMLStreamPid) -> + case SockMod:recv(Socket, 0) of {ok, Text} -> xml_stream:send_text(XMLStreamPid, Text), - receiver(Socket, C2SPid, XMLStreamPid); + receiver(Socket, SockMod, C2SPid, XMLStreamPid); {error, Reason} -> exit(XMLStreamPid, closed), gen_fsm:send_event(C2SPid, closed), ok end. -sender(Socket) -> +sender(Socket, SockMod) -> receive {send_text, Text} -> - gen_tcp:send(Socket,Text), - sender(Socket); + SockMod:send(Socket,Text), + sender(Socket, SockMod); close -> - gen_tcp:close(Socket), + SockMod:close(Socket), ok end. diff --git a/src/ejabberd_listener.erl b/src/ejabberd_listener.erl index 3ed030c7b..004ddba38 100644 --- a/src/ejabberd_listener.erl +++ b/src/ejabberd_listener.erl @@ -10,7 +10,10 @@ -author('alexey@sevcom.net'). -vsn('$Revision$ '). --export([start_link/0, init/1, start/4, init/4]). +-export([start_link/0, init/1, start/4, + init/4, + init_ssl/5 + ]). start_link() -> supervisor:start_link({local, ejabberd_listeners}, ?MODULE, []). @@ -25,7 +28,7 @@ init(_) -> lists:map( fun({Port, Module, Fun, Opts}) -> {Port, - {?MODULE, start, [Port, Module, Fun, [Opts]]}, + {?MODULE, start, [Port, Module, Fun, Opts]}, permanent, brutal_kill, worker, @@ -34,22 +37,45 @@ init(_) -> end. -start(Port, Module, Fun, Args) -> - {ok, spawn_link(?MODULE, init, [Port, Module, Fun, Args])}. +start(Port, Module, Fun, Opts) -> + case lists:keysearch(ssl, 1, Opts) of + {value, {ssl, SSLOpts}} -> + {ok, spawn_link(?MODULE, init_ssl, + [Port, Module, Fun, Opts, SSLOpts])}; + _ -> + {ok, spawn_link(?MODULE, init, [Port, Module, Fun, Opts])} + end. -init(Port, Module, Fun, Args) -> +init(Port, Module, Fun, Opts) -> {ok, ListenSocket} = gen_tcp:listen(Port, [binary, {packet, 0}, {active, false}, {reuseaddr, true}]), - accept(ListenSocket, Module, Fun, Args). + accept(ListenSocket, Module, Fun, Opts). -accept(ListenSocket, Module, Fun, Args) -> +accept(ListenSocket, Module, Fun, Opts) -> case gen_tcp:accept(ListenSocket) of {ok,Socket} -> - apply(Module, Fun, [Socket] ++ Args), - %ejabberd_c2s:start(Socket), - accept(ListenSocket, Module, Fun, Args) + apply(Module, Fun, [{gen_tcp, Socket}, Opts]), + accept(ListenSocket, Module, Fun, Opts) + end. + + +init_ssl(Port, Module, Fun, Opts, SSLOpts) -> + {ok, ListenSocket} = ssl:listen(Port, [binary, + {packet, 0}, + {active, false}, + {nodelay, true}, + {backlog, 0}, + {cachetimout, 0} | + SSLOpts]), + accept_ssl(ListenSocket, Module, Fun, Opts). + +accept_ssl(ListenSocket, Module, Fun, Opts) -> + case ssl:accept(ListenSocket) of + {ok,Socket} -> + apply(Module, Fun, [{ssl, Socket}, Opts]), + accept_ssl(ListenSocket, Module, Fun, Opts) end. diff --git a/src/ejabberd_s2s_in.erl b/src/ejabberd_s2s_in.erl index 388030549..2f25c267b 100644 --- a/src/ejabberd_s2s_in.erl +++ b/src/ejabberd_s2s_in.erl @@ -65,8 +65,8 @@ %%%---------------------------------------------------------------------- %%% API %%%---------------------------------------------------------------------- -start(Socket, Opts) -> - gen_fsm:start(ejabberd_s2s_in, [Socket], ?FSMOPTS). +start(SockData, Opts) -> + gen_fsm:start(ejabberd_s2s_in, [SockData], ?FSMOPTS). %%%---------------------------------------------------------------------- %%% Callback functions from gen_fsm @@ -79,7 +79,7 @@ start(Socket, Opts) -> %% ignore | %% {stop, StopReason} %%---------------------------------------------------------------------- -init([Socket]) -> +init([{SockMod, Socket}]) -> ReceiverPid = spawn(?MODULE, receiver, [Socket, self()]), {ok, wait_for_stream, #state{socket = Socket, receiver = ReceiverPid, diff --git a/src/ejabberd_service.erl b/src/ejabberd_service.erl index 78e7a9c9a..455885f50 100644 --- a/src/ejabberd_service.erl +++ b/src/ejabberd_service.erl @@ -63,8 +63,8 @@ %%%---------------------------------------------------------------------- %%% API %%%---------------------------------------------------------------------- -start(Socket, Opts) -> - gen_fsm:start(ejabberd_service, [Socket, Opts], ?FSMOPTS). +start(SockData, Opts) -> + gen_fsm:start(ejabberd_service, [SockData, Opts], ?FSMOPTS). %%%---------------------------------------------------------------------- %%% Callback functions from gen_fsm @@ -77,7 +77,7 @@ start(Socket, Opts) -> %% ignore | %% {stop, StopReason} %%---------------------------------------------------------------------- -init([Socket, Opts]) -> +init([{SockMod, Socket}, Opts]) -> {Host, Password} = case lists:keysearch(host, 1, Opts) of {value, {_, H, HOpts}} -> diff --git a/src/mod_configure.erl b/src/mod_configure.erl index 7e62bff99..3f6c09a08 100644 --- a/src/mod_configure.erl +++ b/src/mod_configure.erl @@ -283,7 +283,36 @@ get_form(["config", "acls"], Lang) -> lists:flatten(io_lib:format("~p.", [ets:tab2list(acl)])), "\n")) - %{xmlelement, "value", [], [{xmlcdata, ?MYNAME}]} + } + ]}; + +get_form(["config", "access"], Lang) -> + {result, [{xmlelement, "title", [], + [{xmlcdata, + translate:translate( + Lang, "Access Configuration")}]}, + %{xmlelement, "instructions", [], + % [{xmlcdata, + % translate:translate( + % Lang, "")}]}, + {xmlelement, "field", [{"type", "text-multi"}, + {"label", + translate:translate( + Lang, "Access Rules")}, + {"var", "access"}], + lists:map(fun(S) -> + {xmlelement, "value", [], [{xmlcdata, S}]} + end, + string:tokens( + lists:flatten( + io_lib:format( + "~p.", + [ets:select(config, + [{{config, {access, '$1'}, '$2'}, + [], + [{{access, '$1', '$2'}}]}]) + ])), + "\n")) } ]}; @@ -447,25 +476,71 @@ set_form(["config", "hostname"], Lang, XData) -> set_form(["config", "acls"], Lang, XData) -> case lists:keysearch("acls", 1, XData) of {value, {_, Strings}} -> - String = lists:foldl(fun(S, Res) -> - Res ++ S ++ "\n" - end, "", Strings), - case erl_scan:string(String) of - {ok, Tokens, _} -> - case erl_parse:parse_term(Tokens) of - {ok, ACLs} -> - case acl:add_list(ACLs, true) of - ok -> - {result, []}; - _ -> - {error, "406", "Not Acceptable"} - end; + String = lists:foldl(fun(S, Res) -> + Res ++ S ++ "\n" + end, "", Strings), + case erl_scan:string(String) of + {ok, Tokens, _} -> + case erl_parse:parse_term(Tokens) of + {ok, ACLs} -> + case acl:add_list(ACLs, true) of + ok -> + {result, []}; _ -> {error, "406", "Not Acceptable"} end; _ -> {error, "406", "Not Acceptable"} end; + _ -> + {error, "406", "Not Acceptable"} + end; + _ -> + {error, "406", "Not Acceptable"} + end; + +set_form(["config", "access"], Lang, XData) -> + SetAccess = + fun(Rs) -> + mnesia:transaction( + fun() -> + Os = mnesia:select(config, + [{{config, {access, '$1'}, '$2'}, + [], + ['$_']}]), + lists:foreach(fun(O) -> + mnesia:delete_object(O) + end, Os), + lists:foreach( + fun({access, Name, Rules}) -> + mnesia:write({config, + {access, Name}, + Rules}) + end, Rs) + end) + end, + case lists:keysearch("access", 1, XData) of + {value, {_, Strings}} -> + String = lists:foldl(fun(S, Res) -> + Res ++ S ++ "\n" + end, "", Strings), + case erl_scan:string(String) of + {ok, Tokens, _} -> + case erl_parse:parse_term(Tokens) of + {ok, Rs} -> + case SetAccess(Rs) of + {atomic, _} -> + {result, []}; + E -> + io:format("A: ~p~n", [E]), + {error, "406", "Not Acceptable"} + end; + _ -> + {error, "406", "Not Acceptable"} + end; + _ -> + {error, "406", "Not Acceptable"} + end; _ -> {error, "406", "Not Acceptable"} end;