summaryrefslogtreecommitdiffstats
path: root/crypto/openssh/auth1.c
diff options
context:
space:
mode:
authorgreen <green@FreeBSD.org>2000-12-05 02:20:19 +0000
committergreen <green@FreeBSD.org>2000-12-05 02:20:19 +0000
commit2aecee364f2b1fa8b38c4d29600f05f33075cddf (patch)
treebf0881ca432b88e84b40b65bc72970ba5b2a3120 /crypto/openssh/auth1.c
parent100d82038d69581b72d61ea79acb559a97322110 (diff)
downloadFreeBSD-src-2aecee364f2b1fa8b38c4d29600f05f33075cddf.zip
FreeBSD-src-2aecee364f2b1fa8b38c4d29600f05f33075cddf.tar.gz
Import of OpenSSH 2.3.0 (virgin OpenBSD source release).
Diffstat (limited to 'crypto/openssh/auth1.c')
-rw-r--r--crypto/openssh/auth1.c169
1 files changed, 57 insertions, 112 deletions
diff --git a/crypto/openssh/auth1.c b/crypto/openssh/auth1.c
index 59df9e3..8d50d28 100644
--- a/crypto/openssh/auth1.c
+++ b/crypto/openssh/auth1.c
@@ -10,14 +10,13 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: auth1.c,v 1.4 2000/09/07 20:27:49 deraadt Exp $");
+RCSID("$OpenBSD: auth1.c,v 1.6 2000/10/11 20:27:23 markus Exp $");
#include "xmalloc.h"
#include "rsa.h"
#include "ssh.h"
#include "packet.h"
#include "buffer.h"
-#include "cipher.h"
#include "mpaux.h"
#include "servconf.h"
#include "compat.h"
@@ -58,78 +57,16 @@ get_authname(int type)
}
/*
- * The user does not exist or access is denied,
- * but fake indication that authentication is needed.
+ * read packets and try to authenticate local user 'luser'.
+ * return if authentication is successfull. not that pw == NULL
+ * if the user does not exists or is not allowed to login.
+ * each auth method has to 'fake' authentication for nonexisting
+ * users.
*/
void
-do_fake_authloop1(char *user)
-{
- int attempt = 0;
-
- log("Faking authloop for illegal user %.200s from %.200s port %d",
- user,
- get_remote_ipaddr(),
- get_remote_port());
-
- /* Indicate 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 (attempt = 1;; attempt++) {
- /* Read a packet. This will not return if the client disconnects. */
- int plen;
- int type = packet_read(&plen);
-#ifdef SKEY
- unsigned int dlen;
- char *password, *skeyinfo;
- password = NULL;
- /* Try to send a fake s/key challenge. */
- if (options.skey_authentication == 1 &&
- (skeyinfo = skey_fake_keyinfo(user)) != NULL) {
- if (type == SSH_CMSG_AUTH_TIS) {
- packet_start(SSH_SMSG_AUTH_TIS_CHALLENGE);
- packet_put_string(skeyinfo, strlen(skeyinfo));
- packet_send();
- packet_write_wait();
- continue;
- } else if (type == SSH_CMSG_AUTH_PASSWORD &&
- options.password_authentication &&
- (password = packet_get_string(&dlen)) != NULL &&
- dlen == 5 &&
- strncasecmp(password, "s/key", 5) == 0 ) {
- packet_send_debug(skeyinfo);
- }
- }
- if (password != NULL)
- xfree(password);
-#endif
- if (attempt > AUTH_FAIL_MAX)
- packet_disconnect(AUTH_FAIL_MSG, user);
-
- /*
- * Send failure. This should be indistinguishable from a
- * failed authentication.
- */
- packet_start(SSH_SMSG_FAILURE);
- packet_send();
- packet_write_wait();
- }
- /* NOTREACHED */
- abort();
-}
-
-/*
- * read packets and try to authenticate local user *pw.
- * return if authentication is successfull
- */
-void
-do_authloop(struct passwd * pw)
+do_authloop(struct passwd * pw, char *luser)
{
+ int authenticated = 0;
int attempt = 0;
unsigned int bits;
RSA *client_host_key;
@@ -148,7 +85,9 @@ do_authloop(struct passwd * pw)
packet_write_wait();
for (attempt = 1;; attempt++) {
- int authenticated = 0;
+ /* default to fail */
+ authenticated = 0;
+
strlcpy(user, "", sizeof user);
/* Get a packet from the client. */
@@ -159,7 +98,6 @@ do_authloop(struct passwd * pw)
#ifdef AFS
case SSH_CMSG_HAVE_KERBEROS_TGT:
if (!options.kerberos_tgt_passing) {
- /* packet_get_all(); */
verbose("Kerberos tgt passing disabled.");
break;
} else {
@@ -167,14 +105,13 @@ do_authloop(struct passwd * pw)
char *tgt = packet_get_string(&dlen);
packet_integrity_check(plen, 4 + dlen, type);
if (!auth_kerberos_tgt(pw, tgt))
- verbose("Kerberos tgt REFUSED for %s", pw->pw_name);
+ verbose("Kerberos tgt REFUSED for %.100s", luser);
xfree(tgt);
}
continue;
case SSH_CMSG_HAVE_AFS_TOKEN:
if (!options.afs_token_passing || !k_hasafs()) {
- /* packet_get_all(); */
verbose("AFS token passing disabled.");
break;
} else {
@@ -182,7 +119,7 @@ do_authloop(struct passwd * pw)
char *token_string = packet_get_string(&dlen);
packet_integrity_check(plen, 4 + dlen, type);
if (!auth_afs_token(pw, token_string))
- verbose("AFS token REFUSED for %s", pw->pw_name);
+ verbose("AFS token REFUSED for %.100s", luser);
xfree(token_string);
}
continue;
@@ -204,11 +141,12 @@ do_authloop(struct passwd * pw)
memcpy(auth.dat, kdata, auth.length);
xfree(kdata);
- authenticated = auth_krb4(pw->pw_name, &auth, &tkt_user);
-
- if (authenticated) {
- snprintf(user, sizeof user, " tktuser %s", tkt_user);
- xfree(tkt_user);
+ if (pw != NULL) {
+ authenticated = auth_krb4(pw->pw_name, &auth, &tkt_user);
+ if (authenticated) {
+ snprintf(user, sizeof user, " tktuser %s", tkt_user);
+ xfree(tkt_user);
+ }
}
}
break;
@@ -228,8 +166,7 @@ do_authloop(struct passwd * pw)
client_user = packet_get_string(&ulen);
packet_integrity_check(plen, 4 + ulen, type);
- /* Try to authenticate using /etc/hosts.equiv and
- .rhosts. */
+ /* Try to authenticate using /etc/hosts.equiv and .rhosts. */
authenticated = auth_rhosts(pw, client_user);
snprintf(user, sizeof user, " ruser %s", client_user);
@@ -261,7 +198,7 @@ do_authloop(struct passwd * pw)
packet_get_bignum(client_host_key->n, &nlen);
if (bits != BN_num_bits(client_host_key->n))
- log("Warning: keysize mismatch for client_host_key: "
+ verbose("Warning: keysize mismatch for client_host_key: "
"actual %d, announced %d", BN_num_bits(client_host_key->n), bits);
packet_integrity_check(plen, (4 + ulen) + 4 + elen + nlen, type);
@@ -309,16 +246,18 @@ do_authloop(struct passwd * pw)
case SSH_CMSG_AUTH_TIS:
debug("rcvd SSH_CMSG_AUTH_TIS");
if (options.skey_authentication == 1) {
- char *skeyinfo = skey_keyinfo(pw->pw_name);
+ char *skeyinfo = NULL;
+ if (pw != NULL)
+ skey_keyinfo(pw->pw_name);
if (skeyinfo == NULL) {
- debug("generating fake skeyinfo for %.100s.", pw->pw_name);
- skeyinfo = skey_fake_keyinfo(pw->pw_name);
+ debug("generating fake skeyinfo for %.100s.", luser);
+ skeyinfo = skey_fake_keyinfo(luser);
}
if (skeyinfo != NULL) {
/* we send our s/key- in tis-challenge messages */
debug("sending challenge '%s'", skeyinfo);
packet_start(SSH_SMSG_AUTH_TIS_CHALLENGE);
- packet_put_string(skeyinfo, strlen(skeyinfo));
+ packet_put_cstring(skeyinfo);
packet_send();
packet_write_wait();
continue;
@@ -331,8 +270,9 @@ do_authloop(struct passwd * pw)
char *response = packet_get_string(&dlen);
debug("skey response == '%s'", response);
packet_integrity_check(plen, 4 + dlen, type);
- authenticated = (skey_haskey(pw->pw_name) == 0 &&
- skey_passcheck(pw->pw_name, response) != -1);
+ authenticated = (pw != NULL &&
+ skey_haskey(pw->pw_name) == 0 &&
+ skey_passcheck(pw->pw_name, response) != -1);
xfree(response);
}
break;
@@ -351,13 +291,15 @@ do_authloop(struct passwd * pw)
log("Unknown message during authentication: type %d", type);
break;
}
+ if (authenticated && pw == NULL)
+ fatal("internal error: authenticated for pw == NULL");
/*
* Check if the user is logging in as root and root logins
* are disallowed.
* Note that root login is allowed for forced commands.
*/
- if (authenticated && pw->pw_uid == 0 && !options.permit_root_login) {
+ if (authenticated && pw && pw->pw_uid == 0 && !options.permit_root_login) {
if (forced_command) {
log("Root login accepted for forced command.");
} else {
@@ -373,10 +315,11 @@ do_authloop(struct passwd * pw)
type == SSH_CMSG_AUTH_PASSWORD)
authlog = log;
- authlog("%s %s for %.200s from %.200s port %d%s",
+ authlog("%s %s for %s%.100s from %.200s port %d%s",
authenticated ? "Accepted" : "Failed",
get_authname(type),
- pw->pw_uid == 0 ? "ROOT" : pw->pw_name,
+ pw ? "" : "illegal user ",
+ pw && pw->pw_uid == 0 ? "ROOT" : luser,
get_remote_ipaddr(),
get_remote_port(),
user);
@@ -385,7 +328,7 @@ do_authloop(struct passwd * pw)
return;
if (attempt > AUTH_FAIL_MAX)
- packet_disconnect(AUTH_FAIL_MSG, pw->pw_name);
+ packet_disconnect(AUTH_FAIL_MSG, luser);
/* Send a message indicating that the authentication attempt failed. */
packet_start(SSH_SMSG_FAILURE);
@@ -425,29 +368,29 @@ do_authentication()
/* Verify that the user is a valid user. */
pw = getpwnam(user);
- if (!pw || !allowed_user(pw))
- do_fake_authloop1(user);
- xfree(user);
-
- /* Take a copy of the returned structure. */
- memset(&pwcopy, 0, sizeof(pwcopy));
- pwcopy.pw_name = xstrdup(pw->pw_name);
- pwcopy.pw_passwd = xstrdup(pw->pw_passwd);
- pwcopy.pw_uid = pw->pw_uid;
- pwcopy.pw_gid = pw->pw_gid;
- pwcopy.pw_class = xstrdup(pw->pw_class);
- pwcopy.pw_dir = xstrdup(pw->pw_dir);
- pwcopy.pw_shell = xstrdup(pw->pw_shell);
- pw = &pwcopy;
+ if (pw && allowed_user(pw)) {
+ /* Take a copy of the returned structure. */
+ memset(&pwcopy, 0, sizeof(pwcopy));
+ pwcopy.pw_name = xstrdup(pw->pw_name);
+ pwcopy.pw_passwd = xstrdup(pw->pw_passwd);
+ pwcopy.pw_uid = pw->pw_uid;
+ pwcopy.pw_gid = pw->pw_gid;
+ pwcopy.pw_class = xstrdup(pw->pw_class);
+ pwcopy.pw_dir = xstrdup(pw->pw_dir);
+ pwcopy.pw_shell = xstrdup(pw->pw_shell);
+ pw = &pwcopy;
+ } else {
+ pw = NULL;
+ }
/*
* If we are not running as root, the user must have the same uid as
* the server.
*/
- if (getuid() != 0 && pw->pw_uid != getuid())
+ if (getuid() != 0 && pw && pw->pw_uid != getuid())
packet_disconnect("Cannot change user when server not running as root.");
- debug("Attempting authentication for %.100s.", pw->pw_name);
+ debug("Attempting authentication for %s%.100s.", pw ? "" : "illegal user ", user);
/* If the user has no password, accept authentication immediately. */
if (options.password_authentication &&
@@ -457,13 +400,15 @@ do_authentication()
auth_password(pw, "")) {
/* Authentication with empty password succeeded. */
log("Login for user %s from %.100s, accepted without authentication.",
- pw->pw_name, get_remote_ipaddr());
+ user, get_remote_ipaddr());
} else {
/* Loop until the user has been authenticated or the
connection is closed, do_authloop() returns only if
authentication is successfull */
- do_authloop(pw);
+ do_authloop(pw, user);
}
+ if (pw == NULL)
+ fatal("internal error, authentication successfull for user '%.100s'", user);
/* The user has been authenticated and accepted. */
packet_start(SSH_SMSG_SUCCESS);
OpenPOWER on IntegriCloud