Annotation of src/usr.bin/ssh/auth1.c, Revision 1.4
1.1 markus 1: /*
2: * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
3: * All rights reserved
1.4 ! deraadt 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".
1.1 markus 10: */
11:
12: #include "includes.h"
1.4 ! deraadt 13: RCSID("$OpenBSD: auth1.c,v 1.3 2000/08/20 18:42:40 millert Exp $");
1.1 markus 14:
15: #include "xmalloc.h"
16: #include "rsa.h"
17: #include "ssh.h"
18: #include "packet.h"
19: #include "buffer.h"
20: #include "cipher.h"
21: #include "mpaux.h"
22: #include "servconf.h"
23: #include "compat.h"
24: #include "auth.h"
25: #include "session.h"
26:
27: /* import */
28: extern ServerOptions options;
29: extern char *forced_command;
30:
31: /*
32: * convert ssh auth msg type into description
33: */
34: char *
35: get_authname(int type)
36: {
37: static char buf[1024];
38: switch (type) {
39: case SSH_CMSG_AUTH_PASSWORD:
40: return "password";
41: case SSH_CMSG_AUTH_RSA:
42: return "rsa";
43: case SSH_CMSG_AUTH_RHOSTS_RSA:
44: return "rhosts-rsa";
45: case SSH_CMSG_AUTH_RHOSTS:
46: return "rhosts";
47: #ifdef KRB4
48: case SSH_CMSG_AUTH_KERBEROS:
49: return "kerberos";
50: #endif
51: #ifdef SKEY
52: case SSH_CMSG_AUTH_TIS_RESPONSE:
53: return "s/key";
54: #endif
55: }
56: snprintf(buf, sizeof buf, "bad-auth-msg-%d", type);
57: return buf;
58: }
59:
60: /*
61: * The user does not exist or access is denied,
62: * but fake indication that authentication is needed.
63: */
64: void
65: do_fake_authloop1(char *user)
66: {
67: int attempt = 0;
68:
69: log("Faking authloop for illegal user %.200s from %.200s port %d",
70: user,
71: get_remote_ipaddr(),
72: get_remote_port());
73:
74: /* Indicate that authentication is needed. */
75: packet_start(SSH_SMSG_FAILURE);
76: packet_send();
77: packet_write_wait();
78:
79: /*
80: * Keep reading packets, and always respond with a failure. This is
81: * to avoid disclosing whether such a user really exists.
82: */
83: for (attempt = 1;; attempt++) {
84: /* Read a packet. This will not return if the client disconnects. */
85: int plen;
86: int type = packet_read(&plen);
87: #ifdef SKEY
88: unsigned int dlen;
89: char *password, *skeyinfo;
90: password = NULL;
91: /* Try to send a fake s/key challenge. */
92: if (options.skey_authentication == 1 &&
93: (skeyinfo = skey_fake_keyinfo(user)) != NULL) {
94: if (type == SSH_CMSG_AUTH_TIS) {
95: packet_start(SSH_SMSG_AUTH_TIS_CHALLENGE);
96: packet_put_string(skeyinfo, strlen(skeyinfo));
97: packet_send();
98: packet_write_wait();
99: continue;
100: } else if (type == SSH_CMSG_AUTH_PASSWORD &&
101: options.password_authentication &&
102: (password = packet_get_string(&dlen)) != NULL &&
103: dlen == 5 &&
104: strncasecmp(password, "s/key", 5) == 0 ) {
105: packet_send_debug(skeyinfo);
106: }
107: }
108: if (password != NULL)
109: xfree(password);
110: #endif
111: if (attempt > AUTH_FAIL_MAX)
112: packet_disconnect(AUTH_FAIL_MSG, user);
113:
114: /*
115: * Send failure. This should be indistinguishable from a
116: * failed authentication.
117: */
118: packet_start(SSH_SMSG_FAILURE);
119: packet_send();
120: packet_write_wait();
121: }
122: /* NOTREACHED */
123: abort();
124: }
125:
126: /*
127: * read packets and try to authenticate local user *pw.
128: * return if authentication is successfull
129: */
130: void
131: do_authloop(struct passwd * pw)
132: {
133: int attempt = 0;
134: unsigned int bits;
135: RSA *client_host_key;
136: BIGNUM *n;
137: char *client_user, *password;
138: char user[1024];
139: unsigned int dlen;
140: int plen, nlen, elen;
141: unsigned int ulen;
142: int type = 0;
143: void (*authlog) (const char *fmt,...) = verbose;
144:
145: /* Indicate that authentication is needed. */
146: packet_start(SSH_SMSG_FAILURE);
147: packet_send();
148: packet_write_wait();
149:
150: for (attempt = 1;; attempt++) {
151: int authenticated = 0;
152: strlcpy(user, "", sizeof user);
153:
154: /* Get a packet from the client. */
155: type = packet_read(&plen);
156:
157: /* Process the packet. */
158: switch (type) {
159: #ifdef AFS
160: case SSH_CMSG_HAVE_KERBEROS_TGT:
161: if (!options.kerberos_tgt_passing) {
162: /* packet_get_all(); */
163: verbose("Kerberos tgt passing disabled.");
164: break;
165: } else {
166: /* Accept Kerberos tgt. */
167: char *tgt = packet_get_string(&dlen);
168: packet_integrity_check(plen, 4 + dlen, type);
169: if (!auth_kerberos_tgt(pw, tgt))
170: verbose("Kerberos tgt REFUSED for %s", pw->pw_name);
171: xfree(tgt);
172: }
173: continue;
174:
175: case SSH_CMSG_HAVE_AFS_TOKEN:
176: if (!options.afs_token_passing || !k_hasafs()) {
177: /* packet_get_all(); */
178: verbose("AFS token passing disabled.");
179: break;
180: } else {
181: /* Accept AFS token. */
182: char *token_string = packet_get_string(&dlen);
183: packet_integrity_check(plen, 4 + dlen, type);
184: if (!auth_afs_token(pw, token_string))
185: verbose("AFS token REFUSED for %s", pw->pw_name);
186: xfree(token_string);
187: }
188: continue;
189: #endif /* AFS */
190: #ifdef KRB4
191: case SSH_CMSG_AUTH_KERBEROS:
192: if (!options.kerberos_authentication) {
193: /* packet_get_all(); */
194: verbose("Kerberos authentication disabled.");
195: break;
196: } else {
197: /* Try Kerberos v4 authentication. */
198: KTEXT_ST auth;
199: char *tkt_user = NULL;
200: char *kdata = packet_get_string((unsigned int *) &auth.length);
201: packet_integrity_check(plen, 4 + auth.length, type);
202:
203: if (auth.length < MAX_KTXT_LEN)
204: memcpy(auth.dat, kdata, auth.length);
205: xfree(kdata);
206:
207: authenticated = auth_krb4(pw->pw_name, &auth, &tkt_user);
208:
209: if (authenticated) {
210: snprintf(user, sizeof user, " tktuser %s", tkt_user);
211: xfree(tkt_user);
212: }
213: }
214: break;
215: #endif /* KRB4 */
216:
217: case SSH_CMSG_AUTH_RHOSTS:
218: if (!options.rhosts_authentication) {
219: verbose("Rhosts authentication disabled.");
220: break;
221: }
222: /*
223: * Get client user name. Note that we just have to
224: * trust the client; this is one reason why rhosts
225: * authentication is insecure. (Another is
226: * IP-spoofing on a local network.)
227: */
228: client_user = packet_get_string(&ulen);
229: packet_integrity_check(plen, 4 + ulen, type);
230:
231: /* Try to authenticate using /etc/hosts.equiv and
232: .rhosts. */
233: authenticated = auth_rhosts(pw, client_user);
234:
235: snprintf(user, sizeof user, " ruser %s", client_user);
236: xfree(client_user);
237: break;
238:
239: case SSH_CMSG_AUTH_RHOSTS_RSA:
240: if (!options.rhosts_rsa_authentication) {
241: verbose("Rhosts with RSA authentication disabled.");
242: break;
243: }
244: /*
245: * Get client user name. Note that we just have to
246: * trust the client; root on the client machine can
247: * claim to be any user.
248: */
249: client_user = packet_get_string(&ulen);
250:
251: /* Get the client host key. */
252: client_host_key = RSA_new();
253: if (client_host_key == NULL)
254: fatal("RSA_new failed");
255: client_host_key->e = BN_new();
256: client_host_key->n = BN_new();
257: if (client_host_key->e == NULL || client_host_key->n == NULL)
258: fatal("BN_new failed");
259: bits = packet_get_int();
260: packet_get_bignum(client_host_key->e, &elen);
261: packet_get_bignum(client_host_key->n, &nlen);
262:
263: if (bits != BN_num_bits(client_host_key->n))
1.2 markus 264: log("Warning: keysize mismatch for client_host_key: "
265: "actual %d, announced %d", BN_num_bits(client_host_key->n), bits);
1.1 markus 266: packet_integrity_check(plen, (4 + ulen) + 4 + elen + nlen, type);
267:
268: authenticated = auth_rhosts_rsa(pw, client_user, client_host_key);
269: RSA_free(client_host_key);
270:
271: snprintf(user, sizeof user, " ruser %s", client_user);
272: xfree(client_user);
273: break;
274:
275: case SSH_CMSG_AUTH_RSA:
276: if (!options.rsa_authentication) {
277: verbose("RSA authentication disabled.");
278: break;
279: }
280: /* RSA authentication requested. */
281: n = BN_new();
282: packet_get_bignum(n, &nlen);
283: packet_integrity_check(plen, nlen, type);
284: authenticated = auth_rsa(pw, n);
285: BN_clear_free(n);
286: break;
287:
288: case SSH_CMSG_AUTH_PASSWORD:
289: if (!options.password_authentication) {
290: verbose("Password authentication disabled.");
291: break;
292: }
293: /*
294: * Read user password. It is in plain text, but was
295: * transmitted over the encrypted channel so it is
296: * not visible to an outside observer.
297: */
298: password = packet_get_string(&dlen);
299: packet_integrity_check(plen, 4 + dlen, type);
300:
301: /* Try authentication with the password. */
302: authenticated = auth_password(pw, password);
303:
304: memset(password, 0, strlen(password));
305: xfree(password);
306: break;
307:
308: #ifdef SKEY
309: case SSH_CMSG_AUTH_TIS:
310: debug("rcvd SSH_CMSG_AUTH_TIS");
311: if (options.skey_authentication == 1) {
312: char *skeyinfo = skey_keyinfo(pw->pw_name);
313: if (skeyinfo == NULL) {
314: debug("generating fake skeyinfo for %.100s.", pw->pw_name);
315: skeyinfo = skey_fake_keyinfo(pw->pw_name);
316: }
317: if (skeyinfo != NULL) {
318: /* we send our s/key- in tis-challenge messages */
319: debug("sending challenge '%s'", skeyinfo);
320: packet_start(SSH_SMSG_AUTH_TIS_CHALLENGE);
321: packet_put_string(skeyinfo, strlen(skeyinfo));
322: packet_send();
323: packet_write_wait();
324: continue;
325: }
326: }
327: break;
328: case SSH_CMSG_AUTH_TIS_RESPONSE:
329: debug("rcvd SSH_CMSG_AUTH_TIS_RESPONSE");
330: if (options.skey_authentication == 1) {
331: char *response = packet_get_string(&dlen);
332: debug("skey response == '%s'", response);
333: packet_integrity_check(plen, 4 + dlen, type);
334: authenticated = (skey_haskey(pw->pw_name) == 0 &&
335: skey_passcheck(pw->pw_name, response) != -1);
336: xfree(response);
337: }
338: break;
339: #else
340: case SSH_CMSG_AUTH_TIS:
341: /* TIS Authentication is unsupported */
342: log("TIS authentication unsupported.");
343: break;
344: #endif
345:
346: default:
347: /*
348: * Any unknown messages will be ignored (and failure
349: * returned) during authentication.
350: */
351: log("Unknown message during authentication: type %d", type);
352: break;
353: }
354:
355: /*
356: * Check if the user is logging in as root and root logins
357: * are disallowed.
358: * Note that root login is allowed for forced commands.
359: */
360: if (authenticated && pw->pw_uid == 0 && !options.permit_root_login) {
361: if (forced_command) {
362: log("Root login accepted for forced command.");
363: } else {
364: authenticated = 0;
365: log("ROOT LOGIN REFUSED FROM %.200s",
366: get_canonical_hostname());
367: }
368: }
369:
370: /* Raise logging level */
371: if (authenticated ||
372: attempt == AUTH_FAIL_LOG ||
373: type == SSH_CMSG_AUTH_PASSWORD)
374: authlog = log;
375:
376: authlog("%s %s for %.200s from %.200s port %d%s",
377: authenticated ? "Accepted" : "Failed",
378: get_authname(type),
379: pw->pw_uid == 0 ? "ROOT" : pw->pw_name,
380: get_remote_ipaddr(),
381: get_remote_port(),
382: user);
383:
384: if (authenticated)
385: return;
386:
387: if (attempt > AUTH_FAIL_MAX)
388: packet_disconnect(AUTH_FAIL_MSG, pw->pw_name);
389:
390: /* Send a message indicating that the authentication attempt failed. */
391: packet_start(SSH_SMSG_FAILURE);
392: packet_send();
393: packet_write_wait();
394: }
395: }
396:
397: /*
398: * Performs authentication of an incoming connection. Session key has already
399: * been exchanged and encryption is enabled.
400: */
401: void
402: do_authentication()
403: {
404: struct passwd *pw, pwcopy;
405: int plen;
406: unsigned int ulen;
407: char *user;
408:
409: /* Get the name of the user that we wish to log in as. */
410: packet_read_expect(&plen, SSH_CMSG_USER);
411:
412: /* Get the user name. */
413: user = packet_get_string(&ulen);
414: packet_integrity_check(plen, (4 + ulen), SSH_CMSG_USER);
415:
416: setproctitle("%s", user);
417:
418: #ifdef AFS
419: /* If machine has AFS, set process authentication group. */
420: if (k_hasafs()) {
421: k_setpag();
422: k_unlog();
423: }
424: #endif /* AFS */
425:
426: /* Verify that the user is a valid user. */
427: pw = getpwnam(user);
428: if (!pw || !allowed_user(pw))
429: do_fake_authloop1(user);
430: xfree(user);
431:
432: /* Take a copy of the returned structure. */
433: memset(&pwcopy, 0, sizeof(pwcopy));
434: pwcopy.pw_name = xstrdup(pw->pw_name);
435: pwcopy.pw_passwd = xstrdup(pw->pw_passwd);
436: pwcopy.pw_uid = pw->pw_uid;
437: pwcopy.pw_gid = pw->pw_gid;
1.3 millert 438: pwcopy.pw_class = xstrdup(pw->pw_class);
1.1 markus 439: pwcopy.pw_dir = xstrdup(pw->pw_dir);
440: pwcopy.pw_shell = xstrdup(pw->pw_shell);
441: pw = &pwcopy;
442:
443: /*
444: * If we are not running as root, the user must have the same uid as
445: * the server.
446: */
447: if (getuid() != 0 && pw->pw_uid != getuid())
448: packet_disconnect("Cannot change user when server not running as root.");
449:
450: debug("Attempting authentication for %.100s.", pw->pw_name);
451:
452: /* If the user has no password, accept authentication immediately. */
453: if (options.password_authentication &&
454: #ifdef KRB4
455: (!options.kerberos_authentication || options.kerberos_or_local_passwd) &&
456: #endif /* KRB4 */
457: auth_password(pw, "")) {
458: /* Authentication with empty password succeeded. */
459: log("Login for user %s from %.100s, accepted without authentication.",
460: pw->pw_name, get_remote_ipaddr());
461: } else {
462: /* Loop until the user has been authenticated or the
463: connection is closed, do_authloop() returns only if
464: authentication is successfull */
465: do_authloop(pw);
466: }
467:
468: /* The user has been authenticated and accepted. */
469: packet_start(SSH_SMSG_SUCCESS);
470: packet_send();
471: packet_write_wait();
472:
473: /* Perform session preparation. */
474: do_authenticated(pw);
475: }