Gentoo Archives: gentoo-commits

From: "Ulrich Mueller (ulm)" <ulm@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] gentoo commit in src/patchsets/pam_skey/1.1.5: 01_all_gentoo.patch
Date: Wed, 08 Sep 2010 18:29:59
Message-Id: 20100908182954.3B46420051@flycatcher.gentoo.org
1 ulm 10/09/08 18:29:54
2
3 Added: 01_all_gentoo.patch
4 Log:
5 Patchset corresponding to pam_skey-1.1.5-gentoo.patch.bz2.
6
7 Revision Changes Path
8 1.1 src/patchsets/pam_skey/1.1.5/01_all_gentoo.patch
9
10 file : http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/pam_skey/1.1.5/01_all_gentoo.patch?rev=1.1&view=markup
11 plain: http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/pam_skey/1.1.5/01_all_gentoo.patch?rev=1.1&content-type=text/plain
12
13 Index: 01_all_gentoo.patch
14 ===================================================================
15 --- pam_skey-1.1.5/INSTALL
16 +++ pam_skey/INSTALL
17 @@ -1,5 +1,39 @@
18 $Id: 01_all_gentoo.patch,v 1.1 2010/09/08 18:29:54 ulm Exp $
19
20 +Gentoo patch
21 +------------
22 +Most everything below still holds, though the libraries required are now
23 +those used by Gentoo. Other S/Key libraries may work with a bit of
24 +tweaking.
25 +
26 +The options listed for the module below are no longer valid. See the
27 +Gentoo patch section in README for details.
28 +
29 +The intended method for configuring PAM is by using the newer module
30 +specification, with a line like:
31 +
32 +auth [success=done ignore=ignore auth_err=die default=bad] /lib/security/pam_skey.so
33 +
34 +This is a combination of the standard "sufficient" and "requisite"
35 +specifications:
36 +
37 +- If the module returns PAM_SUCCESS, we are authenticated and no other
38 + modules should be tested.
39 +- If the module returns PAM_IGNORE, then the module didn't accept its
40 + input as an S/Key response, and the next module should try using
41 + the input (using the try_first_pass option).
42 +- If the module returns PAM_AUTH_ERR, then the module accepted an
43 + S/Key input but it was invalid. Do not try any more modules in the
44 + stack; the user already chose S/Key authentication.
45 +- If the module returns any other code, it is a simple error in processing.
46 + Set the error flag but try other modules, just in case.
47 +
48 +The module is intended to be placed before another authentication module,
49 +like pam_unix.so; if not, it should be placed before pam_deny.so.
50 +
51 +If the newer module specification is unavailable in your version of PAM,
52 +the "sufficient" specification will work.
53 +
54 Required
55 --------
56 For building this package you will probably need original Wietse Venema's
57 --- pam_skey-1.1.5/Makefile.in
58 +++ pam_skey/Makefile.in
59 @@ -12,41 +12,26 @@
60 LIBS=@LIBS@ @SKEYLIB@ @PAMLIB@
61 LDFLAGS=@LDFLAGS@
62
63 -INSTALL=@INSTALL@ -m 644
64 +INSTALL=@INSTALL@
65 +INSTALL_LIB=${INSTALL} -m 755
66 RM=@RM@ -f
67 CP=@CP@ -f
68 LN=@LN@ -s
69 AWK=@AWK@
70
71 -PAM_FILES=pam_skey.so.1 pam_skey_access.so.1
72 +PAM_FILES=pam_skey.so
73
74 all: $(PAM_FILES)
75
76 -pam_skey.so.1: pam_skey.o
77 - $(CC) $(CFLAGS) -o $@ $< $(LIBS) $(LDFLAGS)
78 -
79 -pam_skey_access.so.1: pam_skey_access.o
80 +pam_skey.so: pam_skey.o
81 $(CC) $(CFLAGS) -o $@ $< $(LIBS) $(LDFLAGS)
82
83 lint-pam_skey:
84 lclint $(CFLAGS) pam_skey.c
85
86 -lint-pam_skey_access:
87 - lclint $(CFLAGS) pam_skey_access.c
88 -
89 -install:
90 - @if test ! -d $(INSTALLDIR); then \
91 - mkdir -p $(INSTALLDIR); \
92 - fi
93 - @for file in $(PAM_FILES); do \
94 - if test ! -f "$(INSTALLDIR)/$$file"; then \
95 - echo "Installing $$file in $(INSTALLDIR)"; \
96 - $(INSTALL) "$$file" "$(INSTALLDIR)/$$file"; \
97 - (cd $(INSTALLDIR) && $(LN) "$$file" `echo $$file | cut -d. -f1,2`); \
98 - else \
99 - echo "$$file exists - will not overwrite it"; \
100 - fi \
101 - done \
102 +install: all
103 + $(INSTALL) -d $(INSTALLDIR)
104 + $(INSTALL_LIB) $(PAM_FILES) $(INSTALLDIR)
105
106 clean:
107 $(RM) a.out core *.so.1 *.o *.bak
108 --- pam_skey-1.1.5/README
109 +++ pam_skey/README
110 @@ -1,5 +1,77 @@
111 $Id: 01_all_gentoo.patch,v 1.1 2010/09/08 18:29:54 ulm Exp $
112
113 +Gentoo patch
114 +------------
115 +
116 +The Gentoo pam_skey patch changes the original module in a number of ways.
117 +The behavior of the module is changed to make it more consistent with the
118 +PAM design, and several changes were made throughout the code to make the
119 +module interact better with the skey library used by Gentoo. Many of
120 +these changes will break pam_skey's compatibility with other systems and
121 +libraries, but this is, after all, the Gentoo patch.
122 +
123 +A (not necessarily) exhaustive list of the changes is as follows:
124 +- pam_skey_access.so is completely removed, since the Gentoo skey library
125 + does not support the skey_access() call.
126 +- The pam_skey.so authentication code is completely rewritten. The
127 + original code contained many references to the standard I/O library
128 + (writing to stderr, etc.), as well as inconsistent communication with
129 + the PAM libraries. Also, the authentication process is different, as
130 + described below.
131 +- The options accepted by the pam_skey.so module are different, as
132 + described below.
133 +
134 +Four options are accepted by the pam_skey.so module:
135 + debug - This option turns on debug logging.
136 + try_first_pass - This option tells the module to first try using
137 + the authentication token passed from the
138 + previous module as an S/Key response, before
139 + informing the user of the challenge. If the
140 + token is not valid, the module will proceed with
141 + the standard process of challenging the user
142 + and requesting a response, subject to the
143 + no_default_skey option below.
144 + use_first_pass - This option is identical to the try_first_pass
145 + option, except that if the token is not valid,
146 + it will return silently without challenging the
147 + user.
148 + no_default_skey - This flag changes the behavior of pam_skey.
149 + Instead of immediately challenging the user with
150 + an S/Key challenge, it will present the user with
151 + a standard "Password: " prompt. If the user enters
152 + the password "s/key" (case insensitive), it will
153 + then challenge the user. Any other input will
154 + cause the module to pass the given password to the
155 + next module in the authentication stack (usually
156 + pam_unix.so with the try_first_pass option).
157 +
158 +The exact behavior of pam_skey.so is detailed below:
159 +
160 +1. Retrieve username from PAM, possibly querying the user for it.
161 +2. If the user does not have any S/Key information, return PAM_IGNORE to
162 + proceed to the next module in the stack.
163 +3. If *_first_pass is enabled, check the given authentication token to see
164 + if it is a valid response to the current S/Key challenge. If so,
165 + return PAM_SUCCESS.
166 + 3a. If the token is invalid and use_first_pass is enabled, return
167 + PAM_IGNORE.
168 +4. If no_default_skey is enabled, issue a "Password: " prompt.
169 + 4a. If the response is anything besides "s/key" (case insensitive),
170 + store it as the authentication token and return PAM_IGNORE.
171 +5. Display the current S/Key challenge and request a response, with
172 + input not echoed. If no_default_skey is enabled, this will only be
173 + an S/Key response request; otherwise, it will request either an
174 + S/Key response or a system passsword.
175 + 5a. If an empty response is given, request the S/Key response again,
176 + this time with input echoed.
177 + 5b. If the response is a valid S/Key response, return PAM_SUCCESS.
178 + Otherwise, return PAM_AUTHERR.
179 +6. If the response is a valid S/Key response, return PAM_SUCCESS.
180 +7. Otherwise, if no_default_skey is enabled (the user specifically
181 + requested "s/key" authentication), return PAM_AUTHERR.
182 +8. Otherwise, store the response as the authentication token and
183 + return PAM_IGNORE.
184 +
185 About
186 -----
187 This is complete pam_skey modul as interface to existing S/Key
188 --- pam_skey-1.1.5/autoconf/acconfig.h
189 +++ pam_skey/autoconf/acconfig.h
190 @@ -1,17 +1,2 @@
191 /* Define if we can include both string.h and strings.h */
192 #undef STRING_WITH_STRINGS
193 -
194 -/* Define if you have Linux */
195 -#undef LINUX
196 -
197 -/* Define if you have *BSD */
198 -#undef BSD
199 -
200 -/* Define if not missing skeyaccess() */
201 -#undef HAVE_SKEYACCESS
202 -
203 -/* Define if not missing skeyinfo() */
204 -#undef HAVE_SKEYINFO
205 -
206 -/* Define if you have skeylookup() instead of skeyinfo() */
207 -#undef HAVE_SKEYLOOKUP
208 --- pam_skey-1.1.5/autoconf/configure.in
209 +++ pam_skey/autoconf/configure.in
210 @@ -10,18 +10,6 @@
211 AC_LANG_C
212 AC_LANG_SAVE
213
214 -dnl Get system type
215 -AC_CANONICAL_HOST
216 -MYHOST=$host_os
217 -case "$host_os" in
218 -*linux*)
219 - AC_DEFINE(LINUX)
220 - ;;
221 -*bsd*)
222 - AC_DEFINE(BSD)
223 - ;;
224 -esac
225 -
226 dnl Package information
227 PACKAGE=pam_skey
228 VERSION=1.1.5
229 @@ -65,13 +53,9 @@
230 AC_ARG_WITH(skey-inc, [ --with-skey-inc=DIR Directory containing skey include files], CFLAGS="${CFLAGS} -I${withval}")
231
232 dnl Check for skey library
233 -AC_CHECK_LIB(socket, socket)
234 -AC_CHECK_LIB(nsl, gethostbyname)
235 +AC_CHECK_LIB(socket, socket, LIBS="${LIBS} -lsocket")
236 +AC_CHECK_LIB(nsl, gethostbyname, LIBS="${LIBS} -lnsl")
237 AC_CHECK_LIB(skey, skeyverify, SKEYLIB="-lskey", AC_MSG_ERROR(skey library not found or unknown interface))
238 -AC_CHECK_LIB(skey, skeyaccess, AC_DEFINE(HAVE_SKEYACCESS))
239 -AC_CHECK_LIB(skey, skeyinfo, AC_DEFINE(HAVE_SKEYINFO),
240 - AC_CHECK_LIB(skey, skeylookup, AC_DEFINE(HAVE_SKEYLOOKUP))
241 -)
242
243 dnl Check against -G linker flag
244 hold_ldflags=$LDFLAGS
245 --- pam_skey-1.1.5/pam_skey.c
246 +++ pam_skey/pam_skey.c
247 @@ -1,5 +1,6 @@
248 /*
249 - * (c) 2001 Dinko Korunic, kreator@××××.hr
250 + * Rewrite (c) 2005 Dani Church, dani.church@×××××.com
251 + * Original (c) 2001 Dinko Korunic, kreator@××××.hr
252 *
253 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
254 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
255 @@ -33,23 +34,23 @@
256 #include <pwd.h>
257 #include <sys/types.h>
258 #include <syslog.h>
259 +#include <ctype.h>
260
261 #define PAM_SM_AUTH
262
263 #include <security/pam_appl.h>
264 #include <security/pam_modules.h>
265 +#include <security/_pam_macros.h>
266
267 #include "skey.h"
268 #include "pam_skey.h"
269 #include "misc.h"
270
271 -#if defined linux || defined BSD
272 -#define _PAM_CONST const
273 -#define _PAM_MSG_CAST
274 -#else
275 -#define _PAM_CONST
276 -#define _PAM_MSG_CAST (struct pam_message **)
277 -#endif
278 +#define LOGDEBUG(x) if (mod_opt & _MOD_DEBUG) { syslog x ;}
279 +#define QUERY_USERNAME NULL /* Use default username prompt */
280 +#define QUERY_PASSWORD "Password: "
281 +#define QUERY_RESPONSE_OR_PASSWORD "S/Key response or system password: "
282 +#define QUERY_RESPONSE "S/Key response: "
283
284 PAM_EXTERN int pam_sm_setcred (pam_handle_t *pamh, int flags,
285 int argc, const char **argv)
286 @@ -57,243 +58,121 @@
287 return PAM_SUCCESS;
288 }
289
290 +/*
291 + * The authentication module will return the following status codes:
292 + * PAM_SUCCESS: Successful authentication via S/Key.
293 + * PAM_IGNORE: The user doesn't have S/Key or doesn't want to use it.
294 + * Continue with the next module, using try_first_pass.
295 + * PAM_AUTH_ERR: The user asked to use S/Key, but failed the authentication.
296 + * Don't try any more PAM modules.
297 + * others: random errors, try next authentication method
298 + */
299 +
300 PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flags,
301 int argc, const char **argv)
302 {
303 - char challenge[CHALLENGE_MAXSIZE]; /* challenge to print in conv */
304 - char msg_text[PAM_MAX_MSG_SIZE]; /* text for pam conv */
305 - char *username = NULL; /* username spacer */
306 + const char *challenge; /* challenge to print in conv */
307 + const char *username = NULL; /* username spacer */
308 char *response = NULL; /* response spacer */
309 - struct skey skey; /* structure that contains skey information */
310 int status; /* return status spacer */
311 unsigned mod_opt = _MOD_NONE_ON; /* module options */
312
313 /* Get module options */
314 mod_getopt(&mod_opt, argc, argv);
315
316 - /* Get username */
317 - if (pam_get_user(pamh, (_PAM_CONST char **)&username, "login:")
318 - != PAM_SUCCESS)
319 - {
320 - fprintf(stderr, "cannot determine username\n");
321 - if (mod_opt & _MOD_DEBUG)
322 - syslog(LOG_DEBUG, "cannot determine username");
323 - return PAM_USER_UNKNOWN;
324 - }
325 -
326 - if (mod_opt & _MOD_DEBUG)
327 - syslog(LOG_DEBUG, "got username %s", username);
328 -
329 -#ifdef HAVE_SKEYACCESS
330 - /* Check S/Key access permissions - user, host and port. Also include
331 - * sanity checks */
332 - if (mod_opt & _MOD_ACCESS_CHECK)
333 - {
334 - char *host; /* points to host */
335 - char *port; /* points to port */
336 - struct passwd *pwuser; /* structure for getpw() */
337 -
338 - /* Get host.. */
339 - if (pam_get_item(pamh, PAM_RHOST, (_PAM_CONST void **)&host)
340 - != PAM_SUCCESS)
341 - host = NULL; /* couldn't get host */
342 - /* ..and port */
343 - if (pam_get_item(pamh, PAM_TTY, (_PAM_CONST void **)&port)
344 - != PAM_SUCCESS)
345 - port = NULL; /* couldn't get port */
346 -
347 - if (mod_opt & _MOD_DEBUG)
348 - syslog(LOG_DEBUG, "checking s/key access for user %s,"
349 - " host %s, port %s", username,
350 - (host != NULL) ? host : "*unknown*",
351 - (port != NULL) ? port : "*unknown*");
352 -
353 - /* Get information from passwd file */
354 - if ((pwuser = getpwnam(username)) == NULL)
355 - {
356 - fprintf(stderr, "no such user\n");
357 - syslog(LOG_NOTICE, "cannot find user %s", username);
358 - return PAM_USER_UNKNOWN; /* perhaps even return PAM_ABORT here? */
359 + /* Get username (taken mainly from pam_unix) */
360 + status = pam_get_user(pamh, &username, QUERY_USERNAME);
361 + if (status == PAM_SUCCESS) {
362 + if (username == NULL || !isalnum(*username)) {
363 + syslog(LOG_ERR, "bad username [%s]", username);
364 + return PAM_USER_UNKNOWN;
365 }
366 + LOGDEBUG((LOG_DEBUG, "username [%s] obtained", username));
367 + } else {
368 + LOGDEBUG((LOG_DEBUG, "trouble reading username"));
369 + if (status == PAM_CONV_AGAIN)
370 + return PAM_INCOMPLETE;
371 + return status;
372 + }
373
374 - /* Do actual checking - we assume skeyaccess() returns PERMIT which is
375 - * by default 1. Notice 4th argument is NULL - we will not perform
376 - * address checks on host itself */
377 - if (skeyaccess(pwuser, port, host, NULL) != 1)
378 - {
379 - fprintf(stderr, "no s/key access permissions\n");
380 - syslog(LOG_NOTICE, "no s/key access permissions for %s",
381 - username);
382 - return PAM_AUTH_ERR;
383 - }
384 + /* Check whether or not this user has an S/Key */
385 + if (skey_haskey(username) != 0) {
386 + LOGDEBUG((LOG_DEBUG, "user [%s] has no S/Key entry", username));
387 + return PAM_IGNORE;
388 }
389 - else
390
391 -#endif /* HAVE_SKEYACCESS */
392 -
393 - /* Only do check whether user has passwd entry */
394 - if (getpwnam(username) == NULL)
395 - {
396 - fprintf(stderr, "no such user\n");
397 - if (mod_opt & _MOD_DEBUG)
398 - syslog(LOG_DEBUG, "cannot find user %s",
399 - username);
400 - return PAM_USER_UNKNOWN;
401 + if ((mod_opt & _MOD_TRY_FIRST_PASS) || (mod_opt & _MOD_USE_FIRST_PASS)) {
402 + status = pam_get_item(pamh, PAM_AUTHTOK, (const void **)(void *)&response);
403 + if (status != PAM_SUCCESS) {
404 + syslog(LOG_ALERT, "pam_get_item returned error to pam_skey");
405 + return status;
406 + } else if (response != NULL) {
407 + if (skey_passcheck(username, response) != -1) {
408 + return PAM_SUCCESS;
409 + } else if (mod_opt & _MOD_USE_FIRST_PASS) {
410 + return PAM_IGNORE;
411 + }
412 + } else if (mod_opt & _MOD_USE_FIRST_PASS) {
413 + return PAM_AUTHTOK_RECOVER_ERR;
414 }
415 -
416 - /* Get S/Key information on user with skeyinfo() */
417 -#ifdef HAVE_SKEYINFO
418 - switch (skeyinfo(&skey, username, NULL))
419 -#else
420 -#ifdef HAVE_SKEYLOOKUP
421 - switch (skeylookup(&skey, username))
422 -#endif /* HAVE_SKEYLOOKUP */
423 -#endif /* HAVE_SKEYINFO */
424 - {
425 - /* 0: OK */
426 - case 0:
427 - break;
428 - /* -1: File error */
429 - case -1:
430 -#if 0
431 - /* XXX- This seems broken in (at least) logdaemon-5.8. It returns -1
432 - * when user not found in keyfile. -kre */
433 - fprintf(stderr, "s/key database error\n");
434 - syslog(LOG_NOTICE, "s/key database error");
435 - return PAM_AUTH_ERR;
436 -#endif
437 - /* 1: No such user in database */
438 - case 1:
439 - /* We won't confuse the ordinary user telling him about missing skeys
440 - * -kre */
441 -#if 0
442 - fprintf(stderr, "no s/key for %s\n", username);
443 -#endif
444 - if (mod_opt & _MOD_DEBUG)
445 - syslog(LOG_DEBUG, "no s/key for %s\n", username);
446 - return PAM_AUTH_ERR;
447 }
448
449 - /* Make challenge string */
450 -#if defined(SKEY_MAX_HASHNAME_LEN) && defined(SKEY_MAX_SEED_LEN)
451 - snprintf(challenge, CHALLENGE_MAXSIZE, "otp-%.*s %d %.*s",
452 - SKEY_MAX_HASHNAME_LEN, skey_get_algorithm(), skey.n - 1, SKEY_MAX_SEED_LEN, skey.seed);
453 -#else
454 - snprintf(challenge, CHALLENGE_MAXSIZE, "s/key %d %s",
455 - skey.n - 1, skey.seed);
456 -#endif
457 -
458 - if (mod_opt & _MOD_DEBUG)
459 - syslog(LOG_DEBUG, "got challenge %s for %s", challenge,
460 - username);
461 -
462 - /* Read response from last module's PAM_AUTHTOK */
463 - if (mod_opt & _MOD_USE_FIRST_PASS)
464 - {
465 - /* Try to extract authtoken */
466 - if (pam_get_item(pamh, PAM_AUTHTOK, (_PAM_CONST void **)&response)
467 - != PAM_SUCCESS)
468 - {
469 - if (mod_opt & _MOD_DEBUG)
470 - syslog(LOG_DEBUG, "could not get PAM_AUTHTOK");
471 - mod_opt &= ~_MOD_USE_FIRST_PASS;
472 + if (mod_opt & _MOD_NO_DEFAULT_SKEY) {
473 + status = mod_talk_touser(pamh, mod_opt, NULL, QUERY_PASSWORD, 0, &response);
474 + if (status != PAM_SUCCESS) {
475 + _pam_delete(response)
476 + return status;
477 }
478 - else
479 - {
480 - /* Got AUTHTOK, but it was empty */
481 - if (empty_authtok(response))
482 - {
483 - if (mod_opt & _MOD_DEBUG)
484 - syslog(LOG_DEBUG, "empty PAM_AUTHTOK");
485 - mod_opt &= ~_MOD_USE_FIRST_PASS;
486 - }
487 - else
488 - /* All OK, print challenge information */
489 - fprintf(stderr, "challenge %s\n", challenge);
490 + if (strcasecmp(response,"s/key")!=0) {
491 + status = pam_set_item(pamh, PAM_AUTHTOK, response);
492 + if (status != PAM_SUCCESS)
493 + return status;
494 + return PAM_IGNORE;
495 }
496 + _pam_delete(response);
497 }
498
499 - /* There was no PAM_AUTHTOK, or there was no such option in pam-conf
500 - * file */
501 - if (!(mod_opt & _MOD_USE_FIRST_PASS))
502 - {
503 - /* Prepare a complete message for conversation */
504 - snprintf(msg_text, PAM_MAX_MSG_SIZE,
505 - "challenge %s\npassword: ", challenge);
506 -
507 - /* Talk with user */
508 - if (mod_talk_touser(pamh, &mod_opt, msg_text, &response)
509 - != PAM_SUCCESS)
510 - return PAM_SERVICE_ERR;
511 -
512 - /* Simulate standard S/Key login procedure - if empty token, turn on
513 - * ECHO and prompt again */
514 - if (empty_authtok(response) && !(mod_opt & _MOD_ONLY_ONE_TRY))
515 - {
516 - /* Was there echo off? */
517 - if (mod_opt & _MOD_ECHO_OFF)
518 - {
519 - _pam_delete(response);
520 - fprintf(stderr, "(turning echo on)\n");
521 - mod_opt &= ~_MOD_ECHO_OFF;
522 -
523 - /* Prepare a complete message for conversation */
524 - snprintf(msg_text, PAM_MAX_MSG_SIZE, "password: ");
525 -
526 - /* Talk with user */
527 - if (mod_talk_touser(pamh, &mod_opt, msg_text, &response)
528 - != PAM_SUCCESS)
529 - return PAM_SERVICE_ERR;
530 -
531 - /* Got again empty response. Bailout and don't save auth token */
532 - if (empty_authtok(response))
533 - return PAM_AUTH_ERR;
534 - }
535 - else
536 - /* There was echo on already - just get out and don't save auth token
537 - * for other modules */
538 - return PAM_AUTH_ERR;
539 - }
540 + challenge = skey_keyinfo(username);
541 + if (challenge == NULL) {
542 + syslog(LOG_ALERT, "Could not retrieve S/Key challenge for [%s]", username);
543 + return PAM_AUTHINFO_UNAVAIL;
544 + }
545
546 - /* XXX - ECHO ON puts '\n' at the end in Solaris 2.7! This is
547 - * cludge to get rid of this nasty `feature' -kre */
548 - _pam_degarbage(response);
549 -
550 - /* Store auth token - that next module can use with `use_first_pass' */
551 - if (pam_set_item(pamh, PAM_AUTHTOK, response) != PAM_SUCCESS)
552 - {
553 - syslog(LOG_NOTICE, "unable to save auth token");
554 - return PAM_SERVICE_ERR;
555 - }
556 - }
557 + if (mod_opt & _MOD_NO_DEFAULT_SKEY)
558 + status = mod_talk_touser(pamh, mod_opt, challenge, QUERY_RESPONSE, 0, &response);
559 + else
560 + status = mod_talk_touser(pamh, mod_opt, challenge, QUERY_RESPONSE_OR_PASSWORD, 0, &response);
561
562 - /* Verify S/Key */
563 - status = skeyverify(&skey, response);
564 + if (status != PAM_SUCCESS)
565 + return status;
566
567 - switch (status)
568 - {
569 - /* 0: Verify successful, database updated */
570 - case 0:
571 - break;
572 - /* -1: Error of some sort; database unchanged */
573 - /* 1: Verify failed, database unchanged */
574 - case -1:
575 - case 1:
576 - if (mod_opt & _MOD_DEBUG)
577 - syslog(LOG_DEBUG, "verify for %s failed, database"
578 - " unchanged", username);
579 -
580 - /* cleanup conversation (error occured) */
581 - _pam_delete(response);
582 + if (*response == '\0') {
583 + _pam_delete(response);
584 + status = mod_talk_touser(pamh, mod_opt, NULL, QUERY_RESPONSE, 1, &response);
585 + if (status != PAM_SUCCESS)
586 + return status;
587 + status = pam_set_item(pamh, PAM_AUTHTOK, response);
588 + status = skey_passcheck(username, response);
589 + _pam_delete(response);
590 + if (status != -1)
591 + return PAM_SUCCESS;
592 + return PAM_AUTH_ERR;
593 + }
594
595 - return PAM_AUTH_ERR;
596 + status = pam_set_item(pamh, PAM_AUTHTOK, response);
597 + status = skey_passcheck(username, response);
598 + if (status != -1) {
599 + _pam_delete(response);
600 + return PAM_SUCCESS;
601 }
602
603 - /* cleanup conversation (it was valid) */
604 - _pam_delete(response);
605 + if (mod_opt & _MOD_NO_DEFAULT_SKEY) {
606 + _pam_delete(response);
607 + return PAM_AUTH_ERR;
608 + }
609
610 - /* Success by default */
611 - return PAM_SUCCESS;
612 + status = pam_set_item(pamh, PAM_AUTHTOK, response);
613 + return PAM_IGNORE;
614 }
615
616 /* Get module optional parameters */
617 @@ -328,13 +207,13 @@
618 }
619
620 /* This will talk to user through PAM_CONV */
621 -static int mod_talk_touser(pam_handle_t *pamh, unsigned *mod_opt,
622 - char *msg_text, char **response)
623 +static int mod_talk_touser(pam_handle_t *pamh, unsigned mod_opt,
624 + const char *info_text, const char *prompt_text, int echo_on, char **response)
625 {
626 - struct pam_message message;
627 - const struct pam_message *pmessage = &message;
628 + struct pam_message message[2], *pmessage[2];
629 struct pam_conv *conv = NULL;
630 struct pam_response *presponse = NULL;
631 + int i=0;
632
633 /* Better safe than sorry */
634 *response = NULL;
635 @@ -342,26 +221,30 @@
636 /* Be paranoid */
637 memset(&message, 0, sizeof(message));
638
639 - /* Turn on/off PAM echo */
640 - if (*mod_opt & _MOD_ECHO_OFF)
641 - message.msg_style = PAM_PROMPT_ECHO_OFF;
642 - else
643 - message.msg_style = PAM_PROMPT_ECHO_ON;
644 -
645 - /* Point to conversation text */
646 - message.msg = msg_text;
647 + pmessage[0] = &message[0];
648 + pmessage[1] = &message[1];
649 +
650 + /* Set info text, if any */
651 + if (info_text) {
652 + message[i].msg = info_text;
653 + message[i].msg_style = PAM_TEXT_INFO;
654 + i++;
655 + }
656 +
657 + /* Set prompt text */
658 + message[i].msg = prompt_text;
659 + message[i].msg_style = echo_on ? PAM_PROMPT_ECHO_ON : PAM_PROMPT_ECHO_OFF;
660 + i++;
661
662 /* Do conversation and see if all is OK */
663 - if (pam_get_item(pamh, PAM_CONV, (_PAM_CONST void **)&conv)
664 + if (pam_get_item(pamh, PAM_CONV, (const void **)(void *)&conv)
665 != PAM_SUCCESS)
666 {
667 - if (*mod_opt & _MOD_DEBUG)
668 - syslog(LOG_DEBUG, "error in conversation");
669 + LOGDEBUG((LOG_DEBUG, "error in conversation"));
670 return PAM_SERVICE_ERR;
671 }
672 -
673 - /* Convert into pam_response - only 1 reply expected */
674 - if (conv->conv(1, _PAM_MSG_CAST &pmessage, &presponse,
675 + /* Convert into pam_response */
676 + if (conv->conv(i, (const struct pam_message **)pmessage, &presponse,
677 conv->appdata_ptr)
678 != PAM_SUCCESS)
679 {
680 @@ -372,10 +255,10 @@
681 if (presponse != NULL)
682 {
683 /* Save address */
684 - *response = presponse->resp;
685 + *response = presponse[i-1].resp;
686 /* To ensure that response address will not be erased */
687 - presponse->resp = NULL;
688 - _pam_drop(presponse);
689 + presponse[i-1].resp = NULL;
690 + _pam_drop_reply(presponse,i);
691 }
692 else
693 return PAM_SERVICE_ERR;
694 --- pam_skey-1.1.5/pam_skey.h
695 +++ pam_skey/pam_skey.h
696 @@ -22,29 +22,25 @@
697 */
698
699 /* Prototypes */
700 -#ifndef BSD
701 -extern int skeyinfo(struct skey *, char *, char *); /* ORGH! Not in skey.h */
702 -#endif
703 -
704 static void mod_getopt(unsigned *, int, const char **);
705 -static int mod_talk_touser(pam_handle_t *, unsigned *, char *, char **);
706 +static int mod_talk_touser(pam_handle_t *, unsigned, const char *, const char *, int, char **);
707
708 /* free() macro */
709 -#define _pam_drop(X) \
710 +/*#define _pam_drop(X) \
711 if (X != NULL) \
712 { \
713 free(X); \
714 X = NULL; \
715 -}
716 +}*/
717
718 /* Secure overwrite */
719 -#define _pam_overwrite(x) \
720 +/*#define _pam_overwrite(x) \
721 { \
722 register char *__xx__; \
723 if ((__xx__ = (x))) \
724 while (*__xx__) \
725 *__xx__++ = '\0'; \
726 -}
727 +}*/
728
729 /* Drop-in secure replacement - we do not want cleartext passwords lying
730 * scattered around */
731 @@ -56,7 +52,7 @@
732
733 /* This will get us rid of first '\n' in response string and cut-off the
734 * rest of the string. It should be ASCIIZ, of course */
735 -#define _pam_degarbage(x) \
736 +/*#define _pam_degarbage(x) \
737 { \
738 register char *__xx__; \
739 if ((__xx__ = (x))) \
740 @@ -70,30 +66,25 @@
741 else \
742 __xx__++; \
743 } \
744 -}
745 +}*/
746
747 /* Handy empty AUTHTOK macro */
748 #define empty_authtok(a) (a == NULL || !*a || *a == '\n')
749
750 -/* Maximum challenge size. It should be 64, but be sure */
751 -#define CHALLENGE_MAXSIZE 128
752 -
753 /* Define module flags */
754 -#define _MOD_NONE_ON 0x0000 /* Generic flag */
755 -#define _MOD_ALL_ON (~_MOD_NONE_ON) /* Generic mask */
756 -#define _MOD_DEBUG 0x0001 /* Debugging options on */
757 -#define _MOD_ECHO_OFF 0x0002 /* PAM_ECHO_OFF */
758 -#define _MOD_ACCESS_CHECK 0x0004 /* Check S/Key access permissions */
759 -#define _MOD_USE_FIRST_PASS 0x0008 /* Use PAM_AUTHTOK */
760 -#define _MOD_ONLY_ONE_TRY 0x0010 /* Only one try, no matter of echo */
761 -#define _MOD_SPACER 0x0020 /* Currently unused */
762 +#define _MOD_NONE_ON 0x0000 /* Generic flag */
763 +#define _MOD_ALL_ON (~_MOD_NONE_ON) /* Generic mask */
764 +#define _MOD_DEBUG 0x0001 /* Debugging options on */
765 +#define _MOD_TRY_FIRST_PASS 0x0002 /* Attempt using PAM_AUTHTOK */
766 +#define _MOD_USE_FIRST_PASS 0x0004 /* Only use PAM_AUTHTOK */
767 +#define _MOD_NO_DEFAULT_SKEY 0x0008 /* Don't use S/Key by default */
768
769 /* Setup defaults - use echo off only */
770 -#define _MOD_DEFAULT_FLAG _MOD_ECHO_OFF
771 +#define _MOD_DEFAULT_FLAG _MOD_NONE_ON
772 #define _MOD_DEFAULT_MASK _MOD_ALL_ON
773
774 /* Number of parameters currently known */
775 -#define _MOD_ARGS 8
776 +#define _MOD_ARGS 4
777
778 /* Structure for flexible argument parsing */
779 typedef struct
780 @@ -108,11 +99,7 @@
781 {
782 /* String Mask Flag */
783 {"debug", _MOD_ALL_ON, _MOD_DEBUG},
784 - {"echo=off", _MOD_ALL_ON, _MOD_ECHO_OFF},
785 - {"echo=on", _MOD_ALL_ON^_MOD_ECHO_OFF, _MOD_NONE_ON},
786 - {"access_check=on", _MOD_ALL_ON, _MOD_ACCESS_CHECK},
787 - {"access_check=off", _MOD_ALL_ON^_MOD_ACCESS_CHECK, _MOD_NONE_ON},
788 + {"try_first_pass", _MOD_ALL_ON, _MOD_TRY_FIRST_PASS},
789 {"use_first_pass", _MOD_ALL_ON, _MOD_USE_FIRST_PASS},
790 - {"try_first_pass", _MOD_ALL_ON, _MOD_USE_FIRST_PASS},
791 - {"only_one_try", _MOD_ALL_ON, _MOD_ONLY_ONE_TRY}
792 + {"no_default_skey", _MOD_ALL_ON, _MOD_NO_DEFAULT_SKEY}
793 };