Annotation of src/usr.bin/ssh/auth.c, Revision 1.5
1.1 markus 1: /*
2: * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
3: * All rights reserved
1.2 markus 4: * Copyright (c) 2000 Markus Friedl. All rights reserved.
1.1 markus 5: */
6:
7: #include "includes.h"
1.5 ! markus 8: RCSID("$OpenBSD: auth.c,v 1.4 2000/04/14 10:30:29 markus Exp $");
! 9:
! 10: #include <openssl/dsa.h>
! 11: #include <openssl/rsa.h>
! 12: #include <openssl/evp.h>
1.1 markus 13:
14: #include "xmalloc.h"
15: #include "rsa.h"
16: #include "ssh.h"
17: #include "pty.h"
18: #include "packet.h"
19: #include "buffer.h"
20: #include "cipher.h"
21: #include "mpaux.h"
22: #include "servconf.h"
1.2 markus 23: #include "compat.h"
1.1 markus 24: #include "channels.h"
25: #include "match.h"
1.2 markus 26: #include "bufaux.h"
27: #include "ssh2.h"
28: #include "auth.h"
1.1 markus 29: #include "session.h"
30: #include "dispatch.h"
31:
1.5 ! markus 32: #include "key.h"
! 33: #include "kex.h"
! 34: #include "dsa.h"
! 35: #include "uidswap.h"
! 36: #include "channels.h"
1.2 markus 37:
1.1 markus 38: /* import */
39: extern ServerOptions options;
40: extern char *forced_command;
41:
42: /*
43: * Check if the user is allowed to log in via ssh. If user is listed in
44: * DenyUsers or user's primary group is listed in DenyGroups, false will
45: * be returned. If AllowUsers isn't empty and user isn't listed there, or
46: * if AllowGroups isn't empty and user isn't listed there, false will be
1.4 markus 47: * returned.
1.1 markus 48: * If the user's shell is not executable, false will be returned.
1.4 markus 49: * Otherwise true is returned.
1.1 markus 50: */
1.5 ! markus 51: int
1.1 markus 52: allowed_user(struct passwd * pw)
53: {
54: struct stat st;
55: struct group *grp;
56: int i;
57:
58: /* Shouldn't be called if pw is NULL, but better safe than sorry... */
59: if (!pw)
60: return 0;
61:
62: /* deny if shell does not exists or is not executable */
63: if (stat(pw->pw_shell, &st) != 0)
64: return 0;
65: if (!((st.st_mode & S_IFREG) && (st.st_mode & (S_IXOTH|S_IXUSR|S_IXGRP))))
66: return 0;
67:
68: /* Return false if user is listed in DenyUsers */
69: if (options.num_deny_users > 0) {
70: if (!pw->pw_name)
71: return 0;
72: for (i = 0; i < options.num_deny_users; i++)
73: if (match_pattern(pw->pw_name, options.deny_users[i]))
74: return 0;
75: }
76: /* Return false if AllowUsers isn't empty and user isn't listed there */
77: if (options.num_allow_users > 0) {
78: if (!pw->pw_name)
79: return 0;
80: for (i = 0; i < options.num_allow_users; i++)
81: if (match_pattern(pw->pw_name, options.allow_users[i]))
82: break;
83: /* i < options.num_allow_users iff we break for loop */
84: if (i >= options.num_allow_users)
85: return 0;
86: }
87: /* Get the primary group name if we need it. Return false if it fails */
88: if (options.num_deny_groups > 0 || options.num_allow_groups > 0) {
89: grp = getgrgid(pw->pw_gid);
90: if (!grp)
91: return 0;
92:
93: /* Return false if user's group is listed in DenyGroups */
94: if (options.num_deny_groups > 0) {
95: if (!grp->gr_name)
96: return 0;
97: for (i = 0; i < options.num_deny_groups; i++)
98: if (match_pattern(grp->gr_name, options.deny_groups[i]))
99: return 0;
100: }
101: /*
102: * Return false if AllowGroups isn't empty and user's group
103: * isn't listed there
104: */
105: if (options.num_allow_groups > 0) {
106: if (!grp->gr_name)
107: return 0;
108: for (i = 0; i < options.num_allow_groups; i++)
109: if (match_pattern(grp->gr_name, options.allow_groups[i]))
110: break;
111: /* i < options.num_allow_groups iff we break for
112: loop */
113: if (i >= options.num_allow_groups)
114: return 0;
115: }
116: }
117: /* We found no reason not to let this user try to log on... */
118: return 1;
119: }
120:
1.5 ! markus 121: /* import */
! 122: extern ServerOptions options;
! 123: extern char *forced_command;
! 124:
1.1 markus 125: /*
126: * convert ssh auth msg type into description
127: */
128: char *
129: get_authname(int type)
130: {
131: static char buf[1024];
132: switch (type) {
133: case SSH_CMSG_AUTH_PASSWORD:
134: return "password";
135: case SSH_CMSG_AUTH_RSA:
136: return "rsa";
137: case SSH_CMSG_AUTH_RHOSTS_RSA:
138: return "rhosts-rsa";
139: case SSH_CMSG_AUTH_RHOSTS:
140: return "rhosts";
141: #ifdef KRB4
142: case SSH_CMSG_AUTH_KERBEROS:
143: return "kerberos";
144: #endif
145: #ifdef SKEY
146: case SSH_CMSG_AUTH_TIS_RESPONSE:
147: return "s/key";
148: #endif
149: }
150: snprintf(buf, sizeof buf, "bad-auth-msg-%d", type);
151: return buf;
152: }
153:
154: #define AUTH_FAIL_MAX 6
155: #define AUTH_FAIL_LOG (AUTH_FAIL_MAX/2)
156: #define AUTH_FAIL_MSG "Too many authentication failures for %.100s"
157:
158: /*
159: * The user does not exist or access is denied,
160: * but fake indication that authentication is needed.
161: */
162: void
163: do_fake_authloop1(char *user)
164: {
165: int attempt = 0;
166:
167: log("Faking authloop for illegal user %.200s from %.200s port %d",
168: user,
169: get_remote_ipaddr(),
170: get_remote_port());
171:
172: /* Indicate that authentication is needed. */
173: packet_start(SSH_SMSG_FAILURE);
174: packet_send();
175: packet_write_wait();
176:
177: /*
178: * Keep reading packets, and always respond with a failure. This is
179: * to avoid disclosing whether such a user really exists.
180: */
181: for (attempt = 1;; attempt++) {
182: /* Read a packet. This will not return if the client disconnects. */
183: int plen;
184: int type = packet_read(&plen);
185: #ifdef SKEY
186: unsigned int dlen;
187: char *password, *skeyinfo;
188: password = NULL;
189: /* Try to send a fake s/key challenge. */
190: if (options.skey_authentication == 1 &&
191: (skeyinfo = skey_fake_keyinfo(user)) != NULL) {
192: if (type == SSH_CMSG_AUTH_TIS) {
193: packet_start(SSH_SMSG_AUTH_TIS_CHALLENGE);
194: packet_put_string(skeyinfo, strlen(skeyinfo));
195: packet_send();
196: packet_write_wait();
197: continue;
198: } else if (type == SSH_CMSG_AUTH_PASSWORD &&
1.4 markus 199: options.password_authentication &&
200: (password = packet_get_string(&dlen)) != NULL &&
201: dlen == 5 &&
202: strncasecmp(password, "s/key", 5) == 0 ) {
1.1 markus 203: packet_send_debug(skeyinfo);
204: }
205: }
206: if (password != NULL)
207: xfree(password);
208: #endif
209: if (attempt > AUTH_FAIL_MAX)
210: packet_disconnect(AUTH_FAIL_MSG, user);
211:
212: /*
213: * Send failure. This should be indistinguishable from a
214: * failed authentication.
215: */
216: packet_start(SSH_SMSG_FAILURE);
217: packet_send();
218: packet_write_wait();
219: }
220: /* NOTREACHED */
221: abort();
222: }
223:
224: /*
225: * read packets and try to authenticate local user *pw.
226: * return if authentication is successfull
227: */
228: void
229: do_authloop(struct passwd * pw)
230: {
231: int attempt = 0;
232: unsigned int bits;
233: RSA *client_host_key;
234: BIGNUM *n;
235: char *client_user, *password;
236: char user[1024];
237: unsigned int dlen;
238: int plen, nlen, elen;
239: unsigned int ulen;
240: int type = 0;
241: void (*authlog) (const char *fmt,...) = verbose;
242:
243: /* Indicate that authentication is needed. */
244: packet_start(SSH_SMSG_FAILURE);
245: packet_send();
246: packet_write_wait();
247:
248: for (attempt = 1;; attempt++) {
249: int authenticated = 0;
250: strlcpy(user, "", sizeof user);
251:
252: /* Get a packet from the client. */
253: type = packet_read(&plen);
254:
255: /* Process the packet. */
256: switch (type) {
257: #ifdef AFS
258: case SSH_CMSG_HAVE_KERBEROS_TGT:
259: if (!options.kerberos_tgt_passing) {
260: /* packet_get_all(); */
261: verbose("Kerberos tgt passing disabled.");
262: break;
263: } else {
264: /* Accept Kerberos tgt. */
265: char *tgt = packet_get_string(&dlen);
266: packet_integrity_check(plen, 4 + dlen, type);
267: if (!auth_kerberos_tgt(pw, tgt))
268: verbose("Kerberos tgt REFUSED for %s", pw->pw_name);
269: xfree(tgt);
270: }
271: continue;
272:
273: case SSH_CMSG_HAVE_AFS_TOKEN:
274: if (!options.afs_token_passing || !k_hasafs()) {
275: /* packet_get_all(); */
276: verbose("AFS token passing disabled.");
277: break;
278: } else {
279: /* Accept AFS token. */
280: char *token_string = packet_get_string(&dlen);
281: packet_integrity_check(plen, 4 + dlen, type);
282: if (!auth_afs_token(pw, token_string))
283: verbose("AFS token REFUSED for %s", pw->pw_name);
284: xfree(token_string);
285: }
286: continue;
287: #endif /* AFS */
288: #ifdef KRB4
289: case SSH_CMSG_AUTH_KERBEROS:
290: if (!options.kerberos_authentication) {
291: /* packet_get_all(); */
292: verbose("Kerberos authentication disabled.");
293: break;
294: } else {
295: /* Try Kerberos v4 authentication. */
296: KTEXT_ST auth;
297: char *tkt_user = NULL;
298: char *kdata = packet_get_string((unsigned int *) &auth.length);
299: packet_integrity_check(plen, 4 + auth.length, type);
300:
301: if (auth.length < MAX_KTXT_LEN)
302: memcpy(auth.dat, kdata, auth.length);
303: xfree(kdata);
304:
305: authenticated = auth_krb4(pw->pw_name, &auth, &tkt_user);
306:
307: if (authenticated) {
308: snprintf(user, sizeof user, " tktuser %s", tkt_user);
309: xfree(tkt_user);
310: }
311: }
312: break;
313: #endif /* KRB4 */
314:
315: case SSH_CMSG_AUTH_RHOSTS:
316: if (!options.rhosts_authentication) {
317: verbose("Rhosts authentication disabled.");
318: break;
319: }
320: /*
321: * Get client user name. Note that we just have to
322: * trust the client; this is one reason why rhosts
323: * authentication is insecure. (Another is
324: * IP-spoofing on a local network.)
325: */
326: client_user = packet_get_string(&ulen);
327: packet_integrity_check(plen, 4 + ulen, type);
328:
329: /* Try to authenticate using /etc/hosts.equiv and
330: .rhosts. */
331: authenticated = auth_rhosts(pw, client_user);
332:
333: snprintf(user, sizeof user, " ruser %s", client_user);
334: xfree(client_user);
335: break;
336:
337: case SSH_CMSG_AUTH_RHOSTS_RSA:
338: if (!options.rhosts_rsa_authentication) {
339: verbose("Rhosts with RSA authentication disabled.");
340: break;
341: }
342: /*
343: * Get client user name. Note that we just have to
344: * trust the client; root on the client machine can
345: * claim to be any user.
346: */
347: client_user = packet_get_string(&ulen);
348:
349: /* Get the client host key. */
350: client_host_key = RSA_new();
351: if (client_host_key == NULL)
352: fatal("RSA_new failed");
353: client_host_key->e = BN_new();
354: client_host_key->n = BN_new();
355: if (client_host_key->e == NULL || client_host_key->n == NULL)
356: fatal("BN_new failed");
357: bits = packet_get_int();
358: packet_get_bignum(client_host_key->e, &elen);
359: packet_get_bignum(client_host_key->n, &nlen);
360:
361: if (bits != BN_num_bits(client_host_key->n))
362: error("Warning: keysize mismatch for client_host_key: "
363: "actual %d, announced %d", BN_num_bits(client_host_key->n), bits);
364: packet_integrity_check(plen, (4 + ulen) + 4 + elen + nlen, type);
365:
366: authenticated = auth_rhosts_rsa(pw, client_user, client_host_key);
367: RSA_free(client_host_key);
368:
369: snprintf(user, sizeof user, " ruser %s", client_user);
370: xfree(client_user);
371: break;
372:
373: case SSH_CMSG_AUTH_RSA:
374: if (!options.rsa_authentication) {
375: verbose("RSA authentication disabled.");
376: break;
377: }
378: /* RSA authentication requested. */
379: n = BN_new();
380: packet_get_bignum(n, &nlen);
381: packet_integrity_check(plen, nlen, type);
382: authenticated = auth_rsa(pw, n);
383: BN_clear_free(n);
384: break;
385:
386: case SSH_CMSG_AUTH_PASSWORD:
387: if (!options.password_authentication) {
388: verbose("Password authentication disabled.");
389: break;
390: }
391: /*
392: * Read user password. It is in plain text, but was
393: * transmitted over the encrypted channel so it is
394: * not visible to an outside observer.
395: */
396: password = packet_get_string(&dlen);
397: packet_integrity_check(plen, 4 + dlen, type);
398:
399: /* Try authentication with the password. */
400: authenticated = auth_password(pw, password);
401:
402: memset(password, 0, strlen(password));
403: xfree(password);
404: break;
405:
406: #ifdef SKEY
407: case SSH_CMSG_AUTH_TIS:
408: debug("rcvd SSH_CMSG_AUTH_TIS");
409: if (options.skey_authentication == 1) {
410: char *skeyinfo = skey_keyinfo(pw->pw_name);
411: if (skeyinfo == NULL) {
412: debug("generating fake skeyinfo for %.100s.", pw->pw_name);
413: skeyinfo = skey_fake_keyinfo(pw->pw_name);
414: }
415: if (skeyinfo != NULL) {
416: /* we send our s/key- in tis-challenge messages */
417: debug("sending challenge '%s'", skeyinfo);
418: packet_start(SSH_SMSG_AUTH_TIS_CHALLENGE);
419: packet_put_string(skeyinfo, strlen(skeyinfo));
420: packet_send();
421: packet_write_wait();
422: continue;
423: }
424: }
425: break;
426: case SSH_CMSG_AUTH_TIS_RESPONSE:
427: debug("rcvd SSH_CMSG_AUTH_TIS_RESPONSE");
428: if (options.skey_authentication == 1) {
429: char *response = packet_get_string(&dlen);
430: debug("skey response == '%s'", response);
431: packet_integrity_check(plen, 4 + dlen, type);
432: authenticated = (skey_haskey(pw->pw_name) == 0 &&
433: skey_passcheck(pw->pw_name, response) != -1);
434: xfree(response);
435: }
436: break;
437: #else
438: case SSH_CMSG_AUTH_TIS:
439: /* TIS Authentication is unsupported */
440: log("TIS authentication unsupported.");
441: break;
442: #endif
443:
444: default:
445: /*
446: * Any unknown messages will be ignored (and failure
447: * returned) during authentication.
448: */
449: log("Unknown message during authentication: type %d", type);
450: break;
451: }
1.4 markus 452:
453: /*
454: * Check if the user is logging in as root and root logins
455: * are disallowed.
456: * Note that root login is allowed for forced commands.
457: */
458: if (authenticated && pw->pw_uid == 0 && !options.permit_root_login) {
459: if (forced_command) {
460: log("Root login accepted for forced command.");
461: } else {
462: authenticated = 0;
463: log("ROOT LOGIN REFUSED FROM %.200s",
464: get_canonical_hostname());
465: }
466: }
1.1 markus 467:
468: /* Raise logging level */
469: if (authenticated ||
470: attempt == AUTH_FAIL_LOG ||
471: type == SSH_CMSG_AUTH_PASSWORD)
472: authlog = log;
473:
474: authlog("%s %s for %.200s from %.200s port %d%s",
475: authenticated ? "Accepted" : "Failed",
476: get_authname(type),
477: pw->pw_uid == 0 ? "ROOT" : pw->pw_name,
478: get_remote_ipaddr(),
479: get_remote_port(),
480: user);
481:
482: if (authenticated)
483: return;
484:
485: if (attempt > AUTH_FAIL_MAX)
486: packet_disconnect(AUTH_FAIL_MSG, pw->pw_name);
487:
488: /* Send a message indicating that the authentication attempt failed. */
489: packet_start(SSH_SMSG_FAILURE);
490: packet_send();
491: packet_write_wait();
492: }
493: }
494:
495: /*
496: * Performs authentication of an incoming connection. Session key has already
497: * been exchanged and encryption is enabled.
498: */
499: void
500: do_authentication()
501: {
502: struct passwd *pw, pwcopy;
503: int plen;
504: unsigned int ulen;
505: char *user;
506:
507: /* Get the name of the user that we wish to log in as. */
508: packet_read_expect(&plen, SSH_CMSG_USER);
509:
510: /* Get the user name. */
511: user = packet_get_string(&ulen);
512: packet_integrity_check(plen, (4 + ulen), SSH_CMSG_USER);
513:
514: setproctitle("%s", user);
515:
516: #ifdef AFS
517: /* If machine has AFS, set process authentication group. */
518: if (k_hasafs()) {
519: k_setpag();
520: k_unlog();
521: }
522: #endif /* AFS */
523:
524: /* Verify that the user is a valid user. */
525: pw = getpwnam(user);
526: if (!pw || !allowed_user(pw))
527: do_fake_authloop1(user);
528: xfree(user);
529:
530: /* Take a copy of the returned structure. */
531: memset(&pwcopy, 0, sizeof(pwcopy));
532: pwcopy.pw_name = xstrdup(pw->pw_name);
533: pwcopy.pw_passwd = xstrdup(pw->pw_passwd);
534: pwcopy.pw_uid = pw->pw_uid;
535: pwcopy.pw_gid = pw->pw_gid;
536: pwcopy.pw_dir = xstrdup(pw->pw_dir);
537: pwcopy.pw_shell = xstrdup(pw->pw_shell);
538: pw = &pwcopy;
539:
540: /*
541: * If we are not running as root, the user must have the same uid as
542: * the server.
543: */
544: if (getuid() != 0 && pw->pw_uid != getuid())
545: packet_disconnect("Cannot change user when server not running as root.");
546:
547: debug("Attempting authentication for %.100s.", pw->pw_name);
548:
549: /* If the user has no password, accept authentication immediately. */
550: if (options.password_authentication &&
551: #ifdef KRB4
552: (!options.kerberos_authentication || options.kerberos_or_local_passwd) &&
553: #endif /* KRB4 */
554: auth_password(pw, "")) {
555: /* Authentication with empty password succeeded. */
556: log("Login for user %s from %.100s, accepted without authentication.",
557: pw->pw_name, get_remote_ipaddr());
558: } else {
559: /* Loop until the user has been authenticated or the
560: connection is closed, do_authloop() returns only if
561: authentication is successfull */
562: do_authloop(pw);
563: }
564:
565: /* The user has been authenticated and accepted. */
566: packet_start(SSH_SMSG_SUCCESS);
567: packet_send();
568: packet_write_wait();
569:
570: /* Perform session preparation. */
571: do_authenticated(pw);
1.2 markus 572: }
573:
1.5 ! markus 574: /* import */
! 575: extern ServerOptions options;
! 576: extern unsigned char *session_id2;
! 577: extern int session_id2_len;
! 578:
! 579: /* protocol */
1.2 markus 580:
1.5 ! markus 581: void input_service_request(int type, int plen);
! 582: void input_userauth_request(int type, int plen);
! 583: void protocol_error(int type, int plen);
! 584:
! 585: /* auth */
! 586: int ssh2_auth_none(struct passwd *pw);
! 587: int ssh2_auth_password(struct passwd *pw);
! 588: int ssh2_auth_pubkey(struct passwd *pw, unsigned char *raw, unsigned int rlen);
! 589:
! 590: /* helper */
! 591: struct passwd* auth_set_user(char *u, char *s);
! 592: int user_dsa_key_allowed(struct passwd *pw, Key *key);
1.2 markus 593:
594: typedef struct Authctxt Authctxt;
595: struct Authctxt {
596: char *user;
597: char *service;
598: struct passwd pw;
599: int valid;
600: };
601: static Authctxt *authctxt = NULL;
602: static int userauth_success = 0;
603:
1.5 ! markus 604: /* set and get current user */
! 605:
1.2 markus 606: struct passwd*
607: auth_get_user(void)
608: {
609: return (authctxt != NULL && authctxt->valid) ? &authctxt->pw : NULL;
610: }
1.5 ! markus 611:
1.2 markus 612: struct passwd*
613: auth_set_user(char *u, char *s)
614: {
615: struct passwd *pw, *copy;
616:
617: if (authctxt == NULL) {
618: authctxt = xmalloc(sizeof(*authctxt));
619: authctxt->valid = 0;
620: authctxt->user = xstrdup(u);
621: authctxt->service = xstrdup(s);
622: setproctitle("%s", u);
623: pw = getpwnam(u);
624: if (!pw || !allowed_user(pw)) {
625: log("auth_set_user: bad user %s", u);
626: return NULL;
627: }
628: copy = &authctxt->pw;
629: memset(copy, 0, sizeof(*copy));
630: copy->pw_name = xstrdup(pw->pw_name);
631: copy->pw_passwd = xstrdup(pw->pw_passwd);
632: copy->pw_uid = pw->pw_uid;
633: copy->pw_gid = pw->pw_gid;
634: copy->pw_dir = xstrdup(pw->pw_dir);
635: copy->pw_shell = xstrdup(pw->pw_shell);
636: authctxt->valid = 1;
637: } else {
638: if (strcmp(u, authctxt->user) != 0 ||
639: strcmp(s, authctxt->service) != 0) {
640: log("auth_set_user: missmatch: (%s,%s)!=(%s,%s)",
641: u, s, authctxt->user, authctxt->service);
642: return NULL;
643: }
644: }
645: return auth_get_user();
646: }
647:
1.5 ! markus 648: /*
! 649: * loop until userauth_success == TRUE
! 650: */
! 651:
! 652: void
! 653: do_authentication2()
! 654: {
! 655: dispatch_init(&protocol_error);
! 656: dispatch_set(SSH2_MSG_SERVICE_REQUEST, &input_service_request);
! 657: dispatch_run(DISPATCH_BLOCK, &userauth_success);
! 658: do_authenticated2();
! 659: }
! 660:
! 661: void
1.2 markus 662: protocol_error(int type, int plen)
663: {
664: log("auth: protocol error: type %d plen %d", type, plen);
665: packet_start(SSH2_MSG_UNIMPLEMENTED);
666: packet_put_int(0);
667: packet_send();
668: packet_write_wait();
669: }
1.5 ! markus 670:
1.2 markus 671: void
672: input_service_request(int type, int plen)
673: {
674: unsigned int len;
675: int accept = 0;
676: char *service = packet_get_string(&len);
1.3 markus 677: packet_done();
1.2 markus 678:
679: if (strcmp(service, "ssh-userauth") == 0) {
680: if (!userauth_success) {
681: accept = 1;
682: /* now we can handle user-auth requests */
683: dispatch_set(SSH2_MSG_USERAUTH_REQUEST, &input_userauth_request);
684: }
685: }
686: /* XXX all other service requests are denied */
687:
688: if (accept) {
689: packet_start(SSH2_MSG_SERVICE_ACCEPT);
690: packet_put_cstring(service);
691: packet_send();
692: packet_write_wait();
693: } else {
694: debug("bad service request %s", service);
695: packet_disconnect("bad service request %s", service);
696: }
697: xfree(service);
698: }
1.5 ! markus 699:
1.2 markus 700: void
701: input_userauth_request(int type, int plen)
702: {
703: static int try = 0;
1.5 ! markus 704: unsigned int len, rlen;
! 705: int authenticated = 0;
! 706: char *raw, *user, *service, *method;
1.2 markus 707: struct passwd *pw;
708:
709: if (++try == AUTH_FAIL_MAX)
710: packet_disconnect("too many failed userauth_requests");
711:
1.5 ! markus 712: raw = packet_get_raw(&rlen);
! 713: if (plen != rlen)
! 714: fatal("plen != rlen");
1.2 markus 715: user = packet_get_string(&len);
716: service = packet_get_string(&len);
717: method = packet_get_string(&len);
718: debug("userauth-request for user %s service %s method %s", user, service, method);
719:
720: /* XXX we only allow the ssh-connection service */
721: pw = auth_set_user(user, service);
722: if (pw && strcmp(service, "ssh-connection")==0) {
1.5 ! markus 723: if (strcmp(method, "none") == 0) {
! 724: authenticated = ssh2_auth_none(pw);
1.2 markus 725: } else if (strcmp(method, "password") == 0) {
1.5 ! markus 726: authenticated = ssh2_auth_password(pw);
1.2 markus 727: } else if (strcmp(method, "publickey") == 0) {
1.5 ! markus 728: authenticated = ssh2_auth_pubkey(pw, raw, rlen);
1.2 markus 729: }
730: }
731: /* XXX check if other auth methods are needed */
1.5 ! markus 732: if (authenticated == 1) {
! 733: log("userauth success for %s method %s", user, method);
1.2 markus 734: /* turn off userauth */
735: dispatch_set(SSH2_MSG_USERAUTH_REQUEST, &protocol_error);
736: packet_start(SSH2_MSG_USERAUTH_SUCCESS);
737: packet_send();
738: packet_write_wait();
739: /* now we can break out */
740: userauth_success = 1;
1.5 ! markus 741: } else if (authenticated == 0) {
! 742: log("userauth failure for %s method %s", user, method);
1.2 markus 743: packet_start(SSH2_MSG_USERAUTH_FAILURE);
1.5 ! markus 744: packet_put_cstring("publickey,password"); /* XXX dynamic */
! 745: packet_put_char(0); /* XXX partial success, unused */
1.2 markus 746: packet_send();
747: packet_write_wait();
1.5 ! markus 748: } else {
! 749: log("userauth postponed for %s method %s", user, method);
1.2 markus 750: }
751: xfree(service);
752: xfree(user);
753: xfree(method);
754: }
1.5 ! markus 755:
! 756: int
! 757: ssh2_auth_none(struct passwd *pw)
! 758: {
! 759: packet_done();
! 760: return auth_password(pw, "");
! 761: }
! 762: int
! 763: ssh2_auth_password(struct passwd *pw)
! 764: {
! 765: char *password;
! 766: int authenticated = 0;
! 767: int change;
! 768: unsigned int len;
! 769: change = packet_get_char();
! 770: if (change)
! 771: log("password change not supported");
! 772: password = packet_get_string(&len);
! 773: packet_done();
! 774: if (auth_password(pw, password))
! 775: authenticated = 1;
! 776: memset(password, 0, len);
! 777: xfree(password);
! 778: return authenticated;
! 779: }
! 780:
! 781: int
! 782: ssh2_auth_pubkey(struct passwd *pw, unsigned char *raw, unsigned int rlen)
1.2 markus 783: {
1.5 ! markus 784: Buffer b;
! 785: Key *key;
! 786: char *pkalg, *pkblob, *sig;
! 787: unsigned int alen, blen, slen;
! 788: int have_sig;
! 789: int authenticated = 0;
! 790:
! 791: have_sig = packet_get_char();
! 792: pkalg = packet_get_string(&alen);
! 793: if (strcmp(pkalg, KEX_DSS) != 0) {
! 794: xfree(pkalg);
! 795: log("bad pkalg %s", pkalg); /*XXX*/
! 796: return 0;
! 797: }
! 798: pkblob = packet_get_string(&blen);
! 799: key = dsa_key_from_blob(pkblob, blen);
! 800:
! 801: if (have_sig && key != NULL) {
! 802: sig = packet_get_string(&slen);
! 803: packet_done();
! 804: buffer_init(&b);
! 805: buffer_append(&b, session_id2, session_id2_len);
! 806: buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
! 807: if (slen + 4 > rlen)
! 808: fatal("bad rlen/slen");
! 809: buffer_append(&b, raw, rlen - slen - 4);
! 810: #ifdef DEBUG_DSS
! 811: buffer_dump(&b);
! 812: #endif
! 813: /* test for correct signature */
! 814: if (user_dsa_key_allowed(pw, key) &&
! 815: dsa_verify(key, sig, slen, buffer_ptr(&b), buffer_len(&b)) == 1)
! 816: authenticated = 1;
! 817: buffer_clear(&b);
! 818: xfree(sig);
! 819: } else if (!have_sig && key != NULL) {
! 820: packet_done();
! 821: debug("test key...");
! 822: /* test whether pkalg/pkblob are acceptable */
! 823: /* XXX fake reply and always send PK_OK ? */
! 824: if (user_dsa_key_allowed(pw, key)) {
! 825: packet_start(SSH2_MSG_USERAUTH_PK_OK);
! 826: packet_put_string(pkalg, alen);
! 827: packet_put_string(pkblob, blen);
! 828: packet_send();
! 829: packet_write_wait();
! 830: authenticated = -1;
! 831: }
! 832: }
! 833: xfree(pkalg);
! 834: xfree(pkblob);
! 835: return authenticated;
! 836: }
! 837:
! 838: /* return 1 if user allows given key */
! 839: int
! 840: user_dsa_key_allowed(struct passwd *pw, Key *key)
! 841: {
! 842: char line[8192], file[1024];
! 843: int found_key = 0;
! 844: unsigned int bits = -1;
! 845: FILE *f;
! 846: unsigned long linenum = 0;
! 847: struct stat st;
! 848: Key *found;
! 849:
! 850: /* Temporarily use the user's uid. */
! 851: temporarily_use_uid(pw->pw_uid);
! 852:
! 853: /* The authorized keys. */
! 854: snprintf(file, sizeof file, "%.500s/%.100s", pw->pw_dir,
! 855: SSH_USER_PERMITTED_KEYS2);
! 856:
! 857: /* Fail quietly if file does not exist */
! 858: if (stat(file, &st) < 0) {
! 859: /* Restore the privileged uid. */
! 860: restore_uid();
! 861: return 0;
! 862: }
! 863: /* Open the file containing the authorized keys. */
! 864: f = fopen(file, "r");
! 865: if (!f) {
! 866: /* Restore the privileged uid. */
! 867: restore_uid();
! 868: packet_send_debug("Could not open %.900s for reading.", file);
! 869: packet_send_debug("If your home is on an NFS volume, it may need to be world-readable.");
! 870: return 0;
! 871: }
! 872: if (options.strict_modes) {
! 873: int fail = 0;
! 874: char buf[1024];
! 875: /* Check open file in order to avoid open/stat races */
! 876: if (fstat(fileno(f), &st) < 0 ||
! 877: (st.st_uid != 0 && st.st_uid != pw->pw_uid) ||
! 878: (st.st_mode & 022) != 0) {
! 879: snprintf(buf, sizeof buf, "DSA authentication refused for %.100s: "
! 880: "bad ownership or modes for '%s'.", pw->pw_name, file);
! 881: fail = 1;
! 882: } else {
! 883: /* Check path to SSH_USER_PERMITTED_KEYS */
! 884: int i;
! 885: static const char *check[] = {
! 886: "", SSH_USER_DIR, NULL
! 887: };
! 888: for (i = 0; check[i]; i++) {
! 889: snprintf(line, sizeof line, "%.500s/%.100s",
! 890: pw->pw_dir, check[i]);
! 891: if (stat(line, &st) < 0 ||
! 892: (st.st_uid != 0 && st.st_uid != pw->pw_uid) ||
! 893: (st.st_mode & 022) != 0) {
! 894: snprintf(buf, sizeof buf,
! 895: "DSA authentication refused for %.100s: "
! 896: "bad ownership or modes for '%s'.",
! 897: pw->pw_name, line);
! 898: fail = 1;
! 899: break;
! 900: }
! 901: }
! 902: }
! 903: if (fail) {
! 904: log(buf);
! 905: fclose(f);
! 906: restore_uid();
! 907: return 0;
! 908: }
! 909: }
! 910: found_key = 0;
! 911: found = key_new(KEY_DSA);
! 912:
! 913: while (fgets(line, sizeof(line), f)) {
! 914: char *cp;
! 915: linenum++;
! 916: /* Skip leading whitespace, empty and comment lines. */
! 917: for (cp = line; *cp == ' ' || *cp == '\t'; cp++)
! 918: ;
! 919: if (!*cp || *cp == '\n' || *cp == '#')
! 920: continue;
! 921: bits = key_read(found, &cp);
! 922: if (bits == 0)
! 923: continue;
! 924: if (key_equal(found, key)) {
! 925: found_key = 1;
! 926: debug("matching key found: file %s, line %ld",
! 927: file, linenum);
! 928: break;
! 929: }
! 930: }
! 931: restore_uid();
! 932: fclose(f);
! 933: key_free(found);
! 934: return found_key;
1.1 markus 935: }