pam_userpass-1.0.2/000075500000000000000000000000001210013403300141755ustar00rootroot00000000000000pam_userpass-1.0.2/LICENSE000064400000000000000000000007531210013403300152070ustar00rootroot00000000000000You're allowed to do whatever you like with this software (including re-distribution in source and/or binary form, with or without modification), provided that credit is given where it is due and any modified versions are marked as such. There's absolutely no warranty. Note that you don't have to re-distribute this software under these same relaxed terms. In particular, you're free to place modified versions under (L)GPL, thus disallowing further re-distribution in binary-only form. pam_userpass-1.0.2/Makefile000064400000000000000000000047461210013403300156500ustar00rootroot00000000000000CC = gcc LD = $(CC) AR = ar RM = rm -f MKDIR = mkdir -p INSTALL = install -c LN_S = ln -sf ifndef CFLAGS CFLAGS = -Wall -O2 -fPIC endif CFLAGS += -Iinclude LDFLAGS = -s ARFLAGS = rv LIBS = -lpam LINK = $(LD) $(LDFLAGS) LINK_SHARED = $(LINK) -shared TITLE = pam_userpass LIBPAMSHARED = $(TITLE).so SONAME = lib$(TITLE).so.1 LIBAPPLSHARED = lib$(TITLE).so.1.0 LIBAPPLSHARED_LINK = lib$(TITLE).so LIBAPPLSTATIC = lib$(TITLE).a PAM_MAP = pam_userpass.map APPL_MAP = libpam_userpass.map SHLIBMODE = 755 STLIBMODE = 644 INCLUDEMODE = 644 SECUREDIR = /lib/security LIBDIR = /usr/lib INCLUDEDIR = /usr/include/security PAMDIR = /etc/pam.d DESTDIR = .SUFFIXES: .c .o .c.o: $(CC) $(CFLAGS) -c $*.c all: $(LIBPAMSHARED) $(LIBAPPLSTATIC) example_userpass $(LIBPAMSHARED): pam_userpass.o $(PAM_MAP) $(LINK_SHARED) -Wl,--version-script,$(PAM_MAP) $< $(LIBS) -o $@ $(LIBAPPLSHARED): appl_userpass.o $(APPL_MAP) $(LINK_SHARED) -Wl,--version-script,$(APPL_MAP),-soname,$(SONAME) \ $< $(LIBS) -o $@ $(LIBAPPLSTATIC): appl_userpass.o $(AR) $(ARFLAGS) $@ $< $(SONAME): $(LIBAPPLSHARED) $(LN_S) $(LIBAPPLSHARED) $(SONAME) $(LIBAPPLSHARED_LINK): $(LIBAPPLSHARED) $(LN_S) $(LIBAPPLSHARED) $(LIBAPPLSHARED_LINK) pam_userpass.o: pam_userpass.c include/security/_pam_userpass.h appl_userpass.o: appl_userpass.c include/security/_pam_userpass.h \ include/security/pam_userpass.h example_userpass: example_userpass.o $(LIBAPPLSHARED_LINK) $(LINK) $< $(LIBS) -L. -l$(TITLE) -o $@ install: all $(MKDIR) $(DESTDIR)$(SECUREDIR) $(INSTALL) -m $(SHLIBMODE) $(LIBPAMSHARED) $(DESTDIR)$(SECUREDIR)/ $(MKDIR) $(DESTDIR)$(LIBDIR) $(INSTALL) -m $(SHLIBMODE) $(LIBAPPLSHARED) $(DESTDIR)$(LIBDIR)/ $(INSTALL) -m $(STLIBMODE) $(LIBAPPLSTATIC) $(DESTDIR)$(LIBDIR)/ $(LN_S) $(LIBAPPLSHARED) $(DESTDIR)$(LIBDIR)/$(SONAME) $(LN_S) $(LIBAPPLSHARED) $(DESTDIR)$(LIBDIR)/$(LIBAPPLSHARED_LINK) $(MKDIR) $(DESTDIR)$(INCLUDEDIR) $(INSTALL) -m $(INCLUDEMODE) include/security/pam_userpass.h \ $(DESTDIR)$(INCLUDEDIR)/ check: install $(MKDIR) $(DESTDIR)$(PAMDIR) $(INSTALL) -m 644 conf/example_userpass $(DESTDIR)$(PAMDIR)/ LD_LIBRARY_PATH=$(DESTDIR)$(LIBDIR) ./example_userpass "`head -1`" "`head -1`" remove: $(RM) $(DESTDIR)$(SECUREDIR)/$(LIBPAMSHARED) \ $(DESTDIR)$(LIBDIR)/$(LIBAPPLSHARED) \ $(DESTDIR)$(LIBDIR)/$(SONAME) \ $(DESTDIR)$(LIBDIR)/$(LIBAPPLSHARED_LINK) \ $(DESTDIR)$(LIBDIR)/$(LIBAPPLSTATIC) \ $(DESTDIR)$(INCLUDEDIR)/pam_userpass.h \ $(DESTDIR)$(PAMDIR)/example_userpass clean: $(RM) example_userpass *.o *.so* *.a pam_userpass-1.0.2/README000064400000000000000000000015001210013403300150510ustar00rootroot00000000000000PAM has traditionally assumed that services doing authentication have the ability to interact with the user. Unfortunately, this isn't true for services that implement non-interactive and/or fixed protocols, such as FTP and POP3. This is typically worked around by making the flawed assumption that PAM_PROMPT_ECHO_ON requests the username and PAM_PROMPT_ECHO_OFF requests the password. With pam_userpass, this assumption is no longer required. pam_userpass uses PAM binary prompts (only available in Linux-PAM) to ask the application for the username and password specifically. pam_userpass doesn't perform any actual authentication. An actual authentication module should be stacked after pam_userpass and told to use the authentication token (password) provided by pam_userpass. -- Solar Designer pam_userpass-1.0.2/appl_userpass.c000064400000000000000000000030211210013403300172160ustar00rootroot00000000000000#include #include #include #include #ifndef PAM_BP_RCONTROL /* Linux-PAM prior to 0.74 */ #define PAM_BP_RCONTROL PAM_BP_CONTROL #define PAM_BP_WDATA PAM_BP_DATA #define PAM_BP_RDATA PAM_BP_DATA #endif #include #include int pam_userpass_conv(int num_msg, const struct pam_message **msg, struct pam_response **resp, void *appdata_ptr) { pam_userpass_t *userpass = (pam_userpass_t *)appdata_ptr; pamc_bp_t prompt; const char *input; char *output; char flags; if (num_msg != 1 || msg[0]->msg_style != PAM_BINARY_PROMPT) return PAM_CONV_ERR; prompt = (pamc_bp_t)msg[0]->msg; input = (const char *)PAM_BP_RDATA(prompt); if (PAM_BP_RCONTROL(prompt) != PAM_BPC_SELECT || strncmp(input, USERPASS_AGENT_ID "/", USERPASS_AGENT_ID_LENGTH + 1)) return PAM_CONV_ERR; flags = input[USERPASS_AGENT_ID_LENGTH + 1]; input += USERPASS_AGENT_ID_LENGTH + 1 + 1; if ((flags & USERPASS_USER_MASK) == USERPASS_USER_FIXED && strcmp(input, userpass->user)) return PAM_CONV_AGAIN; if (!(*resp = malloc(sizeof(struct pam_response)))) return PAM_CONV_ERR; prompt = NULL; PAM_BP_RENEW(&prompt, PAM_BPC_DONE, strlen(userpass->user) + 1 + strlen(userpass->pass)); output = (char *)PAM_BP_WDATA(prompt); strcpy(output, userpass->user); output += strlen(output) + 1; memcpy(output, userpass->pass, strlen(userpass->pass)); (*resp)[0].resp_retcode = 0; (*resp)[0].resp = (char *)prompt; return PAM_SUCCESS; } pam_userpass-1.0.2/conf/000075500000000000000000000000001210013403300151225ustar00rootroot00000000000000pam_userpass-1.0.2/conf/example_userpass000064400000000000000000000002561210013403300204300ustar00rootroot00000000000000#%PAM-1.0 auth required /lib/security/pam_userpass.so auth required /lib/security/pam_unix.so shadow use_first_pass account required /lib/security/pam_unix.so pam_userpass-1.0.2/example_userpass.c000064400000000000000000000023071210013403300177230ustar00rootroot00000000000000#include #include #include #define SERVICE "example_userpass" static char *auth_pam_userpass(const char *user, const char *pass) { pam_handle_t *pamh; pam_userpass_t userpass; struct pam_conv conv = {pam_userpass_conv, &userpass}; const void *item; const char *template; char *retval; int status; userpass.user = user; userpass.pass = pass; if (pam_start(SERVICE, user, &conv, &pamh) != PAM_SUCCESS) return NULL; if ((status = pam_authenticate(pamh, 0)) != PAM_SUCCESS) { pam_end(pamh, status); return NULL; } if ((status = pam_acct_mgmt(pamh, 0)) != PAM_SUCCESS) { pam_end(pamh, status); return NULL; } status = pam_get_item(pamh, PAM_USER, &item); if (status != PAM_SUCCESS) { pam_end(pamh, status); return NULL; } template = item; retval = strdup(template); if (pam_end(pamh, PAM_SUCCESS) != PAM_SUCCESS) return NULL; return retval; } int main(int argc, char **argv) { char *user; if (argc != 3) { printf("Usage: %s USER PASS\n", argv[0] ? argv[0] : "example_userpass"); return 0; } user = auth_pam_userpass(argv[1], argv[2]); printf(user ? "User \"%s\"\n" : "Authentication failed\n", user); return 0; } pam_userpass-1.0.2/include/000075500000000000000000000000001210013403300156205ustar00rootroot00000000000000pam_userpass-1.0.2/include/security/000075500000000000000000000000001210013403300174675ustar00rootroot00000000000000pam_userpass-1.0.2/include/security/_pam_userpass.h000064400000000000000000000004061210013403300225010ustar00rootroot00000000000000#ifndef __PAM_USERPASS_H #define __PAM_USERPASS_H #define USERPASS_AGENT_ID "userpass" #define USERPASS_AGENT_ID_LENGTH 8 #define USERPASS_USER_MASK 0x03 #define USERPASS_USER_REQUIRED 1 #define USERPASS_USER_KNOWN 2 #define USERPASS_USER_FIXED 3 #endif pam_userpass-1.0.2/include/security/pam_userpass.h000064400000000000000000000004361210013403300223450ustar00rootroot00000000000000#ifndef _PAM_USERPASS_H #define _PAM_USERPASS_H #include typedef struct { const char *user; const char *pass; } pam_userpass_t; extern int pam_userpass_conv(int num_msg, const struct pam_message **msg, struct pam_response **resp, void *appdata_ptr); #endif pam_userpass-1.0.2/libpam_userpass.map000064400000000000000000000000771210013403300200710ustar00rootroot00000000000000# $Owl$ { global: pam_userpass_conv; local: *; }; pam_userpass-1.0.2/pam_userpass.c000064400000000000000000000055061210013403300170510ustar00rootroot00000000000000#include #include #define PAM_SM_AUTH #include #include #ifndef PAM_BP_RCONTROL /* Linux-PAM prior to 0.74 */ #define PAM_BP_RCONTROL PAM_BP_CONTROL #define PAM_BP_WDATA PAM_BP_DATA #define PAM_BP_RDATA PAM_BP_DATA #endif #include PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv) { const void *item; const struct pam_conv *conv; pamc_bp_t prompt; struct pam_message msg, *pmsg; struct pam_response *resp; const char *user; const char *input; char *output; int status; status = pam_get_item(pamh, PAM_CONV, &item); if (status != PAM_SUCCESS) return status; conv = item; status = pam_get_item(pamh, PAM_USER, &item); if (status != PAM_SUCCESS) return status; user = item; prompt = NULL; PAM_BP_RENEW(&prompt, PAM_BPC_SELECT, USERPASS_AGENT_ID_LENGTH + 1 + 1 + (user ? strlen(user) : 0)); output = (char *)PAM_BP_WDATA(prompt); memcpy(output, USERPASS_AGENT_ID "/", USERPASS_AGENT_ID_LENGTH + 1); output += USERPASS_AGENT_ID_LENGTH + 1; if (user && *user) { *output++ = USERPASS_USER_KNOWN; memcpy(output, user, strlen(user)); } else *output = USERPASS_USER_REQUIRED; pmsg = &msg; msg.msg_style = PAM_BINARY_PROMPT; msg.msg = (const char *)prompt; resp = NULL; status = conv->conv(1, (const struct pam_message **)&pmsg, &resp, conv->appdata_ptr); PAM_BP_RENEW(&prompt, 0, 0); if (status != PAM_SUCCESS) return status; if (!resp) return PAM_AUTH_ERR; prompt = (pamc_bp_t)resp->resp; input = (const char *)PAM_BP_RDATA(prompt); if (PAM_BP_RCONTROL(prompt) == PAM_BPC_DONE && strlen(input) + 1 <= PAM_BP_LENGTH(prompt)) { status = pam_set_item(pamh, PAM_USER, input); if (status == PAM_SUCCESS) { input += strlen(input) + 1; /* "Note, all non-NULL binary prompts ... are * terminated with a '\0', even when the full * length of the prompt ... does not contain this * delimiter. This is a defined property of the * PAM_BP_RENEW macro, and can be relied upon." */ status = pam_set_item(pamh, PAM_AUTHTOK, input); } } else status = PAM_AUTH_ERR; PAM_BP_RENEW(&prompt, 0, 0); free(resp); return status; } PAM_EXTERN int pam_sm_setcred(pam_handle_t *pamh, int flags, int argc, const char **argv) { return PAM_SUCCESS; } #ifdef PAM_STATIC #define pam_sm_chauthtok pam_sm_authenticate #elif defined(__linux__) && defined(__ELF__) __asm__(".globl pam_sm_chauthtok; pam_sm_chauthtok = pam_sm_authenticate"); #else PAM_EXTERN int pam_sm_chauthtok(pam_handle_t *pamh, int flags, int argc, const char **argv) { return pam_sm_authenticate(pamh, flags, argc, argv); } #endif #ifdef PAM_STATIC struct pam_module _pam_userpass_modstruct = { "pam_userpass", pam_sm_authenticate, pam_sm_setcred, NULL, NULL, NULL, pam_sm_chauthtok }; #endif pam_userpass-1.0.2/pam_userpass.map000064400000000000000000000002641210013403300174000ustar00rootroot00000000000000# $Owl$ { global: pam_sm_acct_mgmt; pam_sm_authenticate; pam_sm_chauthtok; pam_sm_close_session; pam_sm_open_session; pam_sm_setcred; local: *; }; pam_userpass-1.0.2/pam_userpass.spec000064400000000000000000000064611210013403300175620ustar00rootroot00000000000000# $Owl$ Summary: Pluggable authentication module for USER/PASS-style protocols. Name: pam_userpass Version: 1.0.2 Release: owl1 License: relaxed BSD and (L)GPL-compatible Group: System Environment/Base URL: http://www.openwall.com/pam/ Source: ftp://ftp.openwall.com/pub/projects/pam/modules/%name/%name-%version.tar.gz BuildRequires: pam-devel BuildRoot: /override/%name-%version %description pam_userpass is a PAM authentication module for use specifically by services implementing non-interactive protocols and wishing to verify a username/password pair. This module doesn't do any actual authentication, -- other modules, such as pam_tcb, should be stacked after it to provide the authentication. %package devel Summary: Libraries and header files for developing pam_userpass-aware applications. Group: Development/Libraries Requires: %name = %version-%release, pam-devel %description devel This package contains development libraries and header files required for building pam_userpass-aware applications. %prep %setup -q %build CFLAGS="-Wall -fPIC %optflags" make %install rm -rf %buildroot make install DESTDIR=%buildroot SECUREDIR=/%_lib/security LIBDIR=%_libdir %post -p /sbin/ldconfig %postun -p /sbin/ldconfig %files %defattr(-,root,root) %doc LICENSE README /%_lib/security/pam_userpass.so %_libdir/*.so.* %files devel %defattr(-,root,root) %_libdir/*.so %_libdir/*.a %_includedir/security/* %changelog * Sun May 21 2006 Dmitry V. Levin 1.0.2-owl1 - Deal with compilation warnings generated by new gcc compiler. * Tue Apr 04 2006 Dmitry V. Levin 1.0.1-owl1 - Restricted list of global symbols exported by the PAM module to standard set of six pam_sm_* functions. - Changed Makefile to pass list of libraries to linker after regular object files, to fix build with -Wl,--as-needed. - Corrected specfile to make it build on x86_64. * Fri Mar 25 2005 Solar Designer 1.0-owl1 - Corrected the source code to not break C strict aliasing rules. * Sun Nov 02 2003 Solar Designer 0.9.1-owl1 - Use "install -c" (makes a difference on some non-Linux systems). - Moved the "-c" out of CFLAGS. * Wed Apr 02 2003 Dmitry V. Levin 0.9-owl1 - Added libpam_userpass library, in shared and static forms. - Packaged development libraries and header files in separate subpackage, pam_userpass-devel. * Tue Apr 02 2002 Solar Designer - 0.5.1: use const within the declaration of pam_userpass_t, use '=' instead of '.set' to declare the alias. * Thu Feb 07 2002 Michail Litvak - Enforce our new spec file conventions. * Fri Nov 09 2001 Solar Designer - 0.5: provide a pam_sm_chauthtok as well, currently only supporting password changes which don't require the old password to be passed. * Thu Jun 14 2001 Solar Designer - 0.4: deal with null passwords correctly (thanks to Rafal Wojtczuk ), support Linux-PAM 0.74+'s new BP macros. * Tue Dec 19 2000 Solar Designer - Added "-Wall -fPIC" to the CFLAGS. * Fri Aug 18 2000 Solar Designer - 0.3, added README. * Sun Jul 09 2000 Solar Designer - Initial version.