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 |
}; |