From a5c9cd3122a00c434e3d019e4f4c7c443c233d23 Mon Sep 17 00:00:00 2001 From: damien Date: Thu, 30 Dec 1999 04:08:44 +0000 Subject: [PATCH] - Removed most of the pam code into its own file auth-pam.[ch]. This cleaned up sshd.c up significantly. - Several other cleanups --- ChangeLog | 3 + Makefile.in | 21 ++-- auth-pam.c | 239 +++++++++++++++++++++++++++++++++++++++ auth-pam.h | 15 +++ bsd-misc.c | 22 ++++ bsd-misc.h | 13 +++ defines.h | 8 -- includes.h | 7 ++ ssh.h | 4 + sshd.c | 319 ++++++++++------------------------------------------ 10 files changed, 372 insertions(+), 279 deletions(-) create mode 100644 auth-pam.c create mode 100644 auth-pam.h diff --git a/ChangeLog b/ChangeLog index 38bd4506..66d77b0a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -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 diff --git a/Makefile.in b/Makefile.in index 05003227..3364a20a 100644 --- a/Makefile.in +++ b/Makefile.in @@ -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) diff --git a/auth-pam.c b/auth-pam.c new file mode 100644 index 00000000..2c0ffb42 --- /dev/null +++ b/auth-pam.c @@ -0,0 +1,239 @@ +/* + * Author: Damien Miller + * Copyright (c) 1999 Damien Miller + * 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$"); + +/* 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 */ diff --git a/auth-pam.h b/auth-pam.h new file mode 100644 index 00000000..1f3bc252 --- /dev/null +++ b/auth-pam.h @@ -0,0 +1,15 @@ +#include "includes.h" +#ifdef USE_PAM + +#include /* 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 */ diff --git a/bsd-misc.c b/bsd-misc.c index c952fd0f..0ffe5168 100644 --- a/bsd-misc.c +++ b/bsd-misc.c @@ -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) */ diff --git a/bsd-misc.h b/bsd-misc.h index 990dd408..fabaa00b 100644 --- a/bsd-misc.h +++ b/bsd-misc.h @@ -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 */ diff --git a/defines.h b/defines.h index 1a663997..10f72f47 100644 --- a/defines.h +++ b/defines.h @@ -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 */ - diff --git a/includes.h b/includes.h index 3fe76553..bc7db419 100644 --- a/includes.h +++ b/includes.h @@ -79,6 +79,13 @@ static /**/const char *const rcsid[] = { (char *)rcsid, "\100(#)" msg } #ifdef USE_PAM # include #endif +#ifdef HAVE_POLL_H +# include +#else +# ifdef HAVE_SYS_POLL_H +# include +# endif +#endif #include "version.h" #include "bsd-misc.h" diff --git a/ssh.h b/ssh.h index 5b676f4d..d62a9e1e 100644 --- a/ssh.h +++ b/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 */ diff --git a/sshd.c b/sshd.c index 5401bbe2..685fd27f 100644 --- a/sshd.c +++ b/sshd.c @@ -13,14 +13,6 @@ #include "includes.h" RCSID("$Id$"); -#ifdef HAVE_POLL_H -# include -#else /* HAVE_POLL_H */ -# ifdef HAVE_SYS_POLL_H -# include -# endif /* HAVE_SYS_POLL_H */ -#endif /* HAVE_POLL_H */ - #include "xmalloc.h" #include "rsa.h" #include "ssh.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) - return; - - 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); +#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 (attempt > AUTH_FAIL_MAX) { - if (client_user != NULL) - xfree(client_user); + if (client_user != NULL) + xfree(client_user); + if (attempt > AUTH_FAIL_MAX) 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) -- 2.45.1