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