- Removed most of the pam code into its own file auth-pam.[ch]. This

cleaned up sshd.c up significantly.
 - Several other cleanups
This commit is contained in:
Damien Miller 1999-12-30 15:08:44 +11:00
parent ece22a8312
commit e72b7af17e
10 changed files with 377 additions and 284 deletions

View File

@ -2,6 +2,9 @@
- OpenBSD CVS updates:
- [auth-passwd.c]
check for NULL 1st
- Removed most of the pam code into its own file auth-pam.[ch]. This
cleaned up sshd.c up significantly.
- Several other cleanups
19991229
- Applied another NetBSD portability patch from David Rankin

View File

@ -31,7 +31,7 @@ LDFLAGS=-L. @LDFLAGS@
GNOME_CFLAGS=`gnome-config --cflags gnome gnomeui`
GNOME_LIBS=`gnome-config --libs gnome gnomeui`
OBJS= atomicio.o authfd.o authfile.o auth-krb4.o auth-passwd.o \
OBJS= atomicio.o authfd.o authfile.o auth-krb4.o auth-passwd.o auth-pam.o \
auth-rhosts.o auth-rh-rsa.o auth-rsa.o auth-skey.o bsd-daemon.o \
bsd-login.o bsd-misc.o bsd-mktemp.o bsd-snprintf.o bsd-strlcat.o \
bsd-strlcpy.o bufaux.o buffer.o canohost.o channels.o cipher.o \
@ -48,6 +48,12 @@ LIBOBJS= atomicio.o authfd.o authfile.o bsd-daemon.o bsd-misc.o \
packet.o radix.o readpass.o rsa.o tildexpand.o ttymodes.o uidswap.o \
xmalloc.o
SSHOBJS= ssh.o sshconnect.o log-client.o readconf.o clientloop.o
SSHDOBJS= sshd.o auth-rhosts.o auth-krb4.o auth-pam.o auth-passwd.o \
auth-rsa.o auth-rh-rsa.o pty.o log-server.o login.o servconf.o \
serverloop.o bsd-login.o md5crypt.o
all: $(OBJS) $(TARGETS) manpages
$(OBJS): config.h
@ -58,16 +64,11 @@ libssh.a: $(LIBOBJS)
$(AR) rv $@ $(LIBOBJS)
$(RANLIB) $@
ssh: ssh.o sshconnect.o log-client.o readconf.o clientloop.o libssh.a
$(CC) -o $@ ssh.o sshconnect.o log-client.o readconf.o \
clientloop.o $(LDFLAGS) -lssh $(LIBS)
ssh: $(SSHOBJS) libssh.a
$(CC) -o $@ $(SSHOBJS) $(LDFLAGS) -lssh $(LIBS)
sshd: sshd.o auth-rhosts.o auth-krb4.o auth-passwd.o auth-rsa.o \
auth-rh-rsa.o pty.o log-server.o login.o servconf.o serverloop.o \
bsd-login.o md5crypt.o libssh.a
$(CC) -o $@ sshd.o auth-rhosts.o auth-krb4.o auth-passwd.o \
auth-rsa.o auth-rh-rsa.o pty.o log-server.o login.o servconf.o \
serverloop.o bsd-login.o md5crypt.o $(LDFLAGS) -lssh $(LIBS) $(LIBWRAP)
sshd: $(SSHDOBJS) libssh.a
$(CC) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh $(LIBS) $(LIBWRAP)
scp: scp.o libssh.a
$(CC) -o $@ scp.o $(LDFLAGS) -lssh $(LIBS)

239
auth-pam.c Normal file
View File

