aboutsummaryrefslogtreecommitdiff
path: root/src/mod_proxy65
diff options
context:
space:
mode:
authorEvgeniy Khramtsov <ekhramtsov@process-one.net>2013-04-08 11:12:54 +0200
committerChristophe Romain <christophe.romain@process-one.net>2013-06-13 11:11:02 +0200
commit4d8f7706240a1603468968f47fc7b150b788d62f (patch)
tree92d55d789cc7ac979b3c9e161ffb7f908eba043a /src/mod_proxy65
parentFix Guide: ejabberd_service expects a shaper_rule, not a shaper (diff)
Switch to rebar build tool
Use dynamic Rebar configuration Make iconv dependency optional Disable transient_supervisors compile option Add hipe compilation support Only compile ibrowse and lhttpc when needed Make it possible to generate an OTP application release Add --enable-debug compile option Add --enable-all compiler option Add --enable-tools configure option Add --with-erlang configure option. Add --enable-erlang-version-check configure option. Add lager support Improve the test suite
Diffstat (limited to 'src/mod_proxy65')
-rw-r--r--src/mod_proxy65/Makefile.in38
-rw-r--r--src/mod_proxy65/Makefile.win3227
-rw-r--r--src/mod_proxy65/mod_proxy65.erl82
-rw-r--r--src/mod_proxy65/mod_proxy65.hrl74
-rw-r--r--src/mod_proxy65/mod_proxy65_lib.erl73
-rw-r--r--src/mod_proxy65/mod_proxy65_service.erl285
-rw-r--r--src/mod_proxy65/mod_proxy65_sm.erl174
-rw-r--r--src/mod_proxy65/mod_proxy65_stream.erl287
8 files changed, 0 insertions, 1040 deletions
diff --git a/src/mod_proxy65/Makefile.in b/src/mod_proxy65/Makefile.in
deleted file mode 100644
index 3fc94c662..000000000
--- a/src/mod_proxy65/Makefile.in
+++ /dev/null
@@ -1,38 +0,0 @@
-# $Id$
-
-CC = @CC@
-CFLAGS = @CFLAGS@
-CPPFLAGS = @CPPFLAGS@
-LDFLAGS = @LDFLAGS@
-LIBS = @LIBS@
-
-ERLANG_CFLAGS = @ERLANG_CFLAGS@
-ERLANG_LIBS = @ERLANG_LIBS@
-
-EFLAGS += -I ..
-EFLAGS += -pz ..
-
-# make debug=true to compile Erlang module with debug informations.
-ifdef debug
- EFLAGS+=+debug_info
-endif
-
-OUTDIR = ..
-SOURCES = $(wildcard *.erl)
-BEAMS = $(addprefix $(OUTDIR)/,$(SOURCES:.erl=.beam))
-
-
-all: $(BEAMS)
-
-$(OUTDIR)/%.beam: %.erl
- @ERLC@ -W $(EFLAGS) -o $(OUTDIR) $<
-
-clean:
- rm -f $(BEAMS)
-
-distclean: clean
- rm -f Makefile
-
-TAGS:
- etags *.erl
-
diff --git a/src/mod_proxy65/Makefile.win32 b/src/mod_proxy65/Makefile.win32
deleted file mode 100644
index 7683097d3..000000000
--- a/src/mod_proxy65/Makefile.win32
+++ /dev/null
@@ -1,27 +0,0 @@
-
-include ..\Makefile.inc
-
-EFLAGS = -I .. -pz ..
-
-OUTDIR = ..
-BEAMS = ..\mod_proxy65.beam ..\mod_proxy65_lib.beam ..\mod_proxy65_service.beam ..\mod_proxy65_sm.beam ..\mod_proxy65_stream.beam
-
-ALL : $(BEAMS)
-
-CLEAN :
- -@erase $(BEAMS)
-
-$(OUTDIR)\mod_proxy65.beam : mod_proxy65.erl
- erlc -W $(EFLAGS) -o $(OUTDIR) mod_proxy65.erl
-
-$(OUTDIR)\mod_proxy65_service.beam : mod_proxy65_service.erl
- erlc -W $(EFLAGS) -o $(OUTDIR) mod_proxy65_service.erl
-
-$(OUTDIR)\mod_proxy65_sm.beam : mod_proxy65_sm.erl
- erlc -W $(EFLAGS) -o $(OUTDIR) mod_proxy65_sm.erl
-
-$(OUTDIR)\mod_proxy65_stream.beam : mod_proxy65_stream.erl
- erlc -W $(EFLAGS) -o $(OUTDIR) mod_proxy65_stream.erl
-
-$(OUTDIR)\mod_proxy65_lib.beam : mod_proxy65_lib.erl
- erlc -W $(EFLAGS) -o $(OUTDIR) mod_proxy65_lib.erl
diff --git a/src/mod_proxy65/mod_proxy65.erl b/src/mod_proxy65/mod_proxy65.erl
deleted file mode 100644
index 3e8354caf..000000000
--- a/src/mod_proxy65/mod_proxy65.erl
+++ /dev/null
@@ -1,82 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : mod_proxy65.erl
-%%% Author : Evgeniy Khramtsov <xram@jabber.ru>
-%%% Purpose : Main supervisor.
-%%% Created : 12 Oct 2006 by Evgeniy Khramtsov <xram@jabber.ru>
-%%%
-%%%
-%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
-%%%
-%%% This program is free software; you can redistribute it and/or
-%%% modify it under the terms of the GNU General Public License as
-%%% published by the Free Software Foundation; either version 2 of the
-%%% License, or (at your option) any later version.
-%%%
-%%% This program is distributed in the hope that it will be useful,
-%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
-%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%%% General Public License for more details.
-%%%
-%%% You should have received a copy of the GNU General Public License
-%%% along with this program; if not, write to the Free Software
-%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-%%% 02111-1307 USA
-%%%
-%%%----------------------------------------------------------------------
-
--module(mod_proxy65).
-
--author('xram@jabber.ru').
-
--behaviour(gen_mod).
-
--behaviour(supervisor).
-
-%% gen_mod callbacks.
--export([start/2, stop/1]).
-
-%% supervisor callbacks.
--export([init/1]).
-
-%% API.
--export([start_link/2]).
-
--define(PROCNAME, ejabberd_mod_proxy65).
-
-start(Host, Opts) ->
- case mod_proxy65_service:add_listener(Host, Opts) of
- {error, _} = Err -> erlang:error(Err);
- _ ->
- Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
- ChildSpec = {Proc, {?MODULE, start_link, [Host, Opts]},
- transient, infinity, supervisor, [?MODULE]},
- supervisor:start_child(ejabberd_sup, ChildSpec)
- end.
-
-stop(Host) ->
- mod_proxy65_service:delete_listener(Host),
- Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
- supervisor:terminate_child(ejabberd_sup, Proc),
- supervisor:delete_child(ejabberd_sup, Proc).
-
-start_link(Host, Opts) ->
- Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
- supervisor:start_link({local, Proc}, ?MODULE,
- [Host, Opts]).
-
-init([Host, Opts]) ->
- Service = {mod_proxy65_service,
- {mod_proxy65_service, start_link, [Host, Opts]},
- transient, 5000, worker, [mod_proxy65_service]},
- StreamSupervisor = {ejabberd_mod_proxy65_sup,
- {ejabberd_tmp_sup, start_link,
- [gen_mod:get_module_proc(Host,
- ejabberd_mod_proxy65_sup),
- mod_proxy65_stream]},
- transient, infinity, supervisor, [ejabberd_tmp_sup]},
- StreamManager = {mod_proxy65_sm,
- {mod_proxy65_sm, start_link, [Host, Opts]}, transient,
- 5000, worker, [mod_proxy65_sm]},
- {ok,
- {{one_for_one, 10, 1},
- [StreamManager, StreamSupervisor, Service]}}.
diff --git a/src/mod_proxy65/mod_proxy65.hrl b/src/mod_proxy65/mod_proxy65.hrl
deleted file mode 100644
index d0779af14..000000000
--- a/src/mod_proxy65/mod_proxy65.hrl
+++ /dev/null
@@ -1,74 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% RFC 1928 constants.
-%%%
-%%%
-%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
-%%%
-%%% This program is free software; you can redistribute it and/or
-%%% modify it under the terms of the GNU General Public License as
-%%% published by the Free Software Foundation; either version 2 of the
-%%% License, or (at your option) any later version.
-%%%
-%%% This program is distributed in the hope that it will be useful,
-%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
-%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%%% General Public License for more details.
-%%%
-%%% You should have received a copy of the GNU General Public License
-%%% along with this program; if not, write to the Free Software
-%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-%%% 02111-1307 USA
-%%%
-%%%----------------------------------------------------------------------
-
-%% Version
--define(VERSION_5, 5).
-
-%% Authentication methods
--define(AUTH_ANONYMOUS, 0).
-
--define(AUTH_GSSAPI, 1).
-
--define(AUTH_PLAIN, 2).
-
-%% Address Type
--define(AUTH_NO_METHODS, 255).
-
--define(ATYP_IPV4, 1).
-
--define(ATYP_DOMAINNAME, 3).
-
--define(ATYP_IPV6, 4).
-
-%% Commands
--define(CMD_CONNECT, 1).
-
--define(CMD_BIND, 2).
-
--define(CMD_UDP, 3).
-
-%% RFC 1928 replies
--define(SUCCESS, 0).
-
--define(ERR_GENERAL_FAILURE, 1).
-
--define(ERR_NOT_ALLOWED, 2).
-
--define(ERR_NETWORK_UNREACHABLE, 3).
-
--define(ERR_HOST_UNREACHABLE, 4).
-
--define(ERR_CONNECTION_REFUSED, 5).
-
--define(ERR_TTL_EXPIRED, 6).
-
--define(ERR_COMMAND_NOT_SUPPORTED, 7).
-
--define(ERR_ADDRESS_TYPE_NOT_SUPPORTED, 8).
-
-%% RFC 1928 defined timeout.
--define(SOCKS5_REPLY_TIMEOUT, 10000).
-
--record(s5_request, {rsv = 0 :: integer(),
- cmd = connect :: connect | udp,
- sha1 = <<"">> :: binary()}).
diff --git a/src/mod_proxy65/mod_proxy65_lib.erl b/src/mod_proxy65/mod_proxy65_lib.erl
deleted file mode 100644
index 388811436..000000000
--- a/src/mod_proxy65/mod_proxy65_lib.erl
+++ /dev/null
@@ -1,73 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : mod_proxy65_lib.erl
-%%% Author : Evgeniy Khramtsov <xram@jabber.ru>
-%%% Purpose : SOCKS5 parsing library.
-%%% Created : 12 Oct 2006 by Evgeniy Khramtsov <xram@jabber.ru>
-%%%
-%%%
-%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
-%%%
-%%% This program is free software; you can redistribute it and/or
-%%% modify it under the terms of the GNU General Public License as
-%%% published by the Free Software Foundation; either version 2 of the
-%%% License, or (at your option) any later version.
-%%%
-%%% This program is distributed in the hope that it will be useful,
-%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
-%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%%% General Public License for more details.
-%%%
-%%% You should have received a copy of the GNU General Public License
-%%% along with this program; if not, write to the Free Software
-%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-%%% 02111-1307 USA
-%%%
-%%%----------------------------------------------------------------------
-
--module(mod_proxy65_lib).
-
--author('xram@jabber.ru').
-
--include("mod_proxy65.hrl").
-
--export([unpack_init_message/1, unpack_auth_request/1,
- unpack_request/1, make_init_reply/1, make_auth_reply/1,
- make_reply/1, make_error_reply/1, make_error_reply/2]).
-
-unpack_init_message(<<(?VERSION_5), N,
- AuthMethodList:N/binary>>)
- when N > 0, N < 256 ->
- {ok, binary_to_list(AuthMethodList)};
-unpack_init_message(_) -> error.
-
-unpack_auth_request(<<1, ULen, User:ULen/binary, PLen,
- Pass:PLen/binary>>)
- when ULen < 256, PLen < 256 ->
- {(User), (Pass)};
-unpack_auth_request(_) -> error.
-
-unpack_request(<<(?VERSION_5), CMD, RSV,
- (?ATYP_DOMAINNAME), 40, SHA1:40/binary, 0, 0>>)
- when CMD == (?CMD_CONNECT); CMD == (?CMD_UDP) ->
- Command = if CMD == (?CMD_CONNECT) -> connect;
- CMD == (?CMD_UDP) -> udp
- end,
- #s5_request{cmd = Command, rsv = RSV, sha1 = (SHA1)};
-unpack_request(_) -> error.
-
-make_init_reply(Method) -> [?VERSION_5, Method].
-
-make_auth_reply(true) -> [1, ?SUCCESS];
-make_auth_reply(false) -> [1, ?ERR_NOT_ALLOWED].
-
-make_reply(#s5_request{rsv = RSV, sha1 = SHA1}) ->
- [?VERSION_5, ?SUCCESS, RSV, ?ATYP_DOMAINNAME,
- byte_size(SHA1), SHA1, 0, 0].
-
-make_error_reply(Request) ->
- make_error_reply(Request, ?ERR_NOT_ALLOWED).
-
-make_error_reply(#s5_request{rsv = RSV, sha1 = SHA1},
- Reason) ->
- [?VERSION_5, Reason, RSV, ?ATYP_DOMAINNAME,
- byte_size(SHA1), SHA1, 0, 0].
diff --git a/src/mod_proxy65/mod_proxy65_service.erl b/src/mod_proxy65/mod_proxy65_service.erl
deleted file mode 100644
index 22ac6cde6..000000000
--- a/src/mod_proxy65/mod_proxy65_service.erl
+++ /dev/null
@@ -1,285 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : mod_proxy65_service.erl
-%%% Author : Evgeniy Khramtsov <xram@jabber.ru>
-%%% Purpose : SOCKS5 Bytestreams XMPP service.
-%%% Created : 12 Oct 2006 by Evgeniy Khramtsov <xram@jabber.ru>
-%%%
-%%%
-%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
-%%%
-%%% This program is free software; you can redistribute it and/or
-%%% modify it under the terms of the GNU General Public License as
-%%% published by the Free Software Foundation; either version 2 of the
-%%% License, or (at your option) any later version.
-%%%
-%%% This program is distributed in the hope that it will be useful,
-%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
-%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%%% General Public License for more details.
-%%%
-%%% You should have received a copy of the GNU General Public License
-%%% along with this program; if not, write to the Free Software
-%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-%%% 02111-1307 USA
-%%%
-%%%----------------------------------------------------------------------
-
--module(mod_proxy65_service).
-
--author('xram@jabber.ru').
-
--behaviour(gen_server).
-
-%% gen_server callbacks.
--export([init/1, handle_info/2, handle_call/3,
- handle_cast/2, terminate/2, code_change/3]).
-
-%% API.
--export([start_link/2, add_listener/2,
- delete_listener/1]).
-
--include("ejabberd.hrl").
-
--include("jlib.hrl").
-
--define(PROCNAME, ejabberd_mod_proxy65_service).
-
--record(state,
- {myhost = <<"">> :: binary(),
- serverhost = <<"">> :: binary(),
- name = <<"">> :: binary(),
- stream_addr = [] :: [attr()],
- port = 0 :: inet:port_number(),
- ip = {127,0,0,1} :: inet:ip_address(),
- acl = none :: atom()}).
-
-%%%------------------------
-%%% gen_server callbacks
-%%%------------------------
-
-start_link(Host, Opts) ->
- Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
- gen_server:start_link({local, Proc}, ?MODULE,
- [Host, Opts], []).
-
-init([Host, Opts]) ->
- State = parse_options(Host, Opts),
- ejabberd_router:register_route(State#state.myhost),
- {ok, State}.
-
-terminate(_Reason, #state{myhost = MyHost}) ->
- ejabberd_router:unregister_route(MyHost), ok.
-
-handle_info({route, From, To,
- #xmlel{name = <<"iq">>} = Packet},
- State) ->
- IQ = jlib:iq_query_info(Packet),
- case catch process_iq(From, IQ, State) of
- Result when is_record(Result, iq) ->
- ejabberd_router:route(To, From, jlib:iq_to_xml(Result));
- {'EXIT', Reason} ->
- ?ERROR_MSG("Error when processing IQ stanza: ~p",
- [Reason]),
- Err = jlib:make_error_reply(Packet,
- ?ERR_INTERNAL_SERVER_ERROR),
- ejabberd_router:route(To, From, Err);
- _ -> ok
- end,
- {noreply, State};
-handle_info(_Info, State) -> {noreply, State}.
-
-handle_call(get_port_ip, _From, State) ->
- {reply, {port_ip, State#state.port, State#state.ip},
- State};
-handle_call(_Request, _From, State) ->
- {reply, ok, State}.
-
-handle_cast(_Request, State) -> {noreply, State}.
-
-code_change(_OldVsn, State, _Extra) -> {ok, State}.
-
-%%%------------------------
-%%% Listener management
-%%%------------------------
-
-add_listener(Host, Opts) ->
- State = parse_options(Host, Opts),
- NewOpts = [Host | Opts],
- ejabberd_listener:add_listener({State#state.port,
- State#state.ip},
- mod_proxy65_stream, NewOpts).
-
-delete_listener(Host) ->
- Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
- {port_ip, Port, IP} = gen_server:call(Proc,
- get_port_ip),
- catch ejabberd_listener:delete_listener({Port, IP},
- mod_proxy65_stream).
-
-%%%------------------------
-%%% IQ Processing
-%%%------------------------
-
-%% disco#info request
-process_iq(_,
- #iq{type = get, xmlns = ?NS_DISCO_INFO, lang = Lang} =
- IQ,
- #state{name = Name, serverhost = ServerHost}) ->
- Info = ejabberd_hooks:run_fold(disco_info, ServerHost,
- [], [ServerHost, ?MODULE, <<"">>, <<"">>]),
- IQ#iq{type = result,
- sub_el =
- [#xmlel{name = <<"query">>,
- attrs = [{<<"xmlns">>, ?NS_DISCO_INFO}],
- children = iq_disco_info(Lang, Name) ++ Info}]};
-%% disco#items request
-process_iq(_,
- #iq{type = get, xmlns = ?NS_DISCO_ITEMS} = IQ, _) ->
- IQ#iq{type = result,
- sub_el =
- [#xmlel{name = <<"query">>,
- attrs = [{<<"xmlns">>, ?NS_DISCO_ITEMS}],
- children = []}]};
-%% vCard request
-process_iq(_,
- #iq{type = get, xmlns = ?NS_VCARD, lang = Lang} = IQ,
- _) ->
- IQ#iq{type = result,
- sub_el =
- [#xmlel{name = <<"vCard">>,
- attrs = [{<<"xmlns">>, ?NS_VCARD}],
- children = iq_vcard(Lang)}]};
-%% bytestreams info request
-process_iq(JID,
- #iq{type = get, sub_el = SubEl,
- xmlns = ?NS_BYTESTREAMS} =
- IQ,
- #state{acl = ACL, stream_addr = StreamAddr,
- serverhost = ServerHost}) ->
- case acl:match_rule(ServerHost, ACL, JID) of
- allow ->
- StreamHostEl = [#xmlel{name = <<"streamhost">>,
- attrs = StreamAddr, children = []}],
- IQ#iq{type = result,
- sub_el =
- [#xmlel{name = <<"query">>,
- attrs = [{<<"xmlns">>, ?NS_BYTESTREAMS}],
- children = StreamHostEl}]};
- deny ->
- IQ#iq{type = error, sub_el = [SubEl, ?ERR_FORBIDDEN]}
- end;
-%% bytestream activation request
-process_iq(InitiatorJID,
- #iq{type = set, sub_el = SubEl,
- xmlns = ?NS_BYTESTREAMS} =
- IQ,
- #state{acl = ACL, serverhost = ServerHost}) ->
- case acl:match_rule(ServerHost, ACL, InitiatorJID) of
- allow ->
- ActivateEl = xml:get_path_s(SubEl,
- [{elem, <<"activate">>}]),
- SID = xml:get_tag_attr_s(<<"sid">>, SubEl),
- case catch
- jlib:string_to_jid(xml:get_tag_cdata(ActivateEl))
- of
- TargetJID
- when is_record(TargetJID, jid), SID /= <<"">>,
- byte_size(SID) =< 128, TargetJID /= InitiatorJID ->
- Target =
- jlib:jid_to_string(jlib:jid_tolower(TargetJID)),
- Initiator =
- jlib:jid_to_string(jlib:jid_tolower(InitiatorJID)),
- SHA1 = sha:sha(<<SID/binary, Initiator/binary, Target/binary>>),
- case mod_proxy65_sm:activate_stream(SHA1, InitiatorJID,
- TargetJID, ServerHost)
- of
- ok -> IQ#iq{type = result, sub_el = []};
- false ->
- IQ#iq{type = error,
- sub_el = [SubEl, ?ERR_ITEM_NOT_FOUND]};
- limit ->
- IQ#iq{type = error,
- sub_el = [SubEl, ?ERR_RESOURCE_CONSTRAINT]};
- conflict ->
- IQ#iq{type = error, sub_el = [SubEl, ?ERR_CONFLICT]};
- _ ->
- IQ#iq{type = error,
- sub_el = [SubEl, ?ERR_INTERNAL_SERVER_ERROR]}
- end;
- _ ->
- IQ#iq{type = error, sub_el = [SubEl, ?ERR_BAD_REQUEST]}
- end;
- deny ->
- IQ#iq{type = error, sub_el = [SubEl, ?ERR_FORBIDDEN]}
- end;
-%% Unknown "set" or "get" request
-process_iq(_, #iq{type = Type, sub_el = SubEl} = IQ, _)
- when Type == get; Type == set ->
- IQ#iq{type = error,
- sub_el = [SubEl, ?ERR_SERVICE_UNAVAILABLE]};
-%% IQ "result" or "error".
-process_iq(_, _, _) -> ok.
-
-%%%-------------------------
-%%% Auxiliary functions.
-%%%-------------------------
--define(FEATURE(Feat),
- #xmlel{name = <<"feature">>,
- attrs = [{<<"var">>, Feat}], children = []}).
-
-iq_disco_info(Lang, Name) ->
- [#xmlel{name = <<"identity">>,
- attrs =
- [{<<"category">>, <<"proxy">>},
- {<<"type">>, <<"bytestreams">>},
- {<<"name">>, translate:translate(Lang, Name)}],
- children = []},
- ?FEATURE((?NS_DISCO_INFO)), ?FEATURE((?NS_VCARD)),
- ?FEATURE((?NS_BYTESTREAMS))].
-
-iq_vcard(Lang) ->
- [#xmlel{name = <<"FN">>, attrs = [],
- children = [{xmlcdata, <<"ejabberd/mod_proxy65">>}]},
- #xmlel{name = <<"URL">>, attrs = [],
- children = [{xmlcdata, ?EJABBERD_URI}]},
- #xmlel{name = <<"DESC">>, attrs = [],
- children =
- [{xmlcdata,
- <<(translate:translate(Lang,
- <<"ejabberd SOCKS5 Bytestreams module">>))/binary,
- "\nCopyright (c) 2003-2013 ProcessOne">>}]}].
-
-parse_options(ServerHost, Opts) ->
- MyHost = gen_mod:get_opt_host(ServerHost, Opts,
- <<"proxy.@HOST@">>),
- Port = gen_mod:get_opt(port, Opts,
- fun(P) when is_integer(P), P>0, P<65536 -> P end,
- 7777),
- ACL = gen_mod:get_opt(access, Opts, fun(A) when is_atom(A) -> A end,
- all),
- Name = gen_mod:get_opt(name, Opts, fun iolist_to_binary/1,
- <<"SOCKS5 Bytestreams">>),
- IP = gen_mod:get_opt(ip, Opts,
- fun(Addr) ->
- jlib:ip_to_list(Addr),
- Addr
- end, get_my_ip()),
- HostName = gen_mod:get_opt(hostname, Opts,
- fun(Addr) when is_tuple(Addr) ->
- jlib:ip_to_list(Addr);
- (S) ->
- iolist_to_binary(S)
- end, jlib:ip_to_list(IP)),
- StreamAddr = [{<<"jid">>, MyHost},
- {<<"host">>, HostName},
- {<<"port">>, jlib:integer_to_binary(Port)}],
- #state{myhost = MyHost, serverhost = ServerHost,
- name = Name, port = Port, ip = IP,
- stream_addr = StreamAddr, acl = ACL}.
-
-get_my_ip() ->
- {ok, MyHostName} = inet:gethostname(),
- case inet:getaddr(MyHostName, inet) of
- {ok, Addr} -> Addr;
- {error, _} -> {127, 0, 0, 1}
- end.
diff --git a/src/mod_proxy65/mod_proxy65_sm.erl b/src/mod_proxy65/mod_proxy65_sm.erl
deleted file mode 100644
index fa9d257ef..000000000
--- a/src/mod_proxy65/mod_proxy65_sm.erl
+++ /dev/null
@@ -1,174 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : mod_proxy65_sm.erl
-%%% Author : Evgeniy Khramtsov <xram@jabber.ru>
-%%% Purpose : Bytestreams manager.
-%%% Created : 12 Oct 2006 by Evgeniy Khramtsov <xram@jabber.ru>
-%%%
-%%%
-%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
-%%%
-%%% This program is free software; you can redistribute it and/or
-%%% modify it under the terms of the GNU General Public License as
-%%% published by the Free Software Foundation; either version 2 of the
-%%% License, or (at your option) any later version.
-%%%
-%%% This program is distributed in the hope that it will be useful,
-%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
-%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%%% General Public License for more details.
-%%%
-%%% You should have received a copy of the GNU General Public License
-%%% along with this program; if not, write to the Free Software
-%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-%%% 02111-1307 USA
-%%%
-%%%----------------------------------------------------------------------
-
--module(mod_proxy65_sm).
-
--author('xram@jabber.ru').
-
--behaviour(gen_server).
-
-%% gen_server callbacks.
--export([init/1, handle_info/2, handle_call/3,
- handle_cast/2, terminate/2, code_change/3]).
-
-%% API.
--export([start_link/2, register_stream/1,
- unregister_stream/1, activate_stream/4]).
-
--record(state, {max_connections = infinity :: non_neg_integer() | infinity}).
-
--include("jlib.hrl").
-
--record(bytestream,
- {sha1 = <<"">> :: binary() | '$1',
- target :: pid() | '_',
- initiator :: pid() | '_',
- active = false :: boolean() | '_',
- jid_i = {<<"">>, <<"">>, <<"">>} :: ljid() | '_'}).
-
--define(PROCNAME, ejabberd_mod_proxy65_sm).
-
-%% Unused callbacks.
-handle_cast(_Request, State) -> {noreply, State}.
-
-code_change(_OldVsn, State, _Extra) -> {ok, State}.
-
-handle_info(_Info, State) -> {noreply, State}.
-
-%%----------------
-
-start_link(Host, Opts) ->
- Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
- gen_server:start_link({local, Proc}, ?MODULE, [Opts],
- []).
-
-init([Opts]) ->
- mnesia:create_table(bytestream, [{ram_copies, [node()]},
- {attributes, record_info(fields, bytestream)}]),
- mnesia:add_table_copy(bytestream, node(), ram_copies),
- MaxConnections = gen_mod:get_opt(max_connections, Opts,
- fun(I) when is_integer(I), I>0 ->
- I;
- (infinity) ->
- infinity
- end, infinity),
- {ok, #state{max_connections = MaxConnections}}.
-
-terminate(_Reason, _State) -> ok.
-
-handle_call({activate, SHA1, IJid}, _From, State) ->
- MaxConns = State#state.max_connections,
- F = fun () ->
- case mnesia:read(bytestream, SHA1, write) of
- [#bytestream{target = TPid, initiator = IPid} =
- ByteStream]
- when is_pid(TPid), is_pid(IPid) ->
- ActiveFlag = ByteStream#bytestream.active,
- if ActiveFlag == false ->
- ConnsPerJID = mnesia:select(bytestream,
- [{#bytestream{sha1 =
- '$1',
- jid_i =
- IJid,
- _ = '_'},
- [], ['$1']}]),
- if length(ConnsPerJID) < MaxConns ->
- mnesia:write(ByteStream#bytestream{active =
- true,
- jid_i =
- IJid}),
- {ok, IPid, TPid};
- true -> {limit, IPid, TPid}
- end;
- true -> conflict
- end;
- _ -> false
- end
- end,
- Reply = mnesia:transaction(F),
- {reply, Reply, State};
-handle_call(_Request, _From, State) ->
- {reply, ok, State}.
-
-%%%----------------------
-%%% API.
-%%%----------------------
-%%%---------------------------------------------------
-%%% register_stream(SHA1) -> {atomic, ok} |
-%%% {atomic, error} |
-%%% transaction abort
-%%% SHA1 = string()
-%%%---------------------------------------------------
-register_stream(SHA1) when is_binary(SHA1) ->
- StreamPid = self(),
- F = fun () ->
- case mnesia:read(bytestream, SHA1, write) of
- [] ->
- mnesia:write(#bytestream{sha1 = SHA1,
- target = StreamPid});
- [#bytestream{target = Pid, initiator = undefined} =
- ByteStream]
- when is_pid(Pid), Pid /= StreamPid ->
- mnesia:write(ByteStream#bytestream{initiator =
- StreamPid});
- _ -> error
- end
- end,
- mnesia:transaction(F).
-
-%%%----------------------------------------------------
-%%% unregister_stream(SHA1) -> ok | transaction abort
-%%% SHA1 = string()
-%%%----------------------------------------------------
-unregister_stream(SHA1) when is_binary(SHA1) ->
- F = fun () -> mnesia:delete({bytestream, SHA1}) end,
- mnesia:transaction(F).
-
-%%%--------------------------------------------------------
-%%% activate_stream(SHA1, IJid, TJid, Host) -> ok |
-%%% false |
-%%% limit |
-%%% conflict |
-%%% error
-%%% SHA1 = string()
-%%% IJid = TJid = jid()
-%%% Host = string()
-%%%--------------------------------------------------------
-activate_stream(SHA1, IJid, TJid, Host)
- when is_binary(SHA1) ->
- Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
- case catch gen_server:call(Proc, {activate, SHA1, IJid})
- of
- {atomic, {ok, IPid, TPid}} ->
- mod_proxy65_stream:activate({IPid, IJid}, {TPid, TJid});
- {atomic, {limit, IPid, TPid}} ->
- mod_proxy65_stream:stop(IPid),
- mod_proxy65_stream:stop(TPid),
- limit;
- {atomic, conflict} -> conflict;
- {atomic, false} -> false;
- _ -> error
- end.
diff --git a/src/mod_proxy65/mod_proxy65_stream.erl b/src/mod_proxy65/mod_proxy65_stream.erl
deleted file mode 100644
index 1eca99b39..000000000
--- a/src/mod_proxy65/mod_proxy65_stream.erl
+++ /dev/null
@@ -1,287 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : mod_proxy65_stream.erl
-%%% Author : Evgeniy Khramtsov <xram@jabber.ru>
-%%% Purpose : Bytestream process.
-%%% Created : 12 Oct 2006 by Evgeniy Khramtsov <xram@jabber.ru>
-%%%
-%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
-%%%
-%%% This program is free software; you can redistribute it and/or
-%%% modify it under the terms of the GNU General Public License as
-%%% published by the Free Software Foundation; either version 2 of the
-%%% License, or (at your option) any later version.
-%%%
-%%% This program is distributed in the hope that it will be useful,
-%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
-%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%%% General Public License for more details.
-%%%
-%%% You should have received a copy of the GNU General Public License
-%%% along with this program; if not, write to the Free Software
-%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-%%% 02111-1307 USA
-%%%
-%%%----------------------------------------------------------------------
-
--module(mod_proxy65_stream).
-
--author('xram@jabber.ru').
-
--behaviour(gen_fsm).
-
-%% gen_fsm callbacks.
--export([init/1, handle_event/3, handle_sync_event/4,
- code_change/4, handle_info/3, terminate/3]).
-
-%% gen_fsm states.
--export([wait_for_init/2, wait_for_auth/2,
- wait_for_request/2, wait_for_activation/2,
- stream_established/2]).
-
-%% API.
--export([start/2, stop/1, start_link/3, activate/2,
- relay/3, socket_type/0]).
-
--include("mod_proxy65.hrl").
-
--include("ejabberd.hrl").
-
--define(WAIT_TIMEOUT, 60000).
-
--record(state,
- {socket :: inet:socket(),
- timer = make_ref() :: reference(),
- sha1 = <<"">> :: binary(),
- host = <<"">> :: binary(),
- auth_type = anonymous :: plain | anonymous,
- shaper = none :: shaper:shaper()}).
-
-%% Unused callbacks
-handle_event(_Event, StateName, StateData) ->
- {next_state, StateName, StateData}.
-
-code_change(_OldVsn, StateName, StateData, _Extra) ->
- {ok, StateName, StateData}.
-
-%%-------------------------------
-
-start({gen_tcp, Socket}, Opts1) ->
- {[Host], Opts} = lists:partition(fun (O) -> is_binary(O)
- end,
- Opts1),
- Supervisor = gen_mod:get_module_proc(Host,
- ejabberd_mod_proxy65_sup),
- supervisor:start_child(Supervisor,
- [Socket, Host, Opts]).
-
-start_link(Socket, Host, Opts) ->
- gen_fsm:start_link(?MODULE, [Socket, Host, Opts], []).
-
-init([Socket, Host, Opts]) ->
- process_flag(trap_exit, true),
- AuthType = gen_mod:get_opt(auth_type, Opts,
- fun(plain) -> plain;
- (anonymous) -> anonymous
- end, anonymous),
- Shaper = gen_mod:get_opt(shaper, Opts,
- fun(A) when is_atom(A) -> A end,
- none),
- RecvBuf = gen_mod:get_opt(recbuf, Opts,
- fun(I) when is_integer(I), I>0 -> I end,
- 8192),
- SendBuf = gen_mod:get_opt(sndbuf, Opts,
- fun(I) when is_integer(I), I>0 -> I end,
- 8192),
- TRef = erlang:send_after(?WAIT_TIMEOUT, self(), stop),
- inet:setopts(Socket,
- [{active, true}, {recbuf, RecvBuf}, {sndbuf, SendBuf}]),
- {ok, wait_for_init,
- #state{host = Host, auth_type = AuthType,
- socket = Socket, shaper = Shaper, timer = TRef}}.
-
-terminate(_Reason, StateName, #state{sha1 = SHA1}) ->
- catch mod_proxy65_sm:unregister_stream(SHA1),
- if StateName == stream_established ->
- ?INFO_MSG("Bytestream terminated", []);
- true -> ok
- end.
-
-%%%------------------------------
-%%% API.
-%%%------------------------------
-socket_type() -> raw.
-
-stop(StreamPid) -> StreamPid ! stop.
-
-activate({P1, J1}, {P2, J2}) ->
- case catch {gen_fsm:sync_send_all_state_event(P1,
- get_socket),
- gen_fsm:sync_send_all_state_event(P2, get_socket)}
- of
- {S1, S2} when is_port(S1), is_port(S2) ->
- P1 ! {activate, P2, S2, J1, J2},
- P2 ! {activate, P1, S1, J1, J2},
- JID1 = jlib:jid_to_string(J1),
- JID2 = jlib:jid_to_string(J2),
- ?INFO_MSG("(~w:~w) Activated bytestream for ~s "
- "-> ~s",
- [P1, P2, JID1, JID2]),
- ok;
- _ -> error
- end.
-
-%%%-----------------------
-%%% States
-%%%-----------------------
-wait_for_init(Packet,
- #state{socket = Socket, auth_type = AuthType} =
- StateData) ->
- case mod_proxy65_lib:unpack_init_message(Packet) of
- {ok, AuthMethods} ->
- Method = select_auth_method(AuthType, AuthMethods),
- gen_tcp:send(Socket,
- mod_proxy65_lib:make_init_reply(Method)),
- case Method of
- ?AUTH_ANONYMOUS ->
- {next_state, wait_for_request, StateData};
- ?AUTH_PLAIN -> {next_state, wait_for_auth, StateData};
- ?AUTH_NO_METHODS -> {stop, normal, StateData}
- end;
- error -> {stop, normal, StateData}
- end.
-
-wait_for_auth(Packet,
- #state{socket = Socket, host = Host} = StateData) ->
- case mod_proxy65_lib:unpack_auth_request(Packet) of
- {User, Pass} ->
- Result = ejabberd_auth:check_password(User, Host, Pass),
- gen_tcp:send(Socket,
- mod_proxy65_lib:make_auth_reply(Result)),
- case Result of
- true -> {next_state, wait_for_request, StateData};
- false -> {stop, normal, StateData}
- end;
- _ -> {stop, normal, StateData}
- end.
-
-wait_for_request(Packet,
- #state{socket = Socket} = StateData) ->
- Request = mod_proxy65_lib:unpack_request(Packet),
- case Request of
- #s5_request{sha1 = SHA1, cmd = connect} ->
- case catch mod_proxy65_sm:register_stream(SHA1) of
- {atomic, ok} ->
- inet:setopts(Socket, [{active, false}]),
- gen_tcp:send(Socket,
- mod_proxy65_lib:make_reply(Request)),
- {next_state, wait_for_activation,
- StateData#state{sha1 = SHA1}};
- _ ->
- Err = mod_proxy65_lib:make_error_reply(Request),
- gen_tcp:send(Socket, Err),
- {stop, normal, StateData}
- end;
- #s5_request{cmd = udp} ->
- Err = mod_proxy65_lib:make_error_reply(Request,
- ?ERR_COMMAND_NOT_SUPPORTED),
- gen_tcp:send(Socket, Err),
- {stop, normal, StateData};
- _ -> {stop, normal, StateData}
- end.
-
-wait_for_activation(_Data, StateData) ->
- {next_state, wait_for_activation, StateData}.
-
-stream_established(_Data, StateData) ->
- {next_state, stream_established, StateData}.
-
-%%%-----------------------
-%%% Callbacks processing
-%%%-----------------------
-
-%% SOCKS5 packets.
-handle_info({tcp, _S, Data}, StateName, StateData)
- when StateName /= wait_for_activation ->
- erlang:cancel_timer(StateData#state.timer),
- TRef = erlang:send_after(?WAIT_TIMEOUT, self(), stop),
- gen_fsm:send_event(self(), Data),
- {next_state, StateName, StateData#state{timer = TRef}};
-%% Activation message.
-handle_info({activate, PeerPid, PeerSocket, IJid, TJid},
- wait_for_activation, StateData) ->
- erlang:monitor(process, PeerPid),
- erlang:cancel_timer(StateData#state.timer),
- MySocket = StateData#state.socket,
- Shaper = StateData#state.shaper,
- Host = StateData#state.host,
- MaxRate = find_maxrate(Shaper, IJid, TJid, Host),
- spawn_link(?MODULE, relay,
- [MySocket, PeerSocket, MaxRate]),
- {next_state, stream_established, StateData};
-%% Socket closed
-handle_info({tcp_closed, _Socket}, _StateName,
- StateData) ->
- {stop, normal, StateData};
-handle_info({tcp_error, _Socket, _Reason}, _StateName,
- StateData) ->
- {stop, normal, StateData};
-%% Got stop message.
-handle_info(stop, _StateName, StateData) ->
- {stop, normal, StateData};
-%% Either linked process or peer process died.
-handle_info({'EXIT', _, _}, _StateName, StateData) ->
- {stop, normal, StateData};
-handle_info({'DOWN', _, _, _, _}, _StateName,
- StateData) ->
- {stop, normal, StateData};
-%% Packets of no interest
-handle_info(_Info, StateName, StateData) ->
- {next_state, StateName, StateData}.
-
-%% Socket request.
-handle_sync_event(get_socket, _From,
- wait_for_activation, StateData) ->
- Socket = StateData#state.socket,
- {reply, Socket, wait_for_activation, StateData};
-handle_sync_event(_Event, _From, StateName,
- StateData) ->
- {reply, error, StateName, StateData}.
-
-%%%-------------------------------------------------
-%%% Relay Process.
-%%%-------------------------------------------------
-relay(MySocket, PeerSocket, Shaper) ->
- case gen_tcp:recv(MySocket, 0) of
- {ok, Data} ->
- gen_tcp:send(PeerSocket, Data),
- {NewShaper, Pause} = shaper:update(Shaper, byte_size(Data)),
- if Pause > 0 -> timer:sleep(Pause);
- true -> pass
- end,
- relay(MySocket, PeerSocket, NewShaper);
- _ -> stopped
- end.
-
-%%%------------------------
-%%% Auxiliary functions
-%%%------------------------
-select_auth_method(plain, AuthMethods) ->
- case lists:member(?AUTH_PLAIN, AuthMethods) of
- true -> ?AUTH_PLAIN;
- false -> ?AUTH_NO_METHODS
- end;
-select_auth_method(anonymous, AuthMethods) ->
- case lists:member(?AUTH_ANONYMOUS, AuthMethods) of
- true -> ?AUTH_ANONYMOUS;
- false -> ?AUTH_NO_METHODS
- end.
-
-%% Obviously, we must use shaper with maximum rate.
-find_maxrate(Shaper, JID1, JID2, Host) ->
- MaxRate1 = shaper:new(acl:match_rule(Host, Shaper,
- JID1)),
- MaxRate2 = shaper:new(acl:match_rule(Host, Shaper,
- JID2)),
- if MaxRate1 == none; MaxRate2 == none -> none;
- true -> lists:max([MaxRate1, MaxRate2])
- end.