mirror of
https://github.com/processone/ejabberd.git
synced 2024-11-24 16:23:40 +01:00
*** empty log message ***
SVN Revision: 55
This commit is contained in:
parent
45abdd240c
commit
6599d1ecc5
102
doc/guide.html
102
doc/guide.html
@ -101,6 +101,14 @@ database, and in next time they will be APPENDED to existing values. E. g.
|
||||
if this file will not contain ``host'' definition, then old value will be
|
||||
used.<BR>
|
||||
<BR>
|
||||
To override old values following lines can be added in config:
|
||||
<PRE>
|
||||
override_global.
|
||||
override_local.
|
||||
override_acls.
|
||||
</PRE>With this lines old global or local options or ACLs will be removed before
|
||||
adding new ones.<BR>
|
||||
<BR>
|
||||
<!--TOC subsubsection Host Name-->
|
||||
|
||||
<H4>3.1.1 Host Name</H4><!--SEC END -->
|
||||
@ -109,42 +117,9 @@ used.<BR>
|
||||
serves. E. g. to use <TT>jabber.org</TT> domain add following line in config:
|
||||
<PRE>
|
||||
{host, "jabber.org"}.
|
||||
</PRE><!--TOC subsubsection Listened Sockets-->
|
||||
|
||||
<H4>3.1.2 Listened Sockets</H4><!--SEC END -->
|
||||
|
||||
<A NAME="sec:configlistened"></A>Option <TT>listen</TT> defines list of listened sockets and what services
|
||||
runned on them. Each element of list is a tuple with following elements:
|
||||
<UL>
|
||||
<LI>
|
||||
Port number;
|
||||
|
||||
<LI> Module that serves this port;
|
||||
|
||||
<LI> Function in this module that starts connection (likely will be removed);
|
||||
|
||||
<LI> Options to this module.
|
||||
</UL>Currently three modules implemented:
|
||||
<UL>
|
||||
<LI>
|
||||
<TT>ejabberd_c2s</TT>: serves C2S connections;
|
||||
|
||||
<LI> <TT>ejabberd_s2s_in</TT>: serves incoming S2S connections;
|
||||
|
||||
<LI> <TT>ejabberd_service</TT>: serves connections to Jabber services
|
||||
(i. e. that use <TT>jabber:component:accept</TT> namespace).
|
||||
</UL>For example, following configuration defines that C2S connections listened on
|
||||
port 5222, S2S on port 5269 and that service <TT>conference.jabber.org</TT>
|
||||
must be connected to port 8888 with password ``<TT>secret</TT>''.<BR>
|
||||
<BR>
|
||||
<PRE>
|
||||
{listen, [{5222, ejabberd_c2s, start, []},
|
||||
{5269, ejabberd_s2s_in, start, []},
|
||||
{8888, ejabberd_service, start, ["conference.jabber.org", "secret"]}
|
||||
]}.
|
||||
</PRE><!--TOC subsubsection Access Rules-->
|
||||
|
||||
<H4>3.1.3 Access Rules</H4><!--SEC END -->
|
||||
<H4>3.1.2 Access Rules</H4><!--SEC END -->
|
||||
|
||||
<A NAME="sec:configaccess"></A>Access control in <TT>ejabberd</TT> is done via Access Control Lists (ACL). In
|
||||
config file they looks like this:
|
||||
@ -213,6 +188,12 @@ config file they looks like this:
|
||||
If the first character after <TT>`['</TT> is a <TT>`!'</TT>, then any
|
||||
character not enclosed is matched.
|
||||
</DL>
|
||||
</DL>Following ACLs pre-defined:
|
||||
<DL COMPACT=compact>
|
||||
<DT>
|
||||
<TT>all</TT><DD> Matches all JIDs.
|
||||
|
||||
<DT><TT>none</TT><DD> Matches none JIDs.
|
||||
</DL>Allowing or denying of different services is like this:
|
||||
<PRE>
|
||||
{access, <accessname>, [{allow, <aclname>},
|
||||
@ -229,6 +210,57 @@ Example:
|
||||
{access, configure, [{allow, admin}]}.
|
||||
{access, something, [{deny, badmans},
|
||||
{allow, all}]}.
|
||||
</PRE>Following access rules pre-defined:
|
||||
<DL COMPACT=compact>
|
||||
<DT>
|
||||
<TT>all</TT><DD> Always return ``<TT>allow</TT>''
|
||||
|
||||
<DT><TT>none</TT><DD> Always return ``<TT>deny</TT>''
|
||||
</DL><!--TOC subsubsection Listened Sockets-->
|
||||
|
||||
<H4>3.1.3 Listened Sockets</H4><!--SEC END -->
|
||||
|
||||
<A NAME="sec:configlistened"></A>Option <TT>listen</TT> defines list of listened sockets and what services
|
||||
runned on them. Each element of list is a tuple with following elements:
|
||||
<UL>
|
||||
<LI>
|
||||
Port number;
|
||||
|
||||
<LI> Module that serves this port;
|
||||
|
||||
<LI> Function in this module that starts connection (likely will be removed);
|
||||
|
||||
<LI> Options to this module.
|
||||
</UL>Currently three modules implemented:
|
||||
<DL COMPACT=compact>
|
||||
<DT>
|
||||
<TT>ejabberd_c2s</TT><DD> This module serves C2S connections.<BR>
|
||||
<BR>
|
||||
Following options defined:
|
||||
<DL COMPACT=compact>
|
||||
<DT>
|
||||
<TT>{access, <access rule>}</TT><DD> This option defines access of users
|
||||
to this C2S port. Default value is ``<TT>all</TT>''.
|
||||
</DL>
|
||||
|
||||
<DT><TT>ejabberd_s2s_in</TT><DD> This module serves incoming S2S connections.
|
||||
|
||||
<DT><TT>ejabberd_service</TT><DD> This module serves connections to Jabber
|
||||
services (i. e. that use <TT>jabber:component:accept</TT> namespace).
|
||||
</DL>For example, following configuration defines that C2S connections listened on
|
||||
port 5222 and denied for user ``<TT>bad</TT>'', S2S on port 5269 and that
|
||||
service <TT>conference.jabber.org</TT> must be connected to port 8888 with
|
||||
password ``<TT>secret</TT>''.<BR>
|
||||
<BR>
|
||||
<PRE>
|
||||
{acl, blocked, {user, "bad"}}.
|
||||
{access, c2s, [{deny, blocked},
|
||||
{allow, all}]}.
|
||||
{listen, [{5222, ejabberd_c2s, start, [{access, c2s}]},
|
||||
{5269, ejabberd_s2s_in, start, []},
|
||||
{8888, ejabberd_service, start,
|
||||
[{host, "conference.jabber.org", [{password, "secret"}]}]}
|
||||
]}.
|
||||
</PRE><!--TOC subsubsection Modules-->
|
||||
|
||||
<H4>3.1.4 Modules</H4><!--SEC END -->
|
||||
@ -282,7 +314,7 @@ have access to connect to port 4369 of all another nodes, and must have same
|
||||
magic cookie (see Erlang/OTP documentation, in short file
|
||||
<TT>~ejabberd/.erlang.cookie</TT> must be the same on all nodes). This is
|
||||
needed because all nodes exchange information about connected users, S2S
|
||||
connection, registered services, etc...<BR>
|
||||
connections, registered services, etc...<BR>
|
||||
<BR>
|
||||
Each <TT>ejabberd</TT> node run following modules:
|
||||
<UL>
|
||||
|
@ -132,6 +132,15 @@ database, and in next time they will be APPENDED to existing values. E.\,g.\
|
||||
if this file will not contain ``host'' definition, then old value will be
|
||||
used.
|
||||
|
||||
To override old values following lines can be added in config:
|
||||
\begin{verbatim}
|
||||
override_global.
|
||||
override_local.
|
||||
override_acls.
|
||||
\end{verbatim}
|
||||
With this lines old global or local options or ACLs will be removed before
|
||||
adding new ones.
|
||||
|
||||
|
||||
\subsubsection{Host Name}
|
||||
\label{sec:confighostname}
|
||||
@ -146,38 +155,6 @@ serves. E.\,g.\ to use \texttt{jabber.org} domain add following line in config:
|
||||
|
||||
|
||||
|
||||
\subsubsection{Listened Sockets}
|
||||
\label{sec:configlistened}
|
||||
|
||||
Option \texttt{listen} defines list of listened sockets and what services
|
||||
runned on them. Each element of list is a tuple with following elements:
|
||||
\begin{itemize}
|
||||
\item Port number;
|
||||
\item Module that serves this port;
|
||||
\item Function in this module that starts connection (likely will be removed);
|
||||
\item Options to this module.
|
||||
\end{itemize}
|
||||
|
||||
Currently three modules implemented:
|
||||
\begin{itemize}
|
||||
\item \texttt{ejabberd\_c2s}: serves C2S connections;
|
||||
\item \texttt{ejabberd\_s2s\_in}: serves incoming S2S connections;
|
||||
\item \texttt{ejabberd\_service}: serves connections to \Jabber{} services
|
||||
(i.\,e.\ that use \texttt{jabber:component:accept} namespace).
|
||||
\end{itemize}
|
||||
|
||||
For example, following configuration defines that C2S connections listened on
|
||||
port 5222, S2S on port 5269 and that service \texttt{conference.jabber.org}
|
||||
must be connected to port 8888 with password ``\texttt{secret}''.
|
||||
|
||||
\begin{verbatim}
|
||||
{listen, [{5222, ejabberd_c2s, start, []},
|
||||
{5269, ejabberd_s2s_in, start, []},
|
||||
{8888, ejabberd_service, start, ["conference.jabber.org", "secret"]}
|
||||
]}.
|
||||
\end{verbatim}
|
||||
|
||||
|
||||
\subsubsection{Access Rules}
|
||||
\label{sec:configaccess}
|
||||
|
||||
@ -253,6 +230,12 @@ config file they looks like this:
|
||||
\end{description}
|
||||
\end{description}
|
||||
|
||||
Following ACLs pre-defined:
|
||||
\begin{description}
|
||||
\item[\texttt{all}] Matches all JIDs.
|
||||
\item[\texttt{none}] Matches none JIDs.
|
||||
\end{description}
|
||||
|
||||
Allowing or denying of different services is like this:
|
||||
\begin{verbatim}
|
||||
{access, <accessname>, [{allow, <aclname>},
|
||||
@ -272,6 +255,57 @@ Example:
|
||||
{allow, all}]}.
|
||||
\end{verbatim}
|
||||
|
||||
Following access rules pre-defined:
|
||||
\begin{description}
|
||||
\item[\texttt{all}] Always return ``\texttt{allow}''
|
||||
\item[\texttt{none}] Always return ``\texttt{deny}''
|
||||
\end{description}
|
||||
|
||||
|
||||
\subsubsection{Listened Sockets}
|
||||
\label{sec:configlistened}
|
||||
|
||||
Option \texttt{listen} defines list of listened sockets and what services
|
||||
runned on them. Each element of list is a tuple with following elements:
|
||||
\begin{itemize}
|
||||
\item Port number;
|
||||
\item Module that serves this port;
|
||||
\item Function in this module that starts connection (likely will be removed);
|
||||
\item Options to this module.
|
||||
\end{itemize}
|
||||
|
||||
Currently three modules implemented:
|
||||
\begin{description}
|
||||
\item[\texttt{ejabberd\_c2s}] This module serves C2S connections.
|
||||
|
||||
Following options defined:
|
||||
\begin{description}
|
||||
\item[\texttt{\{access, <access rule>\}}] This option defines access of users
|
||||
to this C2S port. Default value is ``\texttt{all}''.
|
||||
\end{description}
|
||||
\item[\texttt{ejabberd\_s2s\_in}] This module serves incoming S2S connections.
|
||||
\item[\texttt{ejabberd\_service}] This module serves connections to \Jabber{}
|
||||
services (i.\,e.\ that use \texttt{jabber:component:accept} namespace).
|
||||
\end{description}
|
||||
|
||||
For example, following configuration defines that C2S connections listened on
|
||||
port 5222 and denied for user ``\texttt{bad}'', S2S on port 5269 and that
|
||||
service \texttt{conference.jabber.org} must be connected to port 8888 with
|
||||
password ``\texttt{secret}''.
|
||||
|
||||
\begin{verbatim}
|
||||
{acl, blocked, {user, "bad"}}.
|
||||
{access, c2s, [{deny, blocked},
|
||||
{allow, all}]}.
|
||||
{listen, [{5222, ejabberd_c2s, start, [{access, c2s}]},
|
||||
{5269, ejabberd_s2s_in, start, []},
|
||||
{8888, ejabberd_service, start,
|
||||
[{host, "conference.jabber.org", [{password, "secret"}]}]}
|
||||
]}.
|
||||
\end{verbatim}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
\subsubsection{Modules}
|
||||
|
@ -3,9 +3,10 @@
|
||||
include Makefile.inc
|
||||
|
||||
INCLUDES = -I/usr/lib/erlang/usr/include \
|
||||
-I$(EI_DIR)/include
|
||||
-I$(EI_DIR)/include \
|
||||
-I/usr/local/include
|
||||
|
||||
LIBDIRS = -L$(EI_DIR)/lib
|
||||
LIBDIRS = -L$(EI_DIR)/lib -L/usr/local/lib
|
||||
|
||||
ERLSHLIBS = expat_erl.so
|
||||
|
||||
|
43
src/acl.erl
43
src/acl.erl
@ -11,7 +11,9 @@
|
||||
-vsn('$Revision$ ').
|
||||
|
||||
-export([start/0,
|
||||
to_record/2,
|
||||
add/2,
|
||||
add_list/2,
|
||||
match_rule/2,
|
||||
% for debugging only
|
||||
match_acl/2]).
|
||||
@ -28,6 +30,8 @@ start() ->
|
||||
mnesia:add_table_copy(acl, node(), ram_copies),
|
||||
ok.
|
||||
|
||||
to_record(ACLName, ACLSpec) ->
|
||||
#acl{aclname = ACLName, aclspec = ACLSpec}.
|
||||
|
||||
add(ACLName, ACLSpec) ->
|
||||
F = fun() ->
|
||||
@ -35,12 +39,44 @@ add(ACLName, ACLSpec) ->
|
||||
end,
|
||||
mnesia:transaction(F).
|
||||
|
||||
add_list(ACLs, Clear) ->
|
||||
F = fun() ->
|
||||
if
|
||||
Clear ->
|
||||
Ks = mnesia:all_keys(acl),
|
||||
lists:foreach(fun(K) ->
|
||||
mnesia:delete({acl, K})
|
||||
end, Ks);
|
||||
true ->
|
||||
ok
|
||||
end,
|
||||
lists:foreach(fun(ACL) ->
|
||||
case ACL of
|
||||
#acl{} ->
|
||||
mnesia:write(ACL)
|
||||
end
|
||||
end, ACLs)
|
||||
end,
|
||||
case mnesia:transaction(F) of
|
||||
{atomic, _} ->
|
||||
ok;
|
||||
_ ->
|
||||
false
|
||||
end.
|
||||
|
||||
|
||||
|
||||
match_rule(Rule, JID) ->
|
||||
case Rule of
|
||||
all -> allow;
|
||||
none -> deny;
|
||||
_ ->
|
||||
case ejabberd_config:get_global_option({access, Rule}) of
|
||||
undefined ->
|
||||
deny;
|
||||
ACLs ->
|
||||
match_acls(ACLs, JID)
|
||||
end
|
||||
end.
|
||||
|
||||
match_acls([], _) ->
|
||||
@ -54,6 +90,10 @@ match_acls([{Access, ACL} | ACLs], JID) ->
|
||||
end.
|
||||
|
||||
match_acl(ACL, JID) ->
|
||||
case ACL of
|
||||
all -> true;
|
||||
none -> false;
|
||||
_ ->
|
||||
{User, Server, Resource} = jlib:jid_tolower(JID),
|
||||
lists:any(fun(#acl{aclspec = Spec}) ->
|
||||
case Spec of
|
||||
@ -88,7 +128,8 @@ match_acl(ACL, JID) ->
|
||||
is_glob_match(Server, SR) andalso
|
||||
is_glob_match(User, UR)
|
||||
end
|
||||
end, ets:lookup(acl, ACL)).
|
||||
end, ets:lookup(acl, ACL))
|
||||
end.
|
||||
|
||||
is_regexp_match(String, RegExp) ->
|
||||
case regexp:first_match(String, RegExp) of
|
||||
|
54
src/ejabberd.app
Normal file
54
src/ejabberd.app
Normal file
@ -0,0 +1,54 @@
|
||||
% $Id$
|
||||
|
||||
{application, ejabberd,
|
||||
[{description, "ejabberd"},
|
||||
{vsn, "0.0.1-alpha"},
|
||||
{modules, [acl,
|
||||
ejabberd,
|
||||
ejabberd_auth,
|
||||
ejabberd_c2s,
|
||||
ejabberd_config,
|
||||
ejabberd_listener,
|
||||
ejabberd_local,
|
||||
ejabberd_router,
|
||||
ejabberd_s2s,
|
||||
ejabberd_s2s_in,
|
||||
ejabberd_s2s_out,
|
||||
ejabberd_service,
|
||||
ejabberd_sm,
|
||||
jlib,
|
||||
mod_configure,
|
||||
mod_disco,
|
||||
mod_echo,
|
||||
mod_offline,
|
||||
mod_private,
|
||||
mod_register,
|
||||
mod_roster,
|
||||
mod_stats,
|
||||
mod_time,
|
||||
mod_vcard,
|
||||
mod_version,
|
||||
randoms,
|
||||
sha,
|
||||
translate,
|
||||
xml,
|
||||
xml_stream
|
||||
]},
|
||||
{registered, [ejabberd,
|
||||
ejabberd_auth,
|
||||
ejabberd_router,
|
||||
ejabberd_sm,
|
||||
ejabberd_s2s,
|
||||
ejabberd_local,
|
||||
ejabberd_mod_roster,
|
||||
ejabberd_listeners
|
||||
]},
|
||||
{applications, [kernel, stdlib, mnesia]},
|
||||
{env, []},
|
||||
{mod, {ejabberd_app, []}}]}.
|
||||
|
||||
|
||||
|
||||
% Local Variables:
|
||||
% mode: erlang
|
||||
% End:
|
@ -6,6 +6,9 @@
|
||||
{acl, admin, {user, "aleksey", "jabber.ru"}}.
|
||||
{acl, admin, {user, "ermine", "jabber.ru"}}.
|
||||
|
||||
|
||||
{acl, blocked, {user, "test2"}}.
|
||||
|
||||
{acl, jabberorg, {server, "jabber.org"}}.
|
||||
{acl, aleksey, {user, "aleksey", "jabber.ru"}}.
|
||||
|
||||
@ -18,11 +21,15 @@
|
||||
|
||||
{access, configure, [{allow, admin}]}.
|
||||
|
||||
{access, c2s, [{deny, blocked},
|
||||
{allow, all}]}.
|
||||
|
||||
{host, "e.localhost"}.
|
||||
|
||||
{listen, [{5522, ejabberd_c2s, start, []},
|
||||
{listen, [{5522, ejabberd_c2s, start, [{access, c2s}]},
|
||||
{5269, ejabberd_s2s_in, start, []},
|
||||
{8888, ejabberd_service, start, ["asd.e.localhost", "asdqwe"]}
|
||||
{8888, ejabberd_service, start,
|
||||
[{host, "asd.e.localhost", [{password, "asdqwe"}]}]}
|
||||
]}.
|
||||
|
||||
% This value (5569) is only for debugging, must be 5269
|
||||
|
112
src/ejabberd.erl
112
src/ejabberd.erl
@ -10,62 +10,70 @@
|
||||
-author('alexey@sevcom.net').
|
||||
-vsn('$Revision$ ').
|
||||
|
||||
-export([start/0, init/0]).
|
||||
|
||||
-include("ejabberd.hrl").
|
||||
-export([start/0, stop/0]).
|
||||
|
||||
start() ->
|
||||
spawn(?MODULE, init, []).
|
||||
application:start(mnesia),
|
||||
application:start(ejabberd).
|
||||
|
||||
init() ->
|
||||
register(ejabberd, self()),
|
||||
% Profiling
|
||||
%eprof:start(),
|
||||
%eprof:profile([self()]),
|
||||
%erlang:system_flag(fullsweep_after, 0),
|
||||
error_logger:logfile({open, ?ERROR_LOG_PATH}),
|
||||
randoms:start(),
|
||||
ok = erl_ddll:load_driver(".", expat_erl),
|
||||
Port = open_port({spawn, expat_erl}, [binary]),
|
||||
db_init(),
|
||||
sha:start(),
|
||||
translate:start(),
|
||||
acl:start(),
|
||||
gen_mod:start(),
|
||||
ejabberd_config:start(),
|
||||
ejabberd_auth:start(),
|
||||
ejabberd_router:start(),
|
||||
ejabberd_sm:start(),
|
||||
ejabberd_s2s:start(),
|
||||
ejabberd_local:start(),
|
||||
ejabberd_listener:start(),
|
||||
load_modules(),
|
||||
loop(Port).
|
||||
stop() ->
|
||||
application:stop(ejabberd).
|
||||
|
||||
|
||||
loop(Port) ->
|
||||
receive
|
||||
_ ->
|
||||
loop(Port)
|
||||
end.
|
||||
%-include("ejabberd.hrl").
|
||||
|
||||
db_init() ->
|
||||
case mnesia:system_info(extra_db_nodes) of
|
||||
[] ->
|
||||
mnesia:create_schema([node()]);
|
||||
_ ->
|
||||
ok
|
||||
end,
|
||||
mnesia:start(),
|
||||
mnesia:wait_for_tables(mnesia:system_info(local_tables), infinity).
|
||||
|
||||
load_modules() ->
|
||||
case ejabberd_config:get_local_option(modules) of
|
||||
undefined ->
|
||||
ok;
|
||||
Modules ->
|
||||
lists:foreach(fun({Module, Args}) ->
|
||||
gen_mod:start_module(Module, Args)
|
||||
end, Modules)
|
||||
end.
|
||||
%start() ->
|
||||
% spawn(?MODULE, init, []).
|
||||
%
|
||||
%init() ->
|
||||
% register(ejabberd, self()),
|
||||
% % Profiling
|
||||
% %eprof:start(),
|
||||
% %eprof:profile([self()]),
|
||||
% %erlang:system_flag(fullsweep_after, 0),
|
||||
% error_logger:logfile({open, ?ERROR_LOG_PATH}),
|
||||
% randoms:start(),
|
||||
% ok = erl_ddll:load_driver(".", expat_erl),
|
||||
% Port = open_port({spawn, expat_erl}, [binary]),
|
||||
% db_init(),
|
||||
% sha:start(),
|
||||
% translate:start(),
|
||||
% acl:start(),
|
||||
% gen_mod:start(),
|
||||
% ejabberd_config:start(),
|
||||
% ejabberd_auth:start(),
|
||||
% ejabberd_router:start(),
|
||||
% ejabberd_sm:start(),
|
||||
% ejabberd_s2s:start(),
|
||||
% ejabberd_local:start(),
|
||||
% ejabberd_listener:start(),
|
||||
% load_modules(),
|
||||
% loop(Port).
|
||||
%
|
||||
%
|
||||
%loop(Port) ->
|
||||
% receive
|
||||
% _ ->
|
||||
% loop(Port)
|
||||
% end.
|
||||
%
|
||||
%db_init() ->
|
||||
% case mnesia:system_info(extra_db_nodes) of
|
||||
% [] ->
|
||||
% mnesia:create_schema([node()]);
|
||||
% _ ->
|
||||
% ok
|
||||
% end,
|
||||
% mnesia:start(),
|
||||
% mnesia:wait_for_tables(mnesia:system_info(local_tables), infinity).
|
||||
%
|
||||
%load_modules() ->
|
||||
% case ejabberd_config:get_local_option(modules) of
|
||||
% undefined ->
|
||||
% ok;
|
||||
% Modules ->
|
||||
% lists:foreach(fun({Module, Args}) ->
|
||||
% gen_mod:start_module(Module, Args)
|
||||
% end, Modules)
|
||||
% end.
|
||||
|
||||
|
79
src/ejabberd_app.erl
Normal file
79
src/ejabberd_app.erl
Normal file
@ -0,0 +1,79 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%% File : ejabberd_app.erl
|
||||
%%% Author : Alexey Shchepin <alexey@sevcom.net>
|
||||
%%% Purpose :
|
||||
%%% Created : 31 Jan 2003 by Alexey Shchepin <alexey@sevcom.net>
|
||||
%%% Id : $Id$
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
-module(ejabberd_app).
|
||||
-author('alexey@sevcom.net').
|
||||
-vsn('$Revision$ ').
|
||||
|
||||
-behaviour(application).
|
||||
|
||||
-export([start/2, stop/1, init/0]).
|
||||
|
||||
-include("ejabberd.hrl").
|
||||
|
||||
start(normal, Args) ->
|
||||
randoms:start(),
|
||||
db_init(),
|
||||
sha:start(),
|
||||
translate:start(),
|
||||
acl:start(),
|
||||
gen_mod:start(),
|
||||
ejabberd_config:start(),
|
||||
ejabberd_auth:start(),
|
||||
Sup = ejabberd_sup:start_link(),
|
||||
start(),
|
||||
load_modules(),
|
||||
Sup;
|
||||
start(_, _) ->
|
||||
{error, badarg}.
|
||||
|
||||
stop(StartArgs) ->
|
||||
ok.
|
||||
|
||||
start() ->
|
||||
spawn(?MODULE, init, []).
|
||||
|
||||
init() ->
|
||||
register(ejabberd, self()),
|
||||
% Profiling
|
||||
%eprof:start(),
|
||||
%eprof:profile([self()]),
|
||||
%erlang:system_flag(fullsweep_after, 0),
|
||||
error_logger:logfile({open, ?ERROR_LOG_PATH}),
|
||||
ok = erl_ddll:load_driver(".", expat_erl),
|
||||
Port = open_port({spawn, expat_erl}, [binary]),
|
||||
|
||||
loop(Port).
|
||||
|
||||
|
||||
loop(Port) ->
|
||||
receive
|
||||
_ ->
|
||||
loop(Port)
|
||||
end.
|
||||
|
||||
db_init() ->
|
||||
case mnesia:system_info(extra_db_nodes) of
|
||||
[] ->
|
||||
mnesia:create_schema([node()]);
|
||||
_ ->
|
||||
ok
|
||||
end,
|
||||
mnesia:start(),
|
||||
mnesia:wait_for_tables(mnesia:system_info(local_tables), infinity).
|
||||
|
||||
load_modules() ->
|
||||
case ejabberd_config:get_local_option(modules) of
|
||||
undefined ->
|
||||
ok;
|
||||
Modules ->
|
||||
lists:foreach(fun({Module, Args}) ->
|
||||
gen_mod:start_module(Module, Args)
|
||||
end, Modules)
|
||||
end.
|
||||
|
@ -13,12 +13,9 @@
|
||||
-behaviour(gen_fsm).
|
||||
|
||||
%% External exports
|
||||
-export([start/1, receiver/2, sender/1, send_text/2, send_element/2]).
|
||||
-export([start/2, receiver/2, sender/1, send_text/2, send_element/2]).
|
||||
|
||||
%% gen_fsm callbacks
|
||||
%-export([init/1, state_name/2, state_name/3, handle_event/3,
|
||||
% handle_sync_event/4, handle_info/3, terminate/3]).
|
||||
%
|
||||
-export([init/1, wait_for_stream/2, wait_for_auth/2, session_established/2,
|
||||
handle_event/3,
|
||||
handle_sync_event/4,
|
||||
@ -32,6 +29,7 @@
|
||||
-define(SETS, gb_sets).
|
||||
|
||||
-record(state, {socket, sender, receiver, streamid,
|
||||
access,
|
||||
user = "", server = ?MYNAME, resource = "",
|
||||
pres_t = ?SETS:new(),
|
||||
pres_f = ?SETS:new(),
|
||||
@ -63,8 +61,8 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%% API
|
||||
%%%----------------------------------------------------------------------
|
||||
start(Socket) ->
|
||||
gen_fsm:start(ejabberd_c2s, [Socket], ?FSMOPTS).
|
||||
start(Socket, Opts) ->
|
||||
gen_fsm:start(ejabberd_c2s, [Socket, Opts], ?FSMOPTS).
|
||||
|
||||
%%%----------------------------------------------------------------------
|
||||
%%% Callback functions from gen_fsm
|
||||
@ -77,13 +75,20 @@ start(Socket) ->
|
||||
%% ignore |
|
||||
%% {stop, StopReason}
|
||||
%%----------------------------------------------------------------------
|
||||
init([Socket]) ->
|
||||
init([Socket, Opts]) ->
|
||||
SenderPid = spawn(?MODULE, sender, [Socket]),
|
||||
ReceiverPid = spawn(?MODULE, receiver, [Socket, self()]),
|
||||
Access = case lists:keysearch(access, 1, Opts) of
|
||||
{value, {_, A}} ->
|
||||
A;
|
||||
_ ->
|
||||
all
|
||||
end,
|
||||
{ok, wait_for_stream, #state{socket = Socket,
|
||||
receiver = ReceiverPid,
|
||||
sender = SenderPid,
|
||||
streamid = new_id()}}.
|
||||
streamid = new_id(),
|
||||
access = Access}}.
|
||||
|
||||
%%----------------------------------------------------------------------
|
||||
%% Func: StateName/2
|
||||
@ -118,8 +123,10 @@ wait_for_auth({xmlstreamelement, El}, StateData) ->
|
||||
{next_state, wait_for_auth, StateData};
|
||||
{auth, ID, {U, P, D, R}} ->
|
||||
io:format("AUTH: ~p~n", [{U, P, D, R}]),
|
||||
case ejabberd_auth:check_password(U, P,
|
||||
StateData#state.streamid, D) of
|
||||
case acl:match_rule(StateData#state.access, {U, ?MYNAME, R}) of
|
||||
allow ->
|
||||
case ejabberd_auth:check_password(
|
||||
U, P, StateData#state.streamid, D) of
|
||||
true ->
|
||||
ejabberd_sm:open_session(U, R),
|
||||
Res = jlib:make_result_iq_reply(El),
|
||||
@ -131,7 +138,13 @@ wait_for_auth({xmlstreamelement, El}, StateData) ->
|
||||
pres_f = ?SETS:from_list(Fs),
|
||||
pres_t = ?SETS:from_list(Ts)}};
|
||||
_ ->
|
||||
Err = jlib:make_error_reply(El, "401", "Unauthorized"),
|
||||
Err = jlib:make_error_reply(
|
||||
El, "401", "Unauthorized"),
|
||||
send_element(StateData#state.sender, Err),
|
||||
{next_state, wait_for_auth, StateData}
|
||||
end;
|
||||
_ ->
|
||||
Err = jlib:make_error_reply(El, "405", "Not Allowed"),
|
||||
send_element(StateData#state.sender, Err),
|
||||
{next_state, wait_for_auth, StateData}
|
||||
end;
|
||||
|
@ -18,6 +18,10 @@
|
||||
|
||||
-record(config, {key, value}).
|
||||
-record(local_config, {key, value}).
|
||||
-record(state, {opts = [],
|
||||
override_local = false,
|
||||
override_global = false,
|
||||
override_acls = false}).
|
||||
|
||||
start() ->
|
||||
%ets:new(ejabberd_config, [named_table, public]),
|
||||
@ -36,23 +40,32 @@ start() ->
|
||||
load_file(File) ->
|
||||
case file:consult(File) of
|
||||
{ok, Terms} ->
|
||||
lists:foreach(fun process_term/1, Terms);
|
||||
Res = lists:foldl(fun process_term/2, #state{}, Terms),
|
||||
set_opts(Res);
|
||||
{error, Reason} ->
|
||||
?ERROR_MSG("~p", [Reason]),
|
||||
exit(file:format_error(Reason))
|
||||
end.
|
||||
|
||||
process_term(Term) ->
|
||||
process_term(Term, State) ->
|
||||
case Term of
|
||||
override_global ->
|
||||
#state{override_global = true};
|
||||
override_local ->
|
||||
#state{override_local = true};
|
||||
override_acls ->
|
||||
#state{override_acls = true};
|
||||
{acl, ACLName, ACLData} ->
|
||||
acl:add(ACLName, ACLData);
|
||||
#state{opts =
|
||||
[acl:to_record(ACLName, ACLData) | State#state.opts]};
|
||||
{access, RuleName, Rules} ->
|
||||
add_global_option({access, RuleName}, Rules);
|
||||
#state{opts = [#config{key = {access, RuleName}, value = Rules} |
|
||||
State#state.opts]};
|
||||
{Opt, Val} ->
|
||||
add_option(Opt, Val)
|
||||
add_option(Opt, Val, State)
|
||||
end.
|
||||
|
||||
add_option(Opt, Val) ->
|
||||
add_option(Opt, Val, State) ->
|
||||
Table = case Opt of
|
||||
host ->
|
||||
config;
|
||||
@ -61,11 +74,51 @@ add_option(Opt, Val) ->
|
||||
end,
|
||||
case Table of
|
||||
config ->
|
||||
add_global_option(Opt, Val);
|
||||
#state{opts = [#config{key = Opt, value = Val} |
|
||||
State#state.opts]};
|
||||
local_config ->
|
||||
add_local_option(Opt, Val)
|
||||
#state{opts = [#local_config{key = Opt, value = Val} |
|
||||
State#state.opts]}
|
||||
end.
|
||||
|
||||
|
||||
set_opts(State) ->
|
||||
Opts = lists:reverse(State#state.opts),
|
||||
mnesia:transaction(
|
||||
fun() ->
|
||||
if
|
||||
State#state.override_global ->
|
||||
Ksg = mnesia:all_keys(config),
|
||||
lists:foreach(fun(K) ->
|
||||
mnesia:delete({config, K})
|
||||
end, Ksg);
|
||||
true ->
|
||||
ok
|
||||
end,
|
||||
if
|
||||
State#state.override_local ->
|
||||
Ksl = mnesia:all_keys(local_config),
|
||||
lists:foreach(fun(K) ->
|
||||
mnesia:delete({local_config, K})
|
||||
end, Ksl);
|
||||
true ->
|
||||
ok
|
||||
end,
|
||||
if
|
||||
State#state.override_acls ->
|
||||
Ksa = mnesia:all_keys(acl),
|
||||
lists:foreach(fun(K) ->
|
||||
mnesia:delete({acl, K})
|
||||
end, Ksa);
|
||||
true ->
|
||||
ok
|
||||
end,
|
||||
lists:foreach(fun(R) ->
|
||||
mnesia:write(R)
|
||||
end, Opts)
|
||||
end).
|
||||
|
||||
|
||||
add_global_option(Opt, Val) ->
|
||||
mnesia:transaction(fun() ->
|
||||
mnesia:write(#config{key = Opt,
|
||||
@ -96,4 +149,3 @@ get_local_option(Opt) ->
|
||||
end.
|
||||
|
||||
|
||||
|
||||
|
@ -10,9 +10,9 @@
|
||||
-author('alexey@sevcom.net').
|
||||
-vsn('$Revision$ ').
|
||||
|
||||
-export([start/0, init/1, start/4, init/4]).
|
||||
-export([start_link/0, init/1, start/4, init/4]).
|
||||
|
||||
start() ->
|
||||
start_link() ->
|
||||
supervisor:start_link({local, ejabberd_listeners}, ?MODULE, []).
|
||||
|
||||
|
||||
@ -23,9 +23,9 @@ init(_) ->
|
||||
Ls ->
|
||||
{ok, {{one_for_one, 10, 1},
|
||||
lists:map(
|
||||
fun({Port, Module, Fun, Args}) ->
|
||||
fun({Port, Module, Fun, Opts}) ->
|
||||
{Port,
|
||||
{?MODULE, start, [Port, Module, Fun, Args]},
|
||||
{?MODULE, start, [Port, Module, Fun, [Opts]]},
|
||||
permanent,
|
||||
brutal_kill,
|
||||
worker,
|
||||
|
@ -10,7 +10,7 @@
|
||||
-author('alexey@sevcom.net').
|
||||
-vsn('$Revision$ ').
|
||||
|
||||
-export([start/0, init/0]).
|
||||
-export([start_link/0, init/0]).
|
||||
|
||||
-export([register_iq_handler/3,
|
||||
register_iq_handler/4,
|
||||
@ -21,9 +21,10 @@
|
||||
|
||||
-record(state, {mydomain, iqtable}).
|
||||
|
||||
start() ->
|
||||
register(ejabberd_local, spawn(ejabberd_local, init, [])),
|
||||
ok.
|
||||
start_link() ->
|
||||
register(ejabberd_local,
|
||||
Pid = proc_lib:spawn_link(ejabberd_local, init, [])),
|
||||
{ok, Pid}.
|
||||
|
||||
init() ->
|
||||
MyDomain = ?MYNAME,
|
||||
|
@ -19,7 +19,7 @@
|
||||
dirty_get_all_domains/0
|
||||
]).
|
||||
|
||||
-export([start/0, init/0]).
|
||||
-export([start_link/0, init/0]).
|
||||
|
||||
-include("ejabberd.hrl").
|
||||
|
||||
@ -27,8 +27,8 @@
|
||||
-record(local_route, {domain, pid}).
|
||||
|
||||
|
||||
start() ->
|
||||
spawn(ejabberd_router, init, []).
|
||||
start_link() ->
|
||||
{ok, proc_lib:spawn_link(ejabberd_router, init, [])}.
|
||||
|
||||
init() ->
|
||||
register(ejabberd_router, self()),
|
||||
|
@ -10,7 +10,7 @@
|
||||
-author('alexey@sevcom.net').
|
||||
-vsn('$Revision$ ').
|
||||
|
||||
-export([start/0, init/0,
|
||||
-export([start_link/0, init/0,
|
||||
have_connection/1,
|
||||
get_key/1,
|
||||
try_register/1,
|
||||
@ -23,8 +23,8 @@
|
||||
-record(local_s2s, {fromto, pid}).
|
||||
|
||||
|
||||
start() ->
|
||||
spawn(ejabberd_s2s, init, []).
|
||||
start_link() ->
|
||||
{ok, proc_lib:spawn_link(ejabberd_s2s, init, [])}.
|
||||
|
||||
init() ->
|
||||
register(ejabberd_s2s, self()),
|
||||
|
@ -13,7 +13,7 @@
|
||||
-behaviour(gen_fsm).
|
||||
|
||||
%% External exports
|
||||
-export([start/1, receiver/2, send_text/2, send_element/2]).
|
||||
-export([start/2, receiver/2, send_text/2, send_element/2]).
|
||||
|
||||
%% gen_fsm callbacks
|
||||
-export([init/1,
|
||||
@ -65,7 +65,7 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%% API
|
||||
%%%----------------------------------------------------------------------
|
||||
start(Socket) ->
|
||||
start(Socket, Opts) ->
|
||||
gen_fsm:start(ejabberd_s2s_in, [Socket], ?FSMOPTS).
|
||||
|
||||
%%%----------------------------------------------------------------------
|
||||
|
@ -13,7 +13,7 @@
|
||||
-behaviour(gen_fsm).
|
||||
|
||||
%% External exports
|
||||
-export([start/3, receiver/2, send_text/2, send_element/2]).
|
||||
-export([start/2, receiver/2, send_text/2, send_element/2]).
|
||||
|
||||
%% gen_fsm callbacks
|
||||
-export([init/1,
|
||||
@ -63,8 +63,8 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%% API
|
||||
%%%----------------------------------------------------------------------
|
||||
start(Socket, Host, Password) ->
|
||||
gen_fsm:start(ejabberd_service, [Socket, Host, Password], ?FSMOPTS).
|
||||
start(Socket, Opts) ->
|
||||
gen_fsm:start(ejabberd_service, [Socket, Opts], ?FSMOPTS).
|
||||
|
||||
%%%----------------------------------------------------------------------
|
||||
%%% Callback functions from gen_fsm
|
||||
@ -77,7 +77,21 @@ start(Socket, Host, Password) ->
|
||||
%% ignore |
|
||||
%% {stop, StopReason}
|
||||
%%----------------------------------------------------------------------
|
||||
init([Socket, Host, Password]) ->
|
||||
init([Socket, Opts]) ->
|
||||
{Host, Password} =
|
||||
case lists:keysearch(host, 1, Opts) of
|
||||
{value, {_, H, HOpts}} ->
|
||||
case lists:keysearch(password, 1, HOpts) of
|
||||
{value, {_, P}} ->
|
||||
{H, P};
|
||||
_ ->
|
||||
% TODO: generate error
|
||||
false
|
||||
end;
|
||||
_ ->
|
||||
% TODO: generate error
|
||||
false
|
||||
end,
|
||||
ReceiverPid = spawn(?MODULE, receiver, [Socket, self()]),
|
||||
{ok, wait_for_stream, #state{socket = Socket,
|
||||
receiver = ReceiverPid,
|
||||
|
@ -10,7 +10,7 @@
|
||||
-author('alexey@sevcom.net').
|
||||
-vsn('$Revision$ ').
|
||||
|
||||
-export([start/0, init/0, open_session/2, close_session/2,
|
||||
-export([start_link/0, init/0, open_session/2, close_session/2,
|
||||
get_user_resources/1,
|
||||
set_presence/3,
|
||||
unset_presence/2,
|
||||
@ -28,8 +28,8 @@
|
||||
-record(local_session, {ur, pid}).
|
||||
-record(presence, {ur, user, priority}).
|
||||
|
||||
start() ->
|
||||
spawn(ejabberd_sm, init, []).
|
||||
start_link() ->
|
||||
{ok, proc_lib:spawn_link(ejabberd_sm, init, [])}.
|
||||
|
||||
init() ->
|
||||
register(ejabberd_sm, self()),
|
||||
|
54
src/ejabberd_sup.erl
Normal file
54
src/ejabberd_sup.erl
Normal file
@ -0,0 +1,54 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%% File : ejabberd_sup.erl
|
||||
%%% Author : Alexey Shchepin <alexey@sevcom.net>
|
||||
%%% Purpose :
|
||||
%%% Created : 31 Jan 2003 by Alexey Shchepin <alexey@sevcom.net>
|
||||
%%% Id : $Id$
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
-module(ejabberd_sup).
|
||||
-author('alexey@sevcom.net').
|
||||
-vsn('$Revision$ ').
|
||||
|
||||
-behaviour(supervisor).
|
||||
|
||||
-export([start_link/0, init/1]).
|
||||
|
||||
start_link() ->
|
||||
supervisor:start_link({local, ?MODULE}, ?MODULE, []).
|
||||
|
||||
|
||||
init([]) ->
|
||||
Router = {ejabberd_router,
|
||||
{ejabberd_router, start_link, []},
|
||||
permanent,
|
||||
brutal_kill,
|
||||
worker,
|
||||
[ejabberd_router]},
|
||||
SM = {ejabberd_sm,
|
||||
{ejabberd_sm, start_link, []},
|
||||
permanent,
|
||||
brutal_kill,
|
||||
worker,
|
||||
[ejabberd_sm]},
|
||||
S2S = {ejabberd_s2s,
|
||||
{ejabberd_s2s, start_link, []},
|
||||
permanent,
|
||||
brutal_kill,
|
||||
worker,
|
||||
[ejabberd_s2s]},
|
||||
Local = {ejabberd_local,
|
||||
{ejabberd_local, start_link, []},
|
||||
permanent,
|
||||
brutal_kill,
|
||||
worker,
|
||||
[ejabberd_local]},
|
||||
Listener = {ejabberd_listener,
|
||||
{ejabberd_listener, start_link, []},
|
||||
permanent,
|
||||
brutal_kill,
|
||||
supervisor,
|
||||
[ejabberd_listener]},
|
||||
{ok, {{one_for_one, 10, 1}, [Router, SM, S2S, Local, Listener]}}.
|
||||
|
||||
|
@ -244,7 +244,7 @@ get_form(["config", "acls"], Lang) ->
|
||||
{xmlelement, "value", [], [{xmlcdata, S}]}
|
||||
end,
|
||||
string:tokens(
|
||||
lists:flatten(io_lib:format("~p",
|
||||
lists:flatten(io_lib:format("~p.",
|
||||
[ets:tab2list(acl)])),
|
||||
"\n"))
|
||||
%{xmlelement, "value", [], [{xmlcdata, ?MYNAME}]}
|
||||
@ -343,22 +343,19 @@ set_form(["running nodes", ENode, "modules", "start"], Lang, XData) ->
|
||||
{ok, Tokens, _} ->
|
||||
case erl_parse:parse_term(Tokens) of
|
||||
{ok, Modules} ->
|
||||
case catch lists:foreach(
|
||||
lists:foreach(
|
||||
fun({Module, Args}) ->
|
||||
gen_mod:start_module(
|
||||
Module, Args)
|
||||
end, Modules) of
|
||||
{'EXIT', Reason} ->
|
||||
{error,
|
||||
"500", "Internal Server Error"};
|
||||
rpc:call(Node,
|
||||
gen_mod,
|
||||
start_module,
|
||||
[Module, Args])
|
||||
end, Modules),
|
||||
{result, []};
|
||||
_ ->
|
||||
{result, []}
|
||||
{error, "406", "Not Acceptable"}
|
||||
end;
|
||||
_ ->
|
||||
{error, "500", "Internal Server Error"}
|
||||
end;
|
||||
_ ->
|
||||
{error, "500", "Internal Server Error"}
|
||||
{error, "406", "Not Acceptable"}
|
||||
end;
|
||||
_ ->
|
||||
{error, "406", "Not Acceptable"}
|
||||
@ -379,6 +376,32 @@ set_form(["config", "hostname"], Lang, XData) ->
|
||||
{error, "406", "Not Acceptable"}
|
||||
end;
|
||||
|
||||
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;
|
||||
_ ->
|
||||
{error, "406", "Not Acceptable"}
|
||||
end;
|
||||
_ ->
|
||||
{error, "406", "Not Acceptable"}
|
||||
end;
|
||||
_ ->
|
||||
{error, "406", "Not Acceptable"}
|
||||
end;
|
||||
|
||||
set_form(["config", "remusers"], Lang, XData) ->
|
||||
lists:foreach(
|
||||
fun({Var, Vals}) ->
|
||||
|
@ -1,11 +1,44 @@
|
||||
% $Id$
|
||||
|
||||
% mod_configure.erl
|
||||
{"DB Tables Configuration", "Конфигурация таблиц БД"}.
|
||||
{"Choose storage type of tables", "Выберите тип хранения таблиц"}.
|
||||
{"", ""}.
|
||||
{"", ""}.
|
||||
{"", ""}.
|
||||
{"", ""}.
|
||||
{"", ""}.
|
||||
{"", ""}.
|
||||
{"", ""}.
|
||||
{"", ""}.
|
||||
{"", ""}.
|
||||
{"", ""}.
|
||||
{"", ""}.
|
||||
{"", ""}.
|
||||
{"", ""}.
|
||||
{"", ""}.
|
||||
{"", ""}.
|
||||
{"", ""}.
|
||||
|
||||
% mod_disco.erl
|
||||
{"Configuration", "Конфигурация"}.
|
||||
{"Online Users", "Подключённые пользователи"}.
|
||||
{"All Users", "Все пользователи"}.
|
||||
{"Outgoing S2S connections", "Исходящие S2S-соединения"}.
|
||||
{"To ~s", "К ~s"}.
|
||||
{"From ~s", "От ~s"}.
|
||||
{"Running Nodes", "Работающие узлы"}.
|
||||
{"Stopped Nodes", "Остановленные узлы"}.
|
||||
{"Host Name", "Имя хоста"}.
|
||||
{"ACLs", "ACLs"}.
|
||||
{"Access Rules", "Правила доступа"}.
|
||||
{"Remove Users", "Удаление пользователей"}.
|
||||
{"DB", "БД"}.
|
||||
{"Modules", "Модули"}.
|
||||
{"Start Modules", "Запуск модулей"}.
|
||||
{"Stop Modules", "Остановка модулей"}.
|
||||
|
||||
|
||||
|
||||
|
||||
% mod_vcard.erl
|
||||
|
Loading…
Reference in New Issue
Block a user