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