Big PAM cleanup

Added header for arc4random to mktemp.c

Fixed return type of arc4random
This commit is contained in:
Damien Miller 1999-10-28 13:20:30 +10:00
parent 332e67fde2
commit 3d112efc67
4 changed files with 105 additions and 102 deletions

View File

@ -57,14 +57,14 @@ void setproctitle(const char *fmt, ...)
/* FIXME */ /* FIXME */
} }
unsigned char arc4random(void) unsigned int arc4random(void)
{ {
unsigned char r; unsigned int r;
if (rc4 == NULL) if (rc4 == NULL)
arc4random_stir(); arc4random_stir();
rc4_getbytes(rc4, &r, 1); rc4_getbytes(rc4, (unsigned char *)&r, sizeof(r));
return(r); return(r);
} }

View File

@ -36,7 +36,7 @@
#ifndef _HELPER_H #ifndef _HELPER_H
#define _HELPER_H #define _HELPER_H
unsigned char arc4random(void); unsigned int arc4random(void);
void arc4random_stir(void); void arc4random_stir(void);
void setproctitle(const char *fmt, ...); void setproctitle(const char *fmt, ...);

View File

@ -47,6 +47,8 @@ static char rcsid[] = "$OpenBSD: mktemp.c,v 1.13 1998/06/30 23:03:13 deraadt Exp
#include <ctype.h> #include <ctype.h>
#include <unistd.h> #include <unistd.h>
#include "helper.h"
static int _gettemp __P((char *, int *, int, int)); static int _gettemp __P((char *, int *, int, int));
int int

197
sshd.c
View File

