Deleted Added
sdiff udiff text old ( 157019 ) new ( 162856 )
full compact
1/*-
2 * Copyright (c) 2002 Networks Associates Technology, Inc.
3 * All rights reserved.
4 *
5 * This software was developed for the FreeBSD Project by ThinkSec AS and
6 * NAI Labs, the Security Research Division of Network Associates, Inc.
7 * under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the
8 * DARPA CHATS research program.

--- 33 unchanged lines hidden (view full) ---

42 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
43 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
44 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
45 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
46 */
47
48/* Based on $xFreeBSD: src/crypto/openssh/auth2-pam-freebsd.c,v 1.11 2003/03/31 13:48:18 des Exp $ */
49#include "includes.h"
50RCSID("$Id: auth-pam.c,v 1.128 2006/01/29 05:46:13 dtucker Exp $");
51RCSID("$FreeBSD: head/crypto/openssh/auth-pam.c 157019 2006-03-22 20:41:37Z des $");
52
53#ifdef USE_PAM
54#if defined(HAVE_SECURITY_PAM_APPL_H)
55#include <security/pam_appl.h>
56#elif defined (HAVE_PAM_PAM_APPL_H)
57#include <pam/pam_appl.h>
58#endif
59
60/* OpenGroup RFC86.0 and XSSO specify no "const" on arguments */
61#ifdef PAM_SUN_CODEBASE
62# define sshpam_const /* Solaris, HP-UX, AIX */
63#else
64# define sshpam_const const /* LinuxPAM, OpenPAM */
65#endif
66
67#include "auth.h"
68#include "auth-pam.h"
69#include "buffer.h"
70#include "bufaux.h"
71#include "canohost.h"
72#include "log.h"
73#include "monitor_wrap.h"
74#include "msg.h"
75#include "packet.h"
76#include "misc.h"
77#include "servconf.h"
78#include "ssh2.h"
79#include "xmalloc.h"
80#include "auth-options.h"
81
82extern ServerOptions options;
83extern Buffer loginmsg;
84extern int compat20;
85extern u_int utmp_len;
86
87/* so we don't silently change behaviour */
88#ifdef USE_POSIX_THREADS

--- 53 unchanged lines hidden (view full) ---

