summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Lindstrom <mouring@eviladmin.org>2001-01-19 04:26:52 +0000
committerBen Lindstrom <mouring@eviladmin.org>2001-01-19 04:26:52 +0000
commitdb65e8fdedadaf79df2d8393a4d43e9094c80649 (patch)
treee5902db5ee2b69f9f3c2fa0dbdeb7f4fc20c68b4
parent5aa80596f76ce36dee4623a00a55548834c3328d (diff)
Please grep through the source and look for 'ISSUE' comments and verify
that I was able to get all the portable bits in the right location. As for the SKEY comment there is an email out to Markus as to how it should be resolved. Until then I just #ifdef SKEY/#endif out the whole block. - (bal) OpenBSD Resync - markus@cvs.openbsd.org 2001/01/18 16:20:21 [log-client.c log-server.c log.c readconf.c servconf.c ssh.1 ssh.h sshd.8 sshd.c] log() is at pri=LOG_INFO, since LOG_NOTICE goes to /dev/console on many systems - markus@cvs.openbsd.org 2001/01/18 16:59:59 [auth-passwd.c auth.c auth.h auth1.c auth2.c serverloop.c session.c session.h sshconnect1.c] 1) removes fake skey from sshd, since this will be much harder with /usr/libexec/auth/login_XXX 2) share/unify code used in ssh-1 and ssh-2 authentication (server side) 3) make addition of BSD_AUTH and other challenge reponse methods easier. - markus@cvs.openbsd.org 2001/01/18 17:12:43 [auth-chall.c auth2-chall.c] rename *-skey.c *-chall.c since the files are not skey specific
-rw-r--r--ChangeLog19
-rw-r--r--Makefile.in2
-rw-r--r--auth-chall.c61
-rw-r--r--auth-passwd.c36
-rw-r--r--auth.c96
-rw-r--r--auth.h15
-rw-r--r--auth1.c216
-rw-r--r--auth2-chall.c113
-rw-r--r--auth2-pam.c6
-rw-r--r--auth2.c124
-rw-r--r--log-client.c6
-rw-r--r--log-server.c10
-rw-r--r--log.c7
-rw-r--r--readconf.c4
-rw-r--r--servconf.c4
-rw-r--r--serverloop.c4
-rw-r--r--session.c11
-rw-r--r--session.h2
-rw-r--r--ssh.16
-rw-r--r--ssh.h4
-rw-r--r--sshconnect1.c5
-rw-r--r--sshd.86
-rw-r--r--sshd.c53
23 files changed, 468 insertions, 342 deletions
diff --git a/ChangeLog b/ChangeLog
index 35937150..8b5df6fd 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,23 @@
20010119
- (djm) Update versions in RPM specfiles
-
+ - (bal) OpenBSD Resync
+ - markus@cvs.openbsd.org 2001/01/18 16:20:21
+ [log-client.c log-server.c log.c readconf.c servconf.c ssh.1 ssh.h
+ sshd.8 sshd.c]
+ log() is at pri=LOG_INFO, since LOG_NOTICE goes to /dev/console on many
+ systems
+ - markus@cvs.openbsd.org 2001/01/18 16:59:59
+ [auth-passwd.c auth.c auth.h auth1.c auth2.c serverloop.c session.c
+ session.h sshconnect1.c]
+ 1) removes fake skey from sshd, since this will be much
+ harder with /usr/libexec/auth/login_XXX
+ 2) share/unify code used in ssh-1 and ssh-2 authentication (server side)
+ 3) make addition of BSD_AUTH and other challenge reponse methods
+ easier.
+ - markus@cvs.openbsd.org 2001/01/18 17:12:43
+ [auth-chall.c auth2-chall.c]
+ rename *-skey.c *-chall.c since the files are not skey specific
+
20010118
- (bal) Super Sized OpenBSD Resync
- markus@cvs.openbsd.org 2001/01/11 22:14:20 GMT 2001 by markus
diff --git a/Makefile.in b/Makefile.in
index d56cd640..57449dcd 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -43,7 +43,7 @@ LIBOPENBSD_COMPAT_OBJS=bsd-arc4random.o bsd-base64.o bsd-bindresvport.o bsd-daem
SSHOBJS= ssh.o sshconnect.o sshconnect1.o sshconnect2.o log-client.o readconf.o clientloop.o
-SSHDOBJS= sshd.o auth.o auth1.o auth2.o auth-skey.o auth2-skey.o auth-rhosts.o auth-options.o auth-krb4.o auth-pam.o auth2-pam.o auth-passwd.o auth-rsa.o auth-rh-rsa.o dh.o pty.o log-server.o login.o loginrec.o servconf.o serverloop.o md5crypt.o session.o groupaccess.o
+SSHDOBJS= sshd.o auth.o auth1.o auth2.o auth-chall.o auth2-chall.o auth-rhosts.o auth-options.o auth-krb4.o auth-pam.o auth2-pam.o auth-passwd.o auth-rsa.o auth-rh-rsa.o dh.o pty.o log-server.o login.o loginrec.o servconf.o serverloop.o md5crypt.o session.o groupaccess.o
TROFFMAN = scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8
CATMAN = scp.0 ssh-add.0 ssh-agent.0 ssh-keygen.0 ssh-keyscan.0 ssh.0 sshd.0 sftp-server.0
diff --git a/auth-chall.c b/auth-chall.c
new file mode 100644
index 00000000..e02e99d3
--- /dev/null
+++ b/auth-chall.c
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2001 Markus Friedl. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "includes.h"
+RCSID("$OpenBSD: auth-chall.c,v 1.1 2001/01/18 17:12:43 markus Exp $");
+
+#include "ssh.h"
+#include "auth.h"
+
+#ifdef SKEY
+char *
+get_challenge(Authctxt *authctxt, char *devs)
+{
+ static char challenge[1024];
+ struct skey skey;
+ if (skeychallenge(&skey, authctxt->user, challenge) == -1)
+ return NULL;
+ strlcat(challenge, "\nS/Key Password: ", sizeof challenge);
+ return challenge;
+}
+int
+verify_response(Authctxt *authctxt, char *response)
+{
+ return (authctxt->valid &&
+ skey_haskey(authctxt->pw->pw_name) == 0 &&
+ skey_passcheck(authctxt->pw->pw_name, response) != -1);
+}
+#else
+/* not available */
+char *
+get_challenge(Authctxt *authctxt, char *devs)
+{
+ return NULL;
+}
+int
+verify_response(Authctxt *authctxt, char *response)
+{
+ return 0;
+}
+#endif
diff --git a/auth-passwd.c b/auth-passwd.c
index 184ce154..8295ea17 100644
--- a/auth-passwd.c
+++ b/auth-passwd.c
@@ -11,30 +11,7 @@
* incompatible with the protocol description in the RFC file, it must be
* called by a name other than "ssh" or "Secure Shell".
*
- *
* Copyright (c) 1999 Dug Song. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -59,7 +36,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: auth-passwd.c,v 1.18 2000/10/03 18:03:03 markus Exp $");
+RCSID("$OpenBSD: auth-passwd.c,v 1.19 2001/01/18 16:59:59 markus Exp $");
#if !defined(USE_PAM) && !defined(HAVE_OSF_SIA)
@@ -68,6 +45,8 @@ RCSID("$OpenBSD: auth-passwd.c,v 1.18 2000/10/03 18:03:03 markus Exp $");
#include "servconf.h"
#include "xmalloc.h"
+#include "auth.h"
+
#ifdef WITH_AIXAUTHENTICATE
# include <login.h>
#endif
@@ -156,15 +135,6 @@ auth_password(struct passwd * pw, const char *password)
}
#endif
-#ifdef SKEY_VIA_PASSWD_IS_DISABLED
- if (options.skey_authentication == 1) {
- int ret = auth_skey_password(pw, password);
- if (ret == 1 || ret == 0)
- return ret;
- /* Fall back to ordinary passwd authentication. */
- }
-#endif
-
#ifdef WITH_AIXAUTHENTICATE
return (authenticate(pw->pw_name,password,&reenter,&authmsg) == 0);
#endif
diff --git a/auth.c b/auth.c
index 59c95fe4..814506d7 100644
--- a/auth.c
+++ b/auth.c
@@ -1,14 +1,4 @@
/*
- * 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 (c) 2000 Markus Friedl. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -33,19 +23,12 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: auth.c,v 1.12 2001/01/13 18:56:48 markus Exp $");
+RCSID("$OpenBSD: auth.c,v 1.13 2001/01/18 16:59:59 markus Exp $");
#include "xmalloc.h"
-#include "rsa.h"
#include "ssh.h"
-#include "pty.h"
-#include "packet.h"
-#include "buffer.h"
-#include "mpaux.h"
-#include "servconf.h"
-#include "compat.h"
-#include "channels.h"
#include "match.h"
+#include "servconf.h"
#include "groupaccess.h"
#ifdef HAVE_LOGIN_H
#include <login.h>
@@ -54,10 +37,8 @@ RCSID("$OpenBSD: auth.c,v 1.12 2001/01/13 18:56:48 markus Exp $");
#include <shadow.h>
#endif /* defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) */
-#include "bufaux.h"
-#include "ssh2.h"
#include "auth.h"
-#include "session.h"
+#include "auth-options.h"
/* import */
extern ServerOptions options;
@@ -179,3 +160,74 @@ allowed_user(struct passwd * pw)
/* We found no reason not to let this user try to log on... */
return 1;
}
+
+Authctxt *
+authctxt_new(void)
+{
+ Authctxt *authctxt = xmalloc(sizeof(*authctxt));
+ memset(authctxt, 0, sizeof(*authctxt));
+ return authctxt;
+}
+
+struct passwd *
+pwcopy(struct passwd *pw)
+{
+ struct passwd *copy = xmalloc(sizeof(*copy));
+ memset(copy, 0, sizeof(*copy));
+ copy->pw_name = xstrdup(pw->pw_name);
+ copy->pw_passwd = xstrdup(pw->pw_passwd);
+ copy->pw_uid = pw->pw_uid;
+ copy->pw_gid = pw->pw_gid;
+#ifdef HAVE_PW_CLASS_IN_PASSWD
+ copy->pw_class = xstrdup(pw->pw_class);
+#endif
+ copy->pw_dir = xstrdup(pw->pw_dir);
+ copy->pw_shell = xstrdup(pw->pw_shell);
+ return copy;
+}
+
+void
+auth_log(Authctxt *authctxt, int authenticated, char *method, char *info)
+{
+ void (*authlog) (const char *fmt,...) = verbose;
+ char *authmsg;
+
+ /* Raise logging level */
+ if (authenticated == 1 ||
+ !authctxt->valid ||
+ authctxt->failures >= AUTH_FAIL_LOG ||
+ strcmp(method, "password") == 0)
+ authlog = log;
+
+ if (authctxt->postponed)
+ authmsg = "Postponed";
+ else
+ authmsg = authenticated ? "Accepted" : "Failed";
+
+ authlog("%s %s for %s%.100s from %.200s port %d%s",
+ authmsg,
+ method,
+ authctxt->valid ? "" : "illegal user ",
+ authctxt->valid && authctxt->pw->pw_uid == 0 ? "ROOT" : authctxt->user,
+ get_remote_ipaddr(),
+ get_remote_port(),
+ info);
+}
+
+/*
+ * Check if the user is logging in as root and root logins are disallowed.
+ * Note that root login is _allways_ allowed for forced commands.
+ */
+int
+auth_root_allowed(void)
+{
+ if (options.permit_root_login)
+ return 1;
+ if (forced_command) {
+ log("Root login accepted for forced command.");
+ return 1;
+ } else {
+ log("ROOT LOGIN REFUSED FROM %.200s", get_canonical_hostname());
+ return 0;
+ }
+}
diff --git a/auth.h b/auth.h
index 4b029f9c..bf4787b6 100644
--- a/auth.h
+++ b/auth.h
@@ -21,7 +21,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $OpenBSD: auth.h,v 1.8 2000/12/28 14:25:51 markus Exp $
+ * $OpenBSD: auth.h,v 1.9 2001/01/18 16:59:59 markus Exp $
*/
#ifndef AUTH_H
#define AUTH_H
@@ -29,12 +29,14 @@
typedef struct Authctxt Authctxt;
struct Authctxt {
int success;
+ int postponed;
int valid;
int attempt;
int failures;
char *user;
char *service;
struct passwd *pw;
+ char *style;
};
#include "auth-pam.h"
@@ -43,13 +45,20 @@ struct Authctxt {
void do_authentication(void);
void do_authentication2(void);
-void userauth_log(Authctxt *authctxt, int authenticated, char *method);
+Authctxt *authctxt_new(void);
+void auth_log(Authctxt *authctxt, int authenticated, char *method, char *info);
void userauth_reply(Authctxt *authctxt, int authenticated);
+int auth_root_allowed(void);
-int auth2_skey(Authctxt *authctxt);
+int auth2_challenge(Authctxt *authctxt, char *devs);
int allowed_user(struct passwd * pw);
+
+char *get_challenge(Authctxt *authctxt, char *devs);
+int verify_response(Authctxt *authctxt, char *response);
+
struct passwd * auth_get_user(void);
+struct passwd * pwcopy(struct passwd *pw);
#define AUTH_FAIL_MAX 6
#define AUTH_FAIL_LOG (AUTH_FAIL_MAX/2)
diff --git a/auth1.c b/auth1.c
index 51ed8f77..0f21c4c7 100644
--- a/auth1.c
+++ b/auth1.c
@@ -10,7 +10,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: auth1.c,v 1.10 2001/01/07 19:06:25 markus Exp $");
+RCSID("$OpenBSD: auth1.c,v 1.11 2001/01/18 16:59:59 markus Exp $");
#ifdef HAVE_OSF_SIA
# include <sia.h>
@@ -56,41 +56,53 @@ get_authname(int type)
return "rhosts-rsa";
case SSH_CMSG_AUTH_RHOSTS:
return "rhosts";
+ case SSH_CMSG_AUTH_TIS:
+ case SSH_CMSG_AUTH_TIS_RESPONSE:
+ return "challenge-response";
#ifdef KRB4
case SSH_CMSG_AUTH_KERBEROS:
return "kerberos";
#endif
-#ifdef SKEY
- case SSH_CMSG_AUTH_TIS_RESPONSE:
- return "s/key";
-#endif
}
snprintf(buf, sizeof buf, "bad-auth-msg-%d", type);
return buf;
}
/*
- * read packets and try to authenticate local user 'luser'.
- * return if authentication is successful. 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.
+ * read packets, try to authenticate the user and
+ * return only if authentication is successful
*/
void
-do_authloop(struct passwd * pw, char *luser)
+do_authloop(Authctxt *authctxt)
{
int authenticated = 0;
- int attempt = 0;
u_int bits;
RSA *client_host_key;
BIGNUM *n;
char *client_user, *password;
- char user[1024];
+ char info[1024];
u_int dlen;
int plen, nlen, elen;
u_int ulen;
int type = 0;
- void (*authlog) (const char *fmt,...) = verbose;
+ struct passwd *pw = authctxt->pw;
+
+ debug("Attempting authentication for %s%.100s.",
+ authctxt->valid ? "" : "illegal user ", authctxt->user);
+
+ /* If the user has no password, accept authentication immediately. */
+ if (options.password_authentication &&
+#ifdef KRB4
+ (!options.kerberos_authentication || options.kerberos_or_local_passwd) &&
+#endif
+#ifdef USE_PAM /* ISSUE: Right?? */
+ auth_pam_password(pw, password)) {
+#else
+ auth_password(pw, "")) {
+#endif
+ auth_log(authctxt, 1, "without authentication", "");
+ return;
+ }
/* Indicate that authentication is needed. */
packet_start(SSH_SMSG_FAILURE);
@@ -99,11 +111,11 @@ do_authloop(struct passwd * pw, char *luser)
client_user = NULL;
- for (attempt = 1;; attempt++) {
+ for (;;) {
/* default to fail */
authenticated = 0;
- strlcpy(user, "", sizeof user);
+ info[0] = '\0';
/* Get a packet from the client. */
type = packet_read(&plen);
@@ -120,7 +132,7 @@ do_authloop(struct passwd * pw, char *luser)
char *tgt = packet_get_string(&dlen);
packet_integrity_check(plen, 4 + dlen, type);
if (!auth_kerberos_tgt(pw, tgt))
- verbose("Kerberos tgt REFUSED for %.100s", luser);
+ verbose("Kerberos tgt REFUSED for %.100s", authctxt->user);
xfree(tgt);
}
continue;
@@ -134,7 +146,7 @@ do_authloop(struct passwd * pw, char *luser)
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 %.100s", luser);
+ verbose("AFS token REFUSED for %.100s", authctxt->user);
xfree(token_string);
}
continue;
@@ -142,7 +154,6 @@ do_authloop(struct passwd * pw, char *luser)
#ifdef KRB4
case SSH_CMSG_AUTH_KERBEROS:
if (!options.kerberos_authentication) {
- /* packet_get_all(); */
verbose("Kerberos authentication disabled.");
break;
} else {
@@ -152,17 +163,17 @@ do_authloop(struct passwd * pw, char *luser)
char *kdata = packet_get_string((u_int *) &auth.length);
packet_integrity_check(plen, 4 + auth.length, type);
- if (auth.length < MAX_KTXT_LEN)
- memcpy(auth.dat, kdata, auth.length);
- xfree(kdata);
-
- if (pw != NULL) {
+ if (authctxt->valid) {
+ if (auth.length < MAX_KTXT_LEN)
+ memcpy(auth.dat, kdata, auth.length);
authenticated = auth_krb4(pw->pw_name, &auth, &tkt_user);
if (authenticated) {
- snprintf(user, sizeof user, " tktuser %s", tkt_user);
+ snprintf(info, sizeof info,
+ " tktuser %.100s", tkt_user);
xfree(tkt_user);
}
}
+ xfree(kdata);
}
break;
#endif /* KRB4 */
@@ -184,7 +195,7 @@ do_authloop(struct passwd * pw, char *luser)
/* Try to authenticate using /etc/hosts.equiv and .rhosts. */
authenticated = auth_rhosts(pw, client_user);
- snprintf(user, sizeof user, " ruser %s", client_user);
+ snprintf(info, sizeof info, " ruser %.100s", client_user);
break;
case SSH_CMSG_AUTH_RHOSTS_RSA:
@@ -219,7 +230,7 @@ do_authloop(struct passwd * pw, char *luser)
authenticated = auth_rhosts_rsa(pw, client_user, client_host_key);
RSA_free(client_host_key);
- snprintf(user, sizeof user, " ruser %s", client_user);
+ snprintf(info, sizeof info, " ruser %.100s", client_user);
break;
case SSH_CMSG_AUTH_RSA:
@@ -267,22 +278,19 @@ do_authloop(struct passwd * pw, char *luser)
xfree(password);
break;
-#ifdef SKEY
+#ifdef SKEY /* ISSUE: Is this right? we don't define
+ having skey_authentication in
+ servconf.h by default so I assume
+ we need to deal with this via #ifdef
+ in some reasonable way */
case SSH_CMSG_AUTH_TIS:
debug("rcvd SSH_CMSG_AUTH_TIS");
if (options.skey_authentication == 1) {
- char *skeyinfo = NULL;
- if (pw != NULL)
- skeyinfo = skey_keyinfo(pw->pw_name);
- if (skeyinfo == NULL) {
- 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);
+ char *challenge = get_challenge(authctxt, authctxt->style);
+ if (challenge != NULL) {
+ debug("sending challenge '%s'", challenge);
packet_start(SSH_SMSG_AUTH_TIS_CHALLENGE);
- packet_put_cstring(skeyinfo);
+ packet_put_cstring(challenge);
packet_send();
packet_write_wait();
continue;
@@ -293,20 +301,14 @@ do_authloop(struct passwd * pw, char *luser)
debug("rcvd SSH_CMSG_AUTH_TIS_RESPONSE");
if (options.skey_authentication == 1) {
char *response = packet_get_string(&dlen);
- debug("skey response == '%s'", response);
+ debug("got response '%s'", response);
packet_integrity_check(plen, 4 + dlen, type);
- authenticated = (pw != NULL &&
- skey_haskey(pw->pw_name) == 0 &&
- skey_passcheck(pw->pw_name, response) != -1);
+ authenticated = verify_response(authctxt, response);
+ memset(response, 'r', dlen);
xfree(response);
}
break;
-#else
- case SSH_CMSG_AUTH_TIS:
- /* TIS Authentication is unsupported */
- log("TIS authentication unsupported.");
- break;
-#endif
+#endif /* ISSUE: End of wrong SKEY defines */
default:
/*
@@ -316,10 +318,11 @@ do_authloop(struct passwd * pw, char *luser)
log("Unknown message during authentication: type %d", type);
break;
}
- if (authenticated && pw == NULL)
- fatal("internal error: authenticated for pw == NULL");
+ if (!authctxt->valid && authenticated)
+ fatal("INTERNAL ERROR: authenticated invalid user %s",
+ authctxt->user);
-#ifdef HAVE_CYGWIN
+#ifdef HAVE_CYGWIN /* ISSUE: Right place? */
if (authenticated &&
!check_nt_auth(type == SSH_CMSG_AUTH_PASSWORD,pw->pw_uid)) {
packet_disconnect("Authentication rejected for uid %d.",
@@ -328,41 +331,18 @@ do_authloop(struct passwd * pw, char *luser)
}
#endif
- /*
- * 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->pw_uid == 0 && !options.permit_root_login) {
- if (forced_command) {
- log("Root login accepted for forced command.");
- } else {
- authenticated = 0;
- log("ROOT LOGIN REFUSED FROM %.200s",
- get_canonical_hostname());
- }
- }
-
- /* Raise logging level */
- if (authenticated ||
- attempt == AUTH_FAIL_LOG ||
- type == SSH_CMSG_AUTH_PASSWORD)
- authlog = log;
-
- authlog("%s %s for %s%.100s from %.200s port %d%s",
- authenticated ? "Accepted" : "Failed",
- get_authname(type),
- pw ? "" : "illegal user ",
- pw && pw->pw_uid == 0 ? "ROOT" : luser,
- get_remote_ipaddr(),
- get_remote_port(),
- user);
+ /* Special handling for root */
+ if (authenticated && authctxt->pw->pw_uid == 0 && !auth_root_allowed())
+ authenticated = 0;
-#ifdef USE_PAM
+#ifdef USE_PAM /* ISSUE: Right place? */
if (authenticated && !do_pam_account(pw->pw_name, client_user))
authenticated = 0;
#endif
+ /* Log before sending the reply */
+ auth_log(authctxt, authenticated, get_authname(type), info);
+
if (client_user != NULL) {
xfree(client_user);
client_user = NULL;
@@ -371,14 +351,13 @@ do_authloop(struct passwd * pw, char *luser)
if (authenticated)
return;
- if (attempt > AUTH_FAIL_MAX) {
+ if (authctxt->failures++ > AUTH_FAIL_MAX) {
#ifdef WITH_AIXAUTHENTICATE
loginfailed(user,get_canonical_hostname(),"ssh");
#endif /* WITH_AIXAUTHENTICATE */
- packet_disconnect(AUTH_FAIL_MSG, luser);
+ packet_disconnect(AUTH_FAIL_MSG, authctxt->user);
}
- /* Send a message indicating that the authentication attempt failed. */
packet_start(SSH_SMSG_FAILURE);
packet_send();
packet_write_wait();
@@ -392,10 +371,11 @@ do_authloop(struct passwd * pw, char *luser)
void
do_authentication()
{
- struct passwd *pw, pwcopy;
+ Authctxt *authctxt;
+ struct passwd *pw;
int plen;
u_int ulen;
- char *user;
+ char *user, *style = NULL;
/* Get the name of the user that we wish to log in as. */
packet_read_expect(&plen, SSH_CMSG_USER);
@@ -404,6 +384,13 @@ do_authentication()
user = packet_get_string(&ulen);
packet_integrity_check(plen, (4 + ulen), SSH_CMSG_USER);
+ if ((style = strchr(user, ':')) != NULL)
+ *style++ = 0;
+
+ authctxt = authctxt_new();
+ authctxt->user = user;
+ authctxt->style = style;
+
setproctitle("%s", user);
#ifdef AFS
@@ -417,21 +404,13 @@ do_authentication()
/* Verify that the user is a valid user. */
pw = getpwnam(user);
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);
-#endif
- pwcopy.pw_dir = xstrdup(pw->pw_dir);
- pwcopy.pw_shell = xstrdup(pw->pw_shell);
- pw = &pwcopy;
+ authctxt->valid = 1;
+ pw = pwcopy(pw);
} else {
+ debug("do_authentication: illegal user %s", user);
pw = NULL;
}
+ authctxt->pw = pw;
#ifdef USE_PAM
if (pw)
@@ -447,44 +426,25 @@ do_authentication()
packet_disconnect("Cannot change user when server not running as root.");
#endif
- debug("Attempting authentication for %s%.100s.", pw ? "" : "illegal user ", user);
-
- /* If the user has no password, accept authentication immediately. */
- if (options.password_authentication &&
-#ifdef KRB4
- (!options.kerberos_authentication || options.kerberos_or_local_passwd) &&
-#endif /* KRB4 */
-#ifdef USE_PAM
- 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)) {
-#else /* !HAVE_OSF_SIA && !USE_PAM */
- auth_password(pw, "")) {
-#endif /* USE_PAM */
- /* Authentication with empty password succeeded. */
- log("Login for user %s from %.100s, accepted without authentication.",
- user, get_remote_ipaddr());
- } else {
- /* Loop until the user has been authenticated or the
- connection is closed, do_authloop() returns only if
- authentication is successful */
- do_authloop(pw, user);
- }
- if (pw == NULL)
- fatal("internal error, authentication successful for user '%.100s'", user);
+ /*
+ * Loop until the user has been authenticated or the connection is
+ * closed, do_authloop() returns only if authentication is successful
+ */
+ do_authloop(authctxt);
/* 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)
+ if (loginsuccess(authctxt->user,get_canonical_hostname(),"ssh",&aixloginmsg) < 0)
aixloginmsg = NULL;
#endif /* WITH_AIXAUTHENTICATE */
- xfree(user);
+
+ xfree(authctxt->user);
+ xfree(authctxt);
/* Perform session preparation. */
do_authenticated(pw);
diff --git a/auth2-chall.c b/auth2-chall.c
new file mode 100644
index 00000000..77294f4b
--- /dev/null
+++ b/auth2-chall.c
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2001 Markus Friedl. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "includes.h"
+RCSID("$OpenBSD: auth2-chall.c,v 1.1 2001/01/18 17:12:43 markus Exp $");
+
+#include "ssh.h"
+#include "ssh2.h"
+#include "auth.h"
+#include "packet.h"
+#include "xmalloc.h"
+#include "dispatch.h"
+
+void send_userauth_into_request(Authctxt *authctxt, char *challenge, int echo);
+void input_userauth_info_response(int type, int plen, void *ctxt);
+
+/*
+ * try challenge-reponse, return -1 (= postponed) if we have to
+ * wait for the response.
+ */
+int
+auth2_challenge(Authctxt *authctxt, char *devs)
+{
+ char *challenge;
+
+ if (!authctxt->valid || authctxt->user == NULL)
+ return 0;
+ if ((challenge = get_challenge(authctxt, devs)) == NULL)
+ return 0;
+ send_userauth_into_request(authctxt, challenge, 0);
+ dispatch_set(SSH2_MSG_USERAUTH_INFO_RESPONSE,
+ &input_userauth_info_response);
+ authctxt->postponed = 1;
+ return 0;
+}
+
+void
+send_userauth_into_request(Authctxt *authctxt, char *challenge, int echo)
+{
+ int nprompts = 1;
+
+ packet_start(SSH2_MSG_USERAUTH_INFO_REQUEST);
+ /* name, instruction and language are unused */
+ packet_put_cstring("");
+ packet_put_cstring("");