@ -0,0 +1,239 @@
/*
* Author: Damien Miller
* Copyright (c) 1999 Damien Miller <djm@mindrot.org>
* All rights reserved
* Created: Thursday December 30 1999
* PAM authentication and session management code.
*/
#include "includes.h"
#ifdef USE_PAM
#include "ssh.h"
#include "xmalloc.h"
#include "servconf.h"
RCSID("$Id: auth-pam.c,v 1.1 1999/12/30 04:11:25 damien Exp $");
/* Callbacks */
static int pamconv(int num_msg, const struct pam_message **msg,
struct pam_response **resp, void *appdata_ptr);
void pam_cleanup_proc(void *context);
/* module-local variables */
static struct pam_conv conv = {
pamconv,
NULL
};
static struct pam_handle_t *pamh = NULL;
static const char *pampasswd = NULL;
static char *pamconv_msg = NULL;
/* PAM conversation function. This is really a kludge to get the password */
/* into PAM and to pick up any messages generated by PAM into pamconv_msg */
static int pamconv(int num_msg, const struct pam_message **msg,
struct pam_response **resp, void *appdata_ptr)
{
struct pam_response *reply;
int count;
size_t msg_len;
char *p;
/* PAM will free this later */
reply = malloc(num_msg * sizeof(*reply));
if (reply == NULL)
return PAM_CONV_ERR;
for(count = 0; count < num_msg; count++) {
switch (msg[count]->msg_style) {
case PAM_PROMPT_ECHO_OFF:
if (pampasswd == NULL) {
free(reply);
return PAM_CONV_ERR;
}
reply[count].resp_retcode = PAM_SUCCESS;
reply[count].resp = xstrdup(pampasswd);
break;
case PAM_TEXT_INFO:
reply[count].resp_retcode = PAM_SUCCESS;
reply[count].resp = xstrdup("");
if (msg[count]->msg == NULL)
break;
debug("Adding PAM message: %s", msg[count]->msg);
msg_len = strlen(msg[count]->msg);
if (pamconv_msg) {
size_t n = strlen(pamconv_msg);
pamconv_msg = xrealloc(pamconv_msg, n + msg_len + 2);
p = pamconv_msg + n;
} else {
pamconv_msg = p = xmalloc(msg_len + 2);
}
memcpy(p, msg[count]->msg, msg_len);
p[msg_len] = '\n';
p[msg_len + 1] = '\0';
break;
case PAM_PROMPT_ECHO_ON:
case PAM_ERROR_MSG:
default:
free(reply);
return PAM_CONV_ERR;
}
}
*resp = reply;
return PAM_SUCCESS;
}
/* Called at exit to cleanly shutdown PAM */
void pam_cleanup_proc(void *context)
{
int pam_retval;
if (pamh != NULL)
{
pam_retval = pam_close_session((pam_handle_t *)pamh, 0);
if (pam_retval != PAM_SUCCESS) {
log("Cannot close PAM session: %.200s",
PAM_STRERROR((pam_handle_t *)pamh, pam_retval));
}
pam_retval = pam_setcred((pam_handle_t *)pamh, PAM_DELETE_CRED);
if (pam_retval != PAM_SUCCESS) {
log("Cannot delete credentials: %.200s",
PAM_STRERROR((pam_handle_t *)pamh, pam_retval));
}
pam_retval = pam_end((pam_handle_t *)pamh, pam_retval);
if (pam_retval != PAM_SUCCESS) {
log("Cannot release PAM authentication: %.200s",
PAM_STRERROR((pam_handle_t *)pamh, pam_retval));
}
}
}
/* Attempt password authentation using PAM */
int auth_pam_password(struct passwd *pw, const char *password)
{
extern ServerOptions options;
int pam_retval;
/* deny if no user. */
if (pw == NULL)
return 0;
if (pw->pw_uid == 0 && options.permit_root_login == 2)
return 0;
if (*password == '\0' && options.permit_empty_passwd == 0)
return 0;
pampasswd = password;
pam_retval = pam_authenticate((pam_handle_t *)pamh, 0);
if (pam_retval == PAM_SUCCESS) {
debug("PAM Password authentication accepted for user \"%.100s\"", pw->pw_name);
return 1;
} else {
debug("PAM Password authentication for \"%.100s\" failed: %s",
pw->pw_name, PAM_STRERROR((pam_handle_t *)pamh, pam_retval));
return 0;
}
}
/* Do account management using PAM */
int do_pam_account(char *username, char *remote_user)
{
int pam_retval;
debug("PAM setting rhost to \"%.200s\"", get_canonical_hostname());
pam_retval = pam_set_item((pam_handle_t *)pamh, PAM_RHOST,
get_canonical_hostname());
if (pam_retval != PAM_SUCCESS) {
fatal("PAM set rhost failed: %.200s", PAM_STRERROR((pam_handle_t *)pamh, pam_retval));
}
if (remote_user != NULL) {
debug("PAM setting ruser to \"%.200s\"", remote_user);
pam_retval = pam_set_item((pam_handle_t *)pamh, PAM_RUSER, remote_user);
if (pam_retval != PAM_SUCCESS) {
fatal("PAM set ruser failed: %.200s", PAM_STRERROR((pam_handle_t *)pamh, pam_retval));
}
}
pam_retval = pam_acct_mgmt((pam_handle_t *)pamh, 0);
if (pam_retval != PAM_SUCCESS) {
log("PAM rejected by account configuration: %.200s", PAM_STRERROR((pam_handle_t *)pamh, pam_retval));
return(0);
}
return(1);
}
/* Do PAM-specific session initialisation */
void do_pam_session(char *username, char *ttyname)
{
int pam_retval;
if (ttyname != NULL) {
debug("PAM setting tty to \"%.200s\"", ttyname);
pam_retval = pam_set_item((pam_handle_t *)pamh, PAM_TTY, ttyname);
if (pam_retval != PAM_SUCCESS)
fatal("PAM set tty failed: %.200s", PAM_STRERROR((pam_handle_t *)pamh, pam_retval));
}
pam_retval = pam_open_session((pam_handle_t *)pamh, 0);
if (pam_retval != PAM_SUCCESS)
fatal("PAM session setup failed: %.200s", PAM_STRERROR((pam_handle_t *)pamh, pam_retval));
}
/* Set PAM credentials */
void do_pam_setcred()
{
int pam_retval;
debug("PAM establishing creds");
pam_retval = pam_setcred((pam_handle_t *)pamh, PAM_ESTABLISH_CRED);
if (pam_retval != PAM_SUCCESS)
fatal("PAM setcred failed: %.200s", PAM_STRERROR((pam_handle_t *)pamh, pam_retval));
}
/* Cleanly shutdown PAM */
void finish_pam(void)
{
pam_cleanup_proc(NULL);
fatal_remove_cleanup(&pam_cleanup_proc, NULL);
}
/* Start PAM authentication for specified account */
void start_pam(struct passwd *pw)
{
int pam_retval;
debug("Starting up PAM with username \"%.200s\"", pw->pw_name);
pam_retval = pam_start("sshd", pw->pw_name, &conv, (pam_handle_t**)&pamh);
if (pam_retval != PAM_SUCCESS)
fatal("PAM initialisation failed: %.200s", PAM_STRERROR((pam_handle_t *)pamh, pam_retval));
fatal_add_cleanup(&pam_cleanup_proc, NULL);
}
/* Return list of PAM enviornment strings */
char **fetch_pam_environment(void)
{
return(pam_getenvlist((pam_handle_t *)pamh));
}
/* Print any messages that have been generated during authentication */
/* or account checking to stderr */
void print_pam_messages(void)
{
if (pamconv_msg != NULL)
fprintf(stderr, pamconv_msg);
}
#endif /* USE_PAM */

