diff options
Diffstat (limited to 'src/pam/epam.erl')
-rw-r--r-- | src/pam/epam.erl | 98 |
1 files changed, 55 insertions, 43 deletions
diff --git a/src/pam/epam.erl b/src/pam/epam.erl index 5b0da0679..e0ea1719a 100644 --- a/src/pam/epam.erl +++ b/src/pam/epam.erl @@ -25,40 +25,46 @@ %%%------------------------------------------------------------------- -module(epam). + -author('xram@jabber.ru'). -behaviour(gen_server). -include_lib("kernel/include/file.hrl"). + -include("ejabberd.hrl"). %% API -export([start_link/0, start/0, stop/0]). + -export([authenticate/3, acct_mgmt/2]). %% gen_server callbacks --export([init/1, handle_call/3, handle_cast/2, handle_info/2, - terminate/2, code_change/3]). +-export([init/1, handle_call/3, handle_cast/2, + handle_info/2, terminate/2, code_change/3]). --define(WARNING, "File ~p is world-wide executable. " - "This is a possible security hole in your system. " - "This file must be setted root on execution " - "and only ejabberd must be able to read/execute it. " - "You have been warned :)"). +-define(WARNING, + "File ~p is world-wide executable. This " + "is a possible security hole in your " + "system. This file must be setted root " + "on execution and only ejabberd must " + "be able to read/execute it. You have " + "been warned :)"). -define(PROCNAME, ?MODULE). + -define(CMD_AUTH, 0). + -define(CMD_ACCT, 1). + -record(state, {port}). %%==================================================================== %% API %%==================================================================== start() -> - ChildSpec = { - ?PROCNAME, {?MODULE, start_link, []}, - transient, 1000, worker, [?MODULE] - }, + ChildSpec = {?PROCNAME, {?MODULE, start_link, []}, + transient, 1000, worker, [?MODULE]}, supervisor:start_child(ejabberd_sup, ChildSpec). stop() -> @@ -67,40 +73,47 @@ stop() -> supervisor:delete_child(ejabberd_sup, ?PROCNAME). start_link() -> - gen_server:start_link({local, ?PROCNAME}, ?MODULE, [], []). + gen_server:start_link({local, ?PROCNAME}, ?MODULE, [], + []). -authenticate(Srv, User, Pass) when is_list(Srv), is_list(User), is_list(Pass) -> - gen_server:call(?PROCNAME, {authenticate, Srv, User, Pass}). +authenticate(Srv, User, Pass) + when is_binary(Srv), is_binary(User), is_binary(Pass) -> + gen_server:call(?PROCNAME, + {authenticate, Srv, User, Pass}). -acct_mgmt(Srv, User) when is_list(Srv), is_list(User) -> +acct_mgmt(Srv, User) + when is_binary(Srv), is_binary(User) -> gen_server:call(?PROCNAME, {acct_mgmt, Srv, User}). %%==================================================================== %% gen_server callbacks %%==================================================================== init([]) -> - FileName = filename:join(ejabberd:get_bin_path(), "epam"), + FileName = filename:join(ejabberd:get_bin_path(), + "epam"), case file:read_file_info(FileName) of - {ok, Info} -> - Mode = Info#file_info.mode band 16#801, - if Mode == 16#801 -> - ?WARNING_MSG(?WARNING, [FileName]); - true -> ok - end, - Port = open_port({spawn, FileName}, [{packet, 2}, binary, exit_status]), - {ok, #state{port = Port}}; - {error, Reason} -> - ?ERROR_MSG("Can't open file ~p: ~p", [FileName, Reason]), - error + {ok, Info} -> + Mode = Info#file_info.mode band 2049, + if Mode == 2049 -> ?WARNING_MSG((?WARNING), [FileName]); + true -> ok + end, + Port = open_port({spawn, FileName}, + [{packet, 2}, binary, exit_status]), + {ok, #state{port = Port}}; + {error, Reason} -> + ?ERROR_MSG("Can't open file ~p: ~p", + [FileName, Reason]), + error end. terminate(_Reason, #state{port = Port}) -> - catch port_close(Port), - ok. + catch port_close(Port), ok. -handle_call({authenticate, Srv, User, Pass}, From, State) -> +handle_call({authenticate, Srv, User, Pass}, From, + State) -> Port = State#state.port, - Data = term_to_binary({?CMD_AUTH, From, {Srv, User, Pass}}), + Data = term_to_binary({?CMD_AUTH, From, + {Srv, User, Pass}}), port_command(Port, Data), {noreply, State}; handle_call({acct_mgmt, Srv, User}, From, State) -> @@ -113,24 +126,23 @@ handle_call(stop, _From, State) -> handle_call(_Request, _From, State) -> {reply, bad_request, State}. -handle_info({Port, {data, Data}}, #state{port=Port} = State) -> +handle_info({Port, {data, Data}}, + #state{port = Port} = State) -> case binary_to_term(Data) of - {Cmd, To, Reply} when Cmd==?CMD_AUTH; Cmd==?CMD_ACCT -> - gen_server:reply(To, Reply); - Err -> - ?ERROR_MSG("Got invalid reply from ~p: ~p", [Port, Err]) + {Cmd, To, Reply} + when Cmd == (?CMD_AUTH); Cmd == (?CMD_ACCT) -> + gen_server:reply(To, Reply); + Err -> + ?ERROR_MSG("Got invalid reply from ~p: ~p", [Port, Err]) end, {noreply, State}; -handle_info({Port, {exit_status, _}}, #state{port=Port} = State) -> - %% We can restart the port here, but, I think, it is not a good idea, - %% since we can run into infinity loop. So let the supervisor restart us. +handle_info({Port, {exit_status, _}}, + #state{port = Port} = State) -> {stop, port_died, State}; handle_info(Msg, State) -> ?WARNING_MSG("Got unexpected message: ~p", [Msg]), {noreply, State}. -handle_cast(_Msg, State) -> - {noreply, State}. +handle_cast(_Msg, State) -> {noreply, State}. -code_change(_OldVsn, State, _Extra) -> - {ok, State}. +code_change(_OldVsn, State, _Extra) -> {ok, State}. |