- (djm) Big OpenBSD sync:
- markus@cvs.openbsd.org 2000/09/30 10:27:44
[log.c]
allow loglevel debug
- markus@cvs.openbsd.org 2000/10/03 11:59:57
[packet.c]
hmac->mac
- markus@cvs.openbsd.org 2000/10/03 12:03:03
[auth-krb4.c auth-passwd.c auth-rh-rsa.c auth-rhosts.c auth-rsa.c auth1.c]
move fake-auth from auth1.c to individual auth methods, disables s/key in
debug-msg
- markus@cvs.openbsd.org 2000/10/03 12:16:48
ssh.c
do not resolve canonname, i have no idea why this was added oin ossh
- markus@cvs.openbsd.org 2000/10/09 15:30:44
ssh-keygen.1 ssh-keygen.c
-X now reads private ssh.com DSA keys, too.
- markus@cvs.openbsd.org 2000/10/09 15:32:34
auth-options.c
clear options on every call.
- markus@cvs.openbsd.org 2000/10/09 15:51:00
authfd.c authfd.h
interop with ssh-agent2, from <res@shore.net>
- markus@cvs.openbsd.org 2000/10/10 14:20:45
compat.c
use rexexp for version string matching
- provos@cvs.openbsd.org 2000/10/10 22:02:18
[kex.c kex.h myproposal.h ssh.h ssh2.h sshconnect2.c sshd.c dh.c dh.h]
First rough implementation of the diffie-hellman group exchange. The
client can ask the server for bigger groups to perform the diffie-hellman
in, thus increasing the attack complexity when using ciphers with longer
keys. University of Windsor provided network, T the company.
- markus@cvs.openbsd.org 2000/10/11 13:59:52
[auth-rsa.c auth2.c]
clear auth options unless auth sucessfull
- markus@cvs.openbsd.org 2000/10/11 14:00:27
[auth-options.h]
clear auth options unless auth sucessfull
- markus@cvs.openbsd.org 2000/10/11 14:03:27
[scp.1 scp.c]
support 'scp -o' with help from mouring@pconline.com
- markus@cvs.openbsd.org 2000/10/11 14:11:35
[dh.c]
Wall
- markus@cvs.openbsd.org 2000/10/11 14:14:40
[auth.h auth2.c readconf.c readconf.h readpass.c servconf.c servconf.h]
[ssh.h sshconnect2.c sshd_config auth2-skey.c cli.c cli.h]
add support for s/key (kbd-interactive) to ssh2, based on work by
mkiernan@avantgo.com and me
- markus@cvs.openbsd.org 2000/10/11 14:27:24
[auth.c auth1.c auth2.c authfile.c cipher.c cipher.h kex.c kex.h]
[myproposal.h packet.c readconf.c session.c ssh.c ssh.h sshconnect1.c]
[sshconnect2.c sshd.c]
new cipher framework
- markus@cvs.openbsd.org 2000/10/11 14:45:21
[cipher.c]
remove DES
- markus@cvs.openbsd.org 2000/10/12 03:59:20
[cipher.c cipher.h sshconnect1.c sshconnect2.c sshd.c]
enable DES in SSH-1 clients only
- markus@cvs.openbsd.org 2000/10/12 08:21:13
[kex.h packet.c]
remove unused
- markus@cvs.openbsd.org 2000/10/13 12:34:46
[sshd.c]
Kludge for F-Secure Macintosh < 1.0.2; appro@fy.chalmers.se
- markus@cvs.openbsd.org 2000/10/13 12:59:15
[cipher.c cipher.h myproposal.h rijndael.c rijndael.h]
rijndael/aes support
- markus@cvs.openbsd.org 2000/10/13 13:10:54
[sshd.8]
more info about -V
- markus@cvs.openbsd.org 2000/10/13 13:12:02
[myproposal.h]
prefer no compression
diff --git a/auth1.c b/auth1.c
index 99639b5..520da64 100644
--- a/auth1.c
+++ b/auth1.c
@@ -10,28 +10,31 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: auth1.c,v 1.4 2000/09/07 20:27:49 deraadt 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"
-#include "auth.h"
-#include "session.h"
+RCSID("$OpenBSD: auth1.c,v 1.6 2000/10/11 20:27:23 markus Exp $");
#ifdef HAVE_OSF_SIA
# include <sia.h>
# include <siad.h>
#endif
+#include "xmalloc.h"
+#include "rsa.h"
+#include "ssh.h"
+#include "packet.h"
+#include "buffer.h"
+#include "mpaux.h"
+#include "servconf.h"
+#include "compat.h"
+#include "auth.h"
+#include "session.h"
+
/* import */
extern ServerOptions options;
extern char *forced_command;
+
+#ifdef WITH_AIXAUTHENTICATE
+extern char *aixloginmsg;
+#endif /* WITH_AIXAUTHENTICATE */
#ifdef HAVE_OSF_SIA
extern int saved_argc;
extern char **saved_argv;
@@ -67,89 +70,21 @@
}
/*
- * 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)
+do_authloop(struct passwd * pw, char *luser)
{
- int attempt = 0;
-
- log("Faking authloop for illegal user %.200s from %.200s port %d",
- user,
- get_remote_ipaddr(),
- get_remote_port());
-
-#ifdef WITH_AIXAUTHENTICATE
- loginfailed(user,get_canonical_hostname(),"ssh");
-#endif /* WITH_AIXAUTHENTICATE */
-
- /* 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;
-#ifndef SKEY
- (void)packet_read(&plen);
-#else /* SKEY */
- int type = packet_read(&plen);
- 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)
-{
+ int authenticated = 0;
int attempt = 0;
unsigned int bits;
RSA *client_host_key;
BIGNUM *n;
- char *client_user = NULL, *password = NULL;
+ char *client_user, *password;
char user[1024];
unsigned int dlen;
int plen, nlen, elen;
@@ -162,8 +97,12 @@
packet_send();
packet_write_wait();
+ client_user = NULL;
+
for (attempt = 1;; attempt++) {
- int authenticated = 0;
+ /* default to fail */
+ authenticated = 0;
+
strlcpy(user, "", sizeof user);
/* Get a packet from the client. */
@@ -174,7 +113,6 @@
#ifdef AFS
case SSH_CMSG_HAVE_KERBEROS_TGT:
if (!options.kerberos_tgt_passing) {
- /* packet_get_all(); */
verbose("Kerberos tgt passing disabled.");
break;
} else {
@@ -182,14 +120,13 @@
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 {
@@ -197,7 +134,7 @@
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;
@@ -219,11 +156,12 @@
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;
@@ -243,8 +181,7 @@
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);
@@ -275,7 +212,7 @@
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);
@@ -322,7 +259,7 @@
authenticated = 1;
}
#else /* !USE_PAM && !HAVE_OSF_SIA */
- /* Try authentication with the password. */
+ /* Try authentication with the password. */
authenticated = auth_password(pw, password);
#endif /* USE_PAM */
@@ -334,16 +271,18 @@
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;
@@ -356,8 +295,9 @@
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;
@@ -376,12 +316,14 @@
log("Unknown message during authentication: type %d", type);
break;
}
+ if (authenticated && pw == NULL)
+ fatal("internal error: authenticated for pw == NULL");
#ifdef HAVE_CYGWIN
- if (authenticated &&
+ if (authenticated &&
!check_nt_auth(type == SSH_CMSG_AUTH_PASSWORD,pw->pw_uid)) {
packet_disconnect("Authentication rejected for uid %d.",
- (int) pw->pw_uid);
+ (int)pw->pw_uid);
authenticated = 0;
}
#endif
@@ -391,7 +333,7 @@
* 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 {
@@ -407,41 +349,33 @@
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);
#ifdef USE_PAM
- if (authenticated) {
- if (!do_pam_account(pw->pw_name, client_user)) {
- if (client_user != NULL) {
- xfree(client_user);
- client_user = NULL;
- }
- do_fake_authloop1(pw->pw_name);
- }
- return;
- }
-#else /* USE_PAM */
- if (authenticated) {
- return;
- }
-#endif /* USE_PAM */
+ if (authenticated && !do_pam_account(pw->pw_name, client_user))
+ authenticated = 0;
+#endif
if (client_user != NULL) {
xfree(client_user);
client_user = NULL;
}
+ if (authenticated)
+ return;
+
if (attempt > AUTH_FAIL_MAX) {
#ifdef WITH_AIXAUTHENTICATE
- loginfailed(pw->pw_name,get_canonical_hostname(),"ssh");
+ loginfailed(user,get_canonical_hostname(),"ssh");
#endif /* WITH_AIXAUTHENTICATE */
- packet_disconnect(AUTH_FAIL_MSG, pw->pw_name);
+ packet_disconnect(AUTH_FAIL_MSG, luser);
}
/* Send a message indicating that the authentication attempt failed. */
@@ -462,9 +396,6 @@
int plen;
unsigned int ulen;
char *user;
-#ifdef WITH_AIXAUTHENTICATE
- extern char *aixloginmsg;
-#endif /* WITH_AIXAUTHENTICATE */
/* Get the name of the user that we wish to log in as. */
packet_read_expect(&plen, SSH_CMSG_USER);
@@ -485,38 +416,38 @@
/* 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;
+ 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;
#ifdef HAVE_PW_CLASS_IN_PASSWD
- pwcopy.pw_class = xstrdup(pw->pw_class);
+ pwcopy.pw_class = xstrdup(pw->pw_class);
#endif
- pwcopy.pw_dir = xstrdup(pw->pw_dir);
- pwcopy.pw_shell = xstrdup(pw->pw_shell);
- pw = &pwcopy;
+ pwcopy.pw_dir = xstrdup(pw->pw_dir);
+ pwcopy.pw_shell = xstrdup(pw->pw_shell);
+ pw = &pwcopy;
+ } else {
+ pw = NULL;
+ }
#ifdef USE_PAM
- start_pam(pw);
+ if (pw)
+ start_pam(pw);
#endif
-#ifndef HAVE_CYGWIN
/*
* If we are not running as root, the user must have the same uid as
- * the server.
- * Rule not valid on Windows systems.
+ * the server. (Unless you are running Windows)
*/
- if (getuid() != 0 && pw->pw_uid != getuid())
+#ifndef HAVE_CYGWIN
+ if (getuid() != 0 && pw && pw->pw_uid != getuid())
packet_disconnect("Cannot change user when server not running as root.");
#endif
- 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 &&
@@ -527,30 +458,33 @@
auth_pam_password(pw, "")) {
#elif defined(HAVE_OSF_SIA)
(sia_validate_user(NULL, saved_argc, saved_argv,
- get_canonical_hostname(), pw->pw_name, NULL, 0, NULL,
- "") == SIASUCCESS)) {
+ get_canonical_hostname(), pw->pw_name, NULL, 0,
+ NULL, "") == SIASUCCESS)) {
#else /* !HAVE_OSF_SIA && !USE_PAM */
- auth_password(pw, "")) {
+ auth_password(pw, "")) {
#endif /* USE_PAM */
/* 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);
+ packet_send();
+ packet_write_wait();
+
#ifdef WITH_AIXAUTHENTICATE
/* We don't have a pty yet, so just label the line as "ssh" */
if (loginsuccess(user,get_canonical_hostname(),"ssh",&aixloginmsg) < 0)
aixloginmsg = NULL;
#endif /* WITH_AIXAUTHENTICATE */
- packet_start(SSH_SMSG_SUCCESS);
- packet_send();
- packet_write_wait();
/* Perform session preparation. */
do_authenticated(pw);