mirror of
https://github.com/PowerShell/openssh-portable.git
synced 2025-07-22 21:35:04 +02:00
Big PAM cleanup
Added header for arc4random to mktemp.c Fixed return type of arc4random
This commit is contained in:
parent
332e67fde2
commit
3d112efc67
6
helper.c
6
helper.c
@ -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);
|
||||||
}
|
}
|
||||||
|
2
helper.h
2
helper.h
@ -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, ...);
|
||||||
|
|
||||||
|
2
mktemp.c
2
mktemp.c
@ -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
197
sshd.c
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user