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 35937150b..8b5df6fde 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,23 @@
120010119 120010119
2 - (djm) Update versions in RPM specfiles 2 - (djm) Update versions in RPM specfiles
3 3 - (bal) OpenBSD Resync
4 - markus@cvs.openbsd.org 2001/01/18 16:20:21
5 [log-client.c log-server.c log.c readconf.c servconf.c ssh.1 ssh.h
6 sshd.8 sshd.c]
7 log() is at pri=LOG_INFO, since LOG_NOTICE goes to /dev/console on many
8 systems
9 - markus@cvs.openbsd.org 2001/01/18 16:59:59
10 [auth-passwd.c auth.c auth.h auth1.c auth2.c serverloop.c session.c
11 session.h sshconnect1.c]
12 1) removes fake skey from sshd, since this will be much
13 harder with /usr/libexec/auth/login_XXX
14 2) share/unify code used in ssh-1 and ssh-2 authentication (server side)
15 3) make addition of BSD_AUTH and other challenge reponse methods
16 easier.
17 - markus@cvs.openbsd.org 2001/01/18 17:12:43
18 [auth-chall.c auth2-chall.c]
19 rename *-skey.c *-chall.c since the files are not skey specific
20
420010118 2120010118
5 - (bal) Super Sized OpenBSD Resync 22 - (bal) Super Sized OpenBSD Resync
6 - markus@cvs.openbsd.org 2001/01/11 22:14:20 GMT 2001 by markus 23 - markus@cvs.openbsd.org 2001/01/11 22:14:20 GMT 2001 by markus
diff --git a/Makefile.in b/Makefile.in
index d56cd640a..57449dcd9 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
43 43
44SSHOBJS= ssh.o sshconnect.o sshconnect1.o sshconnect2.o log-client.o readconf.o clientloop.o 44SSHOBJS= ssh.o sshconnect.o sshconnect1.o sshconnect2.o log-client.o readconf.o clientloop.o
45 45
46SSHDOBJS= 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 46SSHDOBJS= 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
47 47
48TROFFMAN = scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 48TROFFMAN = scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8
49CATMAN = scp.0 ssh-add.0 ssh-agent.0 ssh-keygen.0 ssh-keyscan.0 ssh.0 sshd.0 sftp-server.0 49CATMAN = 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 000000000..e02e99d36
--- /dev/null
+++ b/auth-chall.c
@@ -0,0 +1,61 @@
1/*
2 * Copyright (c) 2001 Markus Friedl. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
15 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
16 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
17 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
18 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
19 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
20 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 */
24
25#include "includes.h"
26RCSID("$OpenBSD: auth-chall.c,v 1.1 2001/01/18 17:12:43 markus Exp $");
27
28#include "ssh.h"
29#include "auth.h"
30
31#ifdef SKEY
32char *
33get_challenge(Authctxt *authctxt, char *devs)
34{
35 static char challenge[1024];
36 struct skey skey;
37 if (skeychallenge(&skey, authctxt->user, challenge) == -1)
38 return NULL;
39 strlcat(challenge, "\nS/Key Password: ", sizeof challenge);
40 return challenge;
41}
42int
43verify_response(Authctxt *authctxt, char *response)
44{
45 return (authctxt->valid &&
46 skey_haskey(authctxt->pw->pw_name) == 0 &&
47 skey_passcheck(authctxt->pw->pw_name, response) != -1);
48}
49#else
50/* not available */
51char *
52get_challenge(Authctxt *authctxt, char *devs)
53{
54 return NULL;
55}
56int
57verify_response(Authctxt *authctxt, char *response)
58{
59 return 0;
60}
61#endif
diff --git a/auth-passwd.c b/auth-passwd.c
index 184ce154c..8295ea177 100644
--- a/auth-passwd.c
+++ b/auth-passwd.c
@@ -11,30 +11,7 @@
11 * incompatible with the protocol description in the RFC file, it must be 11 * incompatible with the protocol description in the RFC file, it must be
12 * called by a name other than "ssh" or "Secure Shell". 12 * called by a name other than "ssh" or "Secure Shell".
13 * 13 *
14 *
15 * Copyright (c) 1999 Dug Song. All rights reserved. 14 * Copyright (c) 1999 Dug Song. All rights reserved.
16 *
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions
19 * are met:
20 * 1. Redistributions of source code must retain the above copyright
21 * notice, this list of conditions and the following disclaimer.
22 * 2. Redistributions in binary form must reproduce the above copyright
23 * notice, this list of conditions and the following disclaimer in the
24 * documentation and/or other materials provided with the distribution.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
27 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
28 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
29 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
30 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
31 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
35 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 *
37 *
38 * Copyright (c) 2000 Markus Friedl. All rights reserved. 15 * Copyright (c) 2000 Markus Friedl. All rights reserved.
39 * 16 *
40 * Redistribution and use in source and binary forms, with or without 17 * Redistribution and use in source and binary forms, with or without
@@ -59,7 +36,7 @@
59 */ 36 */
60 37
61#include "includes.h" 38#include "includes.h"
62RCSID("$OpenBSD: auth-passwd.c,v 1.18 2000/10/03 18:03:03 markus Exp $"); 39RCSID("$OpenBSD: auth-passwd.c,v 1.19 2001/01/18 16:59:59 markus Exp $");
63 40
64#if !defined(USE_PAM) && !defined(HAVE_OSF_SIA) 41#if !defined(USE_PAM) && !defined(HAVE_OSF_SIA)
65 42
@@ -68,6 +45,8 @@ RCSID("$OpenBSD: auth-passwd.c,v 1.18 2000/10/03 18:03:03 markus Exp $");
68#include "servconf.h" 45#include "servconf.h"
69#include "xmalloc.h" 46#include "xmalloc.h"
70 47
48#include "auth.h"
49
71#ifdef WITH_AIXAUTHENTICATE 50#ifdef WITH_AIXAUTHENTICATE
72# include <login.h> 51# include <login.h>
73#endif 52#endif
@@ -156,15 +135,6 @@ auth_password(struct passwd * pw, const char *password)
156 } 135 }
157#endif 136#endif
158 137
159#ifdef SKEY_VIA_PASSWD_IS_DISABLED
160 if (options.skey_authentication == 1) {
161 int ret = auth_skey_password(pw, password);
162 if (ret == 1 || ret == 0)
163 return ret;
164 /* Fall back to ordinary passwd authentication. */
165 }
166#endif
167
168#ifdef WITH_AIXAUTHENTICATE 138#ifdef WITH_AIXAUTHENTICATE
169 return (authenticate(pw->pw_name,password,&reenter,&authmsg) == 0); 139 return (authenticate(pw->pw_name,password,&reenter,&authmsg) == 0);
170#endif 140#endif
diff --git a/auth.c b/auth.c
index 59c95fe48..814506d7c 100644
--- a/auth.c
+++ b/auth.c
@@ -1,14 +1,4 @@
1/* 1/*
2 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
3 * All rights reserved
4 *
5 * As far as I am concerned, the code I have written for this software
6 * can be used freely for any purpose. Any derived versions of this
7 * software must be clearly marked as such, and if the derived work is
8 * incompatible with the protocol description in the RFC file, it must be
9 * called by a name other than "ssh" or "Secure Shell".
10 *
11 *
12 * Copyright (c) 2000 Markus Friedl. All rights reserved. 2 * Copyright (c) 2000 Markus Friedl. All rights reserved.
13 * 3 *
14 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
@@ -33,19 +23,12 @@
33 */ 23 */
34 24
35#include "includes.h" 25#include "includes.h"
36RCSID("$OpenBSD: auth.c,v 1.12 2001/01/13 18:56:48 markus Exp $"); 26RCSID("$OpenBSD: auth.c,v 1.13 2001/01/18 16:59:59 markus Exp $");
37 27
38#include "xmalloc.h" 28#include "xmalloc.h"
39#include "rsa.h"
40#include "ssh.h" 29#include "ssh.h"
41#include "pty.h"
42#include "packet.h"
43#include "buffer.h"
44#include "mpaux.h"
45#include "servconf.h"
46#include "compat.h"
47#include "channels.h"
48#include "match.h" 30#include "match.h"
31#include "servconf.h"
49#include "groupaccess.h" 32#include "groupaccess.h"
50#ifdef HAVE_LOGIN_H 33#ifdef HAVE_LOGIN_H
51#include <login.h> 34#include <login.h>
@@ -54,10 +37,8 @@ RCSID("$OpenBSD: auth.c,v 1.12 2001/01/13 18:56:48 markus Exp $");
54#include <shadow.h> 37#include <shadow.h>
55#endif /* defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) */ 38#endif /* defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) */
56 39
57#include "bufaux.h"
58#include "ssh2.h"
59#include "auth.h" 40#include "auth.h"
60#include "session.h" 41#include "auth-options.h"
61 42
62/* import */ 43/* import */
63extern ServerOptions options; 44extern ServerOptions options;
@@ -179,3 +160,74 @@ allowed_user(struct passwd * pw)
179 /* We found no reason not to let this user try to log on... */ 160 /* We found no reason not to let this user try to log on... */
180 return 1; 161 return 1;
181} 162}
163
164Authctxt *
165authctxt_new(void)
166{
167 Authctxt *authctxt = xmalloc(sizeof(*authctxt));
168 memset(authctxt, 0, sizeof(*authctxt));
169 return authctxt;
170}
171
172struct passwd *
173pwcopy(struct passwd *pw)
174{
175 struct passwd *copy = xmalloc(sizeof(*copy));
176 memset(copy, 0, sizeof(*copy));
177 copy->pw_name = xstrdup(pw->pw_name);
178 copy->pw_passwd = xstrdup(pw->pw_passwd);
179 copy->pw_uid = pw->pw_uid;
180 copy->pw_gid = pw->pw_gid;
181#ifdef HAVE_PW_CLASS_IN_PASSWD
182 copy->pw_class = xstrdup(pw->pw_class);
183#endif
184 copy->pw_dir = xstrdup(pw->pw_dir);
185 copy->pw_shell = xstrdup(pw->pw_shell);
186 return copy;
187}
188
189void
190auth_log(Authctxt *authctxt, int authenticated, char *method, char *info)
191{
192 void (*authlog) (const char *fmt,...) = verbose;
193 char *authmsg;
194
195 /* Raise logging level */
196 if (authenticated == 1 ||
197 !authctxt->valid ||
198 authctxt->failures >= AUTH_FAIL_LOG ||
199 strcmp(method, "password") == 0)
200 authlog = log;
201
202 if (authctxt->postponed)
203 authmsg = "Postponed";
204 else
205 authmsg = authenticated ? "Accepted" : "Failed";
206
207 authlog("%s %s for %s%.100s from %.200s port %d%s",
208 authmsg,
209 method,
210 authctxt->valid ? "" : "illegal user ",
211 authctxt->valid && authctxt->pw->pw_uid == 0 ? "ROOT" : authctxt->user,
212 get_remote_ipaddr(),
213 get_remote_port(),
214 info);
215}
216
217/*
218 * Check if the user is logging in as root and root logins are disallowed.
219 * Note that root login is _allways_ allowed for forced commands.
220 */
221int
222auth_root_allowed(void)
223{
224 if (options.permit_root_login)
225 return 1;
226 if (forced_command) {
227 log("Root login accepted for forced command.");
228 return 1;
229 } else {
230 log("ROOT LOGIN REFUSED FROM %.200s", get_canonical_hostname());
231 return 0;
232 }
233}
diff --git a/auth.h b/auth.h
index 4b029f9cc..bf4787b68 100644
--- a/auth.h
+++ b/auth.h
@@ -21,7 +21,7 @@
21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 22 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 * 23 *
24 * $OpenBSD: auth.h,v 1.8 2000/12/28 14:25:51 markus Exp $ 24 * $OpenBSD: auth.h,v 1.9 2001/01/18 16:59:59 markus Exp $
25 */ 25 */
26#ifndef AUTH_H 26#ifndef AUTH_H
27#define AUTH_H 27#define AUTH_H
@@ -29,12 +29,14 @@
29typedef struct Authctxt Authctxt; 29typedef struct Authctxt Authctxt;
30struct Authctxt { 30struct Authctxt {
31 int success; 31 int success;
32 int postponed;
32 int valid; 33 int valid;
33 int attempt; 34 int attempt;
34 int failures; 35 int failures;
35 char *user; 36 char *user;
36 char *service; 37 char *service;
37 struct passwd *pw; 38 struct passwd *pw;
39 char *style;
38}; 40};
39 41
40#include "auth-pam.h" 42#include "auth-pam.h"
@@ -43,13 +45,20 @@ struct Authctxt {
43void do_authentication(void); 45void do_authentication(void);
44void do_authentication2(void); 46void do_authentication2(void);
45 47
46void userauth_log(Authctxt *authctxt, int authenticated, char *method); 48Authctxt *authctxt_new(void);
49void auth_log(Authctxt *authctxt, int authenticated, char *method, char *info);
47void userauth_reply(Authctxt *authctxt, int authenticated); 50void userauth_reply(Authctxt *authctxt, int authenticated);
51int auth_root_allowed(void);
48 52
49int auth2_skey(Authctxt *authctxt); 53int auth2_challenge(Authctxt *authctxt, char *devs);
50 54
51int allowed_user(struct passwd * pw); 55int allowed_user(struct passwd * pw);
56
57char *get_challenge(Authctxt *authctxt, char *devs);
58int verify_response(Authctxt *authctxt, char *response);
59
52struct passwd * auth_get_user(void); 60struct passwd * auth_get_user(void);
61struct passwd * pwcopy(struct passwd *pw);
53 62
54#define AUTH_FAIL_MAX 6 63#define AUTH_FAIL_MAX 6
55#define AUTH_FAIL_LOG (AUTH_FAIL_MAX/2) 64#define AUTH_FAIL_LOG (AUTH_FAIL_MAX/2)
diff --git a/auth1.c b/auth1.c
index 51ed8f773..0f21c4c7c 100644
--- a/auth1.c
+++ b/auth1.c
@@ -10,7 +10,7 @@
10 */ 10 */
11 11
12#include "includes.h" 12#include "includes.h"
13RCSID("$OpenBSD: auth1.c,v 1.10 2001/01/07 19:06:25 markus Exp $"); 13RCSID("$OpenBSD: auth1.c,v 1.11 2001/01/18 16:59:59 markus Exp $");
14 14
15#ifdef HAVE_OSF_SIA 15#ifdef HAVE_OSF_SIA
16# include <sia.h> 16# include <sia.h>
@@ -56,41 +56,53 @@ get_authname(int type)
56 return "rhosts-rsa"; 56 return "rhosts-rsa";
57 case SSH_CMSG_AUTH_RHOSTS: 57 case SSH_CMSG_AUTH_RHOSTS:
58 return "rhosts"; 58 return "rhosts";
59 case SSH_CMSG_AUTH_TIS:
60 case SSH_CMSG_AUTH_TIS_RESPONSE:
61 return "challenge-response";
59#ifdef KRB4 62#ifdef KRB4
60 case SSH_CMSG_AUTH_KERBEROS: 63 case SSH_CMSG_AUTH_KERBEROS:
61 return "kerberos"; 64 return "kerberos";
62#endif 65#endif
63#ifdef SKEY
64 case SSH_CMSG_AUTH_TIS_RESPONSE:
65 return "s/key";
66#endif
67 } 66 }
68 snprintf(buf, sizeof buf, "bad-auth-msg-%d", type); 67 snprintf(buf, sizeof buf, "bad-auth-msg-%d", type);
69 return buf; 68 return buf;
70} 69}
71 70
72/* 71/*
73 * read packets and try to authenticate local user 'luser'. 72 * read packets, try to authenticate the user and
74 * return if authentication is successful. not that pw == NULL 73 * return only if authentication is successful
75 * if the user does not exists or is not allowed to login.
76 * each auth method has to 'fake' authentication for nonexisting
77 * users.
78 */ 74 */
79void 75void
80do_authloop(struct passwd * pw, char *luser) 76do_authloop(Authctxt *authctxt)
81{ 77{
82 int authenticated = 0; 78 int authenticated = 0;
83 int attempt = 0;
84 u_int bits; 79 u_int bits;
85 RSA *client_host_key; 80 RSA *client_host_key;
86 BIGNUM *n; 81 BIGNUM *n;
87 char *client_user, *password; 82 char *client_user, *password;
88 char user[1024]; 83 char info[1024];
89 u_int dlen; 84 u_int dlen;
90 int plen, nlen, elen; 85 int plen, nlen, elen;
91 u_int ulen; 86 u_int ulen;
92 int type = 0; 87 int type = 0;
93 void (*authlog) (const char *fmt,...) = verbose; 88 struct passwd *pw = authctxt->pw;
89
90 debug("Attempting authentication for %s%.100s.",
91 authctxt->valid ? "" : "illegal user ", authctxt->user);
92
93 /* If the user has no password, accept authentication immediately. */
94 if (options.password_authentication &&
95#ifdef KRB4
96 (!options.kerberos_authentication || options.kerberos_or_local_passwd) &&
97#endif
98#ifdef USE_PAM /* ISSUE: Right?? */
99 auth_pam_password(pw, password)) {
100#else
101 auth_password(pw, "")) {
102#endif
103 auth_log(authctxt, 1, "without authentication", "");
104 return;
105 }
94 106
95 /* Indicate that authentication is needed. */ 107 /* Indicate that authentication is needed. */
96 packet_start(SSH_SMSG_FAILURE); 108 packet_start(SSH_SMSG_FAILURE);
@@ -99,11 +111,11 @@ do_authloop(struct passwd * pw, char *luser)
99 111
100 client_user = NULL; 112 client_user = NULL;
101 113
102 for (attempt = 1;; attempt++) { 114 for (;;) {
103 /* default to fail */ 115 /* default to fail */
104 authenticated = 0; 116 authenticated = 0;
105 117
106 strlcpy(user, "", sizeof user); 118 info[0] = '\0';
107 119
108 /* Get a packet from the client. */ 120 /* Get a packet from the client. */
109 type = packet_read(&plen); 121 type = packet_read(&plen);
@@ -120,7 +132,7 @@ do_authloop(struct passwd * pw, char *luser)
120 char *tgt = packet_get_string(&dlen); 132 char *tgt = packet_get_string(&dlen);
121 packet_integrity_check(plen, 4 + dlen, type); 133 packet_integrity_check(plen, 4 + dlen, type);
122 if (!auth_kerberos_tgt(pw, tgt)) 134 if (!auth_kerberos_tgt(pw, tgt))
123 verbose("Kerberos tgt REFUSED for %.100s", luser); 135 verbose("Kerberos tgt REFUSED for %.100s", authctxt->user);
124 xfree(tgt); 136 xfree(tgt);
125 } 137 }
126 continue; 138 continue;
@@ -134,7 +146,7 @@ do_authloop(struct passwd * pw, char *luser)
134 char *token_string = packet_get_string(&dlen); 146 char *token_string = packet_get_string(&dlen);
135 packet_integrity_check(plen, 4 + dlen, type); 147 packet_integrity_check(plen, 4 + dlen, type);
136 if (!auth_afs_token(pw, token_string)) 148 if (!auth_afs_token(pw, token_string))
137 verbose("AFS token REFUSED for %.100s", luser); 149 verbose("AFS token REFUSED for %.100s", authctxt->user);
138 xfree(token_string); 150 xfree(token_string);
139 } 151 }
140 continue; 152 continue;
@@ -142,7 +154,6 @@ do_authloop(struct passwd * pw, char *luser)
142#ifdef KRB4 154#ifdef KRB4
143 case SSH_CMSG_AUTH_KERBEROS: 155 case SSH_CMSG_AUTH_KERBEROS:
144 if (!options.kerberos_authentication) { 156 if (!options.kerberos_authentication) {
145 /* packet_get_all(); */
146 verbose("Kerberos authentication disabled."); 157 verbose("Kerberos authentication disabled.");
147 break; 158 break;
148 } else { 159 } else {
@@ -152,17 +163,17 @@ do_authloop(struct passwd * pw, char *luser)
152 char *kdata = packet_get_string((u_int *) &auth.length); 163 char *kdata = packet_get_string((u_int *) &auth.length);
153 packet_integrity_check(plen, 4 + auth.length, type); 164 packet_integrity_check(plen, 4 + auth.length, type);
154 165
155 if (auth.length < MAX_KTXT_LEN) 166 if (authctxt->valid) {
156 memcpy(auth.dat, kdata, auth.length); 167 if (auth.length < MAX_KTXT_LEN)
157 xfree(kdata); 168 memcpy(auth.dat, kdata, auth.length);
158
159 if (pw != NULL) {
160 authenticated = auth_krb4(pw->pw_name, &auth, &tkt_user); 169 authenticated = auth_krb4(pw->pw_name, &auth, &tkt_user);
161 if (authenticated) { 170 if (authenticated) {
162 snprintf(user, sizeof user, " tktuser %s", tkt_user); 171 snprintf(info, sizeof info,
172 " tktuser %.100s", tkt_user);
163 xfree(tkt_user); 173 xfree(tkt_user);
164 } 174 }
165 } 175 }
176 xfree(kdata);
166 } 177 }
167 break; 178 break;
168#endif /* KRB4 */ 179#endif /* KRB4 */
@@ -184,7 +195,7 @@ do_authloop(struct passwd * pw, char *luser)
184 /* Try to authenticate using /etc/hosts.equiv and .rhosts. */ 195 /* Try to authenticate using /etc/hosts.equiv and .rhosts. */
185 authenticated = auth_rhosts(pw, client_user); 196 authenticated = auth_rhosts(pw, client_user);
186 197
187 snprintf(user, sizeof user, " ruser %s", client_user); 198 snprintf(info, sizeof info, " ruser %.100s", client_user);
188 break; 199 break;
189 200
190 case SSH_CMSG_AUTH_RHOSTS_RSA: 201 case SSH_CMSG_AUTH_RHOSTS_RSA:
@@ -219,7 +230,7 @@ do_authloop(struct passwd * pw, char *luser)
219 authenticated = auth_rhosts_rsa(pw, client_user, client_host_key); 230 authenticated = auth_rhosts_rsa(pw, client_user, client_host_key);
220 RSA_free(client_host_key); 231 RSA_free(client_host_key);
221 232
222 snprintf(user, sizeof user, " ruser %s", client_user); 233 snprintf(info, sizeof info, " ruser %.100s", client_user);
223 break; 234 break;
224 235
225 case SSH_CMSG_AUTH_RSA: 236 case SSH_CMSG_AUTH_RSA:
@@ -267,22 +278,19 @@ do_authloop(struct passwd * pw, char *luser)
267 xfree(password); 278 xfree(password);
268 break; 279 break;
269 280
270#ifdef SKEY 281#ifdef SKEY /* ISSUE: Is this right? we don't define
282 having skey_authentication in
283 servconf.h by default so I assume
284 we need to deal with this via #ifdef
285 in some reasonable way */
271 case SSH_CMSG_AUTH_TIS: 286 case SSH_CMSG_AUTH_TIS:
272 debug("rcvd SSH_CMSG_AUTH_TIS"); 287 debug("rcvd SSH_CMSG_AUTH_TIS");
273 if (options.skey_authentication == 1) { 288 if (options.skey_authentication == 1) {
274 char *skeyinfo = NULL; 289 char *challenge = get_challenge(authctxt, authctxt->style);
275 if (pw != NULL) 290 if (challenge != NULL) {
276 skeyinfo = skey_keyinfo(pw->pw_name); 291 debug("sending challenge '%s'", challenge);
277 if (skeyinfo == NULL) {
278 debug("generating fake skeyinfo for %.100s.", luser);
279 skeyinfo = skey_fake_keyinfo(luser);
280 }
281 if (skeyinfo != NULL) {
282 /* we send our s/key- in tis-challenge messages */
283 debug("sending challenge '%s'", skeyinfo);
284 packet_start(SSH_SMSG_AUTH_TIS_CHALLENGE); 292 packet_start(SSH_SMSG_AUTH_TIS_CHALLENGE);
285 packet_put_cstring(skeyinfo); 293 packet_put_cstring(challenge);
286 packet_send(); 294 packet_send();
287 packet_write_wait(); 295 packet_write_wait();
288 continue; 296 continue;
@@ -293,20 +301,14 @@ do_authloop(struct passwd * pw, char *luser)
293 debug("rcvd SSH_CMSG_AUTH_TIS_RESPONSE"); 301 debug("rcvd SSH_CMSG_AUTH_TIS_RESPONSE");
294 if (options.skey_authentication == 1) { 302 if (options.skey_authentication == 1) {
295 char *response = packet_get_string(&dlen); 303 char *response = packet_get_string(&dlen);
296 debug("skey response == '%s'", response); 304 debug("got response '%s'", response);
297 packet_integrity_check(plen, 4 + dlen, type); 305 packet_integrity_check(plen, 4 + dlen, type);
298 authenticated = (pw != NULL && 306 authenticated = verify_response(authctxt, response);
299 skey_haskey(pw->pw_name) == 0 && 307 memset(response, 'r', dlen);
300 skey_passcheck(pw->pw_name, response) != -1);
301 xfree(response); 308 xfree(response);
302 } 309 }
303 break; 310 break;
304#else 311#endif /* ISSUE: End of wrong SKEY defines */
305 case SSH_CMSG_AUTH_TIS:
306 /* TIS Authentication is unsupported */
307 log("TIS authentication unsupported.");
308 break;
309#endif
310 312
311 default: 313 default:
312 /* 314 /*
@@ -316,10 +318,11 @@ do_authloop(struct passwd * pw, char *luser)
316 log("Unknown message during authentication: type %d", type); 318 log("Unknown message during authentication: type %d", type);
317 break; 319 break;
318 } 320 }
319 if (authenticated && pw == NULL) 321 if (!authctxt->valid && authenticated)
320 fatal("internal error: authenticated for pw == NULL"); 322 fatal("INTERNAL ERROR: authenticated invalid user %s",
323 authctxt->user);
321 324
322#ifdef HAVE_CYGWIN 325#ifdef HAVE_CYGWIN /* ISSUE: Right place? */
323 if (authenticated && 326 if (authenticated &&
324 !check_nt_auth(type == SSH_CMSG_AUTH_PASSWORD,pw->pw_uid)) { 327 !check_nt_auth(type == SSH_CMSG_AUTH_PASSWORD,pw->pw_uid)) {
325 packet_disconnect("Authentication rejected for uid %d.", 328 packet_disconnect("Authentication rejected for uid %d.",
@@ -328,41 +331,18 @@ do_authloop(struct passwd * pw, char *luser)
328 } 331 }
329#endif 332#endif
330 333
331 /* 334 /* Special handling for root */
332 * Check if the user is logging in as root and root logins 335 if (authenticated && authctxt->pw->pw_uid == 0 && !auth_root_allowed())
333 * are disallowed. 336 authenticated = 0;
334 * Note that root login is allowed for forced commands.
335 */
336 if (authenticated && pw && pw->pw_uid == 0 && !options.permit_root_login) {
337 if (forced_command) {
338 log("Root login accepted for forced command.");
339 } else {
340 authenticated = 0;
341 log("ROOT LOGIN REFUSED FROM %.200s",
342 get_canonical_hostname());
343 }
344 }
345
346 /* Raise logging level */
347 if (authenticated ||
348 attempt == AUTH_FAIL_LOG ||
349 type == SSH_CMSG_AUTH_PASSWORD)
350 authlog = log;
351
352 authlog("%s %s for %s%.100s from %.200s port %d%s",
353 authenticated ? "Accepted" : "Failed",
354 get_authname(type),
355 pw ? "" : "illegal user ",
356 pw && pw->pw_uid == 0 ? "ROOT" : luser,
357 get_remote_ipaddr(),
358 get_remote_port(),
359 user);
360 337
361#ifdef USE_PAM 338#ifdef USE_PAM /* ISSUE: Right place? */
362 if (authenticated && !do_pam_account(pw->pw_name, client_user)) 339 if (authenticated && !do_pam_account(pw->pw_name, client_user))
363 authenticated = 0; 340 authenticated = 0;
364#endif 341#endif
365 342
343 /* Log before sending the reply */
344 auth_log(authctxt, authenticated, get_authname(type), info);
345
366 if (client_user != NULL) { 346 if (client_user != NULL) {
367 xfree(client_user); 347 xfree(client_user);
368 client_user = NULL; 348 client_user = NULL;
@@ -371,14 +351,13 @@ do_authloop(struct passwd * pw, char *luser)
371 if (authenticated) 351 if (authenticated)
372 return; 352 return;
373 353
374 if (attempt > AUTH_FAIL_MAX) { 354 if (authctxt->failures++ > AUTH_FAIL_MAX) {
375#ifdef WITH_AIXAUTHENTICATE 355#ifdef WITH_AIXAUTHENTICATE
376 loginfailed(user,get_canonical_hostname(),"ssh"); 356 loginfailed(user,get_canonical_hostname(),"ssh");
377#endif /* WITH_AIXAUTHENTICATE */ 357#endif /* WITH_AIXAUTHENTICATE */
378 packet_disconnect(AUTH_FAIL_MSG, luser); 358 packet_disconnect(AUTH_FAIL_MSG, authctxt->user);
379 } 359 }
380 360
381 /* Send a message indicating that the authentication attempt failed. */
382 packet_start(SSH_SMSG_FAILURE); 361 packet_start(SSH_SMSG_FAILURE);
383 packet_send(); 362 packet_send();
384 packet_write_wait(); 363 packet_write_wait();
@@ -392,10 +371,11 @@ do_authloop(struct passwd * pw, char *luser)
392void 371void
393do_authentication() 372do_authentication()
394{ 373{
395 struct passwd *pw, pwcopy; 374 Authctxt *authctxt;
375 struct passwd *pw;
396 int plen; 376 int plen;
397 u_int ulen; 377 u_int ulen;
398 char *user; 378 char *user, *style = NULL;
399 379
400 /* Get the name of the user that we wish to log in as. */ 380 /* Get the name of the user that we wish to log in as. */
401 packet_read_expect(&plen, SSH_CMSG_USER); 381 packet_read_expect(&plen, SSH_CMSG_USER);
@@ -404,6 +384,13 @@ do_authentication()
404 user = packet_get_string(&ulen); 384 user = packet_get_string(&ulen);
405 packet_integrity_check(plen, (4 + ulen), SSH_CMSG_USER); 385 packet_integrity_check(plen, (4 + ulen), SSH_CMSG_USER);
406 386
387 if ((style = strchr(user, ':')) != NULL)
388 *style++ = 0;
389
390 authctxt = authctxt_new();
391 authctxt->user = user;
392 authctxt->style = style;
393
407 setproctitle("%s", user); 394 setproctitle("%s", user);
408 395
409#ifdef AFS 396#ifdef AFS
@@ -417,21 +404,13 @@ do_authentication()
417 /* Verify that the user is a valid user. */ 404 /* Verify that the user is a valid user. */
418 pw = getpwnam(user); 405 pw = getpwnam(user);
419 if (pw && allowed_user(pw)) { 406 if (pw && allowed_user(pw)) {
420 /* Take a copy of the returned structure. */ 407 authctxt->valid = 1;
421 memset(&pwcopy, 0, sizeof(pwcopy)); 408 pw = pwcopy(pw);
422 pwcopy.pw_name = xstrdup(pw->pw_name);
423 pwcopy.pw_passwd = xstrdup(pw->pw_passwd);
424 pwcopy.pw_uid = pw->pw_uid;
425 pwcopy.pw_gid = pw->pw_gid;
426#ifdef HAVE_PW_CLASS_IN_PASSWD
427 pwcopy.pw_class = xstrdup(pw->pw_class);
428#endif
429 pwcopy.pw_dir = xstrdup(pw->pw_dir);
430 pwcopy.pw_shell = xstrdup(pw->pw_shell);
431 pw = &pwcopy;
432 } else { 409 } else {
410 debug("do_authentication: illegal user %s", user);
433 pw = NULL; 411 pw = NULL;
434 } 412 }
413 authctxt->pw = pw;
435 414
436#ifdef USE_PAM 415#ifdef USE_PAM
437 if (pw) 416 if (pw)
@@ -447,44 +426,25 @@ do_authentication()
447 packet_disconnect("Cannot change user when server not running as root."); 426 packet_disconnect("Cannot change user when server not running as root.");
448#endif 427#endif
449 428
450 debug("Attempting authentication for %s%.100s.", pw ? "" : "illegal user ", user); 429 /*
451 430 * Loop until the user has been authenticated or the connection is
452 /* If the user has no password, accept authentication immediately. */ 431 * closed, do_authloop() returns only if authentication is successful
453 if (options.password_authentication && 432 */
454#ifdef KRB4 433 do_authloop(authctxt);
455 (!options.kerberos_authentication || options.kerberos_or_local_passwd) &&
456#endif /* KRB4 */
457#ifdef USE_PAM
458 auth_pam_password(pw, "")) {
459#elif defined(HAVE_OSF_SIA)
460 (sia_validate_user(NULL, saved_argc, saved_argv,
461 get_canonical_hostname(), pw->pw_name, NULL, 0,
462 NULL, "") == SIASUCCESS)) {
463#else /* !HAVE_OSF_SIA && !USE_PAM */
464 auth_password(pw, "")) {
465#endif /* USE_PAM */
466 /* Authentication with empty password succeeded. */
467 log("Login for user %s from %.100s, accepted without authentication.",
468 user, get_remote_ipaddr());
469 } else {
470 /* Loop until the user has been authenticated or the
471 connection is closed, do_authloop() returns only if
472 authentication is successful */
473 do_authloop(pw, user);
474 }
475 if (pw == NULL)
476 fatal("internal error, authentication successful for user '%.100s'", user);
477 434
478 /* The user has been authenticated and accepted. */ 435 /* The user has been authenticated and accepted. */
479 packet_start(SSH_SMSG_SUCCESS); 436 packet_start(SSH_SMSG_SUCCESS);
480 packet_send(); 437 packet_send();
481 packet_write_wait(); 438 packet_write_wait();
439
482#ifdef WITH_AIXAUTHENTICATE 440#ifdef WITH_AIXAUTHENTICATE
483 /* We don't have a pty yet, so just label the line as "ssh" */ 441 /* We don't have a pty yet, so just label the line as "ssh" */
484 if (loginsuccess(user,get_canonical_hostname(),"ssh",&aixloginmsg) < 0) 442 if (loginsuccess(authctxt->user,get_canonical_hostname(),"ssh",&aixloginmsg) < 0)
485 aixloginmsg = NULL; 443 aixloginmsg = NULL;
486#endif /* WITH_AIXAUTHENTICATE */ 444#endif /* WITH_AIXAUTHENTICATE */
487 xfree(user); 445
446 xfree(authctxt->user);
447 xfree(authctxt);
488 448
489 /* Perform session preparation. */ 449 /* Perform session preparation. */
490 do_authenticated(pw); 450 do_authenticated(pw);
diff --git a/auth2-chall.c b/auth2-chall.c
new file mode 100644
index 000000000..77294f4b8
--- /dev/null
+++ b/auth2-chall.c
@@ -0,0 +1,113 @@
1/*
2 * Copyright (c) 2001 Markus Friedl. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
15 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
16 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
17 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
18 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
19 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
20 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 */
24#include "includes.h"
25RCSID("$OpenBSD: auth2-chall.c,v 1.1 2001/01/18 17:12:43 markus Exp $");
26
27#include "ssh.h"
28#include "ssh2.h"
29#include "auth.h"
30#include "packet.h"
31#include "xmalloc.h"
32#include "dispatch.h"
33
34void send_userauth_into_request(Authctxt *authctxt, char *challenge, int echo);
35void input_userauth_info_response(int type, int plen, void *ctxt);
36
37/*
38 * try challenge-reponse, return -1 (= postponed) if we have to
39 * wait for the response.
40 */
41int
42auth2_challenge(Authctxt *authctxt, char *devs)
43{
44 char *challenge;
45
46 if (!authctxt->valid || authctxt->user == NULL)
47 return 0;
48 if ((challenge = get_challenge(authctxt, devs)) == NULL)
49 return 0;
50 send_userauth_into_request(authctxt, challenge, 0);
51 dispatch_set(SSH2_MSG_USERAUTH_INFO_RESPONSE,
52 &input_userauth_info_response);
53 authctxt->postponed = 1;
54 return 0;
55}
56
57void
58send_userauth_into_request(Authctxt *authctxt, char *challenge, int echo)
59{
60 int nprompts = 1;
61
62 packet_start(SSH2_MSG_USERAUTH_INFO_REQUEST);
63 /* name, instruction and language are unused */
64 packet_put_cstring("");
65 packet_put_cstring("");
66 packet_put_cstring("");
67 packet_put_int(nprompts);
68 packet_put_cstring(challenge);
69 packet_put_char(echo);
70 packet_send();
71 packet_write_wait();
72}
73
74void
75input_userauth_info_response(int type, int plen, void *ctxt)
76{
77 Authctxt *authctxt = ctxt;
78 int authenticated = 0;
79 u_int nresp, rlen;
80 char *response, *method = "challenge-reponse";
81
82 if (authctxt == NULL)
83 fatal("input_userauth_info_response: no authctxt");
84
85 authctxt->postponed = 0; /* reset */
86 nresp = packet_get_int();
87 if (nresp == 1) {
88 response = packet_get_string(&rlen);
89 packet_done();
90 if (strlen(response) == 0) {
91 /*
92 * if we received an empty response, resend challenge
93 * with echo enabled
94 */
95 char *challenge = get_challenge(authctxt, NULL);
96 if (challenge != NULL) {
97 send_userauth_into_request(authctxt,
98 challenge, 1);
99 authctxt->postponed = 1;
100 }
101 } else if (authctxt->valid) {
102 authenticated = verify_response(authctxt, response);
103 memset(response, 'r', rlen);
104 }
105 xfree(response);
106 }
107 auth_log(authctxt, authenticated, method, " ssh2");
108 if (!authctxt->postponed) {
109 /* unregister callback and send reply */
110 dispatch_set(SSH2_MSG_USERAUTH_INFO_RESPONSE, NULL);
111 userauth_reply(authctxt, authenticated);
112 }
113}
diff --git a/auth2-pam.c b/auth2-pam.c
index 30e02101e..498cc7461 100644
--- a/auth2-pam.c
+++ b/auth2-pam.c
@@ -1,5 +1,5 @@
1#include "includes.h" 1#include "includes.h"
2RCSID("$Id: auth2-pam.c,v 1.2 2000/12/20 02:34:49 djm Exp $"); 2RCSID("$Id: auth2-pam.c,v 1.3 2001/01/19 04:26:52 mouring Exp $");
3 3
4#ifdef USE_PAM 4#ifdef USE_PAM
5#include "ssh.h" 5#include "ssh.h"
@@ -46,8 +46,10 @@ auth2_pam(Authctxt *authctxt)
46 retval = (do_pam_authenticate(0) == PAM_SUCCESS); 46 retval = (do_pam_authenticate(0) == PAM_SUCCESS);
47 dispatch_set(SSH2_MSG_USERAUTH_INFO_RESPONSE, NULL); 47 dispatch_set(SSH2_MSG_USERAUTH_INFO_RESPONSE, NULL);
48 48
49#if 0 /* ISSUE: No longer valid, but should this still be
50 handled?? */
49 userauth_log(authctxt, retval, method); 51 userauth_log(authctxt, retval, method);
50 52#endif
51 return retval; 53 return retval;
52} 54}
53 55
diff --git a/auth2.c b/auth2.c
index 3a247f588..348c2f3a4 100644
--- a/auth2.c
+++ b/auth2.c
@@ -23,7 +23,7 @@
23 */ 23 */
24 24
25#include "includes.h" 25#include "includes.h"
26RCSID("$OpenBSD: auth2.c,v 1.25 2001/01/08 22:29:05 markus Exp $"); 26RCSID("$OpenBSD: auth2.c,v 1.28 2001/01/18 17:00:00 markus Exp $");
27 27
28#ifdef HAVE_OSF_SIA 28#ifdef HAVE_OSF_SIA
29# include <sia.h> 29# include <sia.h>
@@ -84,7 +84,6 @@ void input_service_request(int type, int plen, void *ctxt);
84void input_userauth_request(int type, int plen, void *ctxt); 84void input_userauth_request(int type, int plen, void *ctxt);
85void protocol_error(int type, int plen, void *ctxt); 85void protocol_error(int type, int plen, void *ctxt);
86 86
87
88/* helper */ 87/* helper */
89Authmethod *authmethod_lookup(const char *name); 88Authmethod *authmethod_lookup(const char *name);
90struct passwd *pwcopy(struct passwd *pw); 89struct passwd *pwcopy(struct passwd *pw);
@@ -121,22 +120,21 @@ Authmethod authmethods[] = {
121void 120void
122do_authentication2() 121do_authentication2()
123{ 122{
124 Authctxt *authctxt = xmalloc(sizeof(*authctxt)); 123 Authctxt *authctxt = authctxt_new();
125 memset(authctxt, 'a', sizeof(*authctxt)); 124
126 authctxt->valid = 0;
127 authctxt->attempt = 0;
128 authctxt->failures = 0;
129 authctxt->success = 0;
130 x_authctxt = authctxt; /*XXX*/ 125 x_authctxt = authctxt; /*XXX*/
131 126
132#ifdef KRB4 127#ifdef AFS
133 /* turn off kerberos, not supported by SSH2 */ 128 /* If machine has AFS, set process authentication group. */
134 options.kerberos_authentication = 0; 129 if (k_hasafs()) {
130 k_setpag();
131 k_unlog();
132 }
135#endif 133#endif
136 dispatch_init(&protocol_error); 134 dispatch_init(&protocol_error);
137 dispatch_set(SSH2_MSG_SERVICE_REQUEST, &input_service_request); 135 dispatch_set(SSH2_MSG_SERVICE_REQUEST, &input_service_request);
138 dispatch_run(DISPATCH_BLOCK, &authctxt->success, authctxt); 136 dispatch_run(DISPATCH_BLOCK, &authctxt->success, authctxt);
139 do_authenticated2(); 137 do_authenticated2(authctxt);
140} 138}
141 139
142void 140void
@@ -187,7 +185,7 @@ input_userauth_request(int type, int plen, void *ctxt)
187{ 185{
188 Authctxt *authctxt = ctxt; 186 Authctxt *authctxt = ctxt;
189 Authmethod *m = NULL; 187 Authmethod *m = NULL;
190 char *user, *service, *method; 188 char *user, *service, *method, *style = NULL;
191 int authenticated = 0; 189 int authenticated = 0;
192 190
193 if (authctxt == NULL) 191 if (authctxt == NULL)
@@ -199,6 +197,9 @@ input_userauth_request(int type, int plen, void *ctxt)
199 debug("userauth-request for user %s service %s method %s", user, service, method); 197 debug("userauth-request for user %s service %s method %s", user, service, method);
200 debug("attempt %d failures %d", authctxt->attempt, authctxt->failures); 198 debug("attempt %d failures %d", authctxt->attempt, authctxt->failures);
201 199
200 if ((style = strchr(user, ':')) != NULL)
201 *style++ = 0;
202
202 if (authctxt->attempt++ == 0) { 203 if (authctxt->attempt++ == 0) {
203 /* setup auth context */ 204 /* setup auth context */
204 struct passwd *pw = NULL; 205 struct passwd *pw = NULL;
@@ -216,6 +217,7 @@ input_userauth_request(int type, int plen, void *ctxt)
216 } 217 }
217 authctxt->user = xstrdup(user); 218 authctxt->user = xstrdup(user);
218 authctxt->service = xstrdup(service); 219 authctxt->service = xstrdup(service);
220 authctxt->style = style ? xstrdup(style) : NULL; /* currently unused */
219 } else if (authctxt->valid) { 221 } else if (authctxt->valid) {
220 if (strcmp(user, authctxt->user) != 0 || 222 if (strcmp(user, authctxt->user) != 0 ||
221 strcmp(service, authctxt->service) != 0) { 223 strcmp(service, authctxt->service) != 0) {
@@ -224,25 +226,23 @@ input_userauth_request(int type, int plen, void *ctxt)
224 authctxt->valid = 0; 226 authctxt->valid = 0;
225 } 227 }
226 } 228 }
229 /* reset state */
230 dispatch_set(SSH2_MSG_USERAUTH_INFO_RESPONSE, &protocol_error);
231 authctxt->postponed = 0;
227 232
233 /* try to authenticate user */
228 m = authmethod_lookup(method); 234 m = authmethod_lookup(method);
229 if (m != NULL) { 235 if (m != NULL) {
230 debug2("input_userauth_request: try method %s", method); 236 debug2("input_userauth_request: try method %s", method);
231 authenticated = m->userauth(authctxt); 237 authenticated = m->userauth(authctxt);
232 } else {
233 debug2("input_userauth_request: unsupported method %s", method);
234 }
235 if (!authctxt->valid && authenticated == 1) {
236 log("input_userauth_request: INTERNAL ERROR: authenticated invalid user %s service %s", user, method);
237 authenticated = 0;
238 } 238 }
239 if (!authctxt->valid && authenticated)
240 fatal("INTERNAL ERROR: authenticated invalid user %s",
241 authctxt->user);
239 242
240 /* Special handling for root */ 243 /* Special handling for root */
241 if (authenticated == 1 && 244 if (authenticated && authctxt->pw->pw_uid == 0 && !auth_root_allowed())
242 authctxt->valid && authctxt->pw->pw_uid == 0 && !options.permit_root_login) {
243 authenticated = 0; 245 authenticated = 0;
244 log("ROOT LOGIN REFUSED FROM %.200s", get_canonical_hostname());
245 }
246 246
247#ifdef USE_PAM 247#ifdef USE_PAM
248 if (authenticated && authctxt->user && !do_pam_account(authctxt->user, NULL)) 248 if (authenticated && authctxt->user && !do_pam_account(authctxt->user, NULL))
@@ -250,8 +250,10 @@ input_userauth_request(int type, int plen, void *ctxt)
250#endif /* USE_PAM */ 250#endif /* USE_PAM */
251 251
252 /* Log before sending the reply */ 252 /* Log before sending the reply */
253 userauth_log(authctxt, authenticated, method); 253 auth_log(authctxt, authenticated, method, " ssh2");
254 userauth_reply(authctxt, authenticated); 254
255 if (!authctxt->postponed)
256 userauth_reply(authctxt, authenticated);
255 257
256 xfree(service); 258 xfree(service);
257 xfree(user); 259 xfree(user);
@@ -292,47 +294,13 @@ done:
292 return; 294 return;
293} 295}
294 296
295void
296userauth_log(Authctxt *authctxt, int authenticated, char *method)
297{
298 void (*authlog) (const char *fmt,...) = verbose;
299 char *user = NULL, *authmsg = NULL;
300
301 /* Raise logging level */
302 if (authenticated == 1 ||
303 !authctxt->valid ||
304 authctxt->failures >= AUTH_FAIL_LOG ||
305 strcmp(method, "password") == 0)
306 authlog = log;
307
308 if (authenticated == 1) {
309 authmsg = "Accepted";
310 } else if (authenticated == 0) {
311 authmsg = "Failed";
312 } else {
313 authmsg = "Postponed";
314 }
315
316 if (authctxt->valid) {
317 user = authctxt->pw->pw_uid == 0 ? "ROOT" : authctxt->user;
318 } else {
319 user = "NOUSER";
320 }
321
322 authlog("%s %s for %.200s from %.200s port %d ssh2",
323 authmsg,
324 method,
325 user,
326 get_remote_ipaddr(),
327 get_remote_port());
328}
329
330void 297void
331userauth_reply(Authctxt *authctxt, int authenticated) 298userauth_reply(Authctxt *authctxt, int authenticated)
332{ 299{
333 char *methods; 300 char *methods;
301
334 /* XXX todo: check if multiple auth methods are needed */ 302 /* XXX todo: check if multiple auth methods are needed */
335 if (authenticated == 1) { 303 if (authenticated) {
336#ifdef WITH_AIXAUTHENTICATE 304#ifdef WITH_AIXAUTHENTICATE
337 /* We don't have a pty yet, so just label the line as "ssh" */ 305 /* We don't have a pty yet, so just label the line as "ssh" */
338 if (loginsuccess(authctxt->user?authctxt->user:"NOUSER", 306 if (loginsuccess(authctxt->user?authctxt->user:"NOUSER",
@@ -346,9 +314,9 @@ userauth_reply(Authctxt *authctxt, int authenticated)
346 packet_write_wait(); 314 packet_write_wait();
347 /* now we can break out */ 315 /* now we can break out */
348 authctxt->success = 1; 316 authctxt->success = 1;
349 } else if (authenticated == 0) { 317 } else {
350 if (authctxt->failures++ >= AUTH_FAIL_MAX) 318 if (authctxt->failures++ > AUTH_FAIL_MAX)
351 packet_disconnect("too many failed userauth_requests"); 319 packet_disconnect(AUTH_FAIL_MSG, authctxt->user);
352 methods = authmethods_get(); 320 methods = authmethods_get();
353 packet_start(SSH2_MSG_USERAUTH_FAILURE); 321 packet_start(SSH2_MSG_USERAUTH_FAILURE);
354 packet_put_cstring(methods); 322 packet_put_cstring(methods);
@@ -356,8 +324,6 @@ userauth_reply(Authctxt *authctxt, int authenticated)
356 packet_send(); 324 packet_send();
357 packet_write_wait(); 325 packet_write_wait();
358 xfree(methods); 326 xfree(methods);
359 } else {
360 /* do nothing, we did already send a reply */
361 } 327 }
362} 328}
363 329
@@ -432,16 +398,13 @@ userauth_kbdint(Authctxt *authctxt)
432 packet_done(); 398 packet_done();
433 399
434 debug("keyboard-interactive language %s devs %s", lang, devs); 400 debug("keyboard-interactive language %s devs %s", lang, devs);
401
402 authenticated = auth2_challenge(authctxt, devs);
403
435#ifdef USE_PAM 404#ifdef USE_PAM
436 if (authenticated == 0) 405 if (authenticated == 0)
437 authenticated = auth2_pam(authctxt); 406 authenticated = auth2_pam(authctxt);
438#endif 407#endif
439#ifdef SKEY
440 /* XXX hardcoded, we should look at devs */
441 if (authenticated == 0)
442 if (options.skey_authentication != 0)
443 authenticated = auth2_skey(authctxt);
444#endif
445 xfree(lang); 408 xfree(lang);
446 xfree(devs); 409 xfree(devs);
447#ifdef HAVE_CYGWIN 410#ifdef HAVE_CYGWIN
@@ -732,20 +695,3 @@ user_key_allowed(struct passwd *pw, Key *key)
732 key_free(found); 695 key_free(found);
733 return found_key; 696 return found_key;
734} 697}
735
736struct passwd *
737pwcopy(struct passwd *pw)
738{
739 struct passwd *copy = xmalloc(sizeof(*copy));
740 memset(copy, 0, sizeof(*copy));
741 copy->pw_name = xstrdup(pw->pw_name);
742 copy->pw_passwd = xstrdup(pw->pw_passwd);
743 copy->pw_uid = pw->pw_uid;
744 copy->pw_gid = pw->pw_gid;
745#ifdef HAVE_PW_CLASS_IN_PASSWD
746 copy->pw_class = xstrdup(pw->pw_class);
747#endif
748 copy->pw_dir = xstrdup(pw->pw_dir);
749 copy->pw_shell = xstrdup(pw->pw_shell);
750 return copy;
751}
diff --git a/log-client.c b/log-client.c
index bfcab30ba..656499ad1 100644
--- a/log-client.c
+++ b/log-client.c
@@ -36,12 +36,12 @@
36 */ 36 */
37 37
38#include "includes.h" 38#include "includes.h"
39RCSID("$OpenBSD: log-client.c,v 1.13 2001/01/07 11:28:04 markus Exp $"); 39RCSID("$OpenBSD: log-client.c,v 1.14 2001/01/18 16:20:21 markus Exp $");
40 40
41#include "xmalloc.h" 41#include "xmalloc.h"
42#include "ssh.h" 42#include "ssh.h"
43 43
44static LogLevel log_level = SYSLOG_LEVEL_NOTICE; 44static LogLevel log_level = SYSLOG_LEVEL_INFO;
45 45
46/* Initialize the log. 46/* Initialize the log.
47 * av0 program name (should be argv[0]) 47 * av0 program name (should be argv[0])
@@ -55,7 +55,7 @@ log_init(char *av0, LogLevel level, SyslogFacility ignored1, int ignored2)
55 case SYSLOG_LEVEL_QUIET: 55 case SYSLOG_LEVEL_QUIET:
56 case SYSLOG_LEVEL_FATAL: 56 case SYSLOG_LEVEL_FATAL:
57 case SYSLOG_LEVEL_ERROR: 57 case SYSLOG_LEVEL_ERROR:
58 case SYSLOG_LEVEL_NOTICE: 58 case SYSLOG_LEVEL_INFO:
59 case SYSLOG_LEVEL_VERBOSE: 59 case SYSLOG_LEVEL_VERBOSE:
60 case SYSLOG_LEVEL_DEBUG1: 60 case SYSLOG_LEVEL_DEBUG1:
61 case SYSLOG_LEVEL_DEBUG2: 61 case SYSLOG_LEVEL_DEBUG2:
diff --git a/log-server.c b/log-server.c
index 2335a3ef4..3b19550e3 100644
--- a/log-server.c
+++ b/log-server.c
@@ -36,14 +36,14 @@
36 */ 36 */
37 37
38#include "includes.h" 38#include "includes.h"
39RCSID("$OpenBSD: log-server.c,v 1.18 2001/01/07 11:28:05 markus Exp $"); 39RCSID("$OpenBSD: log-server.c,v 1.19 2001/01/18 16:20:21 markus Exp $");
40 40
41#include <syslog.h> 41#include <syslog.h>
42#include "packet.h" 42#include "packet.h"
43#include "xmalloc.h" 43#include "xmalloc.h"
44#include "ssh.h" 44#include "ssh.h"
45 45
46static LogLevel log_level = SYSLOG_LEVEL_NOTICE; 46static LogLevel log_level = SYSLOG_LEVEL_INFO;
47static int log_on_stderr = 0; 47static int log_on_stderr = 0;
48static int log_facility = LOG_AUTH; 48static int log_facility = LOG_AUTH;
49 49
@@ -60,7 +60,7 @@ log_init(char *av0, LogLevel level, SyslogFacility facility, int on_stderr)
60 case SYSLOG_LEVEL_QUIET: 60 case SYSLOG_LEVEL_QUIET:
61 case SYSLOG_LEVEL_FATAL: 61 case SYSLOG_LEVEL_FATAL:
62 case SYSLOG_LEVEL_ERROR: 62 case SYSLOG_LEVEL_ERROR:
63 case SYSLOG_LEVEL_NOTICE: 63 case SYSLOG_LEVEL_INFO:
64 case SYSLOG_LEVEL_VERBOSE: 64 case SYSLOG_LEVEL_VERBOSE:
65 case SYSLOG_LEVEL_DEBUG1: 65 case SYSLOG_LEVEL_DEBUG1:
66 case SYSLOG_LEVEL_DEBUG2: 66 case SYSLOG_LEVEL_DEBUG2:
@@ -141,8 +141,8 @@ do_log(LogLevel level, const char *fmt, va_list args)
141 txt = "error"; 141 txt = "error";
142 pri = LOG_ERR; 142 pri = LOG_ERR;
143 break; 143 break;
144 case SYSLOG_LEVEL_NOTICE: 144 case SYSLOG_LEVEL_INFO:
145 pri = LOG_NOTICE; 145 pri = LOG_INFO;
146 break; 146 break;
147 case SYSLOG_LEVEL_VERBOSE: 147 case SYSLOG_LEVEL_VERBOSE:
148 pri = LOG_INFO; 148 pri = LOG_INFO;
diff --git a/log.c b/log.c
index e13cc90ce..9df2a93fd 100644
--- a/log.c
+++ b/log.c
@@ -36,7 +36,7 @@
36 */ 36 */
37 37
38#include "includes.h" 38#include "includes.h"
39RCSID("$OpenBSD: log.c,v 1.13 2001/01/07 11:28:05 markus Exp $"); 39RCSID("$OpenBSD: log.c,v 1.14 2001/01/18 16:20:21 markus Exp $");
40 40
41#include "ssh.h" 41#include "ssh.h"
42#include "xmalloc.h" 42#include "xmalloc.h"
@@ -71,7 +71,7 @@ log(const char *fmt,...)
71{ 71{
72 va_list args; 72 va_list args;
73 va_start(args, fmt); 73 va_start(args, fmt);
74 do_log(SYSLOG_LEVEL_NOTICE, fmt, args); 74 do_log(SYSLOG_LEVEL_INFO, fmt, args);
75 va_end(args); 75 va_end(args);
76} 76}
77 77
@@ -209,13 +209,12 @@ static struct {
209 { "QUIET", SYSLOG_LEVEL_QUIET }, 209 { "QUIET", SYSLOG_LEVEL_QUIET },
210 { "FATAL", SYSLOG_LEVEL_FATAL }, 210 { "FATAL", SYSLOG_LEVEL_FATAL },
211 { "ERROR", SYSLOG_LEVEL_ERROR }, 211 { "ERROR", SYSLOG_LEVEL_ERROR },
212 { "NOTICE", SYSLOG_LEVEL_NOTICE }, 212 { "INFO", SYSLOG_LEVEL_INFO },
213 { "VERBOSE", SYSLOG_LEVEL_VERBOSE }, 213 { "VERBOSE", SYSLOG_LEVEL_VERBOSE },
214 { "DEBUG", SYSLOG_LEVEL_DEBUG1 }, 214 { "DEBUG", SYSLOG_LEVEL_DEBUG1 },
215 { "DEBUG1", SYSLOG_LEVEL_DEBUG1 }, 215 { "DEBUG1", SYSLOG_LEVEL_DEBUG1 },
216 { "DEBUG2", SYSLOG_LEVEL_DEBUG2 }, 216 { "DEBUG2", SYSLOG_LEVEL_DEBUG2 },
217 { "DEBUG3", SYSLOG_LEVEL_DEBUG3 }, 217 { "DEBUG3", SYSLOG_LEVEL_DEBUG3 },
218 { "INFO", SYSLOG_LEVEL_NOTICE }, /* backward compatible */
219 { NULL, 0 } 218 { NULL, 0 }
220}; 219};
221 220
diff --git a/readconf.c b/readconf.c
index 5b552815f..7efaf85eb 100644
--- a/readconf.c
+++ b/readconf.c
@@ -12,7 +12,7 @@
12 */ 12 */
13 13
14#include "includes.h" 14#include "includes.h"
15RCSID("$OpenBSD: readconf.c,v 1.53 2001/01/07 11:28:05 markus Exp $"); 15RCSID("$OpenBSD: readconf.c,v 1.54 2001/01/18 16:20:22 markus Exp $");
16 16
17#include "ssh.h" 17#include "ssh.h"
18#include "readconf.h" 18#include "readconf.h"
@@ -804,7 +804,7 @@ fill_default_options(Options * options)
804 if (options->user_hostfile2 == NULL) 804 if (options->user_hostfile2 == NULL)
805 options->user_hostfile2 = SSH_USER_HOSTFILE2; 805 options->user_hostfile2 = SSH_USER_HOSTFILE2;
806 if (options->log_level == (LogLevel) - 1) 806 if (options->log_level == (LogLevel) - 1)
807 options->log_level = SYSLOG_LEVEL_NOTICE; 807 options->log_level = SYSLOG_LEVEL_INFO;
808 /* options->proxy_command should not be set by default */ 808 /* options->proxy_command should not be set by default */
809 /* options->user will be set in the main program if appropriate */ 809 /* options->user will be set in the main program if appropriate */
810 /* options->hostname will be set in the main program if appropriate */ 810 /* options->hostname will be set in the main program if appropriate */
diff --git a/servconf.c b/servconf.c
index fb42d74ef..544bb340e 100644
--- a/servconf.c
+++ b/servconf.c
@@ -10,7 +10,7 @@
10 */ 10 */
11 11
12#include "includes.h" 12#include "includes.h"
13RCSID("$OpenBSD: servconf.c,v 1.57 2001/01/08 22:29:05 markus Exp $"); 13RCSID("$OpenBSD: servconf.c,v 1.58 2001/01/18 16:20:22 markus Exp $");
14 14
15#include "ssh.h" 15#include "ssh.h"
16#include "servconf.h" 16#include "servconf.h"
@@ -130,7 +130,7 @@ fill_default_server_options(ServerOptions *options)
130 if (options->log_facility == (SyslogFacility) (-1)) 130 if (options->log_facility == (SyslogFacility) (-1))
131 options->log_facility = SYSLOG_FACILITY_AUTH; 131 options->log_facility = SYSLOG_FACILITY_AUTH;
132 if (options->log_level == (LogLevel) (-1)) 132 if (options->log_level == (LogLevel) (-1))
133 options->log_level = SYSLOG_LEVEL_NOTICE; 133 options->log_level = SYSLOG_LEVEL_INFO;
134 if (options->rhosts_authentication == -1) 134 if (options->rhosts_authentication == -1)
135 options->rhosts_authentication = 0; 135 options->rhosts_authentication = 0;
136 if (options->rhosts_rsa_authentication == -1) 136 if (options->rhosts_rsa_authentication == -1)
diff --git a/serverloop.c b/serverloop.c
index 5fb0ed020..958c9661e 100644
--- a/serverloop.c
+++ b/serverloop.c
@@ -35,7 +35,7 @@
35 */ 35 */
36 36
37#include "includes.h" 37#include "includes.h"
38RCSID("$OpenBSD: serverloop.c,v 1.39 2000/12/27 14:19:21 markus Exp $"); 38RCSID("$OpenBSD: serverloop.c,v 1.40 2001/01/18 17:00:00 markus Exp $");
39 39
40#include "xmalloc.h" 40#include "xmalloc.h"
41#include "ssh.h" 41#include "ssh.h"
@@ -47,10 +47,10 @@ RCSID("$OpenBSD: serverloop.c,v 1.39 2000/12/27 14:19:21 markus Exp $");
47 47
48#include "compat.h" 48#include "compat.h"
49#include "ssh2.h" 49#include "ssh2.h"
50#include "auth.h"
50#include "session.h" 51#include "session.h"
51#include "dispatch.h" 52#include "dispatch.h"
52#include "auth-options.h" 53#include "auth-options.h"
53#include "auth.h"
54 54
55extern ServerOptions options; 55extern ServerOptions options;
56 56
diff --git a/session.c b/session.c
index e52aed5a2..2c1500431 100644
--- a/session.c
+++ b/session.c
@@ -33,7 +33,7 @@
33 */ 33 */
34 34
35#include "includes.h" 35#include "includes.h"
36RCSID("$OpenBSD: session.c,v 1.48 2001/01/13 18:43:31 markus Exp $"); 36RCSID("$OpenBSD: session.c,v 1.49 2001/01/18 17:00:00 markus Exp $");
37 37
38#include "xmalloc.h" 38#include "xmalloc.h"
39#include "ssh.h" 39#include "ssh.h"
@@ -2000,11 +2000,8 @@ session_proctitle(Session *s)
2000} 2000}
2001 2001
2002void 2002void
2003do_authenticated2(void) 2003do_authenticated2(Authctxt *authctxt)
2004{ 2004{
2005#ifdef HAVE_LOGIN_CAP
2006 struct passwd *pw;
2007#endif
2008 2005
2009 /* 2006 /*
2010 * Cancel the alarm we set to limit the time taken for 2007 * Cancel the alarm we set to limit the time taken for
@@ -2016,8 +2013,8 @@ do_authenticated2(void)
2016 startup_pipe = -1; 2013 startup_pipe = -1;
2017 } 2014 }
2018#if defined(HAVE_LOGIN_CAP) && defined(HAVE_PW_CLASS_IN_PASSWD) 2015#if defined(HAVE_LOGIN_CAP) && defined(HAVE_PW_CLASS_IN_PASSWD)
2019 pw = auth_get_user(); 2016 /* ISSUE: Is this correct? */
2020 if ((lc = login_getclass(pw->pw_class)) == NULL) { 2017 if ((lc = login_getclass(authctxt->pw->pw_class)) == NULL) {
2021 error("unable to get login class"); 2018 error("unable to get login class");
2022 return; 2019 return;
2023 } 2020 }
diff --git a/session.h b/session.h
index bce99f77c..ee2e244c1 100644
--- a/session.h
+++ b/session.h
@@ -28,7 +28,7 @@
28void do_authenticated(struct passwd * pw); 28void do_authenticated(struct passwd * pw);
29 29
30/* SSH2 */ 30/* SSH2 */
31void do_authenticated2(void); 31void do_authenticated2(Authctxt *ac);
32int session_open(int id); 32int session_open(int id);
33void session_input_channel_req(int id, void *arg); 33void session_input_channel_req(int id, void *arg);
34void session_close_by_pid(pid_t pid, int status); 34void session_close_by_pid(pid_t pid, int status);
diff --git a/ssh.1 b/ssh.1
index 59cc7f180..5807ec187 100644
--- a/ssh.1
+++ b/ssh.1
@@ -34,7 +34,7 @@
34.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 34.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
35.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36.\" 36.\"
37.\" $OpenBSD: ssh.1,v 1.76 2001/01/07 11:28:06 markus Exp $ 37.\" $OpenBSD: ssh.1,v 1.77 2001/01/18 16:20:22 markus Exp $
38.Dd September 25, 1999 38.Dd September 25, 1999
39.Dt SSH 1 39.Dt SSH 1
40.Os 40.Os
@@ -814,8 +814,8 @@ Only the superuser can forward privileged ports.
814Gives the verbosity level that is used when logging messages from 814Gives the verbosity level that is used when logging messages from
815.Nm ssh . 815.Nm ssh .
816The possible values are: 816The possible values are:
817QUIET, FATAL, ERROR, NOTICE, VERBOSE and DEBUG. 817QUIET, FATAL, ERROR, INFO, VERBOSE and DEBUG.
818The default is NOTICE. 818The default is INFO.
819.It Cm NumberOfPasswordPrompts 819.It Cm NumberOfPasswordPrompts
820Specifies the number of password prompts before giving up. 820Specifies the number of password prompts before giving up.
821The argument to this keyword must be an integer. 821The argument to this keyword must be an integer.
diff --git a/ssh.h b/ssh.h
index f7330b915..9c487a398 100644
--- a/ssh.h
+++ b/ssh.h
@@ -12,7 +12,7 @@
12 * called by a name other than "ssh" or "Secure Shell". 12 * called by a name other than "ssh" or "Secure Shell".
13 */ 13 */
14 14
15/* RCSID("$OpenBSD: ssh.h,v 1.57 2001/01/07 11:28:06 markus Exp $"); */ 15/* RCSID("$OpenBSD: ssh.h,v 1.58 2001/01/18 16:20:22 markus Exp $"); */
16 16
17#ifndef SSH_H 17#ifndef SSH_H
18#define SSH_H 18#define SSH_H
@@ -445,7 +445,7 @@ typedef enum {
445 SYSLOG_LEVEL_QUIET, 445 SYSLOG_LEVEL_QUIET,
446 SYSLOG_LEVEL_FATAL, 446 SYSLOG_LEVEL_FATAL,
447 SYSLOG_LEVEL_ERROR, 447 SYSLOG_LEVEL_ERROR,
448 SYSLOG_LEVEL_NOTICE, 448 SYSLOG_LEVEL_INFO,
449 SYSLOG_LEVEL_VERBOSE, 449 SYSLOG_LEVEL_VERBOSE,
450 SYSLOG_LEVEL_DEBUG1, 450 SYSLOG_LEVEL_DEBUG1,
451 SYSLOG_LEVEL_DEBUG2, 451 SYSLOG_LEVEL_DEBUG2,
diff --git a/sshconnect1.c b/sshconnect1.c
index 17b381c13..b2d4e57bf 100644
--- a/sshconnect1.c
+++ b/sshconnect1.c
@@ -13,7 +13,7 @@
13 */ 13 */
14 14
15#include "includes.h" 15#include "includes.h"
16RCSID("$OpenBSD: sshconnect1.c,v 1.15 2001/01/16 23:58:09 deraadt Exp $"); 16RCSID("$OpenBSD: sshconnect1.c,v 1.16 2001/01/18 17:00:00 markus Exp $");
17 17
18#include <openssl/bn.h> 18#include <openssl/bn.h>
19#include <openssl/dsa.h> 19#include <openssl/dsa.h>
@@ -630,7 +630,8 @@ try_skey_authentication()
630 } 630 }
631 challenge = packet_get_string(&clen); 631 challenge = packet_get_string(&clen);
632 packet_integrity_check(payload_len, (4 + clen), type); 632 packet_integrity_check(payload_len, (4 + clen), type);
633 snprintf(prompt, sizeof prompt, "%s\nResponse: ", challenge); 633 snprintf(prompt, sizeof prompt, "%s%s", challenge,
634 strchr(challenge, '\n') ? "" : "\nResponse: ");
634 xfree(challenge); 635 xfree(challenge);
635 if (i != 0) 636 if (i != 0)
636 error("Permission denied, please try again."); 637 error("Permission denied, please try again.");
diff --git a/sshd.8 b/sshd.8
index a513978d9..415d960a1 100644
--- a/sshd.8
+++ b/sshd.8
@@ -34,7 +34,7 @@
34.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 34.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
35.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36.\" 36.\"
37.\" $OpenBSD: sshd.8,v 1.81 2001/01/13 18:56:48 markus Exp $ 37.\" $OpenBSD: sshd.8,v 1.82 2001/01/18 16:20:22 markus Exp $
38.Dd September 25, 1999 38.Dd September 25, 1999
39.Dt SSHD 8 39.Dt SSHD 8
40.Os 40.Os
@@ -499,8 +499,8 @@ The default is 600 (seconds).
499Gives the verbosity level that is used when logging messages from 499Gives the verbosity level that is used when logging messages from
500.Nm sshd . 500.Nm sshd .
501The possible values are: 501The possible values are:
502QUIET, FATAL, ERROR, NOTICE, VERBOSE and DEBUG. 502QUIET, FATAL, ERROR, INFO, VERBOSE and DEBUG.
503The default is NOTICE. 503The default is INFO.
504Logging with level DEBUG violates the privacy of users 504Logging with level DEBUG violates the privacy of users
505and is not recommended. 505and is not recommended.
506.It Cm MaxStartups 506.It Cm MaxStartups
diff --git a/sshd.c b/sshd.c
index be7ae5ab4..7f9c3ee7f 100644
--- a/sshd.c
+++ b/sshd.c
@@ -40,7 +40,7 @@
40 */ 40 */
41 41
42#include "includes.h" 42#include "includes.h"
43RCSID("$OpenBSD: sshd.c,v 1.150 2001/01/13 18:32:51 markus Exp $"); 43RCSID("$OpenBSD: sshd.c,v 1.152 2001/01/18 16:20:22 markus Exp $");
44 44
45#include "xmalloc.h" 45#include "xmalloc.h"
46#include "rsa.h" 46#include "rsa.h"
@@ -153,10 +153,10 @@ struct {
153} sensitive_data; 153} sensitive_data;
154 154
155/* 155/*
156 * Flag indicating whether the current session key has been used. This flag 156 * Flag indicating whether the RSA server key needs to be regenerated.
157 * is set whenever the key is used, and cleared when the key is regenerated. 157 * Is set in the SIGALRM handler and cleared when the key is regenerated.
158 */ 158 */
159int key_used = 0; 159int key_do_regen = 0;
160 160
161/* This is set to true when SIGHUP is received. */ 161/* This is set to true when SIGHUP is received. */
162int received_sighup = 0; 162int received_sighup = 0;
@@ -266,7 +266,6 @@ grace_alarm_handler(int sig)
266 * do anything with the private key or random state before forking. 266 * do anything with the private key or random state before forking.
267 * Thus there should be no concurrency control/asynchronous execution 267 * Thus there should be no concurrency control/asynchronous execution
268 * problems. 268 * problems.
269 * XXX calling log() is not safe from races.
270 */ 269 */
271void 270void
272generate_empheral_server_key(void) 271generate_empheral_server_key(void)
@@ -284,17 +283,9 @@ void
284key_regeneration_alarm(int sig) 283key_regeneration_alarm(int sig)
285{ 284{
286 int save_errno = errno; 285 int save_errno = errno;
287 286 signal(SIGALRM, SIG_DFL);
288 /* Check if we should generate a new key. */
289 if (key_used) {
290 /* This should really be done in the background. */
291 generate_empheral_server_key();
292 key_used = 0;
293 }
294 /* Reschedule the alarm. */
295 signal(SIGALRM, key_regeneration_alarm);
296 alarm(options.key_regeneration_time);
297 errno = save_errno; 287 errno = save_errno;
288 key_do_regen = 1;
298} 289}
299 290
300void 291void
@@ -568,6 +559,7 @@ main(int ac, char **av)
568 int listen_sock, maxfd; 559 int listen_sock, maxfd;
569 int startup_p[2]; 560 int startup_p[2];
570 int startups = 0; 561 int startups = 0;
562 int ret, key_used = 0;
571 563
572 __progname = get_progname(av[0]); 564 __progname = get_progname(av[0]);
573 init_rng(); 565 init_rng();
@@ -674,7 +666,7 @@ main(int ac, char **av)
674 * key (unless started from inetd) 666 * key (unless started from inetd)
675 */ 667 */
676 log_init(__progname, 668 log_init(__progname,
677 options.log_level == -1 ? SYSLOG_LEVEL_NOTICE : options.log_level, 669 options.log_level == -1 ? SYSLOG_LEVEL_INFO : options.log_level,
678 options.log_facility == -1 ? SYSLOG_FACILITY_AUTH : options.log_facility, 670 options.log_facility == -1 ? SYSLOG_FACILITY_AUTH : options.log_facility,
679 !silent && !inetd_flag); 671 !silent && !inetd_flag);
680 672
@@ -890,14 +882,9 @@ main(int ac, char **av)
890 fclose(f); 882 fclose(f);
891 } 883 }
892 } 884 }
893 if (options.protocol & SSH_PROTO_1) { 885 if (options.protocol & SSH_PROTO_1)
894 generate_empheral_server_key(); 886 generate_empheral_server_key();
895 887
896 /* Schedule server key regeneration alarm. */
897 signal(SIGALRM, key_regeneration_alarm);
898 alarm(options.key_regeneration_time);
899 }
900
901 /* Arrange to restart on SIGHUP. The handler needs listen_sock. */ 888 /* Arrange to restart on SIGHUP. The handler needs listen_sock. */
902 signal(SIGHUP, sighup_handler); 889 signal(SIGHUP, sighup_handler);
903 890
@@ -938,11 +925,17 @@ main(int ac, char **av)
938 FD_SET(startup_pipes[i], fdset); 925 FD_SET(startup_pipes[i], fdset);
939 926
940 /* Wait in select until there is a connection. */ 927 /* Wait in select until there is a connection. */
941 if (select(maxfd+1, fdset, NULL, NULL, NULL) < 0) { 928 ret = select(maxfd+1, fdset, NULL, NULL, NULL);
942 if (errno != EINTR) 929 if (ret < 0 && errno != EINTR)
943 error("select: %.100s", strerror(errno)); 930 error("select: %.100s", strerror(errno));
944 continue; 931 if (key_used && key_do_regen) {
932 generate_empheral_server_key();
933 key_used = 0;
934 key_do_regen = 0;
945 } 935 }
936 if (ret < 0)
937 continue;
938
946 for (i = 0; i < options.max_startups; i++) 939 for (i = 0; i < options.max_startups; i++)
947 if (startup_pipes[i] != -1 && 940 if (startup_pipes[i] != -1 &&
948 FD_ISSET(startup_pipes[i], fdset)) { 941 FD_ISSET(startup_pipes[i], fdset)) {
@@ -1042,7 +1035,13 @@ main(int ac, char **av)
1042 close(startup_p[1]); 1035 close(startup_p[1]);
1043 1036
1044 /* Mark that the key has been used (it was "given" to the child). */ 1037 /* Mark that the key has been used (it was "given" to the child). */
1045 key_used = 1; 1038 if ((options.protocol & SSH_PROTO_1) &&
1039 key_used == 0) {
1040 /* Schedule server key regeneration alarm. */
1041 signal(SIGALRM, key_regeneration_alarm);
1042 alarm(options.key_regeneration_time);
1043 key_used = 1;
1044 }
1046 1045
1047 arc4random_stir(); 1046 arc4random_stir();
1048 1047