142 WTERMSIG(sshpam_thread_status) == SIGTERM)
143 return; /* terminated by pthread_cancel */
144 if (!WIFEXITED(sshpam_thread_status))
145 fatal("PAM: authentication thread exited unexpectedly");
146 if (WEXITSTATUS(sshpam_thread_status) != 0)
147 fatal("PAM: authentication thread exited uncleanly");
148}
149
150static void
151pthread_exit(void *value __unused)
152{
153 _exit(0);
154}
155
156static int
157pthread_create(sp_pthread_t *thread, const void *attr __unused,
158 void *(*thread_start)(void *), void *arg)
159{
160 pid_t pid;
161 struct pam_ctxt *ctx = arg;
162
163 sshpam_thread_status = -1;
164 switch ((pid = fork())) {
165 case -1:

--- 15 unchanged lines hidden (view full) ---

181
182static int
183pthread_cancel(sp_pthread_t thread)
184{
185 signal(SIGCHLD, sshpam_oldsig);
186 return (kill(thread, SIGTERM));
187}
188
189static int
190pthread_join(sp_pthread_t thread, void **value __unused)
191{
192 int status;
193
194 if (sshpam_thread_status != -1)
195 return (sshpam_thread_status);
196 signal(SIGCHLD, sshpam_oldsig);
197 waitpid(thread, &status, 0);
198 return (status);

--- 81 unchanged lines hidden (view full) ---

280
281#ifndef UNSUPPORTED_POSIX_THREADS_HACK
282 /* Import variables set by do_pam_account */
283 sshpam_account_status = buffer_get_int(b);
284 sshpam_password_change_required(buffer_get_int(b));
285
286 /* Import environment from subprocess */
287 num_env = buffer_get_int(b);
288 sshpam_env = xmalloc((num_env + 1) * sizeof(*sshpam_env));
289 debug3("PAM: num env strings %d", num_env);
290 for(i = 0; i < num_env; i++)
291 sshpam_env[i] = buffer_get_string(b, NULL);
292
293 sshpam_env[num_env] = NULL;
294
295 /* Import PAM environment from subprocess */
296 num_env = buffer_get_int(b);

--- 30 unchanged lines hidden (view full) ---

327 if (data == NULL) {
328 error("PAM: conversation function passed a null context");
329 return (PAM_CONV_ERR);
330 }
331 ctxt = data;
332 if (n <= 0 || n > PAM_MAX_NUM_MSG)
333 return (PAM_CONV_ERR);
334
335 if ((reply = malloc(n * sizeof(*reply))) == NULL)
336 return (PAM_CONV_ERR);
337 memset(reply, 0, n * sizeof(*reply));
338
339 buffer_init(&buffer);
340 for (i = 0; i < n; ++i) {
341 switch (PAM_MSG_MEMBER(msg, i, msg_style)) {
342 case PAM_PROMPT_ECHO_OFF:
343 buffer_put_cstring(&buffer,
344 PAM_MSG_MEMBER(msg, i, msg));
345 if (ssh_msg_send(ctxt->pam_csock,

--- 62 unchanged lines hidden (view full) ---

408 int flags = (options.permit_empty_passwd == 0 ?
409 PAM_DISALLOW_NULL_AUTHTOK : 0);
410#ifndef UNSUPPORTED_POSIX_THREADS_HACK
411 extern char **environ;
412 char **env_from_pam;
413 u_int i;
414 const char *pam_user;
415 const char **ptr_pam_user = &pam_user;
416
417 pam_get_item(sshpam_handle, PAM_USER,
418 (sshpam_const void **)ptr_pam_user);
419 environ[0] = NULL;
420
421 if (sshpam_authctxt != NULL) {
422 setproctitle("%s [pam]",
423 sshpam_authctxt->valid ? pam_user : "unknown");
424 }
425#endif
426
427 sshpam_conv.conv = sshpam_thread_conv;

--- 7 unchanged lines hidden (view full) ---

435 (const void *)&sshpam_conv);
436 if (sshpam_err != PAM_SUCCESS)
437 goto auth_fail;
438 sshpam_err = pam_authenticate(sshpam_handle, flags);
439 if (sshpam_err != PAM_SUCCESS)
440 goto auth_fail;
441
442 if (compat20) {
443 if (!do_pam_account())
444 goto auth_fail;
445 if (sshpam_authctxt->force_pwchange) {
446 sshpam_err = pam_chauthtok(sshpam_handle,
447 PAM_CHANGE_EXPIRED_AUTHTOK);
448 if (sshpam_err != PAM_SUCCESS)
449 goto auth_fail;
450 sshpam_password_change_required(0);
451 }
452 }

--- 25 unchanged lines hidden (view full) ---

478 ssh_msg_send(ctxt->pam_csock, sshpam_err, &buffer);
479 buffer_free(&buffer);
480 pthread_exit(NULL);
481
482 auth_fail:
483 buffer_put_cstring(&buffer,
484 pam_strerror(sshpam_handle, sshpam_err));
485 /* XXX - can't do much about an error here */
486 ssh_msg_send(ctxt->pam_csock, PAM_AUTH_ERR, &buffer);
487 buffer_free(&buffer);
488 pthread_exit(NULL);
489
490 return (NULL); /* Avoid warning for non-pthread case */
491}
492
493void
494sshpam_thread_cleanup(void)

--- 30 unchanged lines hidden (view full) ---

525 size_t len;
526
527 debug3("PAM: %s called with %d messages", __func__, n);
528 *resp = NULL;
529
530 if (n <= 0 || n > PAM_MAX_NUM_MSG)
531 return (PAM_CONV_ERR);
532
533 if ((reply = malloc(n * sizeof(*reply))) == NULL)
534 return (PAM_CONV_ERR);
535 memset(reply, 0, n * sizeof(*reply));
536
537 for (i = 0; i < n; ++i) {
538 switch (PAM_MSG_MEMBER(msg, i, msg_style)) {
539 case PAM_ERROR_MSG:
540 case PAM_TEXT_INFO:
541 len = strlen(PAM_MSG_MEMBER(msg, i, msg));
542 buffer_append(&loginmsg, PAM_MSG_MEMBER(msg, i, msg), len);
543 buffer_append(&loginmsg, "\n", 1 );

--- 90 unchanged lines hidden (view full) ---

634
635static void *
636sshpam_init_ctx(Authctxt *authctxt)
637{
638 struct pam_ctxt *ctxt;
639 int socks[2];
640
641 debug3("PAM: %s entering", __func__);
642 /* Refuse to start if we don't have PAM enabled */
643 if (!options.use_pam)
644 return NULL;
645
646 /* Initialize PAM */
647 if (sshpam_init(authctxt) == -1) {
648 error("PAM: initialization failed");
649 return (NULL);
650 }
651

--- 43 unchanged lines hidden (view full) ---

695 type = buffer_get_char(&buffer);
696 msg = buffer_get_string(&buffer, NULL);
697 mlen = strlen(msg);
698 switch (type) {
699 case PAM_PROMPT_ECHO_ON:
700 case PAM_PROMPT_ECHO_OFF:
701 *num = 1;
702 len = plen + mlen + 1;
703 **prompts = xrealloc(**prompts, len);
704 strlcpy(**prompts + plen, msg, len - plen);
705 plen += mlen;
706 **echo_on = (type == PAM_PROMPT_ECHO_ON);
707 xfree(msg);
708 return (0);
709 case PAM_ERROR_MSG:
710 case PAM_TEXT_INFO:
711 /* accumulate messages */
712 len = plen + mlen + 2;
713 **prompts = xrealloc(**prompts, len);
714 strlcpy(**prompts + plen, msg, len - plen);
715 plen += mlen;
716 strlcat(**prompts + plen, "\n", len - plen);
717 plen++;
718 xfree(msg);
719 break;
720 case PAM_AUTH_ERR:
721 debug3("PAM: PAM_AUTH_ERR");
722 if (**prompts != NULL && strlen(**prompts) != 0) {
723 *info = **prompts;
724 **prompts = NULL;
725 *num = 0;
726 **echo_on = 0;
727 ctxt->pam_done = -1;
728 return 0;
729 }
730 /* FALLTHROUGH */
731 case PAM_SUCCESS:
732 if (**prompts != NULL) {
733 /* drain any accumulated messages */
734 debug("PAM: %s", **prompts);
735 buffer_append(&loginmsg, **prompts,

--- 190 unchanged lines hidden (view full) ---

926
927 debug3("PAM: %s called with %d messages", __func__, n);
928
929 *resp = NULL;
930
931 if (n <= 0 || n > PAM_MAX_NUM_MSG || !isatty(STDIN_FILENO))
932 return (PAM_CONV_ERR);
933
934 if ((reply = malloc(n * sizeof(*reply))) == NULL)
935 return (PAM_CONV_ERR);
936 memset(reply, 0, n * sizeof(*reply));
937
938 for (i = 0; i < n; ++i) {
939 switch (PAM_MSG_MEMBER(msg, i, msg_style)) {
940 case PAM_PROMPT_ECHO_OFF:
941 reply[i].resp =
942 read_passphrase(PAM_MSG_MEMBER(msg, i, msg),
943 RP_ALLOW_STDIN);
944 reply[i].resp_retcode = PAM_SUCCESS;

--- 236 unchanged lines hidden ---