auth1.c revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved
*
* As far as I am concerned, the code I have written for this software
* can be used freely for any purpose. Any derived versions of this
* software must be clearly marked as such, and if the derived work is
* incompatible with the protocol description in the RFC file, it must be
* called by a name other than "ssh" or "Secure Shell".
*/
/*
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include "includes.h"
#pragma ident "%Z%%M% %I% %E% SMI"
#include "xmalloc.h"
#include "rsa.h"
#include "ssh1.h"
#include "packet.h"
#include "buffer.h"
#include "mpaux.h"
#include "log.h"
#include "servconf.h"
#include "compat.h"
#include "auth.h"
#include "channels.h"
#include "session.h"
#include "uidswap.h"
#include "monitor_wrap.h"
#ifdef HAVE_BSM
#include "bsmaudit.h"
extern adt_session_data_t *ah;
#endif /* HAVE_BSM */
/* import */
extern ServerOptions options;
/*
* convert ssh auth msg type into description
*/
static char *
get_authname(int type)
{
static char buf[1024];
switch (type) {
case SSH_CMSG_AUTH_PASSWORD:
return "password";
case SSH_CMSG_AUTH_RSA:
return "rsa";
case SSH_CMSG_AUTH_RHOSTS_RSA:
return "rhosts-rsa";
case SSH_CMSG_AUTH_RHOSTS:
return "rhosts";
case SSH_CMSG_AUTH_TIS:
return "challenge-response";
case SSH_CMSG_AUTH_KERBEROS:
return "kerberos";
#endif
}
return buf;
}
/*
* read packets, try to authenticate the user and
* return only if authentication is successful
*/
static void
{
int authenticated = 0;
BIGNUM *n;
char *client_user, *password;
char info[1024];
int type = 0;
debug("Attempting authentication for %s%.100s.",
/* If the user has no password, accept authentication immediately. */
if (options.password_authentication &&
#endif
return;
}
/* Indicate that authentication is needed. */
packet_send();
client_user = NULL;
for ( ;; ) {
/* default to fail */
authenticated = 0;
info[0] = '\0';
/* Get a packet from the client. */
/* Process the packet. */
switch (type) {
case SSH_CMSG_AUTH_KERBEROS:
if (!options.kerberos_authentication) {
verbose("Kerberos authentication disabled.");
} else {
#ifdef KRB4
&client_user, &reply))) {
authenticated = 1;
" tktuser %.100s",
packet_put_string((char *)
packet_send();
}
#endif /* KRB4 */
} else {
#ifdef KRB5
&client_user, &reply))) {
authenticated = 1;
" tktuser %.100s",
/* Send response to client */
packet_put_string((char *)
packet_send();
}
#endif /* KRB5 */
}
}
break;
#endif /* KRB4 || KRB5 */
/* XXX - punt on backward compatibility here. */
packet_send_debug("Kerberos TGT passing disabled before authentication.");
break;
#ifdef AFS
case SSH_CMSG_HAVE_AFS_TOKEN:
packet_send_debug("AFS token passing disabled before authentication.");
break;
#endif /* AFS */
#endif /* AFS || KRB5 */
case SSH_CMSG_AUTH_RHOSTS:
if (!options.rhosts_authentication) {
verbose("Rhosts authentication disabled.");
break;
}
/*
* Get client user name. Note that we just have to
* trust the client; this is one reason why rhosts
* authentication is insecure. (Another is
* IP-spoofing on a local network.)
*/
/* Try to authenticate using /etc/hosts.equiv and .rhosts. */
break;
case SSH_CMSG_AUTH_RHOSTS_RSA:
if (!options.rhosts_rsa_authentication) {
verbose("Rhosts with RSA authentication disabled.");
break;
}
/*
* Get client user name. Note that we just have to
* trust the client; root on the client machine can
* claim to be any user.
*/
/* Get the client host key. */
bits = packet_get_int();
verbose("Warning: keysize mismatch for client_host_key: "
"actual %d, announced %d",
break;
case SSH_CMSG_AUTH_RSA:
if (!options.rsa_authentication) {
verbose("RSA authentication disabled.");
break;
}
/* RSA authentication requested. */
fatal("do_authloop: BN_new failed");
BN_clear_free(n);
break;
case SSH_CMSG_AUTH_PASSWORD:
authctxt->init_attempt++;
if (!options.password_authentication) {
verbose("Password authentication disabled.");
break;
}
/*
* Read user password. It is in plain text, but was
* transmitted over the encrypted channel so it is
* not visible to an outside observer.
*/
/* Try authentication with the password. */
if (authctxt->init_failures <
password));
break;
case SSH_CMSG_AUTH_TIS:
debug("rcvd SSH_CMSG_AUTH_TIS");
packet_send();
continue;
}
}
break;
debug("rcvd SSH_CMSG_AUTH_TIS_RESPONSE");
}
break;
default:
/*
* Any unknown messages will be ignored (and failure
* returned) during authentication.
*/
break;
}
#ifdef BSD_AUTH
}
#endif
authenticated = 0;
log("Ignoring authenticated invalid user %s",
}
#ifdef _UNICOS
authenticated = 0;
}
#endif /* _UNICOS */
#ifdef HAVE_CYGWIN
if (authenticated &&
packet_disconnect("Authentication rejected for uid %d.",
authenticated = 0;
}
#else
/* Special handling for root */
if (!use_privsep &&
authenticated = 0;
#endif
#ifdef USE_PAM
/* XXX PAM and PRIVSEP don't mix */
if (use_privsep && authenticated)
fatal("Privsep is not supported");
authenticated = 0;
if (!authenticated)
#endif /* USE_PAM */
/* Log before sending the reply */
if (client_user != NULL) {
client_user = NULL;
}
if (authenticated)
return;
if (type == SSH_CMSG_AUTH_PASSWORD)
#ifdef HAVE_BSM
authctxt);
#endif /* HAVE_BSM */
}
packet_send();
}
}
/*
* Performs authentication of an incoming connection. Session key has already
* been exchanged and encryption is enabled.
*/
Authctxt *
do_authentication(void)
{
/* Get the name of the user that we wish to log in as. */
/* Get the user name. */
*style++ = '\0';
#ifdef KRB5
/* XXX - SSH.com Kerberos v5 braindeath. */
if ((datafellows & SSH_BUG_K5USER) &&
char *p;
*p = '\0';
}
#endif
authctxt = authctxt_new();
#ifdef HAVE_BSM
#endif /* HAVE_BSM */
/* Verify that the user is a valid user. */
} else {
}
#if 0
#ifdef USE_PAM
#endif
#endif
/*
* If we are not running as root, the user must have the same uid as
* the server. (Unless you are running Windows)
*/
#ifndef HAVE_CYGWIN
packet_disconnect("Cannot change user when server not running as root.");
#endif
/*
* Loop until the user has been authenticated or the connection is
* closed, do_authloop() returns only if authentication is successful
*/
/* The user has been authenticated and accepted. */
packet_send();
return (authctxt);
}