15
auth-pam.h Normal file
View File

@ -0,0 +1,15 @@
#include "includes.h"
#ifdef USE_PAM
#include <pwd.h> /* For struct passwd */
void start_pam(struct passwd *pw);
void finish_pam(void);
int auth_pam_password(struct passwd *pw, const char *password);
char **fetch_pam_environment(void);
int do_pam_account(char *username, char *remote_user);
void do_pam_session(char *username, char *ttyname);
void do_pam_setcred();
void print_pam_messages(void);
#endif /* USE_PAM */

View File

@ -212,3 +212,25 @@ int setenv(const char *name, const char *value, int overwrite)
return(result);
}
#endif /* !HAVE_SETENV */
#ifndef HAVE_SETLOGIN
int setlogin(const char *name)
{
return(0);
}
#endif /* !HAVE_SETLOGIN */
#ifndef HAVE_INNETGR
int innetgr(const char *netgroup, const char *host,
const char *user, const char *domain)
{
return(0);
}
#endif /* HAVE_INNETGR */
#if !defined(HAVE_SETEUID) && defined(HAVE_SETREUID)
int seteuid(uid_t euid)
{
return(setreuid(-1,euid));
}
#endif /* !defined(HAVE_SETEUID) && defined(HAVE_SETREUID) */

View File

