* src/ejabberd_c2s.erl: Added authentification logging

* src/ejabberd_listener.erl: Added logging of accepted connections

* src/stringprep/stringprep_drv.c: Cleanup

* src/jd2ejd.erl: Added support for iq:private importing

* src/mod_configure.erl: Fixed user removal

* src/mod_private.erl: Added remove_user/1

* doc/guide.tex: Updated

* src/mod_disco.erl: Added "extra_domains" option

SVN Revision: 146
This commit is contained in:
Alexey Shchepin 2003-10-09 18:09:05 +00:00
parent 8e7106dd74
commit 7df146166a
12 changed files with 263 additions and 136 deletions

View File

@ -1,3 +1,21 @@
2003-10-09 Alexey Shchepin <alexey@sevcom.net>
* src/ejabberd_c2s.erl: Added authentification logging
* src/ejabberd_listener.erl: Added logging of accepted connections
* src/stringprep/stringprep_drv.c: Cleanup
* src/jd2ejd.erl: Added support for iq:private importing
* src/mod_configure.erl: Fixed user removal
* src/mod_private.erl: Added remove_user/1
* doc/guide.tex: Updated
* src/mod_disco.erl: Added "extra_domains" option
2003-10-08 Alexey Shchepin <alexey@sevcom.net> 2003-10-08 Alexey Shchepin <alexey@sevcom.net>
* src/ejabberd_c2s.erl: Added support for "jid-malformed" error * src/ejabberd_c2s.erl: Added support for "jid-malformed" error

View File

