--- pam_skey-1.1.5/INSTALL +++ pam_skey/INSTALL @@ -1,5 +1,39 @@ $Id$ +Gentoo patch +------------ +Most everything below still holds, though the libraries required are now +those used by Gentoo. Other S/Key libraries may work with a bit of +tweaking. + +The options listed for the module below are no longer valid. See the +Gentoo patch section in README for details. + +The intended method for configuring PAM is by using the newer module +specification, with a line like: + +auth [success=done ignore=ignore auth_err=die default=bad] /lib/security/pam_skey.so + +This is a combination of the standard "sufficient" and "requisite" +specifications: + +- If the module returns PAM_SUCCESS, we are authenticated and no other + modules should be tested. +- If the module returns PAM_IGNORE, then the module didn't accept its + input as an S/Key response, and the next module should try using + the input (using the try_first_pass option). +- If the module returns PAM_AUTH_ERR, then the module accepted an + S/Key input but it was invalid. Do not try any more modules in the + stack; the user already chose S/Key authentication. +- If the module returns any other code, it is a simple error in processing. + Set the error flag but try other modules, just in case. + +The module is intended to be placed before another authentication module, +like pam_unix.so; if not, it should be placed before pam_deny.so. + +If the newer module specification is unavailable in your version of PAM, +the "sufficient" specification will work. + Required -------- For building this package you will probably need original Wietse Venema's --- pam_skey-1.1.5/Makefile.in +++ pam_skey/Makefile.in @@ -12,41 +12,26 @@ LIBS=@LIBS@ @SKEYLIB@ @PAMLIB@ LDFLAGS=@LDFLAGS@ -INSTALL=@INSTALL@ -m 644 +INSTALL=@INSTALL@ +INSTALL_LIB=${INSTALL} -m 755 RM=@RM@ -f CP=@CP@ -f LN=@LN@ -s AWK=@AWK@ -PAM_FILES=pam_skey.so.1 pam_skey_access.so.1 +PAM_FILES=pam_skey.so all: $(PAM_FILES) -pam_skey.so.1: pam_skey.o - $(CC) $(CFLAGS) -o $@ $< $(LIBS) $(LDFLAGS) - -pam_skey_access.so.1: pam_skey_access.o +pam_skey.so: pam_skey.o $(CC) $(CFLAGS) -o $@ $< $(LIBS) $(LDFLAGS) lint-pam_skey: lclint $(CFLAGS) pam_skey.c -lint-pam_skey_access: - lclint $(CFLAGS) pam_skey_access.c - -install: - @if test ! -d $(INSTALLDIR); then \ - mkdir -p $(INSTALLDIR); \ - fi - @for file in $(PAM_FILES); do \ - if test ! -f "$(INSTALLDIR)/$$file"; then \ - echo "Installing $$file in $(INSTALLDIR)"; \ - $(INSTALL) "$$file" "$(INSTALLDIR)/$$file"; \ - (cd $(INSTALLDIR) && $(LN) "$$file" `echo $$file | cut -d. -f1,2`); \ - else \ - echo "$$file exists - will not overwrite it"; \ - fi \ - done \ +install: all + $(INSTALL) -d $(INSTALLDIR) + $(INSTALL_LIB) $(PAM_FILES) $(INSTALLDIR) clean: $(RM) a.out core *.so.1 *.o *.bak --- pam_skey-1.1.5/README +++ pam_skey/README @@ -1,5 +1,77 @@ $Id$ +Gentoo patch +------------ + +The Gentoo pam_skey patch changes the original module in a number of ways. +The behavior of the module is changed to make it more consistent with the +PAM design, and several changes were made throughout the code to make the +module interact better with the skey library used by Gentoo. Many of +these changes will break pam_skey's compatibility with other systems and +libraries, but this is, after all, the Gentoo patch. + +A (not necessarily) exhaustive list of the changes is as follows: +- pam_skey_access.so is completely removed, since the Gentoo skey library + does not support the skey_access() call. +- The pam_skey.so authentication code is completely rewritten. The + original code contained many references to the standard I/O library + (writing to stderr, etc.), as well as inconsistent communication with + the PAM libraries. Also, the authentication process is different, as + described below. +- The options accepted by the pam_skey.so module are different, as + described below. + +Four options are accepted by the pam_skey.so module: + debug - This option turns on debug logging. + try_first_pass - This option tells the module to first try using + the authentication token passed from the + previous module as an S/Key response, before + informing the user of the challenge. If the + token is not valid, the module will proceed with + the standard process of challenging the user + and requesting a response, subject to the + no_default_skey option below. + use_first_pass - This option is identical to the try_first_pass + option, except that if the token is not valid, + it will return silently without challenging the + user. + no_default_skey - This flag changes the behavior of pam_skey. + Instead of immediately challenging the user with + an S/Key challenge, it will present the user with + a standard "Password: " prompt. If the user enters + the password "s/key" (case insensitive), it will + then challenge the user. Any other input will + cause the module to pass the given password to the + next module in the authentication stack (usually + pam_unix.so with the try_first_pass option). + +The exact behavior of pam_skey.so is detailed below: + +1. Retrieve username from PAM, possibly querying the user for it. +2. If the user does not have any S/Key information, return PAM_IGNORE to + proceed to the next module in the stack. +3. If *_first_pass is enabled, check the given authentication token to see + if it is a valid response to the current S/Key challenge. If so, + return PAM_SUCCESS. + 3a. If the token is invalid and use_first_pass is enabled, return + PAM_IGNORE. +4. If no_default_skey is enabled, issue a "Password: " prompt. + 4a. If the response is anything besides "s/key" (case insensitive), + store it as the authentication token and return PAM_IGNORE. +5. Display the current S/Key challenge and request a response, with + input not echoed. If no_default_skey is enabled, this will only be + an S/Key response request; otherwise, it will request either an + S/Key response or a system passsword. + 5a. If an empty response is given, request the S/Key response again, + this time with input echoed. + 5b. If the response is a valid S/Key response, return PAM_SUCCESS. + Otherwise, return PAM_AUTHERR. +6. If the response is a valid S/Key response, return PAM_SUCCESS. +7. Otherwise, if no_default_skey is enabled (the user specifically + requested "s/key" authentication), return PAM_AUTHERR. +8. Otherwise, store the response as the authentication token and + return PAM_IGNORE. + About ----- This is complete pam_skey modul as interface to existing S/Key --- pam_skey-1.1.5/autoconf/acconfig.h +++ pam_skey/autoconf/acconfig.h @@ -1,17 +1,2 @@ /* Define if we can include both string.h and strings.h */ #undef STRING_WITH_STRINGS - -/* Define if you have Linux */ -#undef LINUX - -/* Define if you have *BSD */ -#undef BSD - -/* Define if not missing skeyaccess() */ -#undef HAVE_SKEYACCESS - -/* Define if not missing skeyinfo() */ -#undef HAVE_SKEYINFO - -/* Define if you have skeylookup() instead of skeyinfo() */ -#undef HAVE_SKEYLOOKUP --- pam_skey-1.1.5/autoconf/configure.in +++ pam_skey/autoconf/configure.in @@ -10,18 +10,6 @@ AC_LANG_C AC_LANG_SAVE -dnl Get system type -AC_CANONICAL_HOST -MYHOST=$host_os -case "$host_os" in -*linux*) - AC_DEFINE(LINUX) - ;; -*bsd*) - AC_DEFINE(BSD) - ;; -esac - dnl Package information PACKAGE=pam_skey VERSION=1.1.5 @@ -65,13 +53,9 @@ AC_ARG_WITH(skey-inc, [ --with-skey-inc=DIR Directory containing skey include files], CFLAGS="${CFLAGS} -I${withval}") dnl Check for skey library -AC_CHECK_LIB(socket, socket) -AC_CHECK_LIB(nsl, gethostbyname) +AC_CHECK_LIB(socket, socket, LIBS="${LIBS} -lsocket") +AC_CHECK_LIB(nsl, gethostbyname, LIBS="${LIBS} -lnsl") AC_CHECK_LIB(skey, skeyverify, SKEYLIB="-lskey", AC_MSG_ERROR(skey library not found or unknown interface)) -AC_CHECK_LIB(skey, skeyaccess, AC_DEFINE(HAVE_SKEYACCESS)) -AC_CHECK_LIB(skey, skeyinfo, AC_DEFINE(HAVE_SKEYINFO), - AC_CHECK_LIB(skey, skeylookup, AC_DEFINE(HAVE_SKEYLOOKUP)) -) dnl Check against -G linker flag hold_ldflags=$LDFLAGS --- pam_skey-1.1.5/pam_skey.c +++ pam_skey/pam_skey.c @@ -1,5 +1,6 @@ -/* - * (c) 2001 Dinko Korunic, kreator@srce.hr +/* + * Rewrite (c) 2005 Dani Church, dani.church@gmail.com + * Original (c) 2001 Dinko Korunic, kreator@srce.hr * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF @@ -33,23 +34,23 @@ #include #include #include +#include #define PAM_SM_AUTH #include #include +#include #include "skey.h" #include "pam_skey.h" #include "misc.h" -#if defined linux || defined BSD -#define _PAM_CONST const -#define _PAM_MSG_CAST -#else -#define _PAM_CONST -#define _PAM_MSG_CAST (struct pam_message **) -#endif +#define LOGDEBUG(x) if (mod_opt & _MOD_DEBUG) { syslog x ;} +#define QUERY_USERNAME NULL /* Use default username prompt */ +#define QUERY_PASSWORD "Password: " +#define QUERY_RESPONSE_OR_PASSWORD "S/Key response or password: " +#define QUERY_RESPONSE "S/Key response: " PAM_EXTERN int pam_sm_setcred (pam_handle_t *pamh, int flags, int argc, const char **argv) @@ -57,243 +58,121 @@ return PAM_SUCCESS; } +/* + * The authentication module will return the following status codes: + * PAM_SUCCESS: Successful authentication via S/Key. + * PAM_IGNORE: The user doesn't have S/Key or doesn't want to use it. + * Continue with the next module, using try_first_pass. + * PAM_AUTH_ERR: The user asked to use S/Key, but failed the authentication. + * Don't try any more PAM modules. + * others: random errors, try next authentication method + */ + PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv) { - char challenge[CHALLENGE_MAXSIZE]; /* challenge to print in conv */ - char msg_text[PAM_MAX_MSG_SIZE]; /* text for pam conv */ - char *username = NULL; /* username spacer */ + const char *challenge; /* challenge to print in conv */ + const char *username = NULL; /* username spacer */ char *response = NULL; /* response spacer */ - struct skey skey; /* structure that contains skey information */ int status; /* return status spacer */ unsigned mod_opt = _MOD_NONE_ON; /* module options */ /* Get module options */ mod_getopt(&mod_opt, argc, argv); - /* Get username */ - if (pam_get_user(pamh, (_PAM_CONST char **)&username, "login:") - != PAM_SUCCESS) - { - fprintf(stderr, "cannot determine username\n"); - if (mod_opt & _MOD_DEBUG) - syslog(LOG_DEBUG, "cannot determine username"); - return PAM_USER_UNKNOWN; - } - - if (mod_opt & _MOD_DEBUG) - syslog(LOG_DEBUG, "got username %s", username); - -#ifdef HAVE_SKEYACCESS - /* Check S/Key access permissions - user, host and port. Also include - * sanity checks */ - if (mod_opt & _MOD_ACCESS_CHECK) - { - char *host; /* points to host */ - char *port; /* points to port */ - struct passwd *pwuser; /* structure for getpw() */ - - /* Get host.. */ - if (pam_get_item(pamh, PAM_RHOST, (_PAM_CONST void **)&host) - != PAM_SUCCESS) - host = NULL; /* couldn't get host */ - /* ..and port */ - if (pam_get_item(pamh, PAM_TTY, (_PAM_CONST void **)&port) - != PAM_SUCCESS) - port = NULL; /* couldn't get port */ - - if (mod_opt & _MOD_DEBUG) - syslog(LOG_DEBUG, "checking s/key access for user %s," - " host %s, port %s", username, - (host != NULL) ? host : "*unknown*", - (port != NULL) ? port : "*unknown*"); - - /* Get information from passwd file */ - if ((pwuser = getpwnam(username)) == NULL) - { - fprintf(stderr, "no such user\n"); - syslog(LOG_NOTICE, "cannot find user %s", username); - return PAM_USER_UNKNOWN; /* perhaps even return PAM_ABORT here? */ + /* Get username (taken mainly from pam_unix) */ + status = pam_get_user(pamh, &username, QUERY_USERNAME); + if (status == PAM_SUCCESS) { + if (username == NULL || !isalnum(*username)) { + syslog(LOG_ERR, "bad username [%s]", username); + return PAM_USER_UNKNOWN; } + LOGDEBUG((LOG_DEBUG, "username [%s] obtained", username)); + } else { + LOGDEBUG((LOG_DEBUG, "trouble reading username")); + if (status == PAM_CONV_AGAIN) + return PAM_INCOMPLETE; + return status; + } - /* Do actual checking - we assume skeyaccess() returns PERMIT which is - * by default 1. Notice 4th argument is NULL - we will not perform - * address checks on host itself */ - if (skeyaccess(pwuser, port, host, NULL) != 1) - { - fprintf(stderr, "no s/key access permissions\n"); - syslog(LOG_NOTICE, "no s/key access permissions for %s", - username); - return PAM_AUTH_ERR; - } + /* Check whether or not this user has an S/Key */ + if (skey_haskey(username) != 0) { + LOGDEBUG((LOG_DEBUG, "user [%s] has no S/Key entry", username)); + return PAM_IGNORE; } - else -#endif /* HAVE_SKEYACCESS */ - - /* Only do check whether user has passwd entry */ - if (getpwnam(username) == NULL) - { - fprintf(stderr, "no such user\n"); - if (mod_opt & _MOD_DEBUG) - syslog(LOG_DEBUG, "cannot find user %s", - username); - return PAM_USER_UNKNOWN; + if ((mod_opt & _MOD_TRY_FIRST_PASS) || (mod_opt & _MOD_USE_FIRST_PASS)) { + status = pam_get_item(pamh, PAM_AUTHTOK, (const void **)(void *)&response); + if (status != PAM_SUCCESS) { + syslog(LOG_ALERT, "pam_get_item returned error to pam_skey"); + return status; + } else if (response != NULL) { + if (skey_passcheck(username, response) != -1) { + return PAM_SUCCESS; + } else if (mod_opt & _MOD_USE_FIRST_PASS) { + return PAM_IGNORE; + } + } else if (mod_opt & _MOD_USE_FIRST_PASS) { + return PAM_AUTHTOK_RECOVER_ERR; } - - /* Get S/Key information on user with skeyinfo() */ -#ifdef HAVE_SKEYINFO - switch (skeyinfo(&skey, username, NULL)) -#else -#ifdef HAVE_SKEYLOOKUP - switch (skeylookup(&skey, username)) -#endif /* HAVE_SKEYLOOKUP */ -#endif /* HAVE_SKEYINFO */ - { - /* 0: OK */ - case 0: - break; - /* -1: File error */ - case -1: -#if 0 - /* XXX- This seems broken in (at least) logdaemon-5.8. It returns -1 - * when user not found in keyfile. -kre */ - fprintf(stderr, "s/key database error\n"); - syslog(LOG_NOTICE, "s/key database error"); - return PAM_AUTH_ERR; -#endif - /* 1: No such user in database */ - case 1: - /* We won't confuse the ordinary user telling him about missing skeys - * -kre */ -#if 0 - fprintf(stderr, "no s/key for %s\n", username); -#endif - if (mod_opt & _MOD_DEBUG) - syslog(LOG_DEBUG, "no s/key for %s\n", username); - return PAM_AUTH_ERR; } - /* Make challenge string */ -#if defined(SKEY_MAX_HASHNAME_LEN) && defined(SKEY_MAX_SEED_LEN) - snprintf(challenge, CHALLENGE_MAXSIZE, "otp-%.*s %d %.*s", - SKEY_MAX_HASHNAME_LEN, skey_get_algorithm(), skey.n - 1, SKEY_MAX_SEED_LEN, skey.seed); -#else - snprintf(challenge, CHALLENGE_MAXSIZE, "s/key %d %s", - skey.n - 1, skey.seed); -#endif - - if (mod_opt & _MOD_DEBUG) - syslog(LOG_DEBUG, "got challenge %s for %s", challenge, - username); - - /* Read response from last module's PAM_AUTHTOK */ - if (mod_opt & _MOD_USE_FIRST_PASS) - { - /* Try to extract authtoken */ - if (pam_get_item(pamh, PAM_AUTHTOK, (_PAM_CONST void **)&response) - != PAM_SUCCESS) - { - if (mod_opt & _MOD_DEBUG) - syslog(LOG_DEBUG, "could not get PAM_AUTHTOK"); - mod_opt &= ~_MOD_USE_FIRST_PASS; + if (mod_opt & _MOD_NO_DEFAULT_SKEY) { + status = mod_talk_touser(pamh, mod_opt, NULL, QUERY_PASSWORD, 0, &response); + if (status != PAM_SUCCESS) { + _pam_delete(response) + return status; } - else - { - /* Got AUTHTOK, but it was empty */ - if (empty_authtok(response)) - { - if (mod_opt & _MOD_DEBUG) - syslog(LOG_DEBUG, "empty PAM_AUTHTOK"); - mod_opt &= ~_MOD_USE_FIRST_PASS; - } - else - /* All OK, print challenge information */ - fprintf(stderr, "challenge %s\n", challenge); + if (strcasecmp(response,"s/key")!=0) { + status = pam_set_item(pamh, PAM_AUTHTOK, response); + if (status != PAM_SUCCESS) + return status; + return PAM_IGNORE; } + _pam_delete(response); } - /* There was no PAM_AUTHTOK, or there was no such option in pam-conf - * file */ - if (!(mod_opt & _MOD_USE_FIRST_PASS)) - { - /* Prepare a complete message for conversation */ - snprintf(msg_text, PAM_MAX_MSG_SIZE, - "challenge %s\npassword: ", challenge); - - /* Talk with user */ - if (mod_talk_touser(pamh, &mod_opt, msg_text, &response) - != PAM_SUCCESS) - return PAM_SERVICE_ERR; - - /* Simulate standard S/Key login procedure - if empty token, turn on - * ECHO and prompt again */ - if (empty_authtok(response) && !(mod_opt & _MOD_ONLY_ONE_TRY)) - { - /* Was there echo off? */ - if (mod_opt & _MOD_ECHO_OFF) - { - _pam_delete(response); - fprintf(stderr, "(turning echo on)\n"); - mod_opt &= ~_MOD_ECHO_OFF; - - /* Prepare a complete message for conversation */ - snprintf(msg_text, PAM_MAX_MSG_SIZE, "password: "); - - /* Talk with user */ - if (mod_talk_touser(pamh, &mod_opt, msg_text, &response) - != PAM_SUCCESS) - return PAM_SERVICE_ERR; - - /* Got again empty response. Bailout and don't save auth token */ - if (empty_authtok(response)) - return PAM_AUTH_ERR; - } - else - /* There was echo on already - just get out and don't save auth token - * for other modules */ - return PAM_AUTH_ERR; - } + challenge = skey_keyinfo(username); + if (challenge == NULL) { + syslog(LOG_ALERT, "Could not retrieve S/Key challenge for [%s]", username); + return PAM_AUTHINFO_UNAVAIL; + } - /* XXX - ECHO ON puts '\n' at the end in Solaris 2.7! This is - * cludge to get rid of this nasty `feature' -kre */ - _pam_degarbage(response); - - /* Store auth token - that next module can use with `use_first_pass' */ - if (pam_set_item(pamh, PAM_AUTHTOK, response) != PAM_SUCCESS) - { - syslog(LOG_NOTICE, "unable to save auth token"); - return PAM_SERVICE_ERR; - } - } + if (mod_opt & _MOD_NO_DEFAULT_SKEY) + status = mod_talk_touser(pamh, mod_opt, challenge, QUERY_RESPONSE, 0, &response); + else + status = mod_talk_touser(pamh, mod_opt, challenge, QUERY_RESPONSE_OR_PASSWORD, 0, &response); - /* Verify S/Key */ - status = skeyverify(&skey, response); + if (status != PAM_SUCCESS) + return status; - switch (status) - { - /* 0: Verify successful, database updated */ - case 0: - break; - /* -1: Error of some sort; database unchanged */ - /* 1: Verify failed, database unchanged */ - case -1: - case 1: - if (mod_opt & _MOD_DEBUG) - syslog(LOG_DEBUG, "verify for %s failed, database" - " unchanged", username); - - /* cleanup conversation (error occured) */ - _pam_delete(response); + if (*response == '\0') { + _pam_delete(response); + status = mod_talk_touser(pamh, mod_opt, NULL, QUERY_RESPONSE, 1, &response); + if (status != PAM_SUCCESS) + return status; + status = pam_set_item(pamh, PAM_AUTHTOK, response); + status = skey_passcheck(username, response); + _pam_delete(response); + if (status != -1) + return PAM_SUCCESS; + return PAM_AUTH_ERR; + } - return PAM_AUTH_ERR; + status = pam_set_item(pamh, PAM_AUTHTOK, response); + status = skey_passcheck(username, response); + if (status != -1) { + _pam_delete(response); + return PAM_SUCCESS; } - /* cleanup conversation (it was valid) */ - _pam_delete(response); + if (mod_opt & _MOD_NO_DEFAULT_SKEY) { + _pam_delete(response); + return PAM_AUTH_ERR; + } - /* Success by default */ - return PAM_SUCCESS; + status = pam_set_item(pamh, PAM_AUTHTOK, response); + return PAM_IGNORE; } /* Get module optional parameters */ @@ -328,13 +207,15 @@ } /* This will talk to user through PAM_CONV */ -static int mod_talk_touser(pam_handle_t *pamh, unsigned *mod_opt, - char *msg_text, char **response) +static int mod_talk_touser(pam_handle_t *pamh, unsigned mod_opt, + const char *info_text, const char *prompt_text, int echo_on, + char **response) { - struct pam_message message; - const struct pam_message *pmessage = &message; + struct pam_message message[2], *pmessage[2]; struct pam_conv *conv = NULL; struct pam_response *presponse = NULL; + int i=0; + int status; /* Better safe than sorry */ *response = NULL; @@ -342,40 +223,45 @@ /* Be paranoid */ memset(&message, 0, sizeof(message)); - /* Turn on/off PAM echo */ - if (*mod_opt & _MOD_ECHO_OFF) - message.msg_style = PAM_PROMPT_ECHO_OFF; - else - message.msg_style = PAM_PROMPT_ECHO_ON; - - /* Point to conversation text */ - message.msg = msg_text; + pmessage[0] = &message[0]; + pmessage[1] = &message[1]; - /* Do conversation and see if all is OK */ - if (pam_get_item(pamh, PAM_CONV, (_PAM_CONST void **)&conv) + /* Set info text, if any */ + if (info_text) { + message[i].msg = info_text; + message[i].msg_style = PAM_TEXT_INFO; + i++; + } + + /* Set prompt text */ + message[i].msg = prompt_text; + message[i].msg_style = echo_on ? PAM_PROMPT_ECHO_ON : PAM_PROMPT_ECHO_OFF; + i++; + + /* Get conversation function */ + if (pam_get_item(pamh, PAM_CONV, (const void **)(void *)&conv) != PAM_SUCCESS) { - if (*mod_opt & _MOD_DEBUG) - syslog(LOG_DEBUG, "error in conversation"); + LOGDEBUG((LOG_DEBUG, "error in conversation")); return PAM_SERVICE_ERR; } - - /* Convert into pam_response - only 1 reply expected */ - if (conv->conv(1, _PAM_MSG_CAST &pmessage, &presponse, - conv->appdata_ptr) - != PAM_SUCCESS) + /* Do conversation and see if all is OK */ + status = conv->conv(i, (const struct pam_message **)pmessage, + &presponse, conv->appdata_ptr); + if (status != PAM_SUCCESS) { - _pam_delete(presponse->resp); - return PAM_SERVICE_ERR; + if (presponse != NULL) + _pam_delete(presponse->resp); + return status; } if (presponse != NULL) { /* Save address */ - *response = presponse->resp; + *response = presponse[i-1].resp; /* To ensure that response address will not be erased */ - presponse->resp = NULL; - _pam_drop(presponse); + presponse[i-1].resp = NULL; + _pam_drop_reply(presponse,i); } else return PAM_SERVICE_ERR; --- pam_skey-1.1.5/pam_skey.h +++ pam_skey/pam_skey.h @@ -22,29 +22,25 @@ */ /* Prototypes */ -#ifndef BSD -extern int skeyinfo(struct skey *, char *, char *); /* ORGH! Not in skey.h */ -#endif - static void mod_getopt(unsigned *, int, const char **); -static int mod_talk_touser(pam_handle_t *, unsigned *, char *, char **); +static int mod_talk_touser(pam_handle_t *, unsigned, const char *, const char *, int, char **); /* free() macro */ -#define _pam_drop(X) \ +/*#define _pam_drop(X) \ if (X != NULL) \ { \ free(X); \ X = NULL; \ -} +}*/ /* Secure overwrite */ -#define _pam_overwrite(x) \ +/*#define _pam_overwrite(x) \ { \ register char *__xx__; \ if ((__xx__ = (x))) \ while (*__xx__) \ *__xx__++ = '\0'; \ -} +}*/ /* Drop-in secure replacement - we do not want cleartext passwords lying * scattered around */ @@ -56,7 +52,7 @@ /* This will get us rid of first '\n' in response string and cut-off the * rest of the string. It should be ASCIIZ, of course */ -#define _pam_degarbage(x) \ +/*#define _pam_degarbage(x) \ { \ register char *__xx__; \ if ((__xx__ = (x))) \ @@ -70,30 +66,25 @@ else \ __xx__++; \ } \ -} +}*/ /* Handy empty AUTHTOK macro */ #define empty_authtok(a) (a == NULL || !*a || *a == '\n') -/* Maximum challenge size. It should be 64, but be sure */ -#define CHALLENGE_MAXSIZE 128 - /* Define module flags */ -#define _MOD_NONE_ON 0x0000 /* Generic flag */ -#define _MOD_ALL_ON (~_MOD_NONE_ON) /* Generic mask */ -#define _MOD_DEBUG 0x0001 /* Debugging options on */ -#define _MOD_ECHO_OFF 0x0002 /* PAM_ECHO_OFF */ -#define _MOD_ACCESS_CHECK 0x0004 /* Check S/Key access permissions */ -#define _MOD_USE_FIRST_PASS 0x0008 /* Use PAM_AUTHTOK */ -#define _MOD_ONLY_ONE_TRY 0x0010 /* Only one try, no matter of echo */ -#define _MOD_SPACER 0x0020 /* Currently unused */ +#define _MOD_NONE_ON 0x0000 /* Generic flag */ +#define _MOD_ALL_ON (~_MOD_NONE_ON) /* Generic mask */ +#define _MOD_DEBUG 0x0001 /* Debugging options on */ +#define _MOD_TRY_FIRST_PASS 0x0002 /* Attempt using PAM_AUTHTOK */ +#define _MOD_USE_FIRST_PASS 0x0004 /* Only use PAM_AUTHTOK */ +#define _MOD_NO_DEFAULT_SKEY 0x0008 /* Don't use S/Key by default */ /* Setup defaults - use echo off only */ -#define _MOD_DEFAULT_FLAG _MOD_ECHO_OFF +#define _MOD_DEFAULT_FLAG _MOD_NONE_ON #define _MOD_DEFAULT_MASK _MOD_ALL_ON /* Number of parameters currently known */ -#define _MOD_ARGS 8 +#define _MOD_ARGS 4 /* Structure for flexible argument parsing */ typedef struct @@ -108,11 +99,7 @@ { /* String Mask Flag */ {"debug", _MOD_ALL_ON, _MOD_DEBUG}, - {"echo=off", _MOD_ALL_ON, _MOD_ECHO_OFF}, - {"echo=on", _MOD_ALL_ON^_MOD_ECHO_OFF, _MOD_NONE_ON}, - {"access_check=on", _MOD_ALL_ON, _MOD_ACCESS_CHECK}, - {"access_check=off", _MOD_ALL_ON^_MOD_ACCESS_CHECK, _MOD_NONE_ON}, + {"try_first_pass", _MOD_ALL_ON, _MOD_TRY_FIRST_PASS}, {"use_first_pass", _MOD_ALL_ON, _MOD_USE_FIRST_PASS}, - {"try_first_pass", _MOD_ALL_ON, _MOD_USE_FIRST_PASS}, - {"only_one_try", _MOD_ALL_ON, _MOD_ONLY_ONE_TRY} + {"no_default_skey", _MOD_ALL_ON, _MOD_NO_DEFAULT_SKEY} };