diff options
author | Colin Watson <cjwatson@debian.org> | 2007-06-12 16:16:35 +0000 |
---|---|---|
committer | Colin Watson <cjwatson@debian.org> | 2007-06-12 16:16:35 +0000 |
commit | b7e40fa9da0b5491534a429dadb321eab5a77558 (patch) | |
tree | bed1da11e9f829925797aa093e379fc0b5868ecd /auth-pam.c | |
parent | 4f84beedf1005e44ff33c854abd6b711ffc0adb7 (diff) | |
parent | 086ea76990b1e6287c24b6db74adffd4605eb3b0 (diff) |
* New upstream release (closes: #395507, #397961, #420035). Important
changes not previously backported to 4.3p2:
- 4.4/4.4p1 (http://www.openssh.org/txt/release-4.4):
+ On portable OpenSSH, fix a GSSAPI authentication abort that could be
used to determine the validity of usernames on some platforms.
+ Implemented conditional configuration in sshd_config(5) using the
"Match" directive. This allows some configuration options to be
selectively overridden if specific criteria (based on user, group,
hostname and/or address) are met. So far a useful subset of
post-authentication options are supported and more are expected to
be added in future releases.
+ Add support for Diffie-Hellman group exchange key agreement with a
final hash of SHA256.
+ Added a "ForceCommand" directive to sshd_config(5). Similar to the
command="..." option accepted in ~/.ssh/authorized_keys, this forces
the execution of the specified command regardless of what the user
requested. This is very useful in conjunction with the new "Match"
option.
+ Add a "PermitOpen" directive to sshd_config(5). This mirrors the
permitopen="..." authorized_keys option, allowing fine-grained
control over the port-forwardings that a user is allowed to
establish.
+ Add optional logging of transactions to sftp-server(8).
+ ssh(1) will now record port numbers for hosts stored in
~/.ssh/known_hosts when a non-standard port has been requested
(closes: #50612).
+ Add an "ExitOnForwardFailure" option to cause ssh(1) to exit (with a
non-zero exit code) when requested port forwardings could not be
established.
+ Extend sshd_config(5) "SubSystem" declarations to allow the
specification of command-line arguments.
+ Replacement of all integer overflow susceptible invocations of
malloc(3) and realloc(3) with overflow-checking equivalents.
+ Many manpage fixes and improvements.
+ Add optional support for OpenSSL hardware accelerators (engines),
enabled using the --with-ssl-engine configure option.
+ Tokens in configuration files may be double-quoted in order to
contain spaces (closes: #319639).
+ Move a debug() call out of a SIGCHLD handler, fixing a hang when the
session exits very quickly (closes: #307890).
+ Fix some incorrect buffer allocation calculations (closes: #410599).
+ ssh-add doesn't ask for a passphrase if key file permissions are too
liberal (closes: #103677).
+ Likewise, ssh doesn't ask either (closes: #99675).
- 4.6/4.6p1 (http://www.openssh.org/txt/release-4.6):
+ sshd now allows the enabling and disabling of authentication methods
on a per user, group, host and network basis via the Match directive
in sshd_config.
+ Fixed an inconsistent check for a terminal when displaying scp
progress meter (closes: #257524).
+ Fix "hang on exit" when background processes are running at the time
of exit on a ttyful/login session (closes: #88337).
* Update to current GSSAPI patch from
http://www.sxw.org.uk/computing/patches/openssh-4.6p1-gsskex-20070312.patch;
install ChangeLog.gssapi.
Diffstat (limited to 'auth-pam.c')
-rw-r--r-- | auth-pam.c | 85 |
1 files changed, 63 insertions, 22 deletions
diff --git a/auth-pam.c b/auth-pam.c index fb9ae954a..c08d47229 100644 --- a/auth-pam.c +++ b/auth-pam.c | |||
@@ -47,7 +47,16 @@ | |||
47 | 47 | ||
48 | /* Based on $FreeBSD: src/crypto/openssh/auth2-pam-freebsd.c,v 1.11 2003/03/31 13:48:18 des Exp $ */ | 48 | /* Based on $FreeBSD: src/crypto/openssh/auth2-pam-freebsd.c,v 1.11 2003/03/31 13:48:18 des Exp $ */ |
49 | #include "includes.h" | 49 | #include "includes.h" |
50 | RCSID("$Id: auth-pam.c,v 1.128 2006/01/29 05:46:13 dtucker Exp $"); | 50 | |
51 | #include <sys/types.h> | ||
52 | #include <sys/stat.h> | ||
53 | #include <sys/wait.h> | ||
54 | |||
55 | #include <errno.h> | ||
56 | #include <signal.h> | ||
57 | #include <stdarg.h> | ||
58 | #include <string.h> | ||
59 | #include <unistd.h> | ||
51 | 60 | ||
52 | #ifdef USE_PAM | 61 | #ifdef USE_PAM |
53 | #if defined(HAVE_SECURITY_PAM_APPL_H) | 62 | #if defined(HAVE_SECURITY_PAM_APPL_H) |
@@ -63,20 +72,31 @@ RCSID("$Id: auth-pam.c,v 1.128 2006/01/29 05:46:13 dtucker Exp $"); | |||
63 | # define sshpam_const const /* LinuxPAM, OpenPAM */ | 72 | # define sshpam_const const /* LinuxPAM, OpenPAM */ |
64 | #endif | 73 | #endif |
65 | 74 | ||
75 | /* Ambiguity in spec: is it an array of pointers or a pointer to an array? */ | ||
76 | #ifdef PAM_SUN_CODEBASE | ||
77 | # define PAM_MSG_MEMBER(msg, n, member) ((*(msg))[(n)].member) | ||
78 | #else | ||
79 | # define PAM_MSG_MEMBER(msg, n, member) ((msg)[(n)]->member) | ||
80 | #endif | ||
81 | |||
82 | #include "xmalloc.h" | ||
83 | #include "buffer.h" | ||
84 | #include "key.h" | ||
85 | #include "hostfile.h" | ||
66 | #include "auth.h" | 86 | #include "auth.h" |
67 | #include "auth-pam.h" | 87 | #include "auth-pam.h" |
68 | #include "buffer.h" | ||
69 | #include "bufaux.h" | ||
70 | #include "canohost.h" | 88 | #include "canohost.h" |
71 | #include "log.h" | 89 | #include "log.h" |
72 | #include "monitor_wrap.h" | ||
73 | #include "msg.h" | 90 | #include "msg.h" |
74 | #include "packet.h" | 91 | #include "packet.h" |
75 | #include "misc.h" | 92 | #include "misc.h" |
76 | #include "servconf.h" | 93 | #include "servconf.h" |
77 | #include "ssh2.h" | 94 | #include "ssh2.h" |
78 | #include "xmalloc.h" | ||
79 | #include "auth-options.h" | 95 | #include "auth-options.h" |
96 | #ifdef GSSAPI | ||
97 | #include "ssh-gss.h" | ||
98 | #endif | ||
99 | #include "monitor_wrap.h" | ||
80 | 100 | ||
81 | extern ServerOptions options; | 101 | extern ServerOptions options; |
82 | extern Buffer loginmsg; | 102 | extern Buffer loginmsg; |
@@ -146,14 +166,16 @@ sshpam_sigchld_handler(int sig) | |||
146 | fatal("PAM: authentication thread exited uncleanly"); | 166 | fatal("PAM: authentication thread exited uncleanly"); |
147 | } | 167 | } |
148 | 168 | ||
169 | /* ARGSUSED */ | ||
149 | static void | 170 | static void |
150 | pthread_exit(void *value __unused) | 171 | pthread_exit(void *value) |
151 | { | 172 | { |
152 | _exit(0); | 173 | _exit(0); |
153 | } | 174 | } |
154 | 175 | ||
176 | /* ARGSUSED */ | ||
155 | static int | 177 | static int |
156 | pthread_create(sp_pthread_t *thread, const void *attr __unused, | 178 | pthread_create(sp_pthread_t *thread, const void *attr, |
157 | void *(*thread_start)(void *), void *arg) | 179 | void *(*thread_start)(void *), void *arg) |
158 | { | 180 | { |
159 | pid_t pid; | 181 | pid_t pid; |
@@ -185,8 +207,9 @@ pthread_cancel(sp_pthread_t thread) | |||
185 | return (kill(thread, SIGTERM)); | 207 | return (kill(thread, SIGTERM)); |
186 | } | 208 | } |
187 | 209 | ||
210 | /* ARGSUSED */ | ||
188 | static int | 211 | static int |
189 | pthread_join(sp_pthread_t thread, void **value __unused) | 212 | pthread_join(sp_pthread_t thread, void **value) |
190 | { | 213 | { |
191 | int status; | 214 | int status; |
192 | 215 | ||
@@ -284,7 +307,10 @@ import_environments(Buffer *b) | |||
284 | 307 | ||
285 | /* Import environment from subprocess */ | 308 | /* Import environment from subprocess */ |
286 | num_env = buffer_get_int(b); | 309 | num_env = buffer_get_int(b); |
287 | sshpam_env = xmalloc((num_env + 1) * sizeof(*sshpam_env)); | 310 | if (num_env > 1024) |
311 | fatal("%s: received %u environment variables, expected <= 1024", | ||
312 | __func__, num_env); | ||
313 | sshpam_env = xcalloc(num_env + 1, sizeof(*sshpam_env)); | ||
288 | debug3("PAM: num env strings %d", num_env); | 314 | debug3("PAM: num env strings %d", num_env); |
289 | for(i = 0; i < num_env; i++) | 315 | for(i = 0; i < num_env; i++) |
290 | sshpam_env[i] = buffer_get_string(b, NULL); | 316 | sshpam_env[i] = buffer_get_string(b, NULL); |
@@ -331,9 +357,8 @@ sshpam_thread_conv(int n, sshpam_const struct pam_message **msg, | |||
331 | if (n <= 0 || n > PAM_MAX_NUM_MSG) | 357 | if (n <= 0 || n > PAM_MAX_NUM_MSG) |
332 | return (PAM_CONV_ERR); | 358 | return (PAM_CONV_ERR); |
333 | 359 | ||
334 | if ((reply = malloc(n * sizeof(*reply))) == NULL) | 360 | if ((reply = calloc(n, sizeof(*reply))) == NULL) |
335 | return (PAM_CONV_ERR); | 361 | return (PAM_CONV_ERR); |
336 | memset(reply, 0, n * sizeof(*reply)); | ||
337 | 362 | ||
338 | buffer_init(&buffer); | 363 | buffer_init(&buffer); |
339 | for (i = 0; i < n; ++i) { | 364 | for (i = 0; i < n; ++i) { |
@@ -412,10 +437,16 @@ sshpam_thread(void *ctxtp) | |||
412 | u_int i; | 437 | u_int i; |
413 | const char *pam_user; | 438 | const char *pam_user; |
414 | const char **ptr_pam_user = &pam_user; | 439 | const char **ptr_pam_user = &pam_user; |
440 | char *tz = getenv("TZ"); | ||
415 | 441 | ||
416 | pam_get_item(sshpam_handle, PAM_USER, | 442 | pam_get_item(sshpam_handle, PAM_USER, |
417 | (sshpam_const void **)ptr_pam_user); | 443 | (sshpam_const void **)ptr_pam_user); |
444 | |||
418 | environ[0] = NULL; | 445 | environ[0] = NULL; |
446 | if (tz != NULL) | ||
447 | if (setenv("TZ", tz, 1) == -1) | ||
448 | error("PAM: could not set TZ environment: %s", | ||
449 | strerror(errno)); | ||
419 | 450 | ||
420 | if (sshpam_authctxt != NULL) { | 451 | if (sshpam_authctxt != NULL) { |
421 | setproctitle("%s [pam]", | 452 | setproctitle("%s [pam]", |
@@ -439,8 +470,10 @@ sshpam_thread(void *ctxtp) | |||
439 | goto auth_fail; | 470 | goto auth_fail; |
440 | 471 | ||
441 | if (compat20) { | 472 | if (compat20) { |
442 | if (!do_pam_account()) | 473 | if (!do_pam_account()) { |
474 | sshpam_err = PAM_ACCT_EXPIRED; | ||
443 | goto auth_fail; | 475 | goto auth_fail; |
476 | } | ||
444 | if (sshpam_authctxt->force_pwchange) { | 477 | if (sshpam_authctxt->force_pwchange) { |
445 | sshpam_err = pam_chauthtok(sshpam_handle, | 478 | sshpam_err = pam_chauthtok(sshpam_handle, |
446 | PAM_CHANGE_EXPIRED_AUTHTOK); | 479 | PAM_CHANGE_EXPIRED_AUTHTOK); |
@@ -482,7 +515,10 @@ sshpam_thread(void *ctxtp) | |||
482 | buffer_put_cstring(&buffer, | 515 | buffer_put_cstring(&buffer, |
483 | pam_strerror(sshpam_handle, sshpam_err)); | 516 | pam_strerror(sshpam_handle, sshpam_err)); |
484 | /* XXX - can't do much about an error here */ | 517 | /* XXX - can't do much about an error here */ |
485 | ssh_msg_send(ctxt->pam_csock, PAM_AUTH_ERR, &buffer); | 518 | if (sshpam_err == PAM_ACCT_EXPIRED) |
519 | ssh_msg_send(ctxt->pam_csock, PAM_ACCT_EXPIRED, &buffer); | ||
520 | else | ||
521 | ssh_msg_send(ctxt->pam_csock, PAM_AUTH_ERR, &buffer); | ||
486 | buffer_free(&buffer); | 522 | buffer_free(&buffer); |
487 | pthread_exit(NULL); | 523 | pthread_exit(NULL); |
488 | 524 | ||
@@ -529,9 +565,8 @@ sshpam_store_conv(int n, sshpam_const struct pam_message **msg, | |||
529 | if (n <= 0 || n > PAM_MAX_NUM_MSG) | 565 | if (n <= 0 || n > PAM_MAX_NUM_MSG) |
530 | return (PAM_CONV_ERR); | 566 | return (PAM_CONV_ERR); |
531 | 567 | ||
532 | if ((reply = malloc(n * sizeof(*reply))) == NULL) | 568 | if ((reply = calloc(n, sizeof(*reply))) == NULL) |
533 | return (PAM_CONV_ERR); | 569 | return (PAM_CONV_ERR); |
534 | memset(reply, 0, n * sizeof(*reply)); | ||
535 | 570 | ||
536 | for (i = 0; i < n; ++i) { | 571 | for (i = 0; i < n; ++i) { |
537 | switch (PAM_MSG_MEMBER(msg, i, msg_style)) { | 572 | switch (PAM_MSG_MEMBER(msg, i, msg_style)) { |
@@ -638,8 +673,11 @@ sshpam_init_ctx(Authctxt *authctxt) | |||
638 | int socks[2]; | 673 | int socks[2]; |
639 | 674 | ||
640 | debug3("PAM: %s entering", __func__); | 675 | debug3("PAM: %s entering", __func__); |
641 | /* Refuse to start if we don't have PAM enabled */ | 676 | /* |
642 | if (!options.use_pam) | 677 | * Refuse to start if we don't have PAM enabled or do_pam_account |
678 | * has previously failed. | ||
679 | */ | ||
680 | if (!options.use_pam || sshpam_account_status == 0) | ||
643 | return NULL; | 681 | return NULL; |
644 | 682 | ||
645 | /* Initialize PAM */ | 683 | /* Initialize PAM */ |
@@ -699,7 +737,7 @@ sshpam_query(void *ctx, char **name, char **info, | |||
699 | case PAM_PROMPT_ECHO_OFF: | 737 | case PAM_PROMPT_ECHO_OFF: |
700 | *num = 1; | 738 | *num = 1; |
701 | len = plen + mlen + 1; | 739 | len = plen + mlen + 1; |
702 | **prompts = xrealloc(**prompts, len); | 740 | **prompts = xrealloc(**prompts, 1, len); |
703 | strlcpy(**prompts + plen, msg, len - plen); | 741 | strlcpy(**prompts + plen, msg, len - plen); |
704 | plen += mlen; | 742 | plen += mlen; |
705 | **echo_on = (type == PAM_PROMPT_ECHO_ON); | 743 | **echo_on = (type == PAM_PROMPT_ECHO_ON); |
@@ -709,21 +747,25 @@ sshpam_query(void *ctx, char **name, char **info, | |||
709 | case PAM_TEXT_INFO: | 747 | case PAM_TEXT_INFO: |
710 | /* accumulate messages */ | 748 | /* accumulate messages */ |
711 | len = plen + mlen + 2; | 749 | len = plen + mlen + 2; |
712 | **prompts = xrealloc(**prompts, len); | 750 | **prompts = xrealloc(**prompts, 1, len); |
713 | strlcpy(**prompts + plen, msg, len - plen); | 751 | strlcpy(**prompts + plen, msg, len - plen); |
714 | plen += mlen; | 752 | plen += mlen; |
715 | strlcat(**prompts + plen, "\n", len - plen); | 753 | strlcat(**prompts + plen, "\n", len - plen); |
716 | plen++; | 754 | plen++; |
717 | xfree(msg); | 755 | xfree(msg); |
718 | break; | 756 | break; |
757 | case PAM_ACCT_EXPIRED: | ||
758 | sshpam_account_status = 0; | ||
759 | /* FALLTHROUGH */ | ||
719 | case PAM_AUTH_ERR: | 760 | case PAM_AUTH_ERR: |
720 | debug3("PAM: PAM_AUTH_ERR"); | 761 | debug3("PAM: %s", pam_strerror(sshpam_handle, type)); |
721 | if (**prompts != NULL && strlen(**prompts) != 0) { | 762 | if (**prompts != NULL && strlen(**prompts) != 0) { |
722 | *info = **prompts; | 763 | *info = **prompts; |
723 | **prompts = NULL; | 764 | **prompts = NULL; |
724 | *num = 0; | 765 | *num = 0; |
725 | **echo_on = 0; | 766 | **echo_on = 0; |
726 | ctxt->pam_done = -1; | 767 | ctxt->pam_done = -1; |
768 | xfree(msg); | ||
727 | return 0; | 769 | return 0; |
728 | } | 770 | } |
729 | /* FALLTHROUGH */ | 771 | /* FALLTHROUGH */ |
@@ -930,9 +972,8 @@ sshpam_tty_conv(int n, sshpam_const struct pam_message **msg, | |||
930 | if (n <= 0 || n > PAM_MAX_NUM_MSG || !isatty(STDIN_FILENO)) | 972 | if (n <= 0 || n > PAM_MAX_NUM_MSG || !isatty(STDIN_FILENO)) |
931 | return (PAM_CONV_ERR); | 973 | return (PAM_CONV_ERR); |
932 | 974 | ||
933 | if ((reply = malloc(n * sizeof(*reply))) == NULL) | 975 | if ((reply = calloc(n, sizeof(*reply))) == NULL) |
934 | return (PAM_CONV_ERR); | 976 | return (PAM_CONV_ERR); |
935 | memset(reply, 0, n * sizeof(*reply)); | ||
936 | 977 | ||
937 | for (i = 0; i < n; ++i) { | 978 | for (i = 0; i < n; ++i) { |
938 | switch (PAM_MSG_MEMBER(msg, i, msg_style)) { | 979 | switch (PAM_MSG_MEMBER(msg, i, msg_style)) { |