@ -51,4 +51,17 @@ void setproctitle(const char *fmt, ...);
int setenv(const char *name, const char *value, int overwrite);
#endif /* !HAVE_SETENV */
#ifndef HAVE_SETLOGIN
int setlogin(const char *name);
#endif /* !HAVE_SETLOGIN */
#ifndef HAVE_INNETGR
int innetgr(const char *netgroup, const char *host,
const char *user, const char *domain);
#endif /* HAVE_INNETGR */
#if !defined(HAVE_SETEUID) && defined(HAVE_SETREUID)
int seteuid(uid_t euid);
#endif /* !defined(HAVE_SETEUID) && defined(HAVE_SETREUID) */
#endif /* _BSD_MISC_H */

View File

@ -226,11 +226,3 @@ typedef unsigned int size_t;
# define PAM_STRERROR(a,b) pam_strerror((a),(b))
#endif
#if !defined(HAVE_SETEUID) && defined(HAVE_SETREUID)
# define seteuid(a) setreuid(-1,a)
#endif /* !defined(HAVE_SETEUID) && defined(HAVE_SETREUID) */
#ifndef HAVE_INNETGR
# define innetgr(a,b,c,d) (0)
#endif /* HAVE_INNETGR */

View File

@ -79,6 +79,13 @@ static /**/const char *const rcsid[] = { (char *)rcsid, "\100(#)" msg }
#ifdef USE_PAM
# include <security/pam_appl.h>
#endif
#ifdef HAVE_POLL_H
# include <poll.h>
#else
# ifdef HAVE_SYS_POLL_H
# include <sys/poll.h>
# endif
#endif
#include "version.h"
#include "bsd-misc.h"

6
ssh.h
View File

@ -13,7 +13,7 @@
*
*/
/* RCSID("$Id: ssh.h,v 1.21 1999/12/21 13:12:39 damien Exp $"); */
/* RCSID("$Id: ssh.h,v 1.22 1999/12/30 04:08:44 damien Exp $"); */
#ifndef SSH_H
#define SSH_H
@ -741,4 +741,8 @@ char *skey_fake_keyinfo(char *username);
int auth_skey_password(struct passwd * pw, const char *password);
#endif /* SKEY */
#ifdef USE_PAM
#include "auth-pam.h"
#endif /* USE_PAM */
#endif /* SSH_H */

327
sshd.c
View File

