diff options
| -rw-r--r-- | .travis.yml | 5 | ||||
| -rw-r--r-- | auth.c | 10 | ||||
| -rw-r--r-- | auth_pam.c | 62 | ||||
| -rw-r--r-- | bitlbee.conf | 5 | ||||
| -rw-r--r-- | conf.c | 3 | ||||
| -rwxr-xr-x | configure | 15 | ||||
| -rw-r--r-- | tests/Makefile | 2 | 
7 files changed, 99 insertions, 3 deletions
| diff --git a/.travis.yml b/.travis.yml index 6a0da07f..992ede90 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,7 +2,7 @@ sudo: false  language: c  script: - - ./configure + - ./configure --pam=1   - make check   - BITLBEE_SKYPE=plugin dpkg-buildpackage -uc -us -d @@ -28,12 +28,13 @@ addons:      - libevent-dev      - libpurple-dev      - check +    - libpam0g-dev    coverity_scan:      project:        name: "bitlbee/bitlbee"        description: "An IRC to other chat networks gateway"      notification_email: dx@dxzone.com.ar -    build_command_prepend: ./configure --otr=1 --debug=1 +    build_command_prepend: ./configure --otr=1 --debug=1 --pam=1      build_command: make      branch_pattern: coverity_scan @@ -1,10 +1,20 @@  #define BITLBEE_CORE  #include "bitlbee.h" +#ifdef WITH_PAM +extern auth_backend_t auth_pam; +#endif +  GList *auth_init(const char *backend)  {  	GList *gl = NULL;  	int ok = backend ? 0 : 1; +#ifdef WITH_PAM +	gl = g_list_append(gl, &auth_pam); +	if (backend && !strcmp(backend, "pam")) { +		ok = 1; +	} +#endif  	return ok ? gl : NULL;  } diff --git a/auth_pam.c b/auth_pam.c new file mode 100644 index 00000000..1a8f4344 --- /dev/null +++ b/auth_pam.c @@ -0,0 +1,62 @@ +#define BITLBEE_CORE +#include "bitlbee.h" +#include <security/pam_appl.h> + +#define PAM_CHECK(x) do { \ +	ret = (x); \ +	if(ret != PAM_SUCCESS) { \ +		pam_func = #x; \ +		goto pam_error; \ +	} \ +} while(0) + +/* This function fills in the password when PAM asks for it */ +int pamconv(int num_msg, const struct pam_message **msg, struct pam_response **resp, void *appdata_ptr) { +	int i; +	struct pam_response *rsp = g_new0(struct pam_response, num_msg); + +	for (i = 0; i < num_msg; i++) { +		rsp[i].resp = NULL; +		rsp[i].resp_retcode = 0; +		if (msg[i]->msg_style == PAM_PROMPT_ECHO_OFF) { +			rsp[i].resp = g_strdup((char *)appdata_ptr); +		} +	} +	*resp = rsp; +	return PAM_SUCCESS; +} + +static storage_status_t pam_check_pass(const char *nick, const char *password) +{ +	int ret; +	const struct pam_conv pamc = { pamconv, (void*) password }; +	pam_handle_t *pamh = NULL; +	char *pam_func; + +	PAM_CHECK(pam_start("bitlbee", nick, &pamc, &pamh)); +	PAM_CHECK(pam_authenticate(pamh, PAM_DISALLOW_NULL_AUTHTOK)); +	PAM_CHECK(pam_acct_mgmt(pamh, 0)); + +	pam_end(pamh, ret); +	return STORAGE_OK; + +pam_error: +	switch (ret) { +		case PAM_AUTH_ERR: +			pam_end(pamh, ret); +			return STORAGE_INVALID_PASSWORD; +		case PAM_USER_UNKNOWN: +		case PAM_PERM_DENIED: +			pam_end(pamh, ret); +			return STORAGE_NO_SUCH_USER; +		default: +			log_message(LOGLVL_WARNING, "%s failed: %s", pam_func, pam_strerror(pamh, ret)); +			pam_end(pamh, ret); +			return STORAGE_OTHER_ERROR; +	} +} + +auth_backend_t auth_pam = { +	.name = "pam", +	.check_pass = pam_check_pass, +}; diff --git a/bitlbee.conf b/bitlbee.conf index 60c5bdf7..d781a7b1 100644 --- a/bitlbee.conf +++ b/bitlbee.conf @@ -60,6 +60,11 @@  ## Beware that this disables password changes and causes passwords for the  ## accounts people create to be stored in plain text instead of encrypted with  ## their bitlbee password. +## +## Currently available backends: +## +## - storage (internal storage) +## - pam (Linux PAM authentication)  #  # AuthBackend = storage  # @@ -244,6 +244,9 @@ static int conf_loadini(conf_t *conf, char *file)  			} else if (g_strcasecmp(ini->key, "authbackend") == 0) {  				if (g_strcasecmp(ini->value, "storage") == 0) {  					conf->auth_backend = NULL; +				} else if (g_strcasecmp(ini->value, "pam") == 0) { +					g_free(conf->auth_backend); +					conf->auth_backend = g_strdup(ini->value);  				} else {  					fprintf(stderr, "Invalid %s value: %s\n", ini->key, ini->value);  					return 0; @@ -51,6 +51,8 @@ skype=0  events=glib  ssl=auto +pam=0 +  pie=1  arch=$(uname -s) @@ -133,6 +135,8 @@ Option		Description				Default  --purple=0/1	Disable/enable libpurple support	$purple  		(automatically disables other protocol modules) +--pam=0/1	Disable/enable PAM authentication	$pam +  --doc=0/1	Disable/enable help.txt generation	$doc  --debug=0/1	Disable/enable debugging		$debug  --strip=0/1	Disable/enable binary stripping		$strip @@ -630,6 +634,17 @@ echo "STORAGE_OBJS="$STORAGE_OBJS >> Makefile.settings  authobjs=  authlibs= +if [ "$pam" = 0 ]; then +	echo '#undef WITH_PAM' >> config.h +else +	if ! echo '#include <security/pam_appl.h>' | $CC -E - >/dev/null 2>/dev/null; then +		echo 'Cannot find libpam development libraries, aborting. (Install libpam0g-dev?)' +		exit 1 +	fi +	echo '#define WITH_PAM' >> config.h +	authobjs=$authobjs'auth_pam.o ' +	authlibs=$authlibs'-lpam ' +fi  echo AUTH_OBJS=$authobjs >> Makefile.settings  echo EFLAGS+=$authlibs >> Makefile.settings diff --git a/tests/Makefile b/tests/Makefile index 02cac9eb..77ed2273 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -14,7 +14,7 @@ clean:  distclean: clean -main_objs = bitlbee.o conf.o dcc.o help.o ipc.o irc.o irc_cap.o irc_channel.o irc_commands.o irc_im.o irc_send.o irc_user.o irc_util.o irc_commands.o log.o nick.o query.o root_commands.o set.o storage.o storage_xml.o auth.o +main_objs = bitlbee.o conf.o dcc.o help.o ipc.o irc.o irc_cap.o irc_channel.o irc_commands.o irc_im.o irc_send.o irc_user.o irc_util.o irc_commands.o log.o nick.o query.o root_commands.o set.o storage.o storage_xml.o auth.o auth_pam.o  test_objs = check.o check_util.o check_nick.o check_md5.o check_arc.o check_irc.o check_help.o check_user.o check_set.o check_jabber_sasl.o check_jabber_util.o | 
