1 |
|
%%%---------------------------------------------------------------------- |
2 |
|
%%% File : mod_sic.erl |
3 |
|
%%% Author : Karim Gemayel <karim.gemayel@process-one.net> |
4 |
|
%%% Purpose : XEP-0279 Server IP Check |
5 |
|
%%% Created : 6 Mar 2010 by Karim Gemayel <karim.gemayel@process-one.net> |
6 |
|
%%% |
7 |
|
%%% |
8 |
|
%%% ejabberd, Copyright (C) 2002-2011 ProcessOne |
9 |
|
%%% |
10 |
|
%%% This program is free software; you can redistribute it and/or |
11 |
|
%%% modify it under the terms of the GNU General Public License as |
12 |
|
%%% published by the Free Software Foundation; either version 2 of the |
13 |
|
%%% License, or (at your option) any later version. |
14 |
|
%%% |
15 |
|
%%% This program is distributed in the hope that it will be useful, |
16 |
|
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of |
17 |
|
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
18 |
|
%%% General Public License for more details. |
19 |
|
%%% |
20 |
|
%%% You should have received a copy of the GNU General Public License |
21 |
|
%%% along with this program; if not, write to the Free Software |
22 |
|
%%% Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
23 |
|
%%% |
24 |
|
%%%---------------------------------------------------------------------- |
25 |
|
|
26 |
|
-module(mod_sic). |
27 |
|
-author('karim.gemayel@process-one.net'). |
28 |
|
-xep([{xep, 279}, {version, "0.2"}]). |
29 |
|
-behaviour(gen_mod). |
30 |
|
-behaviour(mongoose_module_metrics). |
31 |
|
|
32 |
|
%% gen_mod callbacks |
33 |
|
-export([start/2, |
34 |
|
stop/1, |
35 |
|
config_spec/0, |
36 |
|
supported_features/0 |
37 |
|
]). |
38 |
|
|
39 |
|
%% IQ and hook handlers |
40 |
|
-export([process_local_iq/5, |
41 |
|
process_sm_iq/5 |
42 |
|
]). |
43 |
|
|
44 |
|
-ignore_xref([process_local_iq/5, process_sm_iq/5]). |
45 |
|
|
46 |
|
-include("jlib.hrl"). |
47 |
|
-include("mongoose.hrl"). |
48 |
|
-include("mongoose_config_spec.hrl"). |
49 |
|
|
50 |
|
-define(NS_SIC, <<"urn:xmpp:sic:1">>). |
51 |
|
|
52 |
|
-spec start(mongooseim:host_type(), gen_mod:module_opts()) -> ok. |
53 |
|
start(HostType, #{iqdisc := IQDisc}) -> |
54 |
13 |
[gen_iq_handler:add_iq_handler_for_domain(HostType, ?NS_SIC, Component, Fn, #{}, IQDisc) || |
55 |
13 |
{Component, Fn} <- iq_handlers()], |
56 |
13 |
ok. |
57 |
|
|
58 |
|
-spec stop(mongooseim:host_type()) -> ok. |
59 |
|
stop(HostType) -> |
60 |
13 |
[gen_iq_handler:remove_iq_handler_for_domain(HostType, ?NS_LAST, Component) || |
61 |
13 |
{Component, _Fn} <- iq_handlers()], |
62 |
13 |
ok. |
63 |
|
|
64 |
|
iq_handlers() -> |
65 |
26 |
[{ejabberd_local, fun ?MODULE:process_local_iq/5}, |
66 |
|
{ejabberd_sm, fun ?MODULE:process_sm_iq/5}]. |
67 |
|
|
68 |
|
%%% |
69 |
|
%%% config_spec |
70 |
|
%%% |
71 |
|
|
72 |
|
-spec config_spec() -> mongoose_config_spec:config_section(). |
73 |
|
config_spec() -> |
74 |
8 |
#section{items = #{<<"iqdisc">> => mongoose_config_spec:iqdisc()}, |
75 |
|
defaults = #{<<"iqdisc">> => one_queue}}. |
76 |
|
|
77 |
|
-spec supported_features() -> [atom()]. |
78 |
4 |
supported_features() -> [dynamic_domains]. |
79 |
|
|
80 |
|
%%% |
81 |
|
%%% IQ handlers |
82 |
|
%%% |
83 |
|
|
84 |
|
-spec process_local_iq(mongoose_acc:t(), jid:jid(), jid:jid(), jlib:iq(), map()) |
85 |
|
-> {mongoose_acc:t(), jlib:iq()}. |
86 |
|
process_local_iq(Acc, #jid{} = JID, _To, |
87 |
|
#iq{type = 'get', sub_el = _SubEl} = IQ, _Extra) -> |
88 |
:-( |
{Acc, get_ip(JID, IQ)}; |
89 |
|
process_local_iq(Acc, _From, _To, #iq{type = 'set', sub_el = SubEl} = IQ, _Extra) -> |
90 |
:-( |
{Acc, IQ#iq{type = error, sub_el = [SubEl, mongoose_xmpp_errors:not_allowed()]}}. |
91 |
|
|
92 |
|
-spec process_sm_iq(mongoose_acc:t(), jid:jid(), jid:jid(), jlib:iq(), map()) |
93 |
|
-> {mongoose_acc:t(), jlib:iq()}. |
94 |
|
process_sm_iq(Acc, |
95 |
|
#jid{luser = LUser, lserver = LServer} = JID, |
96 |
|
#jid{luser = LUser, lserver = LServer}, |
97 |
|
#iq{type = 'get', sub_el = _SubEl} = IQ, _Extra) -> |
98 |
:-( |
{Acc, get_ip(JID, IQ)}; |
99 |
|
process_sm_iq(Acc, _From, _To, #iq{type = 'get', sub_el = SubEl} = IQ, _Extra) -> |
100 |
:-( |
{Acc, IQ#iq{type = error, sub_el = [SubEl, mongoose_xmpp_errors:forbidden()]}}; |
101 |
|
process_sm_iq(Acc, _From, _To, #iq{type = 'set', sub_el = SubEl} = IQ, _Extra) -> |
102 |
:-( |
{Acc, IQ#iq{type = error, sub_el = [SubEl, mongoose_xmpp_errors:not_allowed()]}}. |
103 |
|
|
104 |
|
get_ip(JID, #iq{sub_el = #xmlel{} = SubEl} = IQ) -> |
105 |
:-( |
case ejabberd_sm:get_session_ip(JID) of |
106 |
|
{IP, Port} when is_tuple(IP) -> |
107 |
:-( |
IQ#iq{ |
108 |
|
type = 'result', |
109 |
|
sub_el = [ |
110 |
|
SubEl#xmlel{ |
111 |
|
children = [ |
112 |
|
#xmlel{name = <<"ip">>, |
113 |
|
children = [#xmlcdata{content = list_to_binary(inet_parse:ntoa(IP))}]}, |
114 |
|
#xmlel{name = <<"port">>, |
115 |
|
children = [#xmlcdata{content = integer_to_binary(Port)}]} |
116 |
|
] |
117 |
|
}]}; |
118 |
|
_ -> |
119 |
:-( |
IQ#iq{ |
120 |
|
type = 'error', |
121 |
|
sub_el = [SubEl, mongoose_xmpp_errors:internal_server_error()] |
122 |
|
} |
123 |
|
end. |