diff options
author | Ben Lindstrom <mouring@eviladmin.org> | 2001-01-19 04:26:52 +0000 |
---|---|---|
committer | Ben Lindstrom <mouring@eviladmin.org> | 2001-01-19 04:26:52 +0000 |
commit | db65e8fdedadaf79df2d8393a4d43e9094c80649 (patch) | |
tree | e5902db5ee2b69f9f3c2fa0dbdeb7f4fc20c68b4 /auth2.c | |
parent | 5aa80596f76ce36dee4623a00a55548834c3328d (diff) |
Please grep through the source and look for 'ISSUE' comments and verify
that I was able to get all the portable bits in the right location. As for
the SKEY comment there is an email out to Markus as to how it should be
resolved. Until then I just #ifdef SKEY/#endif out the whole block.
- (bal) OpenBSD Resync
- markus@cvs.openbsd.org 2001/01/18 16:20:21
[log-client.c log-server.c log.c readconf.c servconf.c ssh.1 ssh.h
sshd.8 sshd.c]
log() is at pri=LOG_INFO, since LOG_NOTICE goes to /dev/console on many
systems
- markus@cvs.openbsd.org 2001/01/18 16:59:59
[auth-passwd.c auth.c auth.h auth1.c auth2.c serverloop.c session.c
session.h sshconnect1.c]
1) removes fake skey from sshd, since this will be much
harder with /usr/libexec/auth/login_XXX
2) share/unify code used in ssh-1 and ssh-2 authentication (server side)
3) make addition of BSD_AUTH and other challenge reponse methods
easier.
- markus@cvs.openbsd.org 2001/01/18 17:12:43
[auth-chall.c auth2-chall.c]
rename *-skey.c *-chall.c since the files are not skey specific
Diffstat (limited to 'auth2.c')
-rw-r--r-- | auth2.c | 124 |
1 files changed, 35 insertions, 89 deletions
@@ -23,7 +23,7 @@ | |||
23 | */ | 23 | */ |
24 | 24 | ||
25 | #include "includes.h" | 25 | #include "includes.h" |
26 | RCSID("$OpenBSD: auth2.c,v 1.25 2001/01/08 22:29:05 markus Exp $"); | 26 | RCSID("$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); | |||
84 | void input_userauth_request(int type, int plen, void *ctxt); | 84 | void input_userauth_request(int type, int plen, void *ctxt); |
85 | void protocol_error(int type, int plen, void *ctxt); | 85 | void protocol_error(int type, int plen, void *ctxt); |
86 | 86 | ||
87 | |||
88 | /* helper */ | 87 | /* helper */ |
89 | Authmethod *authmethod_lookup(const char *name); | 88 | Authmethod *authmethod_lookup(const char *name); |
90 | struct passwd *pwcopy(struct passwd *pw); | 89 | struct passwd *pwcopy(struct passwd *pw); |
@@ -121,22 +120,21 @@ Authmethod authmethods[] = { | |||
121 | void | 120 | void |
122 | do_authentication2() | 121 | do_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 | ||
142 | void | 140 | void |
@@ -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 | ||
295 | void | ||
296 | userauth_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 | |||
330 | void | 297 | void |
331 | userauth_reply(Authctxt *authctxt, int authenticated) | 298 | userauth_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 | |||
736 | struct passwd * | ||
737 | pwcopy(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 | } | ||