summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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("");
+ packet_put_cstring("");
+ packet_put_int(nprompts);
+ packet_put_cstring(challenge);
+ packet_put_char(echo);
+ packet_send();
+ packet_write_wait();
+}
+
+void
+input_userauth_info_response(int type, int plen, void *ctxt)
+{
+ Authctxt *authctxt = ctxt;
+ int authenticated = 0;
+ u_int nresp, rlen;
+ char *response, *method = "challenge-reponse";
+
+ if (authctxt == NULL)
+ fatal("input_userauth_info_response: no authctxt");
+
+ authctxt->postponed = 0; /* reset */
+ nresp = packet_get_int();
+ if (nresp == 1) {
+ response = packet_get_string(&rlen);
+ packet_done();
+ if (strlen(response) == 0) {
+ /*
+ * if we received an empty response, resend challenge
+ * with echo enabled
+ */
+ char *challenge = get_challenge(authctxt, NULL);
+ if (challenge != NULL) {
+ send_userauth_into_request(authctxt,
+ challenge, 1);
+ authctxt->postponed = 1;
+ }
+ } else if (authctxt->valid) {
+ authenticated = verify_response(authctxt, response);
+ memset(response, 'r', rlen);
+ }
+ xfree(response);
+ }
+ auth_log(authctxt, authenticated, method, " ssh2");
+ if (!authctxt->postponed) {
+ /* unregister callback and send reply */
+ dispatch_set(SSH2_MSG_USERAUTH_INFO_RESPONSE, NULL);
+ userauth_reply(authctxt, authenticated);
+ }
+}
diff --git a/auth2-pam.c b/auth2-pam.c
index 30e02101..498cc746 100644
--- a/auth2-pam.c
+++ b/auth2-pam.c
@@ -1,5 +1,5 @@
#include "includes.h"
-RCSID("$Id: auth2-pam.c,v 1.2 2000/12/20 02:34:49 djm Exp $");
+RCSID("$Id: auth2-pam.c,v 1.3 2001/01/19 04:26:52 mouring Exp $");
#ifdef USE_PAM
#include "ssh.h"
@@ -46,8 +46,10 @@ auth2_pam(Authctxt *authctxt)
retval = (do_pam_authenticate(0) == PAM_SUCCESS);
dispatch_set(SSH2_MSG_USERAUTH_INFO_RESPONSE, NULL);
+#if 0 /* ISSUE: No longer valid, but should this still be
+ handled?? */
userauth_log(authctxt, retval, method);
-
+#endif
return retval;
}
diff --git a/auth2.c b/auth2.c
index 3a247f58..348c2f3a 100644
--- a/auth2.c
+++ b/auth2.c
@@ -23,7 +23,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: auth2.c,v 1.25 2001/01/08 22:29:05 markus Exp $");
+RCSID("$OpenBSD: auth2.c,v 1.28 2001/01/18 17:00:00 markus Exp $");
#ifdef HAVE_OSF_SIA
# include <sia.h>
@@ -84,7 +84,6 @@ void input_service_request(int type, int plen, void *ctxt);
void input_userauth_request(int type, int plen, void *ctxt);
void protocol_error(int type, int plen, void *ctxt);
-
/* helper */
Authmethod *authmethod_lookup(const char *name);
struct passwd *pwcopy(struct passwd *pw);
@@ -121,22 +120,21 @@ Authmethod authmethods[] = {
void
do_authentication2()
{
- Authctxt *authctxt = xmalloc(sizeof(*authctxt));
- memset(authctxt, 'a', sizeof(*authctxt));
- authctxt->valid = 0;
- authctxt->attempt = 0;
- authctxt->failures = 0;
- authctxt->success = 0;
+ Authctxt *authctxt = authctxt_new();
+
x_authctxt = authctxt; /*XXX*/
-#ifdef KRB4
- /* turn off kerberos, not supported by SSH2 */
- options.kerberos_authentication = 0;
+#ifdef AFS
+ /* If machine has AFS, set process authentication group. */
+ if (k_hasafs()) {
+ k_setpag();
+ k_unlog();
+ }
#endif
dispatch_init(&protocol_error);
dispatch_set(SSH2_MSG_SERVICE_REQUEST, &input_service_request);
dispatch_run(DISPATCH_BLOCK, &authctxt->success, authctxt);
- do_authenticated2();
+ do_authenticated2(authctxt);
}
void
@@ -187,7 +185,7 @@ input_userauth_request(int type, int plen, void *ctxt)
{
Authctxt *authctxt = ctxt;
Authmethod *m = NULL;
- char *user, *service, *method;
+ char *user, *service, *method, *style = NULL;
int authenticated = 0;
if (authctxt == NULL)
@@ -199,6 +197,9 @@ input_userauth_request(int type, int plen, void *ctxt)
debug("userauth-request for user %s service %s method %s", user, service, method);
debug("attempt %d failures %d", authctxt->attempt, authctxt->failures);
+ if ((style = strchr(user, ':')) != NULL)
+ *style++ = 0;
+
if (authctxt->attempt++ == 0) {
/* setup auth context */
struct passwd *pw = NULL;
@@ -216,6 +217,7 @@ input_userauth_request(int type, int plen, void *ctxt)
}
authctxt->user = xstrdup(user);
authctxt->service = xstrdup(service);
+ authctxt->style = style ? xstrdup(style) : NULL; /* currently unused */
} else if (authctxt->valid) {
if (strcmp(user, authctxt->user) != 0 ||
strcmp(service, authctxt->service) != 0) {
@@ -224,25 +226,23 @@ input_userauth_request(int type, int plen, void *ctxt)
authctxt->valid = 0;
}
}
+ /* reset state */
+ dispatch_set(SSH2_MSG_USERAUTH_INFO_RESPONSE, &protocol_error);
+ authctxt->postponed = 0;
+ /* try to authenticate user */
m = authmethod_lookup(method);
if (m != NULL) {
debug2("input_userauth_request: try method %s", method);
authenticated = m->userauth(authctxt);
- } else {
- debug2("input_userauth_request: unsupported method %s", method);
- }
- if (!authctxt->valid && authenticated == 1) {
- log("input_userauth_request: INTERNAL ERROR: authenticated invalid user %s service %s", user, method);
- authenticated = 0;
}
+ if (!authctxt->valid && authenticated)
+ fatal("INTERNAL ERROR: authenticated invalid user %s",
+ authctxt->user);
/* Special handling for root */
- if (authenticated == 1 &&
- authctxt->valid && authctxt->pw->pw_uid == 0 && !options.permit_root_login) {
+ if (authenticated && authctxt->pw->pw_uid == 0 && !auth_root_allowed())
authenticated = 0;
- log("ROOT LOGIN REFUSED FROM %.200s", get_canonical_hostname());
- }
#ifdef USE_PAM
if (authenticated && authctxt->user && !do_pam_account(authctxt->user, NULL))
@@ -250,8 +250,10 @@ input_userauth_request(int type, int plen, void *ctxt)
#endif /* USE_PAM */
/* Log before sending the reply */
- userauth_log(authctxt, authenticated, method);
- userauth_reply(authctxt, authenticated);
+ auth_log(authctxt, authenticated, method, " ssh2");
+
+ if (!authctxt->postponed)
+ userauth_reply(authctxt, authenticated);
xfree(service);
xfree(user);
@@ -292,47 +294,13 @@ done:
return;
}
-void
-userauth_log(Authctxt *authctxt, int authenticated, char *method)
-{
- void (*authlog) (const char *fmt,...) = verbose;
- char *user = NULL, *authmsg = NULL;
-
- /* Raise logging level */
- if (authenticated == 1 ||
- !authctxt->valid ||
- authctxt->failures >= AUTH_FAIL_LOG ||
- strcmp(method, "password") == 0)
- authlog = log;
-
- if (authenticated == 1) {
- authmsg = "Accepted";
- } else if (authenticated == 0) {
- authmsg = "Failed";
- } else {
- authmsg = "Postponed";
- }
-
- if (authctxt->valid) {
- user = authctxt->pw->pw_uid == 0 ? "ROOT" : authctxt->user;
- } else {
- user = "NOUSER";
- }
-
- authlog("%s %s for %.200s from %.200s port %d ssh2",
- authmsg,
- method,
- user,
- get_remote_ipaddr(),
- get_remote_port());
-}
-
void
userauth_reply(Authctxt *authctxt, int authenticated)
{
char *methods;
+
/* XXX todo: check if multiple auth methods are needed */
- if (authenticated == 1) {
+ if (authenticated) {
#ifdef WITH_AIXAUTHENTICATE
/* We don't have a pty yet, so just label the line as "ssh" */
if (loginsuccess(authctxt->user?authctxt->user:"NOUSER",
@@ -346,9 +314,9 @@ userauth_reply(Authctxt *authctxt, int authenticated)
packet_write_wait();
/* now we can break out */
authctxt->success = 1;
- } else if (authenticated == 0) {
- if (authctxt->failures++ >= AUTH_FAIL_MAX)
- packet_disconnect("too many failed userauth_requests");
+ } else {
+ if (authctxt->failures++ > AUTH_FAIL_MAX)
+ packet_disconnect(AUTH_FAIL_MSG, authctxt->user);
methods = authmethods_get();
packet_start(SSH2_MSG_USERAUTH_FAILURE);
packet_put_cstring(methods);
@@ -356,8 +324,6 @@ userauth_reply(Authctxt *authctxt, int authenticated)
packet_send();
packet_write_wait();
xfree(methods);
- } else {
- /* do nothing, we did already send a reply */
}
}
@@ -432,16 +398,13 @@ userauth_kbdint(Authctxt *authctxt)
packet_done();
debug("keyboard-interactive language %s devs %s", lang, devs);
+
+ authenticated = auth2_challenge(authctxt, devs);
+
#ifdef USE_PAM
if (authenticated == 0)
authenticated = auth2_pam(authctxt);
#endif
-#ifdef SKEY
- /* XXX hardcoded, we should look at devs */
- if (authenticated == 0)
- if (options.skey_authentication != 0)
- authenticated = auth2_skey(authctxt);
-#endif
xfree(lang);
xfree(devs);
#ifdef HAVE_CYGWIN
@@ -732,20 +695,3 @@ user_key_allowed(struct passwd *pw, Key *key)
key_free(found);
return found_key;
}
-
-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;
-}
diff --git a/log-client.c b/log-client.c
index bfcab30b..656499ad 100644
--- a/log-client.c
+++ b/log-client.c
@@ -36,12 +36,12 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: log-client.c,v 1.13 2001/01/07 11:28:04 markus Exp $");
+RCSID("$OpenBSD: log-client.c,v 1.14 2001/01/18 16:20:21 markus Exp $");
#include "xmalloc.h"
#include "ssh.h"
-static LogLevel log_level = SYSLOG_LEVEL_NOTICE;
+static LogLevel log_level = SYSLOG_LEVEL_INFO;
/* Initialize the log.
* av0 program name (should be argv[0])
@@ -55,7 +55,7 @@ log_init(char *av0, LogLevel level, SyslogFacility ignored1, int ignored2)
case SYSLOG_LEVEL_QUIET:
case SYSLOG_LEVEL_FATAL:
case SYSLOG_LEVEL_ERROR:
- case SYSLOG_LEVEL_NOTICE:
+ case SYSLOG_LEVEL_INFO:
case SYSLOG_LEVEL_VERBOSE:
case SYSLOG_LEVEL_DEBUG1:
case SYSLOG_LEVEL_DEBUG2:
diff --git a/log-server.c b/log-server.c
index 2335a3ef..3b19550e 100644
--- a/log-server.c
+++ b/log-server.c
@@ -36,14 +36,14 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: log-server.c,v 1.18 2001/01/07 11:28:05 markus Exp $");
+RCSID("$OpenBSD: log-server.c,v 1.19 2001/01/18 16:20:21 markus Exp $");
#include <syslog.h>
#include "packet.h"
#include "xmalloc.h"
#include "ssh.h"
-static LogLevel log_level = SYSLOG_LEVEL_NOTICE;
+static LogLevel log_level = SYSLOG_LEVEL_INFO;
static int log_on_stderr = 0;
static int log_facility = LOG_AUTH;
@@ -60,7 +60,7 @@ log_init(char *av0, LogLevel level, SyslogFacility facility, int on_stderr)
case SYSLOG_LEVEL_QUIET:
case SYSLOG_LEVEL_FATAL:
case SYSLOG_LEVEL_ERROR:
- case SYSLOG_LEVEL_NOTICE:
+ case SYSLOG_LEVEL_INFO:
case SYSLOG_LEVEL_VERBOSE:
case SYSLOG_LEVEL_DEBUG1:
case SYSLOG_LEVEL_DEBUG2:
@@ -141,8 +141,8 @@ do_log(LogLevel level, const char *fmt, va_list args)
txt = "error";
pri = LOG_ERR;
break;
- case SYSLOG_LEVEL_NOTICE:
- pri = LOG_NOTICE;
+ case SYSLOG_LEVEL_INFO:
+ pri = LOG_INFO;
break;
case SYSLOG_LEVEL_VERBOSE:
pri = LOG_INFO;
diff --git a/log.c b/log.c
index e13cc90c..9df2a93f 100644
--- a/log.c
+++ b/log.c
@@ -36,7 +36,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: log.c,v 1.13 2001/01/07 11:28:05 markus Exp $");
+RCSID("$OpenBSD: log.c,v 1.14 2001/01/18 16:20:21 markus Exp $");
#include "ssh.h"
#include "xmalloc.h"
@@ -71,7 +71,7 @@ log(const char *fmt,...)
{
va_list args;
va_start(args, fmt);
- do_log(SYSLOG_LEVEL_NOTICE, fmt, args);
+ do_log(SYSLOG_LEVEL_INFO, fmt, args);
va_end(args);
}
@@ -209,13 +209,12 @@ static struct {
{ "QUIET", SYSLOG_LEVEL_QUIET },
{ "FATAL", SYSLOG_LEVEL_FATAL },
{ "ERROR", SYSLOG_LEVEL_ERROR },
- { "NOTICE", SYSLOG_LEVEL_NOTICE },
+ { "INFO", SYSLOG_LEVEL_INFO },
{ "VERBOSE", SYSLOG_LEVEL_VERBOSE },
{ "DEBUG", SYSLOG_LEVEL_DEBUG1 },
{ "DEBUG1", SYSLOG_LEVEL_DEBUG1 },
{ "DEBUG2", SYSLOG_LEVEL_DEBUG2 },
{ "DEBUG3", SYSLOG_LEVEL_DEBUG3 },
- { "INFO", SYSLOG_LEVEL_NOTICE }, /* backward compatible */
{ NULL, 0 }
};
diff --git a/readconf.c b/readconf.c
index 5b552815..7efaf85e 100644
--- a/readconf.c
+++ b/readconf.c
@@ -12,7 +12,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: readconf.c,v 1.53 2001/01/07 11:28:05 markus Exp $");
+RCSID("$OpenBSD: readconf.c,v 1.54 2001/01/18 16:20:22 markus Exp $");
#include "ssh.h"
#include "readconf.h"
@@ -804,7 +804,7 @@ fill_default_options(Options * options)
if (options->user_hostfile2 == NULL)
options->user_hostfile2 = SSH_USER_HOSTFILE2;
if (options->log_level == (LogLevel) - 1)
- options->log_level = SYSLOG_LEVEL_NOTICE;
+ options->log_level = SYSLOG_LEVEL_INFO;
/* options->proxy_command should not be set by default */
/* options->user will be set in the main program if appropriate */
/* options->hostname will be set in the main program if appropriate */
diff --git a/servconf.c b/servconf.c
index fb42d74e..544bb340 100644
--- a/servconf.c
+++ b/servconf.c
@@ -10,7 +10,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: servconf.c,v 1.57 2001/01/08 22:29:05 markus Exp $");
+RCSID("$OpenBSD: servconf.c,v 1.58 2001/01/18 16:20:22 markus Exp $");
#include "ssh.h"
#include "servconf.h"
@@ -130,7 +130,7 @@ fill_default_server_options(ServerOptions *options)
if (options->log_facility == (SyslogFacility) (-1))
options->log_facility = SYSLOG_FACILITY_AUTH;
if (options->log_level == (LogLevel) (-1))
- options->log_level = SYSLOG_LEVEL_NOTICE;
+ options->log_level = SYSLOG_LEVEL_INFO;
if (options->rhosts_authentication == -1)
options->rhosts_authentication = 0;
if (options->rhosts_rsa_authentication == -1)
diff --git a/serverloop.c b/serverloop.c
index 5fb0ed02..958c9661 100644
--- a/serverloop.c
+++ b/serverloop.c
@@ -35,7 +35,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: serverloop.c,v 1.39 2000/12/27 14:19:21 markus Exp $");
+RCSID("$OpenBSD: serverloop.c,v 1.40 2001/01/18 17:00:00 markus Exp $");
#include "xmalloc.h"
#include "ssh.h"
@@ -47,10 +47,10 @@ RCSID("$OpenBSD: serverloop.c,v 1.39 2000/12/27 14:19:21 markus Exp $");
#include "compat.h"
#include "ssh2.h"
+#include "auth.h"
#include "session.h"
#include "dispatch.h"
#include "auth-options.h"
-#include "auth.h"
extern ServerOptions options;
diff --git a/session.c b/session.c
index e52aed5a..2c150043 100644
--- a/session.c
+++ b/session.c
@@ -33,7 +33,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: session.c,v 1.48 2001/01/13 18:43:31 markus Exp $");
+RCSID("$OpenBSD: session.c,v 1.49 2001/01/18 17:00:00 markus Exp $");
#include "xmalloc.h"
#include "ssh.h"
@@ -2000,11 +2000,8 @@ session_proctitle(Session *s)
}
void
-do_authenticated2(void)
+do_authenticated2(Authctxt *authctxt)
{
-#ifdef HAVE_LOGIN_CAP
- struct passwd *pw;
-#endif
/*
* Cancel the alarm we set to limit the time taken for
@@ -2016,8 +2013,8 @@ do_authenticated2(void)
startup_pipe = -1;
}
#if defined(HAVE_LOGIN_CAP) && defined(HAVE_PW_CLASS_IN_PASSWD)
- pw = auth_get_user();
- if ((lc = login_getclass(pw->pw_class)) == NULL) {
+ /* ISSUE: Is this correct? */
+ if ((lc = login_getclass(authctxt->pw->pw_class)) == NULL) {
error("unable to get login class");
return;
}
diff --git a/session.h b/session.h
index bce99f77..ee2e244c 100644
--- a/session.h
+++ b/session.h
@@ -28,7 +28,7 @@
void do_authenticated(struct passwd * pw);
/* SSH2 */
-void do_authenticated2(void);
+void do_authenticated2(Authctxt *ac);
int session_open(int id);
void session_input_channel_req(int id, void *arg);
void session_close_by_pid(pid_t pid, int status);
diff --git a/ssh.1 b/ssh.1
index 59cc7f18..5807ec18 100644
--- a/ssh.1
+++ b/ssh.1
@@ -34,7 +34,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: ssh.1,v 1.76 2001/01/07 11:28:06 markus Exp $
+.\" $OpenBSD: ssh.1,v 1.77 2001/01/18 16:20:22 markus Exp $
.Dd September 25, 1999
.Dt SSH 1
.Os
@@ -814,8 +814,8 @@ Only the superuser can forward privileged ports.
Gives the verbosity level that is used when logging messages from
.Nm ssh .
The possible values are:
-QUIET, FATAL, ERROR, NOTICE, VERBOSE and DEBUG.
-The default is NOTICE.
+QUIET, FATAL, ERROR, INFO, VERBOSE and DEBUG.
+The default is INFO.
.It Cm NumberOfPasswordPrompts
Specifies the number of password prompts before giving up.
The argument to this keyword must be an integer.
diff --git a/ssh.h b/ssh.h
index f7330b91..9c487a39 100644
--- a/ssh.h
+++ b/ssh.h
@@ -12,7 +12,7 @@
* called by a name other than "ssh" or "Secure Shell".
*/
-/* RCSID("$OpenBSD: ssh.h,v 1.57 2001/01/07 11:28:06 markus Exp $"); */
+/* RCSID("$OpenBSD: ssh.h,v 1.58 2001/01/18 16:20:22 markus Exp $"); */
#ifndef SSH_H
#define SSH_H
@@ -445,7 +445,7 @@ typedef enum {
SYSLOG_LEVEL_QUIET,
SYSLOG_LEVEL_FATAL,
SYSLOG_LEVEL_ERROR,
- SYSLOG_LEVEL_NOTICE,
+ SYSLOG_LEVEL_INFO,
SYSLOG_LEVEL_VERBOSE,
SYSLOG_LEVEL_DEBUG1,
SYSLOG_LEVEL_DEBUG2,
diff --git a/sshconnect1.c b/sshconnect1.c
index 17b381c1..b2d4e57b 100644
--- a/sshconnect1.c
+++ b/sshconnect1.c
@@ -13,7 +13,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: sshconnect1.c,v 1.15 2001/01/16 23:58:09 deraadt Exp $");
+RCSID("$OpenBSD: sshconnect1.c,v 1.16 2001/01/18 17:00:00 markus Exp $");
#include <openssl/bn.h>
#include <openssl/dsa.h>
@@ -630,7 +630,8 @@ try_skey_authentication()
}
challenge = packet_get_string(&clen);
packet_integrity_check(payload_len, (4 + clen), type);
- snprintf(prompt, sizeof prompt, "%s\nResponse: ", challenge);
+ snprintf(prompt, sizeof prompt, "%s%s", challenge,
+ strchr(challenge, '\n') ? "" : "\nResponse: ");
xfree(challenge);
if (i != 0)
error("Permission denied, please try again.");
diff --git a/sshd.8 b/sshd.8
index a513978d..415d960a 100644
--- a/sshd.8
+++ b/sshd.8
@@ -34,7 +34,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: sshd.8,v 1.81 2001/01/13 18:56:48 markus Exp $
+.\" $OpenBSD: sshd.8,v 1.82 2001/01/18 16:20:22 markus Exp $
.Dd September 25, 1999
.Dt SSHD 8
.Os
@@ -499,8 +499,8 @@ The default is 600 (seconds).
Gives the verbosity level that is used when logging messages from
.Nm sshd .
The possible values are:
-QUIET, FATAL, ERROR, NOTICE, VERBOSE and DEBUG.
-The default is NOTICE.
+QUIET, FATAL, ERROR, INFO, VERBOSE and DEBUG.
+The default is INFO.
Logging with level DEBUG violates the privacy of users
and is not recommended.
.It Cm MaxStartups
diff --git a/sshd.c b/sshd.c
index be7ae5ab..7f9c3ee7 100644
--- a/sshd.c
+++ b/sshd.c
@@ -40,7 +40,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: sshd.c,v 1.150 2001/01/13 18:32:51 markus Exp $");
+RCSID("$OpenBSD: sshd.c,v 1.152 2001/01/18 16:20:22 markus Exp $");
#include "xmalloc.h"
#include "rsa.h"
@@ -153,10 +153,10 @@ struct {
} sensitive_data;
/*
- * Flag indicating whether the current session key has been used. This flag
- * is set whenever the key is used, and cleared when the key is regenerated.
+ * Flag indicating whether the RSA server key needs to be regenerated.
+ * Is set in the SIGALRM handler and cleared when the key is regenerated.
*/
-int key_used = 0;
+int key_do_regen = 0;
/* This is set to true when SIGHUP is received. */
int received_sighup = 0;
@@ -266,7 +266,6 @@ grace_alarm_handler(int sig)
* do anything with the private key or random state before forking.
* Thus there should be no concurrency control/asynchronous execution
* problems.
- * XXX calling log() is not safe from races.
*/
void
generate_empheral_server_key(void)
@@ -284,17 +283,9 @@ void
key_regeneration_alarm(int sig)
{
int save_errno = errno;
-
- /* Check if we should generate a new key. */
- if (key_used) {
- /* This should really be done in the background. */
- generate_empheral_server_key();
- key_used = 0;
- }
- /* Reschedule the alarm. */
- signal(SIGALRM, key_regeneration_alarm);
- alarm(options.key_regeneration_time);
+ signal(SIGALRM, SIG_DFL);
errno = save_errno;
+ key_do_regen = 1;
}
void
@@ -568,6 +559,7 @@ main(int ac, char **av)
int listen_sock, maxfd;
int startup_p[2];
int startups = 0;
+ int ret, key_used = 0;
__progname = get_progname(av[0]);
init_rng();
@@ -674,7 +666,7 @@ main(int ac, char **av)
* key (unless started from inetd)
*/
log_init(__progname,
- options.log_level == -1 ? SYSLOG_LEVEL_NOTICE : options.log_level,
+ options.log_level == -1 ? SYSLOG_LEVEL_INFO : options.log_level,
options.log_facility == -1 ? SYSLOG_FACILITY_AUTH : options.log_facility,
!silent && !inetd_flag);
@@ -890,14 +882,9 @@ main(int ac, char **av)
fclose(f);
}
}
- if (options.protocol & SSH_PROTO_1) {
+ if (options.protocol & SSH_PROTO_1)
generate_empheral_server_key();
- /* Schedule server key regeneration alarm. */
- signal(SIGALRM, key_regeneration_alarm);
- alarm(options.key_regeneration_time);
- }
-
/* Arrange to restart on SIGHUP. The handler needs listen_sock. */
signal(SIGHUP, sighup_handler);
@@ -938,11 +925,17 @@ main(int ac, char **av)
FD_SET(startup_pipes[i], fdset);
/* Wait in select until there is a connection. */
- if (select(maxfd+1, fdset, NULL, NULL, NULL) < 0) {
- if (errno != EINTR)
- error("select: %.100s", strerror(errno));
- continue;
+ ret = select(maxfd+1, fdset, NULL, NULL, NULL);
+ if (ret < 0 && errno != EINTR)
+ error("select: %.100s", strerror(errno));
+ if (key_used && key_do_regen) {
+ generate_empheral_server_key();
+ key_used = 0;
+ key_do_regen = 0;
}
+ if (ret < 0)
+ continue;
+
for (i = 0; i < options.max_startups; i++)
if (startup_pipes[i] != -1 &&
FD_ISSET(startup_pipes[i], fdset)) {
@@ -1042,7 +1035,13 @@ main(int ac, char **av)
close(startup_p[1]);
/* Mark that the key has been used (it was "given" to the child). */
- key_used = 1;
+ if ((options.protocol & SSH_PROTO_1) &&
+ key_used == 0) {
+ /* Schedule server key regeneration alarm. */
+ signal(SIGALRM, key_regeneration_alarm);
+ alarm(options.key_regeneration_time);
+ key_used = 1;
+ }
arc4random_stir();