mirror of
git://anongit.mindrot.org/openssh.git
synced 2024-11-23 09:17:32 +08:00
- (djm) Merge FreeBSD PAM code: replaces PAM password auth kludge with
proper challenge-response module
This commit is contained in:
parent
c437cda328
commit
4f9f42a9bb
@ -3,6 +3,8 @@
|
||||
"make install". Patch by roth@feep.net.
|
||||
- (dtucker) Bug #536: Test for and work around openpty/controlling tty
|
||||
problem on Linux (fixes "could not set controlling tty" errors).
|
||||
- (djm) Merge FreeBSD PAM code: replaces PAM password auth kludge with
|
||||
proper challenge-response module
|
||||
|
||||
20030504
|
||||
- (dtucker) Bug #497: Move #include of bsd-cygwin_util.h to openbsd-compat.h.
|
||||
@ -1376,4 +1378,4 @@
|
||||
save auth method before monitor_reset_key_state(); bugzilla bug #284;
|
||||
ok provos@
|
||||
|
||||
$Id: ChangeLog,v 1.2672 2003/05/10 07:05:46 dtucker Exp $
|
||||
$Id: ChangeLog,v 1.2673 2003/05/10 09:28:02 djm Exp $
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $Id: Makefile.in,v 1.230 2003/05/10 06:48:23 dtucker Exp $
|
||||
# $Id: Makefile.in,v 1.231 2003/05/10 09:28:02 djm Exp $
|
||||
|
||||
# uncomment if you run a non bourne compatable shell. Ie. csh
|
||||
#SHELL = @SH@
|
||||
@ -81,7 +81,7 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o auth-rsa.o auth-rh-rsa.o \
|
||||
monitor_mm.o monitor.o monitor_wrap.o monitor_fdpass.o \
|
||||
kexdhs.o kexgexs.o \
|
||||
auth-krb5.o auth-krb4.o \
|
||||
loginrec.o auth-pam.o auth2-pam.o auth-sia.o md5crypt.o
|
||||
loginrec.o auth-pam.o auth-sia.o md5crypt.o
|
||||
|
||||
MANPAGES = scp.1.out ssh-add.1.out ssh-agent.1.out ssh-keygen.1.out ssh-keyscan.1.out ssh.1.out sshd.8.out sftp-server.8.out sftp.1.out ssh-rand-helper.8.out ssh-keysign.8.out sshd_config.5.out ssh_config.5.out
|
||||
MANPAGES_IN = scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1 ssh-rand-helper.8 ssh-keysign.8 sshd_config.5 ssh_config.5
|
||||
|
26
auth-chall.c
26
auth-chall.c
@ -76,7 +76,33 @@ verify_response(Authctxt *authctxt, const char *response)
|
||||
return 0;
|
||||
resp[0] = (char *)response;
|
||||
res = device->respond(authctxt->kbdintctxt, 1, resp);
|
||||
if (res == 1) {
|
||||
/* postponed - send a null query just in case */
|
||||
char *name, *info, **prompts;
|
||||
u_int i, numprompts, *echo_on;
|
||||
|
||||
res = device->query(authctxt->kbdintctxt, &name, &info,
|
||||
&numprompts, &prompts, &echo_on);
|
||||
if (res == 0) {
|
||||
for (i = 0; i < numprompts; i++)
|
||||
xfree(prompts[i]);
|
||||
xfree(prompts);
|
||||
xfree(name);
|
||||
xfree(echo_on);
|
||||
xfree(info);
|
||||
}
|
||||
/* if we received more prompts, we're screwed */
|
||||
res = (numprompts != 0);
|
||||
}
|
||||
device->free_ctx(authctxt->kbdintctxt);
|
||||
authctxt->kbdintctxt = NULL;
|
||||
return res ? 0 : 1;
|
||||
}
|
||||
void
|
||||
abandon_challenge_response(Authctxt *authctxt)
|
||||
{
|
||||
if (authctxt->kbdintctxt != NULL) {
|
||||
device->free_ctx(authctxt->kbdintctxt);
|
||||
authctxt->kbdintctxt = NULL;
|
||||
}
|
||||
}
|
||||
|
1009
auth-pam.c
1009
auth-pam.c
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,4 @@
|
||||
/* $Id: auth-pam.h,v 1.16 2002/07/23 00:44:07 stevesk Exp $ */
|
||||
/* $Id: auth-pam.h,v 1.17 2003/05/10 09:28:02 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000 Damien Miller. All rights reserved.
|
||||
@ -37,8 +37,8 @@ int auth_pam_password(Authctxt *authctxt, const char *password);
|
||||
char **fetch_pam_environment(void);
|
||||
void free_pam_environment(char **env);
|
||||
int do_pam_authenticate(int flags);
|
||||
int do_pam_account(char *username, char *remote_user);
|
||||
void do_pam_session(char *username, const char *ttyname);
|
||||
int do_pam_account(const char *user, const char *ruser);
|
||||
void do_pam_session(const char *user, const char *tty);
|
||||
void do_pam_setcred(int init);
|
||||
void print_pam_messages(void);
|
||||
int is_pam_password_change_required(void);
|
||||
|
@ -43,8 +43,8 @@ RCSID("$OpenBSD: auth-passwd.c,v 1.27 2002/05/24 16:45:16 stevesk Exp $");
|
||||
#include "servconf.h"
|
||||
#include "auth.h"
|
||||
|
||||
#if !defined(USE_PAM) && !defined(HAVE_OSF_SIA)
|
||||
/* Don't need any of these headers for the PAM or SIA cases */
|
||||
#if !defined(HAVE_OSF_SIA)
|
||||
/* Don't need any of these headers for the SIA cases */
|
||||
# ifdef HAVE_CRYPT_H
|
||||
# include <crypt.h>
|
||||
# endif
|
||||
@ -78,7 +78,7 @@ RCSID("$OpenBSD: auth-passwd.c,v 1.27 2002/05/24 16:45:16 stevesk Exp $");
|
||||
# include <sys/cygwin.h>
|
||||
# define is_winnt (GetVersion() < 0x80000000)
|
||||
# endif
|
||||
#endif /* !USE_PAM && !HAVE_OSF_SIA */
|
||||
#endif /* !HAVE_OSF_SIA */
|
||||
|
||||
extern ServerOptions options;
|
||||
#ifdef WITH_AIXAUTHENTICATE
|
||||
@ -94,7 +94,7 @@ auth_password(Authctxt *authctxt, const char *password)
|
||||
{
|
||||
struct passwd * pw = authctxt->pw;
|
||||
int ok = authctxt->valid;
|
||||
#if !defined(USE_PAM) && !defined(HAVE_OSF_SIA)
|
||||
#if !defined(HAVE_OSF_SIA)
|
||||
char *encrypted_password;
|
||||
char *pw_password;
|
||||
char *salt;
|
||||
@ -112,7 +112,7 @@ auth_password(Authctxt *authctxt, const char *password)
|
||||
int authsuccess;
|
||||
int reenter = 1;
|
||||
# endif
|
||||
#endif /* !defined(USE_PAM) && !defined(HAVE_OSF_SIA) */
|
||||
#endif /* !defined(HAVE_OSF_SIA) */
|
||||
|
||||
/* deny if no user. */
|
||||
if (pw == NULL)
|
||||
@ -124,9 +124,7 @@ auth_password(Authctxt *authctxt, const char *password)
|
||||
if (*password == '\0' && options.permit_empty_passwd == 0)
|
||||
ok = 0;
|
||||
|
||||
#if defined(USE_PAM)
|
||||
return auth_pam_password(authctxt, password) && ok;
|
||||
#elif defined(HAVE_OSF_SIA)
|
||||
#if defined(HAVE_OSF_SIA)
|
||||
if (!ok)
|
||||
return 0;
|
||||
return auth_sia_password(authctxt, password);
|
||||
@ -235,5 +233,5 @@ auth_password(Authctxt *authctxt, const char *password)
|
||||
|
||||
/* Authentication is accepted if the encrypted passwords are identical. */
|
||||
return (strcmp(encrypted_password, pw_password) == 0);
|
||||
#endif /* !USE_PAM && !HAVE_OSF_SIA */
|
||||
#endif /* !HAVE_OSF_SIA */
|
||||
}
|
||||
|
3
auth.h
3
auth.h
@ -1,4 +1,5 @@
|
||||
/* $OpenBSD: auth.h,v 1.41 2002/09/26 11:38:43 markus Exp $ */
|
||||
/* $FreeBSD: src/crypto/openssh/auth.h,v 1.10 2003/03/31 13:45:36 des Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
@ -133,7 +134,6 @@ void krb5_cleanup_proc(void *authctxt);
|
||||
#endif /* KRB5 */
|
||||
|
||||
#include "auth-pam.h"
|
||||
#include "auth2-pam.h"
|
||||
|
||||
Authctxt *do_authentication(void);
|
||||
Authctxt *do_authentication2(void);
|
||||
@ -159,6 +159,7 @@ struct passwd * getpwnamallow(const char *user);
|
||||
|
||||
char *get_challenge(Authctxt *);
|
||||
int verify_response(Authctxt *, const char *);
|
||||
void abandon_challenge_response(Authctxt *);
|
||||
|
||||
struct passwd * auth_get_user(void);
|
||||
|
||||
|
14
auth1.c
14
auth1.c
@ -73,7 +73,7 @@ do_authloop(Authctxt *authctxt)
|
||||
char info[1024];
|
||||
u_int dlen;
|
||||
u_int ulen;
|
||||
int type = 0;
|
||||
int prev, type = 0;
|
||||
struct passwd *pw = authctxt->pw;
|
||||
|
||||
debug("Attempting authentication for %s%.100s.",
|
||||
@ -103,8 +103,20 @@ do_authloop(Authctxt *authctxt)
|
||||
info[0] = '\0';
|
||||
|
||||
/* Get a packet from the client. */
|
||||
prev = type;
|
||||
type = packet_read();
|
||||
|
||||
/*
|
||||
* If we started challenge-response authentication but the
|
||||
* next packet is not a response to our challenge, release
|
||||
* the resources allocated by get_challenge() (which would
|
||||
* normally have been released by verify_response() had we
|
||||
* received such a response)
|
||||
*/
|
||||
if (prev == SSH_CMSG_AUTH_TIS &&
|
||||
type != SSH_CMSG_AUTH_TIS_RESPONSE)
|
||||
abandon_challenge_response(authctxt);
|
||||
|
||||
/* Process the packet. */
|
||||
switch (type) {
|
||||
|
||||
|
@ -41,6 +41,9 @@ static void input_userauth_info_response(int, u_int32_t, void *);
|
||||
#ifdef BSD_AUTH
|
||||
extern KbdintDevice bsdauth_device;
|
||||
#else
|
||||
#ifdef USE_PAM
|
||||
extern KbdintDevice sshpam_device;
|
||||
#endif
|
||||
#ifdef SKEY
|
||||
extern KbdintDevice skey_device;
|
||||
#endif
|
||||
@ -50,6 +53,9 @@ KbdintDevice *devices[] = {
|
||||
#ifdef BSD_AUTH
|
||||
&bsdauth_device,
|
||||
#else
|
||||
#ifdef USE_PAM
|
||||
&sshpam_device,
|
||||
#endif
|
||||
#ifdef SKEY
|
||||
&skey_device,
|
||||
#endif
|
||||
@ -323,15 +329,22 @@ privsep_challenge_enable(void)
|
||||
#ifdef BSD_AUTH
|
||||
extern KbdintDevice mm_bsdauth_device;
|
||||
#endif
|
||||
#ifdef USE_PAM
|
||||
extern KbdintDevice mm_sshpam_device;
|
||||
#endif
|
||||
#ifdef SKEY
|
||||
extern KbdintDevice mm_skey_device;
|
||||
#endif
|
||||
/* As long as SSHv1 has devices[0] hard coded this is fine */
|
||||
int n = 0;
|
||||
|
||||
#ifdef BSD_AUTH
|
||||
devices[0] = &mm_bsdauth_device;
|
||||
devices[n++] = &mm_bsdauth_device;
|
||||
#else
|
||||
#ifdef USE_PAM
|
||||
devices[n++] = &mm_sshpam_device;
|
||||
#endif
|
||||
#ifdef SKEY
|
||||
devices[0] = &mm_skey_device;
|
||||
devices[n++] = &mm_skey_device;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
@ -49,10 +49,6 @@ userauth_kbdint(Authctxt *authctxt)
|
||||
if (options.challenge_response_authentication)
|
||||
authenticated = auth2_challenge(authctxt, devs);
|
||||
|
||||
#ifdef USE_PAM
|
||||
if (authenticated == 0 && options.pam_authentication_via_kbd_int)
|
||||
authenticated = auth2_pam(authctxt);
|
||||
#endif
|
||||
xfree(devs);
|
||||
xfree(lang);
|
||||
#ifdef HAVE_CYGWIN
|
||||
|
165
auth2-pam.c
165
auth2-pam.c
@ -1,165 +0,0 @@
|
||||
#include "includes.h"
|
||||
RCSID("$Id: auth2-pam.c,v 1.15 2003/01/08 01:37:03 djm Exp $");
|
||||
|
||||
#ifdef USE_PAM
|
||||
#include <security/pam_appl.h>
|
||||
|
||||
#include "ssh.h"
|
||||
#include "ssh2.h"
|
||||
#include "auth.h"
|
||||
#include "auth-pam.h"
|
||||
#include "packet.h"
|
||||
#include "xmalloc.h"
|
||||
#include "dispatch.h"
|
||||
#include "log.h"
|
||||
|
||||
static int do_pam_conversation_kbd_int(int num_msg,
|
||||
const struct pam_message **msg, struct pam_response **resp,
|
||||
void *appdata_ptr);
|
||||
void input_userauth_info_response_pam(int type, u_int32_t seqnr, void *ctxt);
|
||||
|
||||
struct {
|
||||
int finished, num_received, num_expected;
|
||||
int *prompts;
|
||||
struct pam_response *responses;
|
||||
} context_pam2 = {0, 0, 0, NULL};
|
||||
|
||||
static struct pam_conv conv2 = {
|
||||
do_pam_conversation_kbd_int,
|
||||
NULL,
|
||||
};
|
||||
|
||||
int
|
||||
auth2_pam(Authctxt *authctxt)
|
||||
{
|
||||
int retval = -1;
|
||||
|
||||
if (authctxt->user == NULL)
|
||||
fatal("auth2_pam: internal error: no user");
|
||||
|
||||
conv2.appdata_ptr = authctxt;
|
||||
do_pam_set_conv(&conv2);
|
||||
|
||||
dispatch_set(SSH2_MSG_USERAUTH_INFO_RESPONSE,
|
||||
&input_userauth_info_response_pam);
|
||||
retval = (do_pam_authenticate(0) == PAM_SUCCESS);
|
||||
dispatch_set(SSH2_MSG_USERAUTH_INFO_RESPONSE, NULL);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int
|
||||
do_pam_conversation_kbd_int(int num_msg, const struct pam_message **msg,
|
||||
struct pam_response **resp, void *appdata_ptr)
|
||||
{
|
||||
int i, j, done;
|
||||
char *text;
|
||||
|
||||
context_pam2.finished = 0;
|
||||
context_pam2.num_received = 0;
|
||||
context_pam2.num_expected = 0;
|
||||
context_pam2.prompts = xmalloc(sizeof(int) * num_msg);
|
||||
context_pam2.responses = xmalloc(sizeof(struct pam_response) * num_msg);
|
||||
memset(context_pam2.responses, 0, sizeof(struct pam_response) * num_msg);
|
||||
|
||||
text = NULL;
|
||||
for (i = 0, context_pam2.num_expected = 0; i < num_msg; i++) {
|
||||
int style = PAM_MSG_MEMBER(msg, i, msg_style);
|
||||
switch (style) {
|
||||
case PAM_PROMPT_ECHO_ON:
|
||||
case PAM_PROMPT_ECHO_OFF:
|
||||
context_pam2.num_expected++;
|
||||
break;
|
||||
case PAM_TEXT_INFO:
|
||||
case PAM_ERROR_MSG:
|
||||
default:
|
||||
/* Capture all these messages to be sent at once */
|
||||
message_cat(&text, PAM_MSG_MEMBER(msg, i, msg));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (context_pam2.num_expected == 0)
|
||||
return PAM_SUCCESS;
|
||||
|
||||
packet_start(SSH2_MSG_USERAUTH_INFO_REQUEST);
|
||||
packet_put_cstring(""); /* Name */
|
||||
packet_put_cstring(""); /* Instructions */
|
||||
packet_put_cstring(""); /* Language */
|
||||
packet_put_int(context_pam2.num_expected);
|
||||
|
||||
for (i = 0, j = 0; i < num_msg; i++) {
|
||||
int style = PAM_MSG_MEMBER(msg, i, msg_style);
|
||||
|
||||
/* Skip messages which don't need a reply */
|
||||
if (style != PAM_PROMPT_ECHO_ON && style != PAM_PROMPT_ECHO_OFF)
|
||||
continue;
|
||||
|
||||
context_pam2.prompts[j++] = i;
|
||||
if (text) {
|
||||
message_cat(&text, PAM_MSG_MEMBER(msg, i, msg));
|
||||
packet_put_cstring(text);
|
||||
text = NULL;
|
||||
} else
|
||||
packet_put_cstring(PAM_MSG_MEMBER(msg, i, msg));
|
||||
packet_put_char(style == PAM_PROMPT_ECHO_ON);
|
||||
}
|
||||
packet_send();
|
||||
packet_write_wait();
|
||||
|
||||
/*
|
||||
* Grabbing control of execution and spinning until we get what
|
||||
* we want is probably rude, but it seems to work properly, and
|
||||
* the client *should* be in lock-step with us, so the loop should
|
||||
* only be traversed once.
|
||||
*/
|
||||
while(context_pam2.finished == 0) {
|
||||
done = 1;
|
||||
dispatch_run(DISPATCH_BLOCK, &done, appdata_ptr);
|
||||
if (context_pam2.finished == 0)
|
||||
debug("extra packet during conversation");
|
||||
}
|
||||
|
||||
if (context_pam2.num_received == context_pam2.num_expected) {
|
||||
*resp = context_pam2.responses;
|
||||
return PAM_SUCCESS;
|
||||
} else
|
||||
return PAM_CONV_ERR;
|
||||
}
|
||||
|
||||
void
|
||||
input_userauth_info_response_pam(int type, u_int32_t seqnr, void *ctxt)
|
||||
{
|
||||
Authctxt *authctxt = ctxt;
|
||||
unsigned int nresp = 0, rlen = 0, i = 0;
|
||||
char *resp;
|
||||
|
||||
if (authctxt == NULL)
|
||||
fatal("input_userauth_info_response_pam: no authentication context");
|
||||
|
||||
nresp = packet_get_int(); /* Number of responses. */
|
||||
debug("got %d responses", nresp);
|
||||
|
||||
|
||||
if (nresp != context_pam2.num_expected)
|
||||
fatal("%s: Received incorrect number of responses "
|
||||
"(expected %d, received %u)", __func__,
|
||||
context_pam2.num_expected, nresp);
|
||||
|
||||
if (nresp > 100)
|
||||
fatal("%s: too many replies", __func__);
|
||||
|
||||
for (i = 0; i < nresp; i++) {
|
||||
int j = context_pam2.prompts[i];
|
||||
|
||||
resp = packet_get_string(&rlen);
|
||||
context_pam2.responses[j].resp_retcode = PAM_SUCCESS;
|
||||
context_pam2.responses[j].resp = resp;
|
||||
context_pam2.num_received++;
|
||||
}
|
||||
|
||||
context_pam2.finished = 1;
|
||||
|
||||
packet_check_eom();
|
||||
}
|
||||
#endif
|
@ -1,8 +0,0 @@
|
||||
/* $Id: auth2-pam.h,v 1.2 2001/02/09 01:55:36 djm Exp $ */
|
||||
|
||||
#include "includes.h"
|
||||
#ifdef USE_PAM
|
||||
|
||||
int auth2_pam(Authctxt *authctxt);
|
||||
|
||||
#endif /* USE_PAM */
|
@ -1,4 +1,4 @@
|
||||
# $Id: configure.ac,v 1.116 2003/05/10 07:05:46 dtucker Exp $
|
||||
# $Id: configure.ac,v 1.117 2003/05/10 09:28:02 djm Exp $
|
||||
|
||||
AC_INIT
|
||||
AC_CONFIG_SRCDIR([ssh.c])
|
||||
@ -963,7 +963,7 @@ int main(void) { exit(SSLeay() == OPENSSL_VERSION_NUMBER ? 0 : 1); }
|
||||
|
||||
# Some Linux systems (Slackware) need crypt() from libcrypt, *not* the
|
||||
# version in OpenSSL. Skip this for PAM
|
||||
if test "x$PAM_MSG" = "xno" -a "x$check_for_libcrypt_later" = "x1"; then
|
||||
if test "x$check_for_libcrypt_later" = "x1"; then
|
||||
AC_CHECK_LIB(crypt, crypt, LIBS="$LIBS -lcrypt")
|
||||
fi
|
||||
|
||||
|
113
monitor.c
113
monitor.c
@ -118,6 +118,10 @@ int mm_answer_sessid(int, Buffer *);
|
||||
|
||||
#ifdef USE_PAM
|
||||
int mm_answer_pam_start(int, Buffer *);
|
||||
int mm_answer_pam_init_ctx(int, Buffer *);
|
||||
int mm_answer_pam_query(int, Buffer *);
|
||||
int mm_answer_pam_respond(int, Buffer *);
|
||||
int mm_answer_pam_free_ctx(int, Buffer *);
|
||||
#endif
|
||||
|
||||
#ifdef KRB4
|
||||
@ -163,6 +167,10 @@ struct mon_table mon_dispatch_proto20[] = {
|
||||
{MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword},
|
||||
#ifdef USE_PAM
|
||||
{MONITOR_REQ_PAM_START, MON_ONCE, mm_answer_pam_start},
|
||||
{MONITOR_REQ_PAM_INIT_CTX, MON_ISAUTH, mm_answer_pam_init_ctx},
|
||||
{MONITOR_REQ_PAM_QUERY, MON_ISAUTH, mm_answer_pam_query},
|
||||
{MONITOR_REQ_PAM_RESPOND, MON_ISAUTH, mm_answer_pam_respond},
|
||||
{MONITOR_REQ_PAM_FREE_CTX, MON_ONCE|MON_AUTHDECIDE, mm_answer_pam_free_ctx},
|
||||
#endif
|
||||
#ifdef BSD_AUTH
|
||||
{MONITOR_REQ_BSDAUTHQUERY, MON_ISAUTH, mm_answer_bsdauthquery},
|
||||
@ -205,6 +213,10 @@ struct mon_table mon_dispatch_proto15[] = {
|
||||
#endif
|
||||
#ifdef USE_PAM
|
||||
{MONITOR_REQ_PAM_START, MON_ONCE, mm_answer_pam_start},
|
||||
{MONITOR_REQ_PAM_INIT_CTX, MON_ISAUTH, mm_answer_pam_init_ctx},
|
||||
{MONITOR_REQ_PAM_QUERY, MON_ISAUTH, mm_answer_pam_query},
|
||||
{MONITOR_REQ_PAM_RESPOND, MON_ISAUTH, mm_answer_pam_respond},
|
||||
{MONITOR_REQ_PAM_FREE_CTX, MON_ONCE|MON_AUTHDECIDE, mm_answer_pam_free_ctx},
|
||||
#endif
|
||||
#ifdef KRB4
|
||||
{MONITOR_REQ_KRB4, MON_ONCE|MON_AUTH, mm_answer_krb4},
|
||||
@ -285,10 +297,6 @@ monitor_child_preauth(struct monitor *pmonitor)
|
||||
if (authctxt->pw->pw_uid == 0 &&
|
||||
!auth_root_allowed(auth_method))
|
||||
authenticated = 0;
|
||||
#ifdef USE_PAM
|
||||
if (!do_pam_account(authctxt->pw->pw_name, NULL))
|
||||
authenticated = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (ent->flags & MON_AUTHDECIDE) {
|
||||
@ -747,6 +755,103 @@ mm_answer_pam_start(int socket, Buffer *m)
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void *sshpam_ctxt, *sshpam_authok;
|
||||
extern KbdintDevice sshpam_device;
|
||||
|
||||
int
|
||||
mm_answer_pam_init_ctx(int socket, Buffer *m)
|
||||
{
|
||||
|
||||
debug3("%s", __func__);
|
||||
authctxt->user = buffer_get_string(m, NULL);
|
||||
sshpam_ctxt = (sshpam_device.init_ctx)(authctxt);
|
||||
sshpam_authok = NULL;
|
||||
buffer_clear(m);
|
||||
if (sshpam_ctxt != NULL) {
|
||||
monitor_permit(mon_dispatch, MONITOR_REQ_PAM_FREE_CTX, 1);
|
||||
buffer_put_int(m, 1);
|
||||
} else {
|
||||
buffer_put_int(m, 0);
|
||||
}
|
||||
mm_request_send(socket, MONITOR_ANS_PAM_INIT_CTX, m);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
mm_answer_pam_query(int socket, Buffer *m)
|
||||
{
|
||||
char *name, *info, **prompts;
|
||||
u_int num, *echo_on;
|
||||
int i, ret;
|
||||
|
||||
debug3("%s", __func__);
|
||||
sshpam_authok = NULL;
|
||||
ret = (sshpam_device.query)(sshpam_ctxt, &name, &info, &num, &prompts, &echo_on);
|
||||
if (ret == 0 && num == 0)
|
||||
sshpam_authok = sshpam_ctxt;
|
||||
if (num > 1 || name == NULL || info == NULL)
|
||||
ret = -1;
|
||||
buffer_clear(m);
|
||||
buffer_put_int(m, ret);
|
||||
buffer_put_cstring(m, name);
|
||||
xfree(name);
|
||||
buffer_put_cstring(m, info);
|
||||
xfree(info);
|
||||
buffer_put_int(m, num);
|
||||
for (i = 0; i < num; ++i) {
|
||||
buffer_put_cstring(m, prompts[i]);
|
||||
xfree(prompts[i]);
|
||||
buffer_put_int(m, echo_on[i]);
|
||||
}
|
||||
if (prompts != NULL)
|
||||
xfree(prompts);
|
||||
if (echo_on != NULL)
|
||||
xfree(echo_on);
|
||||
mm_request_send(socket, MONITOR_ANS_PAM_QUERY, m);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
mm_answer_pam_respond(int socket, Buffer *m)
|
||||
{
|
||||
char **resp;
|
||||
u_int num;
|
||||
int i, ret;
|
||||
|
||||
debug3("%s", __func__);
|
||||
sshpam_authok = NULL;
|
||||
num = buffer_get_int(m);
|
||||
if (num > 0) {
|
||||
resp = xmalloc(num * sizeof(char *));
|
||||
for (i = 0; i < num; ++i)
|
||||
resp[i] = buffer_get_string(m, NULL);
|
||||
ret = (sshpam_device.respond)(sshpam_ctxt, num, resp);
|
||||
for (i = 0; i < num; ++i)
|
||||
xfree(resp[i]);
|
||||
xfree(resp);
|
||||
} else {
|
||||
ret = (sshpam_device.respond)(sshpam_ctxt, num, NULL);
|
||||
}
|
||||
buffer_clear(m);
|
||||
buffer_put_int(m, ret);
|
||||
mm_request_send(socket, MONITOR_ANS_PAM_RESPOND, m);
|
||||
auth_method = "keyboard-interactive/pam";
|
||||
if (ret == 0)
|
||||
sshpam_authok = sshpam_ctxt;
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
mm_answer_pam_free_ctx(int socket, Buffer *m)
|
||||
{
|
||||
|
||||
debug3("%s", __func__);
|
||||
(sshpam_device.free_ctx)(sshpam_ctxt);
|
||||
buffer_clear(m);
|
||||
mm_request_send(socket, MONITOR_ANS_PAM_FREE_CTX, m);
|
||||
return (sshpam_authok == sshpam_ctxt);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
|
@ -1,4 +1,5 @@
|
||||
/* $OpenBSD: monitor.h,v 1.8 2002/09/26 11:38:43 markus Exp $ */
|
||||
/* $FreeBSD: src/crypto/openssh/monitor.h,v 1.3 2002/10/29 10:16:02 des Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
|
||||
@ -52,6 +53,10 @@ enum monitor_reqtype {
|
||||
MONITOR_REQ_KRB4, MONITOR_ANS_KRB4,
|
||||
MONITOR_REQ_KRB5, MONITOR_ANS_KRB5,
|
||||
MONITOR_REQ_PAM_START,
|
||||
MONITOR_REQ_PAM_INIT_CTX, MONITOR_ANS_PAM_INIT_CTX,
|
||||
MONITOR_REQ_PAM_QUERY, MONITOR_ANS_PAM_QUERY,
|
||||
MONITOR_REQ_PAM_RESPOND, MONITOR_ANS_PAM_RESPOND,
|
||||
MONITOR_REQ_PAM_FREE_CTX, MONITOR_ANS_PAM_FREE_CTX,
|
||||
MONITOR_REQ_TERM
|
||||
};
|
||||
|
||||
|
@ -677,6 +677,88 @@ mm_start_pam(char *user)
|
||||
|
||||
buffer_free(&m);
|
||||
}
|
||||
|
||||
void *
|
||||
mm_sshpam_init_ctx(Authctxt *authctxt)
|
||||
{
|
||||
Buffer m;
|
||||
int success;
|
||||
|
||||
debug3("%s", __func__);
|
||||
buffer_init(&m);
|
||||
buffer_put_cstring(&m, authctxt->user);
|
||||
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_INIT_CTX, &m);
|
||||
debug3("%s: waiting for MONITOR_ANS_PAM_INIT_CTX", __func__);
|
||||
mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_INIT_CTX, &m);
|
||||
success = buffer_get_int(&m);
|
||||
if (success == 0) {
|
||||
debug3("%s: pam_init_ctx failed", __func__);
|
||||
buffer_free(&m);
|
||||
return (NULL);
|
||||
}
|
||||
buffer_free(&m);
|
||||
return (authctxt);
|
||||
}
|
||||
|
||||
int
|
||||
mm_sshpam_query(void *ctx, char **name, char **info,
|
||||
u_int *num, char ***prompts, u_int **echo_on)
|
||||
{
|
||||
Buffer m;
|
||||
int i, ret;
|
||||
|
||||
debug3("%s", __func__);
|
||||
buffer_init(&m);
|
||||
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_QUERY, &m);
|
||||
debug3("%s: waiting for MONITOR_ANS_PAM_QUERY", __func__);
|
||||
mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_QUERY, &m);
|
||||
ret = buffer_get_int(&m);
|
||||
debug3("%s: pam_query returned %d", __func__, ret);
|
||||
*name = buffer_get_string(&m, NULL);
|
||||
*info = buffer_get_string(&m, NULL);
|
||||
*num = buffer_get_int(&m);
|
||||
*prompts = xmalloc((*num + 1) * sizeof(char *));
|
||||
*echo_on = xmalloc((*num + 1) * sizeof(u_int));
|
||||
for (i = 0; i < *num; ++i) {
|
||||
(*prompts)[i] = buffer_get_string(&m, NULL);
|
||||
(*echo_on)[i] = buffer_get_int(&m);
|
||||
}
|
||||
buffer_free(&m);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int
|
||||
mm_sshpam_respond(void *ctx, u_int num, char **resp)
|
||||
{
|
||||
Buffer m;
|
||||
int i, ret;
|
||||
|
||||
debug3("%s", __func__);
|
||||
buffer_init(&m);
|
||||
buffer_put_int(&m, num);
|
||||
for (i = 0; i < num; ++i)
|
||||
buffer_put_cstring(&m, resp[i]);
|
||||
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_RESPOND, &m);
|
||||
debug3("%s: waiting for MONITOR_ANS_PAM_RESPOND", __func__);
|
||||
mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_RESPOND, &m);
|
||||
ret = buffer_get_int(&m);
|
||||
debug3("%s: pam_respond returned %d", __func__, ret);
|
||||
buffer_free(&m);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
void
|
||||
mm_sshpam_free_ctx(void *ctxtp)
|
||||
{
|
||||
Buffer m;
|
||||
|
||||
debug3("%s", __func__);
|
||||
buffer_init(&m);
|
||||
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_FREE_CTX, &m);
|
||||
debug3("%s: waiting for MONITOR_ANS_PAM_FREE_CTX", __func__);
|
||||
mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_FREE_CTX, &m);
|
||||
buffer_free(&m);
|
||||
}
|
||||
#endif /* USE_PAM */
|
||||
|
||||
/* Request process termination */
|
||||
|
@ -1,4 +1,5 @@
|
||||
/* $OpenBSD: monitor_wrap.h,v 1.8 2002/09/26 11:38:43 markus Exp $ */
|
||||
/* $FreeBSD: src/crypto/openssh/monitor_wrap.h,v 1.3 2002/10/29 10:16:02 des Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
|
||||
@ -57,6 +58,10 @@ BIGNUM *mm_auth_rsa_generate_challenge(Key *);
|
||||
|
||||
#ifdef USE_PAM
|
||||
void mm_start_pam(char *);
|
||||
void *mm_sshpam_init_ctx(struct Authctxt *);
|
||||
int mm_sshpam_query(void *, char **, char **, u_int *, char ***, u_int **);
|
||||
int mm_sshpam_respond(void *, u_int, char **);
|
||||
void mm_sshpam_free_ctx(void *);
|
||||
#endif
|
||||
|
||||
void mm_terminate(void);
|
||||
|
Loading…
Reference in New Issue
Block a user