diff options
Diffstat (limited to 'src/pam')
-rw-r--r-- | src/pam/Makefile.in | 47 | ||||
-rw-r--r-- | src/pam/epam.c | 270 | ||||
-rw-r--r-- | src/pam/epam.erl | 148 |
3 files changed, 0 insertions, 465 deletions
diff --git a/src/pam/Makefile.in b/src/pam/Makefile.in deleted file mode 100644 index bde289402..000000000 --- a/src/pam/Makefile.in +++ /dev/null @@ -1,47 +0,0 @@ -# $Id: Makefile.in 775 2007-05-29 14:31:12Z mremond $ - -CC = @CC@ -CFLAGS = @CFLAGS@ @PAM_CFLAGS@ -CPPFLAGS = @CPPFLAGS@ -LDFLAGS = @LDFLAGS@ -LIBS = @LIBS@ @PAM_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 - -ERLSHLIBS = ../epam -OUTDIR = .. -SOURCES = $(wildcard *.erl) -BEAMS = $(addprefix $(OUTDIR)/,$(SOURCES:.erl=.beam)) - - -all: $(BEAMS) $(ERLSHLIBS) - -$(OUTDIR)/%.beam: %.erl - @ERLC@ -W $(EFLAGS) -o $(OUTDIR) $< - -#all: $(ERLSHLIBS) -# erl -s make all report "{outdir, \"..\"}" -noinput -s erlang halt - -$(ERLSHLIBS): ../%: %.c - $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) \ - $(subst ../,,$(subst ,.c,$@)) $(LIBS) \ - $(ERLANG_LIBS) $(ERLANG_CFLAGS) \ - -o $@ -lpthread - -clean: - rm -f $(BEAMS) $(ERLSHLIBS) - -distclean: clean - rm -f Makefile - -TAGS: - etags *.erl diff --git a/src/pam/epam.c b/src/pam/epam.c deleted file mode 100644 index bbb0fa482..000000000 --- a/src/pam/epam.c +++ /dev/null @@ -1,270 +0,0 @@ -/* - * 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 - * - */ - -#include <security/pam_appl.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <erl_interface.h> -#include <ei.h> -#include <unistd.h> - -#define dec_int16(s) ((((unsigned char*) (s))[0] << 8) | \ - (((unsigned char*) (s))[1])) - -#define enc_int16(i, s) {((unsigned char*)(s))[0] = ((i) >> 8) & 0xff; \ - ((unsigned char*)(s))[1] = (i) & 0xff;} - -#define BUFSIZE (1 << 16) -#define CMD_AUTH 0 -#define CMD_ACCT 1 - -typedef unsigned char byte; - -#ifdef PAM_FAIL_DELAY -static void delay_fn(int retval, unsigned usec_delay, void *appdata_ptr) -{ - /* No delay. However, looks like some PAM modules ignore this */ -} -#endif - -static int misc_conv(int num_msg, - const struct pam_message **msg, - struct pam_response **resp, - void *password) -{ - int msg_style; - if (num_msg != 1) - return PAM_CONV_ERR; - msg_style = msg[0]->msg_style; - if ((msg_style != PAM_PROMPT_ECHO_OFF) && (msg_style != PAM_PROMPT_ECHO_ON)) - return PAM_CONV_ERR; - *resp = malloc(sizeof(struct pam_response)); - (*resp)[0].resp_retcode = 0; - (*resp)[0].resp = strdup(password); - return PAM_SUCCESS; -} - -static int auth(char *service, char *user, char *password) -{ - struct pam_conv conv = {misc_conv, password}; - int retval; - pam_handle_t *pamh = NULL; - retval = pam_start(service, user, &conv, &pamh); - if (retval == PAM_SUCCESS) - retval = pam_set_item(pamh, PAM_RUSER, user); -#ifdef PAM_FAIL_DELAY - if (retval == PAM_SUCCESS) - retval = pam_set_item(pamh, PAM_FAIL_DELAY, (void *)delay_fn); -#endif - if (retval == PAM_SUCCESS) - retval = pam_authenticate(pamh, 0); - if (retval == PAM_SUCCESS) - retval = pam_acct_mgmt(pamh, 0); - pam_end(pamh, retval); - return retval; -} - -static int acct_mgmt(char *service, char *user) -{ - struct pam_conv conv = {misc_conv, NULL}; - int retval; - pam_handle_t *pamh = NULL; - retval = pam_start(service, user, &conv, &pamh); - if (retval == PAM_SUCCESS) - retval = pam_set_item(pamh, PAM_RUSER, user); -#ifdef PAM_FAIL_DELAY - if (retval == PAM_SUCCESS) - retval = pam_set_item(pamh, PAM_FAIL_DELAY, (void *)delay_fn); -#endif - if (retval == PAM_SUCCESS) - retval = pam_acct_mgmt(pamh, 0); - pam_end(pamh, retval); - return retval; -} - -static int read_buf(int fd, byte *buf, int len) -{ - int i, got = 0; - do { - if ((i = read(fd, buf+got, len-got)) <= 0) { - if (i == 0) return got; - if (errno != EINTR) - return got; - i = 0; - } - got += i; - } while (got < len); - return (len); -} - -static int read_cmd(byte *buf) -{ - int len; - if (read_buf(0, buf, 2) != 2) - return 0; - len = dec_int16(buf); - if (read_buf(0, buf, len) != len) - return 0; - return 1; -} - -static int write_buf(int fd, char *buf, int len) -{ - int i, done = 0; - do { - if ((i = write(fd, buf+done, len-done)) < 0) { - if (errno != EINTR) - return (i); - i = 0; - } - done += i; - } while (done < len); - return (len); -} - -static int write_cmd(char *buf, int len) -{ - byte hd[2]; - enc_int16(len, hd); - if (write_buf(1, (char *)hd, 2) != 2) - return 0; - if (write_buf(1, buf, len) != len) - return 0; - return 1; -} - -static int process_reply(ETERM *pid, int cmd, int res) -{ - ETERM *result; - int len, retval; - const char *errtxt; - byte *buf; - if (res == PAM_SUCCESS) - result = erl_format("{~i, ~w, true}", cmd, pid); - else - { - errtxt = pam_strerror(NULL, res); - result = erl_format("{~i, ~w, {false, ~s}}", cmd, pid, errtxt); - } - len = erl_term_len(result); - buf = erl_malloc(len); - erl_encode(result, buf); - retval = write_cmd((char *)buf, len); - erl_free_term(result); - erl_free(buf); - return retval; -} - -static int process_acct(ETERM *pid, ETERM *data) -{ - int retval = 0; - ETERM *pattern, *srv, *user; - char *service, *username; - pattern = erl_format("{Srv, User}"); - if (erl_match(pattern, data)) - { - srv = erl_var_content(pattern, "Srv"); - service = erl_iolist_to_string(srv); - user = erl_var_content(pattern, "User"); - username = erl_iolist_to_string(user); - retval = process_reply(pid, CMD_ACCT, acct_mgmt(service, username)); - erl_free_term(srv); - erl_free_term(user); - erl_free(service); - erl_free(username); - } - erl_free_term(pattern); - return retval; -} - -static int process_auth(ETERM *pid, ETERM *data) -{ - int retval = 0; - ETERM *pattern, *srv, *user, *pass; - char *service, *username, *password; - pattern = erl_format("{Srv, User, Pass}"); - if (erl_match(pattern, data)) - { - srv = erl_var_content(pattern, "Srv"); - service = erl_iolist_to_string(srv); - user = erl_var_content(pattern, "User"); - username = erl_iolist_to_string(user); - pass = erl_var_content(pattern, "Pass"); - password = erl_iolist_to_string(pass); - retval = process_reply(pid, CMD_AUTH, auth(service, username, password)); - erl_free_term(srv); - erl_free_term(user); - erl_free_term(pass); - erl_free(service); - erl_free(username); - erl_free(password); - }; - erl_free_term(pattern); - return retval; -} - -static int process_command(byte *buf) -{ - int retval = 0; - ETERM *pattern, *tuple, *cmd, *port, *data; - pattern = erl_format("{Cmd, Port, Data}"); - tuple = erl_decode(buf); - if (erl_match(pattern, tuple)) - { - cmd = erl_var_content(pattern, "Cmd"); - port = erl_var_content(pattern, "Port"); - data = erl_var_content(pattern, "Data"); - switch (ERL_INT_VALUE(cmd)) - { - case CMD_AUTH: - retval = process_auth(port, data); - break; - case CMD_ACCT: - retval = process_acct(port, data); - break; - }; - erl_free_term(cmd); - erl_free_term(port); - erl_free_term(data); - } - erl_free_term(pattern); - erl_free_term(tuple); - return retval; -} - -static void loop(void) -{ - byte buf[BUFSIZE]; - int retval = 0; - do { - if (read_cmd(buf) > 0) - retval = process_command(buf); - else - retval = 0; - } while (retval); -} - -int main(int argc, char *argv[]) -{ - erl_init(NULL, 0); - loop(); - return 0; -} diff --git a/src/pam/epam.erl b/src/pam/epam.erl deleted file mode 100644 index e0ea1719a..000000000 --- a/src/pam/epam.erl +++ /dev/null @@ -1,148 +0,0 @@ -%%%------------------------------------------------------------------- -%%% File : epam.erl -%%% Author : Evgeniy Khramtsov <xram@jabber.ru> -%%% Purpose : PAM authentication and accounting management -%%% Created : 5 Jul 2007 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(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]). - --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]}, - supervisor:start_child(ejabberd_sup, ChildSpec). - -stop() -> - gen_server:call(?PROCNAME, stop), - supervisor:terminate_child(ejabberd_sup, ?PROCNAME), - supervisor:delete_child(ejabberd_sup, ?PROCNAME). - -start_link() -> - gen_server:start_link({local, ?PROCNAME}, ?MODULE, [], - []). - -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_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"), - case file:read_file_info(FileName) of - {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. - -handle_call({authenticate, Srv, User, Pass}, From, - State) -> - Port = State#state.port, - Data = term_to_binary({?CMD_AUTH, From, - {Srv, User, Pass}}), - port_command(Port, Data), - {noreply, State}; -handle_call({acct_mgmt, Srv, User}, From, State) -> - Port = State#state.port, - Data = term_to_binary({?CMD_ACCT, From, {Srv, User}}), - port_command(Port, Data), - {noreply, State}; -handle_call(stop, _From, State) -> - {stop, normal, ok, State}; -handle_call(_Request, _From, State) -> - {reply, bad_request, 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]) - end, - {noreply, State}; -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}. - -code_change(_OldVsn, State, _Extra) -> {ok, State}. |