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, Opts) -> |
54 |
285 |
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue), |
55 |
|
|
56 |
285 |
[gen_iq_handler:add_iq_handler_for_domain(HostType, ?NS_SIC, Component, Fn, #{}, IQDisc) || |
57 |
285 |
{Component, Fn} <- iq_handlers()], |
58 |
285 |
ok. |
59 |
|
|
60 |
|
-spec stop(mongooseim:host_type()) -> ok. |
61 |
|
stop(HostType) -> |
62 |
285 |
[gen_iq_handler:remove_iq_handler_for_domain(HostType, ?NS_LAST, Component) || |
63 |
285 |
{Component, _Fn} <- iq_handlers()], |
64 |
285 |
ok. |
65 |
|
|
66 |
|
iq_handlers() -> |
67 |
570 |
[{ejabberd_local, fun ?MODULE:process_local_iq/5}, |
68 |
|
{ejabberd_sm, fun ?MODULE:process_sm_iq/5}]. |
69 |
|
|
70 |
|
%%% |
71 |
|
%%% config_spec |
72 |
|
%%% |
73 |
|
|
74 |
|
-spec config_spec() -> mongoose_config_spec:config_section(). |
75 |
|
config_spec() -> |
76 |
146 |
#section{ |
77 |
|
items = #{<<"iqdisc">> => mongoose_config_spec:iqdisc()}}. |
78 |
|
|
79 |
|
-spec supported_features() -> [atom()]. |
80 |
132 |
supported_features() -> [dynamic_domains]. |
81 |
|
|
82 |
|
%%% |
83 |
|
%%% IQ handlers |
84 |
|
%%% |
85 |
|
|
86 |
|
-spec process_local_iq(mongoose_acc:t(), jid:jid(), jid:jid(), jlib:iq(), map()) |
87 |
|
-> {mongoose_acc:t(), jlib:iq()}. |
88 |
|
process_local_iq(Acc, #jid{} = JID, _To, |
89 |
|
#iq{type = 'get', sub_el = _SubEl} = IQ, _Extra) -> |
90 |
:-( |
{Acc, get_ip(JID, IQ)}; |
91 |
|
process_local_iq(Acc, _From, _To, #iq{type = 'set', sub_el = SubEl} = IQ, _Extra) -> |
92 |
:-( |
{Acc, IQ#iq{type = error, sub_el = [SubEl, mongoose_xmpp_errors:not_allowed()]}}. |
93 |
|
|
94 |
|
-spec process_sm_iq(mongoose_acc:t(), jid:jid(), jid:jid(), jlib:iq(), map()) |
95 |
|
-> {mongoose_acc:t(), jlib:iq()}. |
96 |
|
process_sm_iq(Acc, #jid{user = User, server = Server} = JID, |
97 |
|
#jid{user = User, server = Server}, |
98 |
|
#iq{type = 'get', sub_el = _SubEl} = IQ, _Extra) -> |
99 |
1 |
{Acc, get_ip(JID, IQ)}; |
100 |
|
process_sm_iq(Acc, _From, _To, #iq{type = 'get', sub_el = SubEl} = IQ, _Extra) -> |
101 |
1 |
{Acc, IQ#iq{type = error, sub_el = [SubEl, mongoose_xmpp_errors:forbidden()]}}; |
102 |
|
process_sm_iq(Acc, _From, _To, #iq{type = 'set', sub_el = SubEl} = IQ, _Extra) -> |
103 |
:-( |
{Acc, IQ#iq{type = error, sub_el = [SubEl, mongoose_xmpp_errors:not_allowed()]}}. |
104 |
|
|
105 |
|
get_ip(JID, #iq{sub_el = #xmlel{} = SubEl} = IQ) -> |
106 |
1 |
case ejabberd_sm:get_session_ip(JID) of |
107 |
|
{IP, Port} when is_tuple(IP) -> |
108 |
1 |
IQ#iq{ |
109 |
|
type = 'result', |
110 |
|
sub_el = [ |
111 |
|
SubEl#xmlel{ |
112 |
|
children = [ |
113 |
|
#xmlel{name = <<"ip">>, |
114 |
|
children = [#xmlcdata{content = list_to_binary(inet_parse:ntoa(IP))}]}, |
115 |
|
#xmlel{name = <<"port">>, |
116 |
|
children = [#xmlcdata{content = integer_to_binary(Port)}]} |
117 |
|
] |
118 |
|
}]}; |
119 |
|
_ -> |
120 |
:-( |
IQ#iq{ |
121 |
|
type = 'error', |
122 |
|
sub_el = [SubEl, mongoose_xmpp_errors:internal_server_error()] |
123 |
|
} |
124 |
|
end. |