aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.travis.yml5
-rw-r--r--auth.c10
-rw-r--r--auth_pam.c62
-rw-r--r--bitlbee.conf5
-rw-r--r--conf.c3
-rwxr-xr-xconfigure15
-rw-r--r--tests/Makefile2
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
diff --git a/auth.c b/auth.c
index e83a683f..9717acc1 100644
--- a/auth.c
+++ b/auth.c
@@ -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
#
diff --git a/conf.c b/conf.c
index 24e71b91..403f417a 100644
--- a/conf.c
+++ b/conf.c
@@ -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;
diff --git a/configure b/configure
index 8089d1a2..4c08b034 100755
--- a/configure
+++ b/configure
@@ -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