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
|
if this file will not contain ``host'' definition, then old value will be
|
||||||
used.<BR>
|
used.<BR>
|
||||||
<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-->
|
<!--TOC subsubsection Host Name-->
|
||||||
|
|
||||||
<H4>3.1.1 Host Name</H4><!--SEC END -->
|
<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:
|
serves. E. g. to use <TT>jabber.org</TT> domain add following line in config:
|
||||||
<PRE>
|
<PRE>
|
||||||
{host, "jabber.org"}.
|
{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-->
|
</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
|
<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:
|
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
|
If the first character after <TT>`['</TT> is a <TT>`!'</TT>, then any
|
||||||
character not enclosed is matched.
|
character not enclosed is matched.
|
||||||
</DL>
|
</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:
|
</DL>Allowing or denying of different services is like this:
|
||||||
<PRE>
|
<PRE>
|
||||||
{access, <accessname>, [{allow, <aclname>},
|
{access, <accessname>, [{allow, <aclname>},
|
||||||
@ -229,6 +210,57 @@ Example:
|
|||||||
{access, configure, [{allow, admin}]}.
|
{access, configure, [{allow, admin}]}.
|
||||||
{access, something, [{deny, badmans},
|
{access, something, [{deny, badmans},
|
||||||
{allow, all}]}.
|
{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-->
|
</PRE><!--TOC subsubsection Modules-->
|
||||||
|
|
||||||
<H4>3.1.4 Modules</H4><!--SEC END -->
|
<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
|
magic cookie (see Erlang/OTP documentation, in short file
|
||||||
<TT>~ejabberd/.erlang.cookie</TT> must be the same on all nodes). This is
|
<TT>~ejabberd/.erlang.cookie</TT> must be the same on all nodes). This is
|
||||||
needed because all nodes exchange information about connected users, S2S
|
needed because all nodes exchange information about connected users, S2S
|
||||||
connection, registered services, etc...<BR>
|
connections, registered services, etc...<BR>
|
||||||
<BR>
|
<BR>
|
||||||
Each <TT>ejabberd</TT> node run following modules:
|
Each <TT>ejabberd</TT> node run following modules:
|
||||||
<UL>
|
<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
|
if this file will not contain ``host'' definition, then old value will be
|
||||||
used.
|
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}
|
\subsubsection{Host Name}
|
||||||
\label{sec:confighostname}
|
\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}
|
\subsubsection{Access Rules}
|
||||||
\label{sec:configaccess}
|
\label{sec:configaccess}
|
||||||
|
|
||||||
@ -253,6 +230,12 @@ config file they looks like this:
|
|||||||
\end{description}
|
\end{description}
|
||||||
\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:
|
Allowing or denying of different services is like this:
|
||||||
\begin{verbatim}
|
\begin{verbatim}
|
||||||
{access, <accessname>, [{allow, <aclname>},
|
{access, <accessname>, [{allow, <aclname>},
|
||||||
@ -272,6 +255,57 @@ Example:
|
|||||||
{allow, all}]}.
|
{allow, all}]}.
|
||||||
\end{verbatim}
|
\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}
|
\subsubsection{Modules}
|
||||||
|
@ -3,9 +3,10 @@
|
|||||||
include Makefile.inc
|
include Makefile.inc
|
||||||
|
|
||||||
INCLUDES = -I/usr/lib/erlang/usr/include \
|
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
|
ERLSHLIBS = expat_erl.so
|
||||||
|
|
||||||
|
121
src/acl.erl
121
src/acl.erl
@ -11,7 +11,9 @@
|
|||||||
-vsn('$Revision$ ').
|
-vsn('$Revision$ ').
|
||||||
|
|
||||||
-export([start/0,
|
-export([start/0,
|
||||||
|
to_record/2,
|
||||||
add/2,
|
add/2,
|
||||||
|
add_list/2,
|
||||||
match_rule/2,
|
match_rule/2,
|
||||||
% for debugging only
|
% for debugging only
|
||||||
match_acl/2]).
|
match_acl/2]).
|
||||||
@ -28,6 +30,8 @@ start() ->
|
|||||||
mnesia:add_table_copy(acl, node(), ram_copies),
|
mnesia:add_table_copy(acl, node(), ram_copies),
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
|
to_record(ACLName, ACLSpec) ->
|
||||||
|
#acl{aclname = ACLName, aclspec = ACLSpec}.
|
||||||
|
|
||||||
add(ACLName, ACLSpec) ->
|
add(ACLName, ACLSpec) ->
|
||||||
F = fun() ->
|
F = fun() ->
|
||||||
@ -35,12 +39,44 @@ add(ACLName, ACLSpec) ->
|
|||||||
end,
|
end,
|
||||||
mnesia:transaction(F).
|
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) ->
|
match_rule(Rule, JID) ->
|
||||||
case ejabberd_config:get_global_option({access, Rule}) of
|
case Rule of
|
||||||
undefined ->
|
all -> allow;
|
||||||
deny;
|
none -> deny;
|
||||||
ACLs ->
|
_ ->
|
||||||
match_acls(ACLs, JID)
|
case ejabberd_config:get_global_option({access, Rule}) of
|
||||||
|
undefined ->
|
||||||
|
deny;
|
||||||
|
ACLs ->
|
||||||
|
match_acls(ACLs, JID)
|
||||||
|
end
|
||||||
end.
|
end.
|
||||||
|
|
||||||
match_acls([], _) ->
|
match_acls([], _) ->
|
||||||
@ -54,41 +90,46 @@ match_acls([{Access, ACL} | ACLs], JID) ->
|
|||||||
end.
|
end.
|
||||||
|
|
||||||
match_acl(ACL, JID) ->
|
match_acl(ACL, JID) ->
|
||||||
{User, Server, Resource} = jlib:jid_tolower(JID),
|
case ACL of
|
||||||
lists:any(fun(#acl{aclspec = Spec}) ->
|
all -> true;
|
||||||
case Spec of
|
none -> false;
|
||||||
all ->
|
_ ->
|
||||||
true;
|
{User, Server, Resource} = jlib:jid_tolower(JID),
|
||||||
{user, U} ->
|
lists:any(fun(#acl{aclspec = Spec}) ->
|
||||||
(U == User) andalso (?MYNAME == Server);
|
case Spec of
|
||||||
{user, U, S} ->
|
all ->
|
||||||
(U == User) andalso (S == Server);
|
true;
|
||||||
{server, S} ->
|
{user, U} ->
|
||||||
S == Server;
|
(U == User) andalso (?MYNAME == Server);
|
||||||
{user_regexp, UR} ->
|
{user, U, S} ->
|
||||||
(?MYNAME == Server) andalso
|
(U == User) andalso (S == Server);
|
||||||
is_regexp_match(User, UR);
|
{server, S} ->
|
||||||
{user_regexp, UR, S} ->
|
S == Server;
|
||||||
(S == Server) andalso
|
{user_regexp, UR} ->
|
||||||
is_regexp_match(User, UR);
|
(?MYNAME == Server) andalso
|
||||||
{server_regexp, SR} ->
|
is_regexp_match(User, UR);
|
||||||
is_regexp_match(Server, SR);
|
{user_regexp, UR, S} ->
|
||||||
{node_regexp, UR, SR} ->
|
(S == Server) andalso
|
||||||
is_regexp_match(Server, SR) andalso
|
is_regexp_match(User, UR);
|
||||||
is_regexp_match(User, UR);
|
{server_regexp, SR} ->
|
||||||
{user_glob, UR} ->
|
is_regexp_match(Server, SR);
|
||||||
(?MYNAME == Server) andalso
|
{node_regexp, UR, SR} ->
|
||||||
is_glob_match(User, UR);
|
is_regexp_match(Server, SR) andalso
|
||||||
{user_glob, UR, S} ->
|
is_regexp_match(User, UR);
|
||||||
(S == Server) andalso
|
{user_glob, UR} ->
|
||||||
is_glob_match(User, UR);
|
(?MYNAME == Server) andalso
|
||||||
{server_glob, SR} ->
|
is_glob_match(User, UR);
|
||||||
is_glob_match(Server, SR);
|
{user_glob, UR, S} ->
|
||||||
{node_glob, UR, SR} ->
|
(S == Server) andalso
|
||||||
is_glob_match(Server, SR) andalso
|
is_glob_match(User, UR);
|
||||||
is_glob_match(User, UR)
|
{server_glob, SR} ->
|
||||||
end
|
is_glob_match(Server, SR);
|
||||||
end, ets:lookup(acl, ACL)).
|
{node_glob, UR, SR} ->
|
||||||
|
is_glob_match(Server, SR) andalso
|
||||||
|
is_glob_match(User, UR)
|
||||||
|
end
|
||||||
|
end, ets:lookup(acl, ACL))
|
||||||
|
end.
|
||||||
|
|
||||||
is_regexp_match(String, RegExp) ->
|
is_regexp_match(String, RegExp) ->
|
||||||
case regexp:first_match(String, RegExp) of
|
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, "aleksey", "jabber.ru"}}.
|
||||||
{acl, admin, {user, "ermine", "jabber.ru"}}.
|
{acl, admin, {user, "ermine", "jabber.ru"}}.
|
||||||
|
|
||||||
|
|
||||||
|
{acl, blocked, {user, "test2"}}.
|
||||||
|
|
||||||
{acl, jabberorg, {server, "jabber.org"}}.
|
{acl, jabberorg, {server, "jabber.org"}}.
|
||||||
{acl, aleksey, {user, "aleksey", "jabber.ru"}}.
|
{acl, aleksey, {user, "aleksey", "jabber.ru"}}.
|
||||||
|
|
||||||
@ -18,11 +21,15 @@
|
|||||||
|
|
||||||
{access, configure, [{allow, admin}]}.
|
{access, configure, [{allow, admin}]}.
|
||||||
|
|
||||||
|
{access, c2s, [{deny, blocked},
|
||||||
|
{allow, all}]}.
|
||||||
|
|
||||||
{host, "e.localhost"}.
|
{host, "e.localhost"}.
|
||||||
|
|
||||||
{listen, [{5522, ejabberd_c2s, start, []},
|
{listen, [{5522, ejabberd_c2s, start, [{access, c2s}]},
|
||||||
{5269, ejabberd_s2s_in, start, []},
|
{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
|
% 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').
|
-author('alexey@sevcom.net').
|
||||||
-vsn('$Revision$ ').
|
-vsn('$Revision$ ').
|
||||||
|
|
||||||
-export([start/0, init/0]).
|
-export([start/0, stop/0]).
|
||||||
|
|
||||||
-include("ejabberd.hrl").
|
|
||||||
|
|
||||||
start() ->
|
start() ->
|
||||||
spawn(?MODULE, init, []).
|
application:start(mnesia),
|
||||||
|
application:start(ejabberd).
|
||||||
|
|
||||||
init() ->
|
stop() ->
|
||||||
register(ejabberd, self()),
|
application:stop(ejabberd).
|
||||||
% 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) ->
|
%-include("ejabberd.hrl").
|
||||||
receive
|
|
||||||
_ ->
|
|
||||||
loop(Port)
|
|
||||||
end.
|
|
||||||
|
|
||||||
db_init() ->
|
%start() ->
|
||||||
case mnesia:system_info(extra_db_nodes) of
|
% spawn(?MODULE, init, []).
|
||||||
[] ->
|
%
|
||||||
mnesia:create_schema([node()]);
|
%init() ->
|
||||||
_ ->
|
% register(ejabberd, self()),
|
||||||
ok
|
% % Profiling
|
||||||
end,
|
% %eprof:start(),
|
||||||
mnesia:start(),
|
% %eprof:profile([self()]),
|
||||||
mnesia:wait_for_tables(mnesia:system_info(local_tables), infinity).
|
% %erlang:system_flag(fullsweep_after, 0),
|
||||||
|
% error_logger:logfile({open, ?ERROR_LOG_PATH}),
|
||||||
load_modules() ->
|
% randoms:start(),
|
||||||
case ejabberd_config:get_local_option(modules) of
|
% ok = erl_ddll:load_driver(".", expat_erl),
|
||||||
undefined ->
|
% Port = open_port({spawn, expat_erl}, [binary]),
|
||||||
ok;
|
% db_init(),
|
||||||
Modules ->
|
% sha:start(),
|
||||||
lists:foreach(fun({Module, Args}) ->
|
% translate:start(),
|
||||||
gen_mod:start_module(Module, Args)
|
% acl:start(),
|
||||||
end, Modules)
|
% gen_mod:start(),
|
||||||
end.
|
% 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).
|
-behaviour(gen_fsm).
|
||||||
|
|
||||||
%% External exports
|
%% 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
|
%% 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,
|
-export([init/1, wait_for_stream/2, wait_for_auth/2, session_established/2,
|
||||||
handle_event/3,
|
handle_event/3,
|
||||||
handle_sync_event/4,
|
handle_sync_event/4,
|
||||||
@ -32,6 +29,7 @@
|
|||||||
-define(SETS, gb_sets).
|
-define(SETS, gb_sets).
|
||||||
|
|
||||||
-record(state, {socket, sender, receiver, streamid,
|
-record(state, {socket, sender, receiver, streamid,
|
||||||
|
access,
|
||||||
user = "", server = ?MYNAME, resource = "",
|
user = "", server = ?MYNAME, resource = "",
|
||||||
pres_t = ?SETS:new(),
|
pres_t = ?SETS:new(),
|
||||||
pres_f = ?SETS:new(),
|
pres_f = ?SETS:new(),
|
||||||
@ -63,8 +61,8 @@
|
|||||||
%%%----------------------------------------------------------------------
|
%%%----------------------------------------------------------------------
|
||||||
%%% API
|
%%% API
|
||||||
%%%----------------------------------------------------------------------
|
%%%----------------------------------------------------------------------
|
||||||
start(Socket) ->
|
start(Socket, Opts) ->
|
||||||
gen_fsm:start(ejabberd_c2s, [Socket], ?FSMOPTS).
|
gen_fsm:start(ejabberd_c2s, [Socket, Opts], ?FSMOPTS).
|
||||||
|
|
||||||
%%%----------------------------------------------------------------------
|
%%%----------------------------------------------------------------------
|
||||||
%%% Callback functions from gen_fsm
|
%%% Callback functions from gen_fsm
|
||||||
@ -77,13 +75,20 @@ start(Socket) ->
|
|||||||
%% ignore |
|
%% ignore |
|
||||||
%% {stop, StopReason}
|
%% {stop, StopReason}
|
||||||
%%----------------------------------------------------------------------
|
%%----------------------------------------------------------------------
|
||||||
init([Socket]) ->
|
init([Socket, Opts]) ->
|
||||||
SenderPid = spawn(?MODULE, sender, [Socket]),
|
SenderPid = spawn(?MODULE, sender, [Socket]),
|
||||||
ReceiverPid = spawn(?MODULE, receiver, [Socket, self()]),
|
ReceiverPid = spawn(?MODULE, receiver, [Socket, self()]),
|
||||||
{ok, wait_for_stream, #state{socket = Socket,
|
Access = case lists:keysearch(access, 1, Opts) of
|
||||||
|
{value, {_, A}} ->
|
||||||
|
A;
|
||||||
|
_ ->
|
||||||
|
all
|
||||||
|
end,
|
||||||
|
{ok, wait_for_stream, #state{socket = Socket,
|
||||||
receiver = ReceiverPid,
|
receiver = ReceiverPid,
|
||||||
sender = SenderPid,
|
sender = SenderPid,
|
||||||
streamid = new_id()}}.
|
streamid = new_id(),
|
||||||
|
access = Access}}.
|
||||||
|
|
||||||
%%----------------------------------------------------------------------
|
%%----------------------------------------------------------------------
|
||||||
%% Func: StateName/2
|
%% Func: StateName/2
|
||||||
@ -118,20 +123,28 @@ wait_for_auth({xmlstreamelement, El}, StateData) ->
|
|||||||
{next_state, wait_for_auth, StateData};
|
{next_state, wait_for_auth, StateData};
|
||||||
{auth, ID, {U, P, D, R}} ->
|
{auth, ID, {U, P, D, R}} ->
|
||||||
io:format("AUTH: ~p~n", [{U, P, D, R}]),
|
io:format("AUTH: ~p~n", [{U, P, D, R}]),
|
||||||
case ejabberd_auth:check_password(U, P,
|
case acl:match_rule(StateData#state.access, {U, ?MYNAME, R}) of
|
||||||
StateData#state.streamid, D) of
|
allow ->
|
||||||
true ->
|
case ejabberd_auth:check_password(
|
||||||
ejabberd_sm:open_session(U, R),
|
U, P, StateData#state.streamid, D) of
|
||||||
Res = jlib:make_result_iq_reply(El),
|
true ->
|
||||||
send_element(StateData#state.sender, Res),
|
ejabberd_sm:open_session(U, R),
|
||||||
{Fs, Ts} = mod_roster:get_subscription_lists(U),
|
Res = jlib:make_result_iq_reply(El),
|
||||||
{next_state, session_established,
|
send_element(StateData#state.sender, Res),
|
||||||
StateData#state{user = U,
|
{Fs, Ts} = mod_roster:get_subscription_lists(U),
|
||||||
resource = R,
|
{next_state, session_established,
|
||||||
pres_f = ?SETS:from_list(Fs),
|
StateData#state{user = U,
|
||||||
pres_t = ?SETS:from_list(Ts)}};
|
resource = R,
|
||||||
|
pres_f = ?SETS:from_list(Fs),
|
||||||
|
pres_t = ?SETS:from_list(Ts)}};
|
||||||
|
_ ->
|
||||||
|
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, "401", "Unauthorized"),
|
Err = jlib:make_error_reply(El, "405", "Not Allowed"),
|
||||||
send_element(StateData#state.sender, Err),
|
send_element(StateData#state.sender, Err),
|
||||||
{next_state, wait_for_auth, StateData}
|
{next_state, wait_for_auth, StateData}
|
||||||
end;
|
end;
|
||||||
|
@ -18,6 +18,10 @@
|
|||||||
|
|
||||||
-record(config, {key, value}).
|
-record(config, {key, value}).
|
||||||
-record(local_config, {key, value}).
|
-record(local_config, {key, value}).
|
||||||
|
-record(state, {opts = [],
|
||||||
|
override_local = false,
|
||||||
|
override_global = false,
|
||||||
|
override_acls = false}).
|
||||||
|
|
||||||
start() ->
|
start() ->
|
||||||
%ets:new(ejabberd_config, [named_table, public]),
|
%ets:new(ejabberd_config, [named_table, public]),
|
||||||
@ -36,23 +40,32 @@ start() ->
|
|||||||
load_file(File) ->
|
load_file(File) ->
|
||||||
case file:consult(File) of
|
case file:consult(File) of
|
||||||
{ok, Terms} ->
|
{ok, Terms} ->
|
||||||
lists:foreach(fun process_term/1, Terms);
|
Res = lists:foldl(fun process_term/2, #state{}, Terms),
|
||||||
|
set_opts(Res);
|
||||||
{error, Reason} ->
|
{error, Reason} ->
|
||||||
?ERROR_MSG("~p", [Reason]),
|
?ERROR_MSG("~p", [Reason]),
|
||||||
exit(file:format_error(Reason))
|
exit(file:format_error(Reason))
|
||||||
end.
|
end.
|
||||||
|
|
||||||
process_term(Term) ->
|
process_term(Term, State) ->
|
||||||
case Term of
|
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, ACLName, ACLData} ->
|
||||||
acl:add(ACLName, ACLData);
|
#state{opts =
|
||||||
|
[acl:to_record(ACLName, ACLData) | State#state.opts]};
|
||||||
{access, RuleName, Rules} ->
|
{access, RuleName, Rules} ->
|
||||||
add_global_option({access, RuleName}, Rules);
|
#state{opts = [#config{key = {access, RuleName}, value = Rules} |
|
||||||
|
State#state.opts]};
|
||||||
{Opt, Val} ->
|
{Opt, Val} ->
|
||||||
add_option(Opt, Val)
|
add_option(Opt, Val, State)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
add_option(Opt, Val) ->
|
add_option(Opt, Val, State) ->
|
||||||
Table = case Opt of
|
Table = case Opt of
|
||||||
host ->
|
host ->
|
||||||
config;
|
config;
|
||||||
@ -61,11 +74,51 @@ add_option(Opt, Val) ->
|
|||||||
end,
|
end,
|
||||||
case Table of
|
case Table of
|
||||||
config ->
|
config ->
|
||||||
add_global_option(Opt, Val);
|
#state{opts = [#config{key = Opt, value = Val} |
|
||||||
|
State#state.opts]};
|
||||||
local_config ->
|
local_config ->
|
||||||
add_local_option(Opt, Val)
|
#state{opts = [#local_config{key = Opt, value = Val} |
|
||||||
|
State#state.opts]}
|
||||||
end.
|
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) ->
|
add_global_option(Opt, Val) ->
|
||||||
mnesia:transaction(fun() ->
|
mnesia:transaction(fun() ->
|
||||||
mnesia:write(#config{key = Opt,
|
mnesia:write(#config{key = Opt,
|
||||||
@ -96,4 +149,3 @@ get_local_option(Opt) ->
|
|||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -10,9 +10,9 @@
|
|||||||
-author('alexey@sevcom.net').
|
-author('alexey@sevcom.net').
|
||||||
-vsn('$Revision$ ').
|
-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, []).
|
supervisor:start_link({local, ejabberd_listeners}, ?MODULE, []).
|
||||||
|
|
||||||
|
|
||||||
@ -23,9 +23,9 @@ init(_) ->
|
|||||||
Ls ->
|
Ls ->
|
||||||
{ok, {{one_for_one, 10, 1},
|
{ok, {{one_for_one, 10, 1},
|
||||||
lists:map(
|
lists:map(
|
||||||
fun({Port, Module, Fun, Args}) ->
|
fun({Port, Module, Fun, Opts}) ->
|
||||||
{Port,
|
{Port,
|
||||||
{?MODULE, start, [Port, Module, Fun, Args]},
|
{?MODULE, start, [Port, Module, Fun, [Opts]]},
|
||||||
permanent,
|
permanent,
|
||||||
brutal_kill,
|
brutal_kill,
|
||||||
worker,
|
worker,
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
-author('alexey@sevcom.net').
|
-author('alexey@sevcom.net').
|
||||||
-vsn('$Revision$ ').
|
-vsn('$Revision$ ').
|
||||||
|
|
||||||
-export([start/0, init/0]).
|
-export([start_link/0, init/0]).
|
||||||
|
|
||||||
-export([register_iq_handler/3,
|
-export([register_iq_handler/3,
|
||||||
register_iq_handler/4,
|
register_iq_handler/4,
|
||||||
@ -21,9 +21,10 @@
|
|||||||
|
|
||||||
-record(state, {mydomain, iqtable}).
|
-record(state, {mydomain, iqtable}).
|
||||||
|
|
||||||
start() ->
|
start_link() ->
|
||||||
register(ejabberd_local, spawn(ejabberd_local, init, [])),
|
register(ejabberd_local,
|
||||||
ok.
|
Pid = proc_lib:spawn_link(ejabberd_local, init, [])),
|
||||||
|
{ok, Pid}.
|
||||||
|
|
||||||
init() ->
|
init() ->
|
||||||
MyDomain = ?MYNAME,
|
MyDomain = ?MYNAME,
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
dirty_get_all_domains/0
|
dirty_get_all_domains/0
|
||||||
]).
|
]).
|
||||||
|
|
||||||
-export([start/0, init/0]).
|
-export([start_link/0, init/0]).
|
||||||
|
|
||||||
-include("ejabberd.hrl").
|
-include("ejabberd.hrl").
|
||||||
|
|
||||||
@ -27,8 +27,8 @@
|
|||||||
-record(local_route, {domain, pid}).
|
-record(local_route, {domain, pid}).
|
||||||
|
|
||||||
|
|
||||||
start() ->
|
start_link() ->
|
||||||
spawn(ejabberd_router, init, []).
|
{ok, proc_lib:spawn_link(ejabberd_router, init, [])}.
|
||||||
|
|
||||||
init() ->
|
init() ->
|
||||||
register(ejabberd_router, self()),
|
register(ejabberd_router, self()),
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
-author('alexey@sevcom.net').
|
-author('alexey@sevcom.net').
|
||||||
-vsn('$Revision$ ').
|
-vsn('$Revision$ ').
|
||||||
|
|
||||||
-export([start/0, init/0,
|
-export([start_link/0, init/0,
|
||||||
have_connection/1,
|
have_connection/1,
|
||||||
get_key/1,
|
get_key/1,
|
||||||
try_register/1,
|
try_register/1,
|
||||||
@ -23,8 +23,8 @@
|
|||||||
-record(local_s2s, {fromto, pid}).
|
-record(local_s2s, {fromto, pid}).
|
||||||
|
|
||||||
|
|
||||||
start() ->
|
start_link() ->
|
||||||
spawn(ejabberd_s2s, init, []).
|
{ok, proc_lib:spawn_link(ejabberd_s2s, init, [])}.
|
||||||
|
|
||||||
init() ->
|
init() ->
|
||||||
register(ejabberd_s2s, self()),
|
register(ejabberd_s2s, self()),
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
-behaviour(gen_fsm).
|
-behaviour(gen_fsm).
|
||||||
|
|
||||||
%% External exports
|
%% 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
|
%% gen_fsm callbacks
|
||||||
-export([init/1,
|
-export([init/1,
|
||||||
@ -65,7 +65,7 @@
|
|||||||
%%%----------------------------------------------------------------------
|
%%%----------------------------------------------------------------------
|
||||||
%%% API
|
%%% API
|
||||||
%%%----------------------------------------------------------------------
|
%%%----------------------------------------------------------------------
|
||||||
start(Socket) ->
|
start(Socket, Opts) ->
|
||||||
gen_fsm:start(ejabberd_s2s_in, [Socket], ?FSMOPTS).
|
gen_fsm:start(ejabberd_s2s_in, [Socket], ?FSMOPTS).
|
||||||
|
|
||||||
%%%----------------------------------------------------------------------
|
%%%----------------------------------------------------------------------
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
-behaviour(gen_fsm).
|
-behaviour(gen_fsm).
|
||||||
|
|
||||||
%% External exports
|
%% 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
|
%% gen_fsm callbacks
|
||||||
-export([init/1,
|
-export([init/1,
|
||||||
@ -63,8 +63,8 @@
|
|||||||
%%%----------------------------------------------------------------------
|
%%%----------------------------------------------------------------------
|
||||||
%%% API
|
%%% API
|
||||||
%%%----------------------------------------------------------------------
|
%%%----------------------------------------------------------------------
|
||||||
start(Socket, Host, Password) ->
|
start(Socket, Opts) ->
|
||||||
gen_fsm:start(ejabberd_service, [Socket, Host, Password], ?FSMOPTS).
|
gen_fsm:start(ejabberd_service, [Socket, Opts], ?FSMOPTS).
|
||||||
|
|
||||||
%%%----------------------------------------------------------------------
|
%%%----------------------------------------------------------------------
|
||||||
%%% Callback functions from gen_fsm
|
%%% Callback functions from gen_fsm
|
||||||
@ -77,7 +77,21 @@ start(Socket, Host, Password) ->
|
|||||||
%% ignore |
|
%% ignore |
|
||||||
%% {stop, StopReason}
|
%% {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()]),
|
ReceiverPid = spawn(?MODULE, receiver, [Socket, self()]),
|
||||||
{ok, wait_for_stream, #state{socket = Socket,
|
{ok, wait_for_stream, #state{socket = Socket,
|
||||||
receiver = ReceiverPid,
|
receiver = ReceiverPid,
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
-author('alexey@sevcom.net').
|
-author('alexey@sevcom.net').
|
||||||
-vsn('$Revision$ ').
|
-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,
|
get_user_resources/1,
|
||||||
set_presence/3,
|
set_presence/3,
|
||||||
unset_presence/2,
|
unset_presence/2,
|
||||||
@ -28,8 +28,8 @@
|
|||||||
-record(local_session, {ur, pid}).
|
-record(local_session, {ur, pid}).
|
||||||
-record(presence, {ur, user, priority}).
|
-record(presence, {ur, user, priority}).
|
||||||
|
|
||||||
start() ->
|
start_link() ->
|
||||||
spawn(ejabberd_sm, init, []).
|
{ok, proc_lib:spawn_link(ejabberd_sm, init, [])}.
|
||||||
|
|
||||||
init() ->
|
init() ->
|
||||||
register(ejabberd_sm, self()),
|
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}]}
|
{xmlelement, "value", [], [{xmlcdata, S}]}
|
||||||
end,
|
end,
|
||||||
string:tokens(
|
string:tokens(
|
||||||
lists:flatten(io_lib:format("~p",
|
lists:flatten(io_lib:format("~p.",
|
||||||
[ets:tab2list(acl)])),
|
[ets:tab2list(acl)])),
|
||||||
"\n"))
|
"\n"))
|
||||||
%{xmlelement, "value", [], [{xmlcdata, ?MYNAME}]}
|
%{xmlelement, "value", [], [{xmlcdata, ?MYNAME}]}
|
||||||
@ -343,22 +343,19 @@ set_form(["running nodes", ENode, "modules", "start"], Lang, XData) ->
|
|||||||
{ok, Tokens, _} ->
|
{ok, Tokens, _} ->
|
||||||
case erl_parse:parse_term(Tokens) of
|
case erl_parse:parse_term(Tokens) of
|
||||||
{ok, Modules} ->
|
{ok, Modules} ->
|
||||||
case catch lists:foreach(
|
lists:foreach(
|
||||||
fun({Module, Args}) ->
|
fun({Module, Args}) ->
|
||||||
gen_mod:start_module(
|
rpc:call(Node,
|
||||||
Module, Args)
|
gen_mod,
|
||||||
end, Modules) of
|
start_module,
|
||||||
{'EXIT', Reason} ->
|
[Module, Args])
|
||||||
{error,
|
end, Modules),
|
||||||
"500", "Internal Server Error"};
|
{result, []};
|
||||||
_ ->
|
|
||||||
{result, []}
|
|
||||||
end;
|
|
||||||
_ ->
|
_ ->
|
||||||
{error, "500", "Internal Server Error"}
|
{error, "406", "Not Acceptable"}
|
||||||
end;
|
end;
|
||||||
_ ->
|
_ ->
|
||||||
{error, "500", "Internal Server Error"}
|
{error, "406", "Not Acceptable"}
|
||||||
end;
|
end;
|
||||||
_ ->
|
_ ->
|
||||||
{error, "406", "Not Acceptable"}
|
{error, "406", "Not Acceptable"}
|
||||||
@ -379,6 +376,32 @@ set_form(["config", "hostname"], Lang, XData) ->
|
|||||||
{error, "406", "Not Acceptable"}
|
{error, "406", "Not Acceptable"}
|
||||||
end;
|
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) ->
|
set_form(["config", "remusers"], Lang, XData) ->
|
||||||
lists:foreach(
|
lists:foreach(
|
||||||
fun({Var, Vals}) ->
|
fun({Var, Vals}) ->
|
||||||
|
@ -1,11 +1,44 @@
|
|||||||
% $Id$
|
% $Id$
|
||||||
|
|
||||||
|
% mod_configure.erl
|
||||||
|
{"DB Tables Configuration", "Конфигурация таблиц БД"}.
|
||||||
|
{"Choose storage type of tables", "Выберите тип хранения таблиц"}.
|
||||||
|
{"", ""}.
|
||||||
|
{"", ""}.
|
||||||
|
{"", ""}.
|
||||||
|
{"", ""}.
|
||||||
|
{"", ""}.
|
||||||
|
{"", ""}.
|
||||||
|
{"", ""}.
|
||||||
|
{"", ""}.
|
||||||
|
{"", ""}.
|
||||||
|
{"", ""}.
|
||||||
|
{"", ""}.
|
||||||
|
{"", ""}.
|
||||||
|
{"", ""}.
|
||||||
|
{"", ""}.
|
||||||
|
{"", ""}.
|
||||||
|
{"", ""}.
|
||||||
|
|
||||||
% mod_disco.erl
|
% mod_disco.erl
|
||||||
|
{"Configuration", "Конфигурация"}.
|
||||||
{"Online Users", "Подключённые пользователи"}.
|
{"Online Users", "Подключённые пользователи"}.
|
||||||
{"All Users", "Все пользователи"}.
|
{"All Users", "Все пользователи"}.
|
||||||
{"Outgoing S2S connections", "Исходящие S2S-соединения"}.
|
{"Outgoing S2S connections", "Исходящие S2S-соединения"}.
|
||||||
{"To ~s", "К ~s"}.
|
{"To ~s", "К ~s"}.
|
||||||
{"From ~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
|
% mod_vcard.erl
|
||||||
|
Loading…
Reference in New Issue
Block a user