- (djm) Merge FreeBSD PAM code: replaces PAM password auth kludge with

proper challenge-response module
This commit is contained in:
Damien Miller 2003-05-10 19:28:02 +10:00
parent c437cda328
commit 4f9f42a9bb
17 changed files with 876 additions and 611 deletions

View File

@ -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 $

View File

@ -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

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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);

View File

@ -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
View File

@ -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
View File

@ -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) {

View File

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

View File

@ -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

View File

@ -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

View File

@ -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 */

View File

@ -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
View File

@ -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

View File

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

View File

@ -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 */

View File

@ -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);