@ -11,15 +11,7 @@
*/
#include "includes.h"
RCSID("$Id: sshd.c,v 1.48 1999/12/28 23:25:41 damien Exp $");
#ifdef HAVE_POLL_H
# include <poll.h>
#else /* HAVE_POLL_H */
# ifdef HAVE_SYS_POLL_H
# include <sys/poll.h>
# endif /* HAVE_SYS_POLL_H */
#endif /* HAVE_POLL_H */
RCSID("$Id: sshd.c,v 1.49 1999/12/30 04:08:44 damien Exp $");
#include "xmalloc.h"
#include "rsa.h"
@ -143,183 +135,6 @@ void do_child(const char *command, struct passwd * pw, const char *term,
const char *display, const char *auth_proto,
const char *auth_data, const char *ttyname);
#ifdef USE_PAM
static int pamconv(int num_msg, const struct pam_message **msg,
struct pam_response **resp, void *appdata_ptr);
int do_pam_auth(const char *user, const char *password);
void do_pam_account(char *username, char *remote_user);
void do_pam_session(char *username, char *ttyname);
void do_pam_setcred();
void pam_cleanup_proc(void *context);
static struct pam_conv conv = {
pamconv,
NULL
};
struct pam_handle_t *pamh = NULL;
const char *pampasswd = NULL;
char *pamconv_msg = NULL;
static int pamconv(int num_msg, const struct pam_message **msg,
struct pam_response **resp, void *appdata_ptr)
{
struct pam_response *reply;
int count;
size_t msg_len;
char *p;
/* PAM will free this later */
reply = malloc(num_msg * sizeof(*reply));
if (reply == NULL)
return PAM_CONV_ERR;
for(count = 0; count < num_msg; count++) {
switch (msg[count]->msg_style) {
case PAM_PROMPT_ECHO_OFF:
if (pampasswd == NULL) {
free(reply);
return PAM_CONV_ERR;
}
reply[count].resp_retcode = PAM_SUCCESS;
reply[count].resp = xstrdup(pampasswd);
break;
case PAM_TEXT_INFO:
reply[count].resp_retcode = PAM_SUCCESS;
reply[count].resp = xstrdup("");
if (msg[count]->msg == NULL)
break;
debug("Adding PAM message: %s", msg[count]->msg);
msg_len = strlen(msg[count]->msg);
if (pamconv_msg) {
size_t n = strlen(pamconv_msg);
pamconv_msg = xrealloc(pamconv_msg, n + msg_len + 2);
p = pamconv_msg + n;
} else {
pamconv_msg = p = xmalloc(msg_len + 2);
}
memcpy(p, msg[count]->msg, msg_len);
p[msg_len] = '\n';
p[msg_len + 1] = '\0';
break;
case PAM_PROMPT_ECHO_ON:
case PAM_ERROR_MSG:
default:
free(reply);
return PAM_CONV_ERR;
}
}
*resp = reply;
return PAM_SUCCESS;
}
void pam_cleanup_proc(void *context)
{
int pam_retval;
if (pamh != NULL)
{
pam_retval = pam_close_session((pam_handle_t *)pamh, 0);
if (pam_retval != PAM_SUCCESS) {
log("Cannot close PAM session: %.200s",
PAM_STRERROR((pam_handle_t *)pamh, pam_retval));
}
pam_retval = pam_setcred((pam_handle_t *)pamh, PAM_DELETE_CRED);
if (pam_retval != PAM_SUCCESS) {
log("Cannot delete credentials: %.200s",
PAM_STRERROR((pam_handle_t *)pamh, pam_retval));
}
pam_retval = pam_end((pam_handle_t *)pamh, pam_retval);
if (pam_retval != PAM_SUCCESS) {
log("Cannot release PAM authentication: %.200s",
PAM_STRERROR((pam_handle_t *)pamh, pam_retval));
}
}
}
int do_pam_auth(const char *user, const char *password)
{
int pam_retval;
if ((options.permit_empty_passwd == 0) && (password[0] == '\0'))
return 0;
pampasswd = password;
pam_retval = pam_authenticate((pam_handle_t *)pamh, 0);
if (pam_retval == PAM_SUCCESS) {
debug("PAM Password authentication accepted for user \"%.100s\"", user);
return 1;
} else {
debug("PAM Password authentication for \"%.100s\" failed: %s",
user, PAM_STRERROR((pam_handle_t *)pamh, pam_retval));
return 0;
}
}
void do_pam_account(char *username, char *remote_user)
{
int pam_retval;
debug("PAM setting rhost to \"%.200s\"", get_canonical_hostname());
pam_retval = pam_set_item((pam_handle_t *)pamh, PAM_RHOST,
get_canonical_hostname());
if (pam_retval != PAM_SUCCESS) {
log("PAM set rhost failed: %.200s", PAM_STRERROR((pam_handle_t *)pamh, pam_retval));
do_fake_authloop(username);
}
if (remote_user != NULL) {
debug("PAM setting ruser to \"%.200s\"", remote_user);
pam_retval = pam_set_item((pam_handle_t *)pamh, PAM_RUSER, remote_user);
if (pam_retval != PAM_SUCCESS) {
log("PAM set ruser failed: %.200s", PAM_STRERROR((pam_handle_t *)pamh, pam_retval));
do_fake_authloop(username);
}
}
pam_retval = pam_acct_mgmt((pam_handle_t *)pamh, 0);
if (pam_retval != PAM_SUCCESS) {
log("PAM rejected by account configuration: %.200s", PAM_STRERROR((pam_handle_t *)pamh, pam_retval));
do_fake_authloop(username);
}
}
void do_pam_session(char *username, char *ttyname)
{
int pam_retval;
if (ttyname != NULL) {
debug("PAM setting tty to \"%.200s\"", ttyname);
pam_retval = pam_set_item((pam_handle_t *)pamh, PAM_TTY, ttyname);
if (pam_retval != PAM_SUCCESS)
fatal("PAM set tty failed: %.200s", PAM_STRERROR((pam_handle_t *)pamh, pam_retval));
}
pam_retval = pam_open_session((pam_handle_t *)pamh, 0);
if (pam_retval != PAM_SUCCESS)
fatal("PAM session setup failed: %.200s", PAM_STRERROR((pam_handle_t *)pamh, pam_retval));
}
void do_pam_setcred()
{
int pam_retval;
debug("PAM establishing creds");
pam_retval = pam_setcred((pam_handle_t *)pamh, PAM_ESTABLISH_CRED);
if (pam_retval != PAM_SUCCESS)
fatal("PAM setcred failed: %.200s", PAM_STRERROR((pam_handle_t *)pamh, pam_retval));
}
#endif /* USE_PAM */
/*
* Signal handler for SIGHUP. Sshd execs itself when it receives SIGHUP;
* the effect is to reread the configuration file (and to regenerate
@ -973,20 +788,7 @@ main(int ac, char **av)
verbose("Closing connection to %.100s", remote_ip);
#ifdef USE_PAM
{
int retval;
if (pamh != NULL) {
debug("Closing PAM session.");
retval = pam_close_session((pam_handle_t *)pamh, 0);
debug("Terminating PAM library.");
if (pam_end((pam_handle_t *)pamh, retval) != PAM_SUCCESS)
log("Cannot release PAM authentication.");
fatal_remove_cleanup(&pam_cleanup_proc, NULL);
}
}
finish_pam();
#endif /* USE_PAM */
packet_close();
@ -1306,17 +1108,7 @@ do_authentication(char *user)
pw = &pwcopy;
#ifdef USE_PAM
{
int pam_retval;
debug("Starting up PAM with username \"%.200s\"", pw->pw_name);
pam_retval = pam_start("sshd", pw->pw_name, &conv, (pam_handle_t**)&pamh);
if (pam_retval != PAM_SUCCESS)
fatal("PAM initialisation failed: %.200s", PAM_STRERROR((pam_handle_t *)pamh, pam_retval));
fatal_add_cleanup(&pam_cleanup_proc, NULL);
}
start_pam(pw);
#endif
/*
@ -1334,7 +1126,7 @@ do_authentication(char *user)
(!options.kerberos_authentication || options.kerberos_or_local_passwd) &&
#endif /* KRB4 */
#ifdef USE_PAM
do_pam_auth(pw->pw_name, "")) {
auth_pam_password(pw, "")) {
#else /* USE_PAM */
auth_password(pw, "")) {
#endif /* USE_PAM */
@ -1477,9 +1269,6 @@ do_authloop(struct passwd * pw)
authenticated = auth_rhosts(pw, client_user);
snprintf(user, sizeof user, " ruser %s", client_user);
#ifndef USE_PAM
xfree(client_user);
#endif /* USE_PAM */
break;
case SSH_CMSG_AUTH_RHOSTS_RSA:
@ -1512,9 +1301,6 @@ do_authloop(struct passwd * pw)
BN_clear_free(client_host_key_n);
snprintf(user, sizeof user, " ruser %s", client_user);
#ifndef USE_PAM
xfree(client_user);
#endif /* USE_PAM */
break;
case SSH_CMSG_AUTH_RSA:
@ -1545,7 +1331,7 @@ do_authloop(struct passwd * pw)
#ifdef USE_PAM
/* Do PAM auth with password */
authenticated = do_pam_auth(pw->pw_name, password);
authenticated = auth_pam_password(pw, password);
#else /* USE_PAM */
/* Try authentication with the password. */
authenticated = auth_password(pw, password);
@ -1615,29 +1401,24 @@ do_authloop(struct passwd * pw)
get_remote_port(),
user);
#ifndef USE_PAM
if (authenticated)
if (authenticated) {
#ifdef USE_PAM
if (!do_pam_account(pw->pw_name, client_user))
{
if (client_user != NULL)
xfree(client_user);
do_fake_authloop(pw->pw_name);
}
#endif /* USE_PAM */
return;
}
if (client_user != NULL)
xfree(client_user);
if (attempt > AUTH_FAIL_MAX)
packet_disconnect(AUTH_FAIL_MSG, pw->pw_name);
#else /* USE_PAM */
if (authenticated) {
do_pam_account(pw->pw_name, client_user);
if (client_user != NULL)
xfree(client_user);
return;
}
if (attempt > AUTH_FAIL_MAX) {
if (client_user != NULL)
xfree(client_user);
packet_disconnect(AUTH_FAIL_MSG, pw->pw_name);
}
#endif /* USE_PAM */
/* Send a message indicating that the authentication attempt failed. */
packet_start(SSH_SMSG_FAILURE);
@ -1672,8 +1453,10 @@ do_fake_authloop(char *user)
for (attempt = 1;; attempt++) {
/* Read a packet. This will not return if the client disconnects. */
int plen;
#ifndef SKEY
(void)packet_read(&plen);
#else /* SKEY */
int type = packet_read(&plen);
#ifdef SKEY
int dlen;
char *password, *skeyinfo;
/* Try to send a fake s/key challenge. */
@ -1845,7 +1628,7 @@ do_authenticated(struct passwd * pw)
#ifdef USE_PAM
/* do the pam_open_session since we have the pty */
do_pam_session(pw->pw_name,ttyname);
do_pam_session(pw->pw_name, ttyname);
#endif /* USE_PAM */
break;
@ -1925,7 +1708,7 @@ do_authenticated(struct passwd * pw)
#ifdef USE_PAM
do_pam_setcred();
#endif
#endif /* USE_PAM */
if (forced_command != NULL)
goto do_forced_command;
debug("Forking shell.");
@ -1943,7 +1726,7 @@ do_authenticated(struct passwd * pw)
#ifdef USE_PAM
do_pam_setcred();
#endif
#endif /* USE_PAM */
if (forced_command != NULL)
goto do_forced_command;
/* Get command from the packet. */
@ -2221,10 +2004,9 @@ do_exec_pty(const char *command, int ptyfd, int ttyfd,
quiet_login = stat(line, &st) >= 0;
#ifdef USE_PAM
/* output the results of the pamconv() */
if (!quiet_login && pamconv_msg != NULL)
fprintf(stderr, pamconv_msg);
#endif
if (!quiet_login)
print_pam_messages();
#endif /* USE_PAM */
/*
* If the user has logged in before, display the time of last
@ -2389,6 +2171,39 @@ read_environment_file(char ***env, unsigned int *envsize,
fclose(f);
}
#ifdef USE_PAM
/*
* Sets any environment variables which have been specified by PAM
*/
void do_pam_environment(char ***env, int *envsize)
{
char *equals, var_name[512], var_val[512];
char **pam_env;
int i;
if ((pam_env = fetch_pam_environment()) == NULL)
return;
for(i = 0; pam_env[i] != NULL; i++) {
if ((equals = strstr(pam_env[i], "=")) == NULL)
continue;
if (strlen(pam_env[i]) < (sizeof(var_name) - 1))
{
memset(var_name, '\0', sizeof(var_name));
memset(var_val, '\0', sizeof(var_val));
strncpy(var_name, pam_env[i], equals - pam_env[i]);
strcpy(var_val, equals + 1);
debug("PAM environment: %s=%s", var_name, var_val);
child_set_env(env, envsize, var_name, var_val);
}
}
}
#endif /* USE_PAM */
/*
* Performs common processing for the child, such as setting up the
* environment, closing extra file descriptors, setting the user and group
@ -2421,11 +2236,9 @@ do_child(const char *command, struct passwd * pw, const char *term,
}
#endif /* USE_PAM */
#ifdef HAVE_SETLOGIN
/* Set login name in the kernel. */
if (setlogin(pw->pw_name) < 0)
error("setlogin failed: %s", strerror(errno));
#endif /* HAVE_SETLOGIN */
/* Set uid, gid, and groups. */
/* Login(1) does this as well, and it needs uid 0 for the "-h"
@ -2526,23 +2339,7 @@ do_child(const char *command, struct passwd * pw, const char *term,
#ifdef USE_PAM
/* Pull in any environment variables that may have been set by PAM. */
{
char *equals, var_name[512], var_val[512];
char **pam_env = pam_getenvlist((pam_handle_t *)pamh);
int i;
for(i = 0; pam_env && pam_env[i]; i++) {
equals = strstr(pam_env[i], "=");
if ((strlen(pam_env[i]) < (sizeof(var_name) - 1)) && (equals != NULL))
{
debug("PAM environment: %s=%s", var_name, var_val);
memset(var_name, '\0', sizeof(var_name));
memset(var_val, '\0', sizeof(var_val));
strncpy(var_name, pam_env[i], equals - pam_env[i]);
strcpy(var_val, equals + 1);
child_set_env(&env, &envsize, var_name, var_val);
}
}
}
do_pam_environment(&env, &envsize);
#endif /* USE_PAM */
if (xauthfile)