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