@ -65,7 +65,7 @@
<UL><LI> <UL><LI>
<A HREF="#htoc19">3.2.1&nbsp;&nbsp;Node <TT>config</TT>: Global Configuration</A> <A HREF="#htoc19">3.2.1&nbsp;&nbsp;Node <TT>config</TT>: Global Configuration</A>
<LI><A HREF="#htoc20">3.2.2&nbsp;&nbsp;Node <TT>online users</TT>: List of Online Users</A> <LI><A HREF="#htoc20">3.2.2&nbsp;&nbsp;Node <TT>online users</TT>: List of Online Users</A>
<LI><A HREF="#htoc21">3.2.3&nbsp;&nbsp;Node <TT>all users</TT>: List of Registered User</A> <LI><A HREF="#htoc21">3.2.3&nbsp;&nbsp;Node <TT>all users</TT>: List of Registered Users</A>
<LI><A HREF="#htoc22">3.2.4&nbsp;&nbsp;Node <TT>outgoing s2s</TT>: List of Outgoing S2S connections</A> <LI><A HREF="#htoc22">3.2.4&nbsp;&nbsp;Node <TT>outgoing s2s</TT>: List of Outgoing S2S connections</A>
<LI><A HREF="#htoc23">3.2.5&nbsp;&nbsp;Node <TT>running nodes</TT>: List of Running <TT>ejabberd</TT> Nodes</A> <LI><A HREF="#htoc23">3.2.5&nbsp;&nbsp;Node <TT>running nodes</TT>: List of Running <TT>ejabberd</TT> Nodes</A>
<LI><A HREF="#htoc24">3.2.6&nbsp;&nbsp;Node <TT>stopped nodes</TT>: List of Stopped Nodes</A> <LI><A HREF="#htoc24">3.2.6&nbsp;&nbsp;Node <TT>stopped nodes</TT>: List of Stopped Nodes</A>
@ -411,15 +411,13 @@ runned on them. Each element of list is a tuple with following elements:
<UL><LI> <UL><LI>
Port number; Port number;
<LI>Module that serves this port; <LI>Module that serves this port;
<LI>Function in this module that starts connection (likely will be removed in
future versions of <TT>ejabberd</TT>);
<LI>Options to this module. <LI>Options to this module.
</UL> </UL>
Currently three modules are implemented: Currently three modules are implemented:
<DL COMPACT=compact><DT> <DL COMPACT=compact><DT>
<B><TT>ejabberd_c2s</TT></B><DD> This module serves C2S connections.<BR> <B><TT>ejabberd_c2s</TT></B><DD> This module serves C2S connections.<BR>
<BR> <BR>
Following options defined: The following options are defined:
<DL COMPACT=compact><DT> <DL COMPACT=compact><DT>
<B><TT>{access, &lt;access rule&gt;}</TT></B><DD> This option defines access of users <B><TT>{access, &lt;access rule&gt;}</TT></B><DD> This option defines access of users
to this C2S port. Default value is ``<TT>all</TT>''. to this C2S port. Default value is ``<TT>all</TT>''.
@ -432,10 +430,10 @@ Following options defined:
services (i.&nbsp;e. that use the <TT>jabber:component:accept</TT> namespace). services (i.&nbsp;e. that use the <TT>jabber:component:accept</TT> namespace).
</DL> </DL>
For example, the following configuration defines that C2S connections are For example, the following configuration defines that C2S connections are
listened on port 5222 and denied for user ``<TT>bad</TT>'', S2S on port 5269 listened on port 5222 and 5223 (SSL) and denied for user ``<TT>bad</TT>'', S2S
and that service <TT>conference.jabber.org</TT> must be connected to port 8888 on port 5269, and that service <TT>conference.example.org</TT> must be
with a password ``<TT>secret</TT>''. Also all users except admins have traffic connected to port 8888 with a password ``<TT>secret</TT>''. Also all users
limit 1000&nbsp;b/s. except admins have traffic limit 1000&nbsp;b/s.
<PRE> <PRE>
{acl, blocked, {user, "bad"}}. {acl, blocked, {user, "bad"}}.
{access, c2s, [{deny, blocked}, {access, c2s, [{deny, blocked},
@ -443,11 +441,13 @@ limit 1000&nbsp;b/s.
{shaper, normal, {maxrate, 1000}}. {shaper, normal, {maxrate, 1000}}.
{access, c2s_shaper, [{none, admin}, {access, c2s_shaper, [{none, admin},
{normal, all}]}. {normal, all}]}.
{listen, [{5222, ejabberd_c2s, start, [{access, c2s}, {listen, [{5222, ejabberd_c2s, [{access, c2s},
{shaper, c2s_shaper}]}, {shaper, c2s_shaper}]},
{5269, ejabberd_s2s_in, start, []}, {5223, ejabberd_c2s, [{access, c2s},
{8888, ejabberd_service, start, {ssl, [{certfile, "/path/to/ssl.pem"}]}]},
[{host, "conference.jabber.org", [{password, "secret"}]}]} {5269, ejabberd_s2s_in, []},
{8888, ejabberd_service,
[{host, "conference.example.org", [{password, "secret"}]}]}
]}. ]}.
</PRE> </PRE>
<!--TOC subsubsection Modules--> <!--TOC subsubsection Modules-->
@ -565,9 +565,9 @@ removed user is online, then he will be disconnected. Also user-related data
<H4><A NAME="htoc20">3.2.2</A>&nbsp;&nbsp;Node <TT>online users</TT>: List of Online Users</H4><!--SEC END --> <H4><A NAME="htoc20">3.2.2</A>&nbsp;&nbsp;Node <TT>online users</TT>: List of Online Users</H4><!--SEC END -->
<!--TOC subsubsection Node <TT>all users</TT>: List of Registered User--> <!--TOC subsubsection Node <TT>all users</TT>: List of Registered Users-->
<H4><A NAME="htoc21">3.2.3</A>&nbsp;&nbsp;Node <TT>all users</TT>: List of Registered User</H4><!--SEC END --> <H4><A NAME="htoc21">3.2.3</A>&nbsp;&nbsp;Node <TT>all users</TT>: List of Registered Users</H4><!--SEC END -->
<BLOCKQUOTE><DIV ALIGN=center><DIV ALIGN=center><HR WIDTH="80%" SIZE=2></DIV> <BLOCKQUOTE><DIV ALIGN=center><DIV ALIGN=center><HR WIDTH="80%" SIZE=2></DIV>
@ -678,15 +678,16 @@ does not exist, then it is opened and registered.<BR>
<H3><A NAME="htoc32">A.1</A>&nbsp;&nbsp;Common Options</H3><!--SEC END --> <H3><A NAME="htoc32">A.1</A>&nbsp;&nbsp;Common Options</H3><!--SEC END -->
<A NAME="sec:modcommonopts"></A> <A NAME="sec:modcommonopts"></A>
Following options used by many modules, so they described in separate section.<BR> The following options are used by many modules, so they are described in
separate section.<BR>
<BR> <BR>
<!--TOC subsubsection Option <TT>iqdisc</TT>--> <!--TOC subsubsection Option <TT>iqdisc</TT>-->
<H4><A NAME="htoc33">A.1.1</A>&nbsp;&nbsp;Option <TT>iqdisc</TT></H4><!--SEC END --> <H4><A NAME="htoc33">A.1.1</A>&nbsp;&nbsp;Option <TT>iqdisc</TT></H4><!--SEC END -->
Many modules define handlers for processing IQ queries of different namespaces Many modules define handlers for processing IQ queries of different namespaces
to this server or to user (e.&nbsp;g. to <TT>myjabber.org</TT> or to to this server or to user (e.&nbsp;g. to <TT>example.org</TT> or to
<TT>user@myjabber.org</TT>). This option defines processing discipline of <TT>user@example.org</TT>). This option defines processing discipline of
these queries. Possible values are: these queries. Possible values are:
<DL COMPACT=compact><DT> <DL COMPACT=compact><DT>
<B><TT>no_queue</TT></B><DD> All queries of namespace with this processing <B><TT>no_queue</TT></B><DD> All queries of namespace with this processing
@ -721,7 +722,7 @@ Example:
<PRE> <PRE>
{modules, [ {modules, [
... ...
{mod_echo, [{host, "echo.myjabber.org"}]}, {mod_echo, [{host, "echo.example.org"}]},
... ...
]}. ]}.
</PRE> </PRE>
@ -745,12 +746,32 @@ Example:
<H3><A NAME="htoc38">A.5</A>&nbsp;&nbsp;<TT>mod_disco</TT></H3><!--SEC END --> <H3><A NAME="htoc38">A.5</A>&nbsp;&nbsp;<TT>mod_disco</TT></H3><!--SEC END -->
<A NAME="sec:moddisco"></A> <A NAME="sec:moddisco"></A>
This module adds support for
<A HREF="http://www.jabber.org/jeps/jep-0030.html">JEP-0030</A> (Service
Discovery).<BR>
<BR>
Options:
<DL COMPACT=compact><DT>
<B><TT>iqdisc</TT></B><DD> <TT>http://jabber.org/protocol/disco#items</TT> and
<TT>http://jabber.org/protocol/disco#info</TT> IQ queries processing discipline.
<DT><B><TT>extra_domains</TT></B><DD> List of domains that will be added to server
items reply
</DL>
Example:
<PRE>
{modules, [
...
{mod_disco, [[{extra_domains, ["jit.example.com",
"etc.example.com"]}]]},
...
]}.
</PRE>
<!--TOC subsection <TT>mod_stats</TT>--> <!--TOC subsection <TT>mod_stats</TT>-->
<H3><A NAME="htoc39">A.6</A>&nbsp;&nbsp;<TT>mod_stats</TT></H3><!--SEC END --> <H3><A NAME="htoc39">A.6</A>&nbsp;&nbsp;<TT>mod_stats</TT></H3><!--SEC END -->
<A NAME="sec:modstats"></A> <A NAME="sec:modstats"></A>
This module adds support of This module adds support for
<A HREF="http://www.jabber.org/jeps/jep-0039.html">JEP-0039</A> (Statistics Gathering).<BR> <A HREF="http://www.jabber.org/jeps/jep-0039.html">JEP-0039</A> (Statistics Gathering).<BR>
<BR> <BR>
Options: Options:
@ -816,8 +837,8 @@ Options:
<A NAME="sec:i18nl10n"></A> <A NAME="sec:i18nl10n"></A>
Many modules supports <TT>xml:lang</TT> attribute inside IQ queries. E.&nbsp;g. Many modules supports <TT>xml:lang</TT> attribute inside IQ queries. E.&nbsp;g.
on figure&nbsp;<A HREF="#fig:discorus">6</A> (compare with figure&nbsp;<A HREF="#fig:disco">1</A>) showed reply on figure&nbsp;<A HREF="#fig:discorus">6</A> (compare it with figure&nbsp;<A HREF="#fig:disco">1</A>) showed
on following query: reply on following query:
<PRE> <PRE>
&lt;iq id='5' &lt;iq id='5'
to='e.localhost' to='e.localhost'

View File

@ -390,8 +390,6 @@ runned on them. Each element of list is a tuple with following elements:
\begin{itemize} \begin{itemize}
\item Port number; \item Port number;
\item Module that serves this port; \item Module that serves this port;
\item Function in this module that starts connection (likely will be removed in
future versions of \ejabberd);
\item Options to this module. \item Options to this module.
\end{itemize} \end{itemize}
@ -399,7 +397,7 @@ Currently three modules are implemented:
\begin{description} \begin{description}
\item[\texttt{ejabberd\_c2s}] This module serves C2S connections. \item[\texttt{ejabberd\_c2s}] This module serves C2S connections.
Following options defined: The following options are defined:
\begin{description} \begin{description}
\item[\texttt{\{access, <access rule>\}}] This option defines access of users \item[\texttt{\{access, <access rule>\}}] This option defines access of users
to this C2S port. Default value is ``\texttt{all}''. to this C2S port. Default value is ``\texttt{all}''.
@ -413,10 +411,10 @@ Currently three modules are implemented:
\end{description} \end{description}
For example, the following configuration defines that C2S connections are For example, the following configuration defines that C2S connections are
listened on port 5222 and denied for user ``\texttt{bad}'', S2S on port 5269 listened on port 5222 and 5223 (SSL) and denied for user ``\texttt{bad}'', S2S
and that service \texttt{conference.jabber.org} must be connected to port 8888 on port 5269, and that service \texttt{conference.example.org} must be
with a password ``\texttt{secret}''. Also all users except admins have traffic connected to port 8888 with a password ``\texttt{secret}''. Also all users
limit 1000\,b/s. except admins have traffic limit 1000\,b/s.
\begin{verbatim} \begin{verbatim}
{acl, blocked, {user, "bad"}}. {acl, blocked, {user, "bad"}}.
{access, c2s, [{deny, blocked}, {access, c2s, [{deny, blocked},
@ -424,11 +422,13 @@ limit 1000\,b/s.
{shaper, normal, {maxrate, 1000}}. {shaper, normal, {maxrate, 1000}}.
{access, c2s_shaper, [{none, admin}, {access, c2s_shaper, [{none, admin},
{normal, all}]}. {normal, all}]}.
{listen, [{5222, ejabberd_c2s, start, [{access, c2s}, {listen, [{5222, ejabberd_c2s, [{access, c2s},
{shaper, c2s_shaper}]}, {shaper, c2s_shaper}]},
{5269, ejabberd_s2s_in, start, []}, {5223, ejabberd_c2s, [{access, c2s},
{8888, ejabberd_service, start, {ssl, [{certfile, "/path/to/ssl.pem"}]}]},
[{host, "conference.jabber.org", [{password, "secret"}]}]} {5269, ejabberd_s2s_in, []},
{8888, ejabberd_service,
[{host, "conference.example.org", [{password, "secret"}]}]}
]}. ]}.
\end{verbatim} \end{verbatim}
@ -539,7 +539,7 @@ removed user is online, then he will be disconnected. Also user-related data
\subsubsection{Node \texttt{all users}: List of Registered User} \subsubsection{Node \texttt{all users}: List of Registered Users}
\begin{figure}[htbp] \begin{figure}[htbp]
\centering \centering
@ -640,19 +640,17 @@ does not exist, then it is opened and registered.
\section{Built-in Modules} \section{Built-in Modules}
\label{sec:modules} \label{sec:modules}
\subsection{Common Options} \subsection{Common Options}
\label{sec:modcommonopts} \label{sec:modcommonopts}
Following options used by many modules, so they described in separate section. The following options are used by many modules, so they are described in
separate section.
\subsubsection{Option \texttt{iqdisc}} \subsubsection{Option \texttt{iqdisc}}
Many modules define handlers for processing IQ queries of different namespaces Many modules define handlers for processing IQ queries of different namespaces
to this server or to user (e.\,g.\ to \texttt{myjabber.org} or to to this server or to user (e.\,g.\ to \texttt{example.org} or to
\texttt{user@myjabber.org}). This option defines processing discipline of \texttt{user@example.org}). This option defines processing discipline of
these queries. Possible values are: these queries. Possible values are:
\begin{description} \begin{description}
\item[\texttt{no\_queue}] All queries of namespace with this processing \item[\texttt{no\_queue}] All queries of namespace with this processing
@ -688,7 +686,7 @@ Example:
\begin{verbatim} \begin{verbatim}
{modules, [ {modules, [
... ...
{mod_echo, [{host, "echo.myjabber.org"}]}, {mod_echo, [{host, "echo.example.org"}]},
... ...
]}. ]}.
\end{verbatim} \end{verbatim}
@ -713,12 +711,33 @@ Example:
\subsection{\moddisco{}} \subsection{\moddisco{}}
\label{sec:moddisco} \label{sec:moddisco}
This module adds support for
\footahref{http://www.jabber.org/jeps/jep-0030.html}{JEP-0030} (Service
Discovery).
Options:
\begin{description}
\item[\texttt{iqdisc}] \ns{http://jabber.org/protocol/disco#items} and
\ns{http://jabber.org/protocol/disco#info} IQ queries processing discipline.
\item[\texttt{extra\_domains}] List of domains that will be added to server
items reply
\end{description}
Example:
\begin{verbatim}
{modules, [
...
{mod_disco, [[{extra_domains, ["jit.example.com",
"etc.example.com"]}]]},
...
]}.
\end{verbatim}
\subsection{\modstats{}} \subsection{\modstats{}}
\label{sec:modstats} \label{sec:modstats}
This module adds support of This module adds support for
\footahref{http://www.jabber.org/jeps/jep-0039.html}{JEP-0039} (Statistics Gathering). \footahref{http://www.jabber.org/jeps/jep-0039.html}{JEP-0039} (Statistics Gathering).
Options: Options:
@ -784,8 +803,8 @@ Options:
\label{sec:i18nl10n} \label{sec:i18nl10n}
Many modules supports \texttt{xml:lang} attribute inside IQ queries. E.\,g.\ Many modules supports \texttt{xml:lang} attribute inside IQ queries. E.\,g.\
on figure~\ref{fig:discorus} (compare with figure~\ref{fig:disco}) showed reply on figure~\ref{fig:discorus} (compare it with figure~\ref{fig:disco}) showed
on following query: reply on following query:
\begin{verbatim} \begin{verbatim}
<iq id='5' <iq id='5'
to='e.localhost' to='e.localhost'

View File

@ -212,6 +212,10 @@ wait_for_auth({xmlstreamelement, El}, StateData) ->
case ejabberd_auth:check_password( case ejabberd_auth:check_password(
U, P, StateData#state.streamid, D) of U, P, StateData#state.streamid, D) of
true -> true ->
?INFO_MSG(
"(~w) Accepted legacy authentification for ~s",
[StateData#state.socket,
jlib:jid_to_string(JID)]),
ejabberd_sm:open_session(U, R), ejabberd_sm:open_session(U, R),
Res = jlib:make_result_iq_reply(El), Res = jlib:make_result_iq_reply(El),
send_element(StateData, Res), send_element(StateData, Res),
@ -230,12 +234,19 @@ wait_for_auth({xmlstreamelement, El}, StateData) ->
pres_t = ?SETS:from_list(Ts), pres_t = ?SETS:from_list(Ts),
privacy_list = PrivList}}; privacy_list = PrivList}};
_ -> _ ->
?INFO_MSG(
"(~w) Failed legacy authentification for ~s",
[StateData#state.socket,
jlib:jid_to_string(JID)]),
Err = jlib:make_error_reply( Err = jlib:make_error_reply(
El, ?ERR_FORBIDDEN), El, ?ERR_FORBIDDEN),
send_element(StateData, Err), send_element(StateData, Err),
{next_state, wait_for_auth, StateData} {next_state, wait_for_auth, StateData}
end; end;
_ -> _ ->
?INFO_MSG("(~w) Forbidden legacy authentification for ~s",
[StateData#state.socket,
jlib:jid_to_string(JID)]),
Err = jlib:make_error_reply(El, ?ERR_NOT_ALLOWED), Err = jlib:make_error_reply(El, ?ERR_NOT_ALLOWED),
send_element(StateData, Err), send_element(StateData, Err),
{next_state, wait_for_auth, StateData} {next_state, wait_for_auth, StateData}
@ -286,6 +297,9 @@ wait_for_sasl_auth({xmlstreamelement, El}, StateData) ->
JID = #jid{user = U, resource = R} = JID = #jid{user = U, resource = R} =
jlib:string_to_jid( jlib:string_to_jid(
xml:get_attr_s(authzid, Props)), xml:get_attr_s(authzid, Props)),
?INFO_MSG("(~w) Accepted authentification for ~s",
[StateData#state.socket,
jlib:jid_to_string(JID)]),
{next_state, wait_for_stream, {next_state, wait_for_stream,
StateData#state{authentificated = true, StateData#state{authentificated = true,
user = U, user = U,
@ -350,6 +364,9 @@ wait_for_sasl_response({xmlstreamelement, El}, StateData) ->
[{"xmlns", ?NS_SASL}], []}), [{"xmlns", ?NS_SASL}], []}),
JID = #jid{user = U, resource = R} = JID = #jid{user = U, resource = R} =
jlib:string_to_jid(xml:get_attr_s(authzid, Props)), jlib:string_to_jid(xml:get_attr_s(authzid, Props)),
?INFO_MSG("(~w) Accepted authentification for ~s",
[StateData#state.socket,
jlib:jid_to_string(JID)]),
{next_state, wait_for_stream, {next_state, wait_for_stream,
StateData#state{authentificated = true, StateData#state{authentificated = true,
user = U, user = U,
@ -410,6 +427,9 @@ wait_for_session({xmlstreamelement, El}, StateData) ->
JID = jlib:make_jid(U, StateData#state.server, R), JID = jlib:make_jid(U, StateData#state.server, R),
case acl:match_rule(StateData#state.access, JID) of case acl:match_rule(StateData#state.access, JID) of
allow -> allow ->
?INFO_MSG("(~w) Opened session for ~s",
[StateData#state.socket,
jlib:jid_to_string(JID)]),
ejabberd_sm:open_session(U, R), ejabberd_sm:open_session(U, R),
Res = jlib:make_result_iq_reply(El), Res = jlib:make_result_iq_reply(El),
send_element(StateData, Res), send_element(StateData, Res),
@ -425,6 +445,9 @@ wait_for_session({xmlstreamelement, El}, StateData) ->
pres_t = ?SETS:from_list(Ts), pres_t = ?SETS:from_list(Ts),
privacy_list = PrivList}}; privacy_list = PrivList}};
_ -> _ ->
?INFO_MSG("(~w) Forbidden session for ~s",
[StateData#state.socket,
jlib:jid_to_string(JID)]),
Err = jlib:make_error_reply(El, ?ERR_NOT_ALLOWED), Err = jlib:make_error_reply(El, ?ERR_NOT_ALLOWED),
send_element(StateData, Err), send_element(StateData, Err),
{next_state, wait_for_session, StateData} {next_state, wait_for_session, StateData}
@ -700,6 +723,9 @@ terminate(Reason, StateName, StateData) ->
"" -> "" ->
ok; ok;
_ -> _ ->
?INFO_MSG("(~w) Close session for ~s",
[StateData#state.socket,
jlib:jid_to_string(StateData#state.jid)]),
ejabberd_sm:close_session(StateData#state.user, ejabberd_sm:close_session(StateData#state.user,
StateData#state.resource), StateData#state.resource),
From = StateData#state.jid, From = StateData#state.jid,

View File

@ -15,6 +15,8 @@
init_ssl/4 init_ssl/4
]). ]).
-include("ejabberd.hrl").
start_link() -> start_link() ->
supervisor:start_link({local, ejabberd_listeners}, ?MODULE, []). supervisor:start_link({local, ejabberd_listeners}, ?MODULE, []).
@ -56,6 +58,13 @@ init(Port, Module, Opts) ->
accept(ListenSocket, Module, Opts) -> accept(ListenSocket, Module, Opts) ->
case gen_tcp:accept(ListenSocket) of case gen_tcp:accept(ListenSocket) of
{ok, Socket} -> {ok, Socket} ->
case {inet:sockname(Socket), inet:peername(Socket)} of
{{ok, Addr}, {ok, PAddr}} ->
?INFO_MSG("(~w) Accepted connection ~w -> ~w",
[Socket, PAddr, Addr]);
_ ->
ok
end,
{ok, Pid} = Module:start({gen_tcp, Socket}, Opts), {ok, Pid} = Module:start({gen_tcp, Socket}, Opts),
%{ok, Pid} = %{ok, Pid} =
% supervisor:start_child( % supervisor:start_child(
@ -82,6 +91,13 @@ init_ssl(Port, Module, Opts, SSLOpts) ->
accept_ssl(ListenSocket, Module, Opts) -> accept_ssl(ListenSocket, Module, Opts) ->
case ssl:accept(ListenSocket) of case ssl:accept(ListenSocket) of
{ok, Socket} -> {ok, Socket} ->
case {ssl:sockname(Socket), ssl:peername(Socket)} of
{{ok, Addr}, {ok, PAddr}} ->
?INFO_MSG("(~w) Accepted SSL connection ~w -> ~w",
[Socket, PAddr, Addr]);
_ ->
ok
end,
apply(Module, start_link, [{ssl, Socket}, Opts]), apply(Module, start_link, [{ssl, Socket}, Opts]),
accept_ssl(ListenSocket, Module, Opts) accept_ssl(ListenSocket, Module, Opts)
end. end.

View File

@ -93,9 +93,7 @@ wait_for_xdb(closed, StateData) ->
xdb_data({xmlstreamelement, El}, StateData) -> xdb_data({xmlstreamelement, El}, StateData) ->
{xmlelement, Name, Attrs, Els} = El, {xmlelement, Name, Attrs, Els} = El,
Server = StateData#state.server, Server = StateData#state.server,
From = {StateData#state.user, From = jlib:make_jid(StateData#state.user, Server, ""),
Server,
""},
NewState = NewState =
case xml:get_attr_s("xmlns", Attrs) of case xml:get_attr_s("xmlns", Attrs) of
?NS_AUTH -> ?NS_AUTH ->
@ -109,9 +107,9 @@ xdb_data({xmlstreamelement, El}, StateData) ->
mod_roster:set_items(StateData#state.user, El), mod_roster:set_items(StateData#state.user, El),
StateData; StateData;
?NS_VCARD -> ?NS_VCARD ->
Res = mod_vcard:process_local_iq(From, Res = mod_vcard:process_sm_iq(From,
{"", ?MYNAME, ""}, jlib:make_jid("", ?MYNAME, ""),
{iq, "", set, ?NS_VCARD, El}), {iq, "", set, ?NS_VCARD, El}),
StateData; StateData;
"jabber:x:offline" -> "jabber:x:offline" ->
process_offline(From, El), process_offline(From, El),
@ -124,8 +122,22 @@ xdb_data({xmlstreamelement, El}, StateData) ->
% io:format("user ~s~n", [User]), % io:format("user ~s~n", [User]),
% StateData; % StateData;
XMLNS -> XMLNS ->
io:format("jd2ejd: Unknown namespace \"~s\"~n", [XMLNS]), case xml:get_attr_s("j_private_flag", Attrs) of
StateData "1" ->
mod_private:process_local_iq(
From,
jlib:make_jid("", ?MYNAME, ""),
{iq, "", set, ?NS_PRIVATE,
{xmlelement, "query", [],
[jlib:remove_attr(
"j_private_flag",
jlib:remove_attr("xdbns", El))]}}),
StateData;
_ ->
io:format("jd2ejd: Unknown namespace \"~s\"~n",
[XMLNS]),
StateData
end
end, end,
{next_state, xdb_data, NewState}; {next_state, xdb_data, NewState};
@ -191,7 +203,7 @@ handle_info(_, StateName, StateData) ->
%% Returns: any %% Returns: any
%%---------------------------------------------------------------------- %%----------------------------------------------------------------------
terminate(Reason, StateName, StateData) -> terminate(Reason, StateName, StateData) ->
StateData#state.pid ! {jd2ejd, exited}, StateData#state.pid ! {jd2ejd, Reason},
ok. ok.
%%%---------------------------------------------------------------------- %%%----------------------------------------------------------------------
@ -217,12 +229,20 @@ process_offline(To, {xmlelement, _, _, Els}) ->
import_file(File) -> import_file(File) ->
clear_queue(),
start(File), start(File),
receive receive
M -> M {jd2ejd, Result} -> Result
after 1000 -> ok after 4000 -> timeout
end. end.
clear_queue() ->
receive
{jd2ejd, _Result} -> clear_queue
after 0 -> ok
end.
import_dir(Dir) -> import_dir(Dir) ->
{ok, Files} = file:list_dir(Dir), {ok, Files} = file:list_dir(Dir),
MsgFiles = lists:filter( MsgFiles = lists:filter(

View File

@ -665,13 +665,16 @@ set_form(["config", "remusers"], Lang, XData) ->
fun({Var, Vals}) -> fun({Var, Vals}) ->
case Vals of case Vals of
["1"] -> ["1"] ->
ejabberd_sm ! {route, {"", "", ""}, {Var, "", ""}, ejabberd_sm ! {route,
jlib:make_jid("", "", ""),
jlib:make_jid(Var, "", ""),
{xmlelement, "broadcast", [], {xmlelement, "broadcast", [],
[{exit, "User removed"}]}}, [{exit, "User removed"}]}},
catch ejabberd_auth:remove_user(Var), catch ejabberd_auth:remove_user(Var),
catch mod_roster:remove_user(Var), catch mod_roster:remove_user(Var),
catch mod_offline:remove_user(Var), catch mod_offline:remove_user(Var),
catch mod_vcard:remove_user(Var); catch mod_vcard:remove_user(Var),
catch mod_private:remove_user(Var);
_ -> _ ->
ok ok
end end
@ -703,7 +706,7 @@ process_sm_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
deny -> deny ->
{iq, ID, error, XMLNS, [SubEl, ?ERR_NOT_ALLOWED]}; {iq, ID, error, XMLNS, [SubEl, ?ERR_NOT_ALLOWED]};
allow -> allow ->
{User, _, _} = To, #jid{user = User} = To,
Lang = xml:get_tag_attr_s("xml:lang", SubEl), Lang = xml:get_tag_attr_s("xml:lang", SubEl),
case Type of case Type of
set -> set ->
@ -790,5 +793,24 @@ get_sm_form(_, _, Lang) ->
{error, ?ERR_SERVICE_UNAVAILABLE}. {error, ?ERR_SERVICE_UNAVAILABLE}.
set_sm_form(User, [], Lang, XData) ->
case lists:keysearch("action", 1, XData) of
{value, {_, ["edit"]}} ->
{error, ?ERR_FEATURE_NOT_IMPLEMENTED};
{value, {_, ["remove"]}} ->
ejabberd_sm ! {route,
jlib:make_jid("", "", ""),
jlib:make_jid(User, "", ""),
{xmlelement, "broadcast", [],
[{exit, "User removed"}]}},
catch ejabberd_auth:remove_user(User),
catch mod_roster:remove_user(User),
catch mod_offline:remove_user(User),
catch mod_vcard:remove_user(User),
catch mod_private:remove_user(User),
{result, []};
_ ->
{error, ?ERR_BAD_REQUEST}
end;
set_sm_form(_, _, Lang, XData) -> set_sm_form(_, _, Lang, XData) ->
{error, ?ERR_SERVICE_UNAVAILABLE}. {error, ?ERR_SERVICE_UNAVAILABLE}.

View File

@ -19,7 +19,9 @@
process_sm_iq_items/3, process_sm_iq_items/3,
process_sm_iq_info/3, process_sm_iq_info/3,
register_feature/1, register_feature/1,
unregister_feature/1]). unregister_feature/1,
register_extra_domain/1,
unregister_extra_domain/1]).
-include("ejabberd.hrl"). -include("ejabberd.hrl").
-include("jlib.hrl"). -include("jlib.hrl").
@ -42,6 +44,9 @@ start(Opts) ->
register_feature("iq"), register_feature("iq"),
register_feature("presence"), register_feature("presence"),
register_feature("presence-invisible"), register_feature("presence-invisible"),
catch ets:new(disco_extra_domains, [named_table, ordered_set, public]),
ExtraDomains = gen_mod:get_opt(extra_domains, Opts, []),
lists:foreach(fun register_extra_domain/1, ExtraDomains),
ok. ok.
stop() -> stop() ->
@ -59,6 +64,14 @@ unregister_feature(Feature) ->
catch ets:new(disco_features, [named_table, ordered_set, public]), catch ets:new(disco_features, [named_table, ordered_set, public]),
ets:delete(disco_features, Feature). ets:delete(disco_features, Feature).
register_extra_domain(Domain) ->
catch ets:new(disco_extra_domains, [named_table, ordered_set, public]),
ets:insert(disco_extra_domains, {Domain}).
unregister_extra_domain(Domain) ->
catch ets:new(disco_extra_domains, [named_table, ordered_set, public]),
ets:delete(disco_extra_domains, Domain).
process_local_iq_items(From, To, {iq, ID, Type, XMLNS, SubEl}) -> process_local_iq_items(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
Lang = xml:get_tag_attr_s("xml:lang", SubEl), Lang = xml:get_tag_attr_s("xml:lang", SubEl),
case Type of case Type of
@ -180,10 +193,11 @@ process_local_iq_info(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
feature_to_xml({Feature}) -> feature_to_xml({Feature}) ->
{xmlelement, "feature", [{"var", Feature}], []}. {xmlelement, "feature", [{"var", Feature}], []}.
domain_to_xml({Domain}) ->
{xmlelement, "item", [{"jid", Domain}], []};
domain_to_xml(Domain) -> domain_to_xml(Domain) ->
{xmlelement, "item", [{"jid", Domain}], []}. {xmlelement, "item", [{"jid", Domain}], []}.
-define(NODE(Name, Node), -define(NODE(Name, Node),
{xmlelement, "item", {xmlelement, "item",
[{"jid", Server}, [{"jid", Server},
@ -193,12 +207,14 @@ domain_to_xml(Domain) ->
get_services_only() -> get_services_only() ->
lists:map(fun domain_to_xml/1, lists:map(fun domain_to_xml/1,
ejabberd_router:dirty_get_all_routes()). ejabberd_router:dirty_get_all_routes()) ++
lists:map(fun domain_to_xml/1, ets:tab2list(disco_extra_domains)).
get_local_items([], Server, Lang) -> get_local_items([], Server, Lang) ->
Domains = Domains =
lists:map(fun domain_to_xml/1, lists:map(fun domain_to_xml/1,
ejabberd_router:dirty_get_all_routes()), ejabberd_router:dirty_get_all_routes()) ++
lists:map(fun domain_to_xml/1, ets:tab2list(disco_extra_domains)),
{result, {result,
Domains ++ Domains ++
[?NODE("Configuration", "config"), [?NODE("Configuration", "config"),

View File

@ -14,7 +14,8 @@
-export([start/1, -export([start/1,
stop/0, stop/0,
process_local_iq/3]). process_local_iq/3,
remove_user/1]).
-include("ejabberd.hrl"). -include("ejabberd.hrl").
-include("jlib.hrl"). -include("jlib.hrl").
@ -95,3 +96,20 @@ get_data(LUser, [El | Els], Res) ->
_ -> _ ->
get_data(LUser, Els, Res) get_data(LUser, Els, Res)
end. end.
remove_user(User) ->
LUser = jlib:nodeprep(User),
F = fun() ->
lists:foreach(
fun({U, _} = Key) ->
if
U == LUser ->
mnesia:delete({private_storage, Key});
true ->
ok
end
end, mnesia:all_keys(private_storage))
end,
mnesia:transaction(F).

View File

@ -37,7 +37,7 @@ static void stringprep_erl_stop(ErlDrvData handle)
* library * library
*/ */
void canonical_ordering(int *str, int len) static void canonical_ordering(int *str, int len)
{ {
int i, j, t; int i, j, t;
int last, next; int last, next;
@ -232,13 +232,6 @@ static int stringprep_erl_control(ErlDrvData drv_data,
} }
info = GetUniCharInfo(uc); info = GetUniCharInfo(uc);
//if(info & prohibit) {
// *rbuf = rstring;
// driver_free(str32);
// return 1;
//}
//printf("Got %x\r\n", uc);
if(!(info & B1Mask)) if(!(info & B1Mask))
{ {
@ -247,34 +240,10 @@ static int stringprep_erl_control(ErlDrvData drv_data,
{ {
ruc = uc + GetDelta(info); ruc = uc + GetDelta(info);
ADD_DECOMP(ruc); ADD_DECOMP(ruc);
//info = GetUniCharDecompInfo(ruc);
//if(info >= 0) {
// decomp_len = GetDecompLen(info);
// decomp_shift = GetDecompShift(info);
// for(j = 0; j < decomp_len; j++) {
// ADD_UCHAR32(str32, str32pos, str32len,
// decompList[decomp_shift + j]);
// }
//} else {
// ADD_UCHAR32(str32, str32pos, str32len, ruc);
//}
//info = GetUniCharDecompInfo(ruc);
//if(info >= 0) {
// printf("Decomposition %x: ", ruc);
// for(j = 0; j < GetDecompLen(info); j++) {
// printf("%x ", decompList[GetDecompShift(info) + j]);
// }
// printf("\r\n");
//}
//ADD_UCHAR(ruc);
} else { } else {
mc = GetMC(info); mc = GetMC(info);
for(j = 1; j <= mc[0]; j++) { for(j = 1; j <= mc[0]; j++) {
ruc = mc[j]; ruc = mc[j];
//printf("Char %x cclass %d\r\n", ruc, GetUniCharCClass(ruc));
ADD_DECOMP(ruc); ADD_DECOMP(ruc);
} }
} }
@ -292,19 +261,8 @@ static int stringprep_erl_control(ErlDrvData drv_data,
return 1; return 1;
} }
//printf("\r\n");
//printf("DECOMPOSED:\t");
//for(i = 0; i < str32pos; i++)
// printf("%4x ", str32[i]);
//printf("\r\n");
canonical_ordering(str32, str32pos); canonical_ordering(str32, str32pos);
//printf("ORDERED:\t");
//for(i = 0; i < str32pos; i++)
// printf("%4x ", str32[i]);
//printf("\r\n");
comp_pos = 1; comp_pos = 1;
comp_starter_pos = 0; comp_starter_pos = 0;
ch1 = str32[0]; ch1 = str32[0];
@ -314,7 +272,6 @@ static int stringprep_erl_control(ErlDrvData drv_data,
{ {
ch2 = str32[i]; ch2 = str32[i];
cclass2 = GetUniCharCClass(ch2); cclass2 = GetUniCharCClass(ch2);
//printf("Compose: %x + %x = %x\r\n", ch1, ch2, compose(ch1, ch2));
if(cclass1 == 0 && cclass2 > cclass_prev && (ruc = compose(ch1, ch2))) { if(cclass1 == 0 && cclass2 > cclass_prev && (ruc = compose(ch1, ch2))) {
ch1 = ruc; ch1 = ruc;
} else { } else {
@ -332,11 +289,6 @@ static int stringprep_erl_control(ErlDrvData drv_data,
str32[comp_starter_pos] = ch1; str32[comp_starter_pos] = ch1;
str32pos = comp_pos; str32pos = comp_pos;
//printf("COMPOSED:\t");
//for(i = 0; i < str32pos; i++)
// printf("%4x ", str32[i]);
//printf("\r\n");
for(i = 0; i < str32pos; i++) for(i = 0; i < str32pos; i++)
{ {
ruc = str32[i]; ruc = str32[i];
@ -349,9 +301,6 @@ static int stringprep_erl_control(ErlDrvData drv_data,
ADD_UCHAR(ruc); ADD_UCHAR(ruc);
} }
//printf("Compose: %x\r\n", compose(0x438, 0x301));
//printf("Pos: %d\r\n", pos);
rstring[0] = 1; rstring[0] = 1;
*rbuf = rstring; *rbuf = rstring;
driver_free(str32); driver_free(str32);

View File

@ -77,9 +77,8 @@ static unsigned char cclassPageMap[] = {
}; };
/* /*
* The groupMap is indexed by combining the alternate page number with * The cclassGroupMap is indexed by combining the alternate page number with
* the page offset and returns a group number that identifies a unique * the page offset and returns a combining class number.
* set of character attributes.
*/ */
static unsigned char cclassGroupMap[] = { static unsigned char cclassGroupMap[] = {
@ -297,9 +296,9 @@ static unsigned char decompPageMap[] = {
}; };
/* /*
* The groupMap is indexed by combining the alternate page number with * The decompGroupMap is indexed by combining the alternate page number with
* the page offset and returns a group number that identifies a unique * the page offset and returns a group number that identifies a length and
* set of character attributes. * shift of decomposition sequence in decompList
*/ */
static int decompGroupMap[] = { static int decompGroupMap[] = {
@ -839,7 +838,7 @@ static int decompGroupMap[] = {
}; };
/* /*
* Each group represents a unique set of character attributes. The attributes... * List of decomposition sequences
*/ */
static int decompList[] = { static int decompList[] = {
@ -1295,8 +1294,6 @@ static int decompList[] = {
* Unicode character tables. * Unicode character tables.
*/ */
//#define GetUniCharInfo(ch) (groups[groupMap[(pageMap[(((int)(ch)) & 0xffff) >> CCLASS_OFFSET_BITS] << CCLASS_OFFSET_BITS) | ((ch) & ((1 << CCLASS_OFFSET_BITS)-1))]])
#define GetUniCharDecompInfo(ch) (decompGroupMap[(decompPageMap[(((int)(ch)) & 0xffff) >> DECOMP_OFFSET_BITS] << DECOMP_OFFSET_BITS) | ((ch) & ((1 << DECOMP_OFFSET_BITS)-1))]) #define GetUniCharDecompInfo(ch) (decompGroupMap[(decompPageMap[(((int)(ch)) & 0xffff) >> DECOMP_OFFSET_BITS] << DECOMP_OFFSET_BITS) | ((ch) & ((1 << DECOMP_OFFSET_BITS)-1))])
#define GetDecompShift(info) ((info) & 0xffff) #define GetDecompShift(info) ((info) & 0xffff)
@ -1556,7 +1553,7 @@ static int compGroupMap[] = {
}; };
/* /*
* ... * Lists of compositions for characters that appears only in one composition
*/ */
static int compFirstList[][2] = { static int compFirstList[][2] = {
@ -1612,6 +1609,10 @@ static int compSecondList[][2] = {
{1575, 1570}, {1575, 1573} {1575, 1570}, {1575, 1573}
}; };
/*
* Compositions matrix
*/
static int compBothList[144][37] = { static int compBothList[144][37] = {
{ {
8179, 8060, 974, 0, 8032, 0, 8033, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8179, 8060, 974, 0, 8032, 0, 8033, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,

View File

@ -423,9 +423,8 @@ static unsigned char cclassPageMap\[\] = {"
puts $f "}; puts $f "};
/* /*
* The groupMap is indexed by combining the alternate page number with * The cclassGroupMap is indexed by combining the alternate page number with
* the page offset and returns a group number that identifies a unique * the page offset and returns a combining class number.
* set of character attributes.
*/ */
static unsigned char cclassGroupMap\[\] = {" static unsigned char cclassGroupMap\[\] = {"
@ -476,9 +475,9 @@ static unsigned char decompPageMap\[\] = {"
puts $f "}; puts $f "};
/* /*
* The groupMap is indexed by combining the alternate page number with * The decompGroupMap is indexed by combining the alternate page number with
* the page offset and returns a group number that identifies a unique * the page offset and returns a group number that identifies a length and
* set of character attributes. * shift of decomposition sequence in decompList
*/ */
static int decompGroupMap\[\] = {" static int decompGroupMap\[\] = {"
@ -502,7 +501,7 @@ static int decompGroupMap\[\] = {"
puts $f "}; puts $f "};
/* /*
* Each group represents a unique set of character attributes. The attributes... * List of decomposition sequences
*/ */
static int decompList\[\] = {" static int decompList\[\] = {"
@ -529,8 +528,6 @@ static int decompList\[\] = {"
* Unicode character tables. * Unicode character tables.
*/ */
//#define GetUniCharInfo(ch) (groups\[groupMap\[(pageMap\[(((int)(ch)) & 0xffff) >> CCLASS_OFFSET_BITS\] << CCLASS_OFFSET_BITS) | ((ch) & ((1 << CCLASS_OFFSET_BITS)-1))\]\])
#define GetUniCharDecompInfo(ch) (decompGroupMap\[(decompPageMap\[(((int)(ch)) & 0xffff) >> DECOMP_OFFSET_BITS\] << DECOMP_OFFSET_BITS) | ((ch) & ((1 << DECOMP_OFFSET_BITS)-1))\]) #define GetUniCharDecompInfo(ch) (decompGroupMap\[(decompPageMap\[(((int)(ch)) & 0xffff) >> DECOMP_OFFSET_BITS\] << DECOMP_OFFSET_BITS) | ((ch) & ((1 << DECOMP_OFFSET_BITS)-1))\])
#define GetDecompShift(info) ((info) & 0xffff) #define GetDecompShift(info) ((info) & 0xffff)
@ -588,7 +585,7 @@ static int compGroupMap\[\] = {"
puts $f "}; puts $f "};
/* /*
* ... * Lists of compositions for characters that appears only in one composition
*/ */
static int compFirstList\[\]\[2\] = {" static int compFirstList\[\]\[2\] = {"
@ -627,6 +624,10 @@ static int compSecondList\[\]\[2\] = {"
puts $f $line puts $f $line
puts $f "}; puts $f "};
/*
* Compositions matrix
*/
static int compBothList\[[llength $comp_x_list]\]\[[llength $comp_y_list]\] = {" static int compBothList\[[llength $comp_x_list]\]\[[llength $comp_y_list]\] = {"
set lastx [expr {[llength $comp_x_list] - 1}] set lastx [expr {[llength $comp_x_list] - 1}]
set lasty [expr {[llength $comp_y_list] - 1}] set lasty [expr {[llength $comp_y_list] - 1}]