@ -18,7 +18,7 @@ agent connections.
*/ */
#include "includes.h" #include "includes.h"
RCSID("$Id: sshd.c,v 1.2 1999/10/27 13:42:05 damien Exp $"); RCSID("$Id: sshd.c,v 1.3 1999/10/28 03:20:30 damien Exp $");
#include "xmalloc.h" #include "xmalloc.h"
#include "rsa.h" #include "rsa.h"
@ -117,6 +117,7 @@ RSA *public_key;
/* Prototypes for various functions defined later in this file. */ /* Prototypes for various functions defined later in this file. */
void do_connection(int privileged_port); void do_connection(int privileged_port);
void do_authentication(char *user, int privileged_port); void do_authentication(char *user, int privileged_port);
void eat_packets_and_disconnect(const char *user);
void do_authenticated(struct passwd *pw); void do_authenticated(struct passwd *pw);
void do_exec_pty(const char *command, int ptyfd, int ttyfd, void do_exec_pty(const char *command, int ptyfd, int ttyfd,
const char *ttyname, struct passwd *pw, const char *term, const char *ttyname, struct passwd *pw, const char *term,
@ -131,7 +132,7 @@ void do_child(const char *command, struct passwd *pw, const char *term,
#ifdef HAVE_PAM #ifdef HAVE_PAM
static int pamconv(int num_msg, const struct pam_message **msg, static int pamconv(int num_msg, const struct pam_message **msg,
struct pam_response **resp, void *appdata_ptr); struct pam_response **resp, void *appdata_ptr);
void do_pam_authentication(const char *username, const char *password, void do_pam_account_and_session(const char *username, const char *password,
const char *remote_user, const char *remote_host); const char *remote_user, const char *remote_host);
void pam_cleanup_proc(void *context); void pam_cleanup_proc(void *context);
@ -158,7 +159,7 @@ static int pamconv(int num_msg, const struct pam_message **msg,
switch (msg[count]->msg_style) switch (msg[count]->msg_style)
{ {
case PAM_PROMPT_ECHO_OFF: case PAM_PROMPT_ECHO_OFF:
if (pampasswd == NULL) if (pampasswd == NULL)
{ {
free(reply); free(reply);
return PAM_CONV_ERR; return PAM_CONV_ERR;
@ -198,59 +199,30 @@ void pam_cleanup_proc(void *context)
} }
} }
void do_pam_authentication(const char *username, const char *password, const char *remote_user, const char *remote_host) void do_pam_account_and_session(const char *username, const char *password, const char *remote_user, const char *remote_host)
{ {
int pam_auth_ok = 1; if (remote_host && (PAM_SUCCESS != pam_set_item((pam_handle_t *)pamh, PAM_RHOST, remote_host)))
pampasswd = password;
do
{ {
if (PAM_SUCCESS != pam_start("ssh", username, &conv, (pam_handle_t**)&pamh)) log("PAM setup failed.");
{ eat_packets_and_disconnect(username);
pam_auth_ok = 0; }
break;
}
fatal_add_cleanup(&pam_cleanup_proc, NULL); if (remote_user && (PAM_SUCCESS != pam_set_item((pam_handle_t *)pamh, PAM_RUSER, remote_user)))
{
if (remote_host && (PAM_SUCCESS != pam_set_item((pam_handle_t *)pamh, PAM_RHOST, remote_host))) log("PAM setup failed.");
{ eat_packets_and_disconnect(username);
pam_auth_ok = 0; }
break;
}
if (remote_user && (PAM_SUCCESS != pam_set_item((pam_handle_t *)pamh, PAM_RUSER, remote_user)))
{
pam_auth_ok = 0;
break;
}
if (PAM_SUCCESS != pam_authenticate((pam_handle_t *)pamh, 0)) if (PAM_SUCCESS != pam_acct_mgmt((pam_handle_t *)pamh, 0))
{
pam_auth_ok = 0;
break;
}
if (PAM_SUCCESS != pam_acct_mgmt((pam_handle_t *)pamh, 0))
{
pam_auth_ok = 0;
break;
}
if (PAM_SUCCESS != pam_open_session((pam_handle_t *)pamh, 0))
{
pam_auth_ok = 0;
break;
}
} while (0);
if (!pam_auth_ok)
{ {
packet_start(SSH_SMSG_FAILURE); log("PAM rejected by account configuration.");
packet_send(); eat_packets_and_disconnect(username);
packet_write_wait(); }
packet_disconnect("PAM authentication failed.");
if (PAM_SUCCESS != pam_open_session((pam_handle_t *)pamh, 0))
{
log("PAM session setup failed.");
eat_packets_and_disconnect(username);
} }
} }
#endif /* HAVE_PAM */ #endif /* HAVE_PAM */
@ -1151,48 +1123,8 @@ do_authentication(char *user, int privileged_port)
/* Verify that the user is a valid user. */ /* Verify that the user is a valid user. */
pw = getpwnam(user); pw = getpwnam(user);
if (!pw || !allowed_user(pw)) if (!pw || !allowed_user(pw))
{ eat_packets_and_disconnect(user);
/* The user does not exist or access is denied,
but fake indication that authentication is needed. */
packet_start(SSH_SMSG_FAILURE);
packet_send();
packet_write_wait();
/* Keep reading packets, and always respond with a failure. This is to
avoid disclosing whether such a user really exists. */
for (;;)
{
/* Read a packet. This will not return if the client disconnects. */
int plen;
int type = packet_read(&plen);
#ifdef SKEY
int passw_len;
char *password, *skeyinfo;
if (options.password_authentication &&
options.skey_authentication == 1 &&
type == SSH_CMSG_AUTH_PASSWORD &&
(password = packet_get_string(&passw_len)) != NULL &&
passw_len == 5 &&
strncasecmp(password, "s/key", 5) == 0 &&
(skeyinfo = skey_fake_keyinfo(user)) != NULL ){
/* Send a fake s/key challenge. */
packet_send_debug(skeyinfo);
}
#endif
/* Send failure. This should be indistinguishable from a failed
authentication. */
packet_start(SSH_SMSG_FAILURE);
packet_send();
packet_write_wait();
if (++authentication_failures >= MAX_AUTH_FAILURES) {
packet_disconnect("Too many authentication failures for %.100s from %.200s",
user, get_canonical_hostname());
}
}
/*NOTREACHED*/
abort();
}
/* Take a copy of the returned structure. */ /* Take a copy of the returned structure. */
memset(&pwcopy, 0, sizeof(pwcopy)); memset(&pwcopy, 0, sizeof(pwcopy));
pwcopy.pw_name = xstrdup(pw->pw_name); pwcopy.pw_name = xstrdup(pw->pw_name);
@ -1203,6 +1135,18 @@ do_authentication(char *user, int privileged_port)
pwcopy.pw_shell = xstrdup(pw->pw_shell); pwcopy.pw_shell = xstrdup(pw->pw_shell);
pw = &pwcopy; pw = &pwcopy;
#ifdef HAVE_PAM
if (PAM_SUCCESS != pam_start("ssh", pw->pw_name, &conv, (pam_handle_t**)&pamh))
{
packet_start(SSH_SMSG_FAILURE);
packet_send();
packet_write_wait();
packet_disconnect("PAM initialisation failed.");
}
#endif
fatal_add_cleanup(&pam_cleanup_proc, NULL);
/* If we are not running as root, the user must have the same uid as the /* If we are not running as root, the user must have the same uid as the
server. */ server. */
if (getuid() != 0 && pw->pw_uid != getuid()) if (getuid() != 0 && pw->pw_uid != getuid())
@ -1460,10 +1404,18 @@ do_authentication(char *user, int privileged_port)
} }
#ifdef HAVE_PAM #ifdef HAVE_PAM
/* Authentication will be handled later */ pampasswd = password;
/* keep password around until then */
authenticated = 1; if (PAM_SUCCESS == pam_authenticate((pam_handle_t *)pamh, 0))
break; {
log("PAM Password authentication accepted for %.100s.", user);
authenticated = 1;
break;
} else
{
log("PAM Password authentication for %.100s failed.", user);
break;
}
#else /* HAVE_PAM */ #else /* HAVE_PAM */
/* Try authentication with the password. */ /* Try authentication with the password. */
if (auth_password(pw, password)) if (auth_password(pw, password))
@ -1519,7 +1471,7 @@ do_authentication(char *user, int privileged_port)
} }
#ifdef HAVE_PAM #ifdef HAVE_PAM
do_pam_authentication(pw->pw_name, password, client_user, get_canonical_hostname()); do_pam_account_and_session(pw->pw_name, password, client_user, get_canonical_hostname());
/* Clean up */ /* Clean up */
if (client_user != NULL) if (client_user != NULL)
@ -1541,6 +1493,55 @@ do_authentication(char *user, int privileged_port)
do_authenticated(pw); do_authenticated(pw);
} }
/* Read authentication messages, but return only failures until */
/* max auth attempts exceeded, then disconnect */
void eat_packets_and_disconnect(const char *user)
{
int authentication_failures = 0;
packet_start(SSH_SMSG_FAILURE);
packet_send();
packet_write_wait();
/* Keep reading packets, and always respond with a failure. This is to
avoid disclosing whether such a user really exists. */
while(1)
{
/* 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);
int passw_len;
char *password, *skeyinfo;
if (options.password_authentication &&
options.skey_authentication == 1 &&
type == SSH_CMSG_AUTH_PASSWORD &&
(password = packet_get_string(&passw_len)) != NULL &&
passw_len == 5 &&
strncasecmp(password, "s/key", 5) == 0 &&
(skeyinfo = skey_fake_keyinfo(user)) != NULL )
{
/* Send a fake s/key challenge. */
packet_send_debug(skeyinfo);
}
#endif /* SKEY */
/* Send failure. This should be indistinguishable from a failed
authentication. */
packet_start(SSH_SMSG_FAILURE);
packet_send();
packet_write_wait();
if (++authentication_failures >= MAX_AUTH_FAILURES)
{
packet_disconnect("Too many authentication failures for %.100s from %.200s",
user, get_canonical_hostname());
}
}
/*NOTREACHED*/
abort();
}
/* Prepares for an interactive session. This is called after the user has /* Prepares for an interactive session. This is called after the user has
been successfully authenticated. During this message exchange, pseudo been successfully authenticated. During this message exchange, pseudo
terminals are allocated, X11, TCP/IP, and authentication agent forwardings terminals are allocated, X11, TCP/IP, and authentication agent forwardings