Annotation of src/usr.bin/ssh/auth1.c, Revision 1.38
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.38 ! provos 13: RCSID("$OpenBSD: auth1.c,v 1.35 2002/02/03 17:53:25 markus Exp $");
1.1 markus 14:
15: #include "xmalloc.h"
16: #include "rsa.h"
1.12 markus 17: #include "ssh1.h"
1.1 markus 18: #include "packet.h"
19: #include "buffer.h"
20: #include "mpaux.h"
1.13 markus 21: #include "log.h"
1.1 markus 22: #include "servconf.h"
23: #include "compat.h"
24: #include "auth.h"
1.35 markus 25: #include "channels.h"
1.1 markus 26: #include "session.h"
1.18 markus 27: #include "misc.h"
1.25 dugsong 28: #include "uidswap.h"
1.38 ! provos 29: #include "monitor_wrap.h"
1.1 markus 30:
31: /* import */
32: extern ServerOptions options;
33:
34: /*
35: * convert ssh auth msg type into description
36: */
1.24 itojun 37: static char *
1.1 markus 38: get_authname(int type)
39: {
40: static char buf[1024];
41: switch (type) {
42: case SSH_CMSG_AUTH_PASSWORD:
43: return "password";
44: case SSH_CMSG_AUTH_RSA:
45: return "rsa";
46: case SSH_CMSG_AUTH_RHOSTS_RSA:
47: return "rhosts-rsa";
48: case SSH_CMSG_AUTH_RHOSTS:
49: return "rhosts";
1.11 markus 50: case SSH_CMSG_AUTH_TIS:
51: case SSH_CMSG_AUTH_TIS_RESPONSE:
52: return "challenge-response";
1.25 dugsong 53: #if defined(KRB4) || defined(KRB5)
1.1 markus 54: case SSH_CMSG_AUTH_KERBEROS:
55: return "kerberos";
56: #endif
57: }
58: snprintf(buf, sizeof buf, "bad-auth-msg-%d", type);
59: return buf;
60: }
61:
62: /*
1.11 markus 63: * read packets, try to authenticate the user and
64: * return only if authentication is successful
1.1 markus 65: */
1.24 itojun 66: static void
1.11 markus 67: do_authloop(Authctxt *authctxt)
1.1 markus 68: {
1.5 markus 69: int authenticated = 0;
1.8 markus 70: u_int bits;
1.29 markus 71: Key *client_host_key;
1.1 markus 72: BIGNUM *n;
73: char *client_user, *password;
1.11 markus 74: char info[1024];
1.8 markus 75: u_int dlen;
76: u_int ulen;
1.1 markus 77: int type = 0;
1.11 markus 78: struct passwd *pw = authctxt->pw;
79:
80: debug("Attempting authentication for %s%.100s.",
1.27 deraadt 81: authctxt->valid ? "" : "illegal user ", authctxt->user);
1.11 markus 82:
83: /* If the user has no password, accept authentication immediately. */
84: if (options.password_authentication &&
1.25 dugsong 85: #if defined(KRB4) || defined(KRB5)
1.11 markus 86: (!options.kerberos_authentication || options.kerberos_or_local_passwd) &&
87: #endif
1.38 ! provos 88: PRIVSEP(auth_password(authctxt, ""))) {
1.11 markus 89: auth_log(authctxt, 1, "without authentication", "");
90: return;
91: }
1.27 deraadt 92:
1.1 markus 93: /* Indicate that authentication is needed. */
94: packet_start(SSH_SMSG_FAILURE);
95: packet_send();
96: packet_write_wait();
97:
1.11 markus 98: for (;;) {
1.5 markus 99: /* default to fail */
100: authenticated = 0;
101:
1.11 markus 102: info[0] = '\0';
1.1 markus 103:
104: /* Get a packet from the client. */
1.34 markus 105: type = packet_read();
1.1 markus 106:
107: /* Process the packet. */
108: switch (type) {
109:
1.25 dugsong 110: #if defined(KRB4) || defined(KRB5)
1.1 markus 111: case SSH_CMSG_AUTH_KERBEROS:
112: if (!options.kerberos_authentication) {
113: verbose("Kerberos authentication disabled.");
114: } else {
1.25 dugsong 115: char *kdata = packet_get_string(&dlen);
1.32 markus 116: packet_check_eom();
1.27 deraadt 117:
1.25 dugsong 118: if (kdata[0] == 4) { /* KRB_PROT_VERSION */
119: #ifdef KRB4
120: KTEXT_ST tkt;
1.27 deraadt 121:
1.25 dugsong 122: tkt.length = dlen;
123: if (tkt.length < MAX_KTXT_LEN)
124: memcpy(tkt.dat, kdata, tkt.length);
1.27 deraadt 125:
1.25 dugsong 126: if (auth_krb4(authctxt, &tkt, &client_user)) {
127: authenticated = 1;
128: snprintf(info, sizeof(info),
129: " tktuser %.100s",
130: client_user);
131: xfree(client_user);
1.5 markus 132: }
1.25 dugsong 133: #endif /* KRB4 */
134: } else {
135: #ifdef KRB5
136: krb5_data tkt;
137: tkt.length = dlen;
138: tkt.data = kdata;
1.27 deraadt 139:
1.25 dugsong 140: if (auth_krb5(authctxt, &tkt, &client_user)) {
141: authenticated = 1;
142: snprintf(info, sizeof(info),
143: " tktuser %.100s",
144: client_user);
145: xfree(client_user);
146: }
147: #endif /* KRB5 */
1.1 markus 148: }
1.11 markus 149: xfree(kdata);
1.1 markus 150: }
151: break;
1.25 dugsong 152: #endif /* KRB4 || KRB5 */
1.27 deraadt 153:
1.25 dugsong 154: #if defined(AFS) || defined(KRB5)
155: /* XXX - punt on backward compatibility here. */
156: case SSH_CMSG_HAVE_KERBEROS_TGT:
157: packet_send_debug("Kerberos TGT passing disabled before authentication.");
158: break;
159: #ifdef AFS
160: case SSH_CMSG_HAVE_AFS_TOKEN:
161: packet_send_debug("AFS token passing disabled before authentication.");
162: break;
163: #endif /* AFS */
164: #endif /* AFS || KRB5 */
1.27 deraadt 165:
1.1 markus 166: case SSH_CMSG_AUTH_RHOSTS:
167: if (!options.rhosts_authentication) {
168: verbose("Rhosts authentication disabled.");
169: break;
170: }
171: /*
172: * Get client user name. Note that we just have to
173: * trust the client; this is one reason why rhosts
174: * authentication is insecure. (Another is
175: * IP-spoofing on a local network.)
176: */
177: client_user = packet_get_string(&ulen);
1.32 markus 178: packet_check_eom();
1.1 markus 179:
1.5 markus 180: /* Try to authenticate using /etc/hosts.equiv and .rhosts. */
1.1 markus 181: authenticated = auth_rhosts(pw, client_user);
182:
1.11 markus 183: snprintf(info, sizeof info, " ruser %.100s", client_user);
1.1 markus 184: xfree(client_user);
185: break;
186:
187: case SSH_CMSG_AUTH_RHOSTS_RSA:
188: if (!options.rhosts_rsa_authentication) {
189: verbose("Rhosts with RSA authentication disabled.");
190: break;
191: }
192: /*
193: * Get client user name. Note that we just have to
194: * trust the client; root on the client machine can
195: * claim to be any user.
196: */
197: client_user = packet_get_string(&ulen);
198:
199: /* Get the client host key. */
1.29 markus 200: client_host_key = key_new(KEY_RSA1);
1.1 markus 201: bits = packet_get_int();
1.33 markus 202: packet_get_bignum(client_host_key->rsa->e);
203: packet_get_bignum(client_host_key->rsa->n);
1.1 markus 204:
1.29 markus 205: if (bits != BN_num_bits(client_host_key->rsa->n))
1.5 markus 206: verbose("Warning: keysize mismatch for client_host_key: "
1.29 markus 207: "actual %d, announced %d",
208: BN_num_bits(client_host_key->rsa->n), bits);
1.32 markus 209: packet_check_eom();
1.1 markus 210:
1.29 markus 211: authenticated = auth_rhosts_rsa(pw, client_user,
1.30 markus 212: client_host_key);
1.29 markus 213: key_free(client_host_key);
1.1 markus 214:
1.11 markus 215: snprintf(info, sizeof info, " ruser %.100s", client_user);
1.1 markus 216: xfree(client_user);
217: break;
218:
219: case SSH_CMSG_AUTH_RSA:
220: if (!options.rsa_authentication) {
221: verbose("RSA authentication disabled.");
222: break;
223: }
224: /* RSA authentication requested. */
1.29 markus 225: if ((n = BN_new()) == NULL)
226: fatal("do_authloop: BN_new failed");
1.33 markus 227: packet_get_bignum(n);
1.32 markus 228: packet_check_eom();
1.1 markus 229: authenticated = auth_rsa(pw, n);
230: BN_clear_free(n);
231: break;
232:
233: case SSH_CMSG_AUTH_PASSWORD:
234: if (!options.password_authentication) {
235: verbose("Password authentication disabled.");
236: break;
237: }
238: /*
239: * Read user password. It is in plain text, but was
240: * transmitted over the encrypted channel so it is
241: * not visible to an outside observer.
242: */
243: password = packet_get_string(&dlen);
1.32 markus 244: packet_check_eom();
1.1 markus 245:
246: /* Try authentication with the password. */
1.38 ! provos 247: authenticated = PRIVSEP(auth_password(authctxt, password));
1.1 markus 248:
249: memset(password, 0, strlen(password));
250: xfree(password);
251: break;
252:
253: case SSH_CMSG_AUTH_TIS:
254: debug("rcvd SSH_CMSG_AUTH_TIS");
1.23 markus 255: if (options.challenge_response_authentication == 1) {
256: char *challenge = get_challenge(authctxt);
1.11 markus 257: if (challenge != NULL) {
258: debug("sending challenge '%s'", challenge);
1.1 markus 259: packet_start(SSH_SMSG_AUTH_TIS_CHALLENGE);
1.11 markus 260: packet_put_cstring(challenge);
1.23 markus 261: xfree(challenge);
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");
1.23 markus 270: if (options.challenge_response_authentication == 1) {
1.1 markus 271: char *response = packet_get_string(&dlen);
1.11 markus 272: debug("got response '%s'", response);
1.32 markus 273: packet_check_eom();
1.11 markus 274: authenticated = verify_response(authctxt, response);
275: memset(response, 'r', dlen);
1.1 markus 276: xfree(response);
277: }
278: break;
279:
280: default:
281: /*
282: * Any unknown messages will be ignored (and failure
283: * returned) during authentication.
284: */
285: log("Unknown message during authentication: type %d", type);
286: break;
287: }
1.20 markus 288: #ifdef BSD_AUTH
289: if (authctxt->as) {
290: auth_close(authctxt->as);
291: authctxt->as = NULL;
292: }
293: #endif
1.11 markus 294: if (!authctxt->valid && authenticated)
295: fatal("INTERNAL ERROR: authenticated invalid user %s",
296: authctxt->user);
297:
298: /* Special handling for root */
1.16 markus 299: if (authenticated && authctxt->pw->pw_uid == 0 &&
300: !auth_root_allowed(get_authname(type)))
1.11 markus 301: authenticated = 0;
1.1 markus 302:
1.11 markus 303: /* Log before sending the reply */
304: auth_log(authctxt, authenticated, get_authname(type), info);
1.1 markus 305:
306: if (authenticated)
307: return;
308:
1.11 markus 309: if (authctxt->failures++ > AUTH_FAIL_MAX)
310: packet_disconnect(AUTH_FAIL_MSG, authctxt->user);
1.1 markus 311:
312: packet_start(SSH_SMSG_FAILURE);
313: packet_send();
314: packet_write_wait();
315: }
316: }
317:
318: /*
319: * Performs authentication of an incoming connection. Session key has already
320: * been exchanged and encryption is enabled.
321: */
1.37 provos 322: Authctxt *
1.26 itojun 323: do_authentication(void)
1.1 markus 324: {
1.11 markus 325: Authctxt *authctxt;
1.38 ! provos 326: struct passwd *pw = NULL, *pwent;
1.8 markus 327: u_int ulen;
1.25 dugsong 328: char *p, *user, *style = NULL;
1.1 markus 329:
330: /* Get the name of the user that we wish to log in as. */
1.34 markus 331: packet_read_expect(SSH_CMSG_USER);
1.1 markus 332:
333: /* Get the user name. */
334: user = packet_get_string(&ulen);
1.32 markus 335: packet_check_eom();
1.1 markus 336:
1.11 markus 337: if ((style = strchr(user, ':')) != NULL)
1.25 dugsong 338: *style++ = '\0';
1.11 markus 339:
1.25 dugsong 340: /* XXX - SSH.com Kerberos v5 braindeath. */
341: if ((p = strchr(user, '@')) != NULL)
342: *p = '\0';
1.27 deraadt 343:
1.11 markus 344: authctxt = authctxt_new();
345: authctxt->user = user;
346: authctxt->style = style;
347:
1.1 markus 348: /* Verify that the user is a valid user. */
1.38 ! provos 349: pwent = PRIVSEP(getpwnamallow(user));
! 350: if (pwent) {
1.11 markus 351: authctxt->valid = 1;
1.38 ! provos 352: pw = pwcopy(pwent);
1.5 markus 353: } else {
1.11 markus 354: debug("do_authentication: illegal user %s", user);
1.5 markus 355: pw = NULL;
356: }
1.38 ! provos 357: /* Free memory */
! 358: if (use_privsep && pwent != NULL)
! 359: pwfree(pwent);
! 360:
1.11 markus 361: authctxt->pw = pw;
1.17 markus 362:
1.38 ! provos 363: setproctitle("%s%s", pw ? user : "unknown",
! 364: use_privsep ? " [net]" : "");
1.1 markus 365:
366: /*
367: * If we are not running as root, the user must have the same uid as
368: * the server.
369: */
1.38 ! provos 370: if (!use_privsep && getuid() != 0 && pw && pw->pw_uid != getuid())
1.1 markus 371: packet_disconnect("Cannot change user when server not running as root.");
372:
1.11 markus 373: /*
374: * Loop until the user has been authenticated or the connection is
375: * closed, do_authloop() returns only if authentication is successful
376: */
377: do_authloop(authctxt);
1.1 markus 378:
379: /* The user has been authenticated and accepted. */
380: packet_start(SSH_SMSG_SUCCESS);
381: packet_send();
382: packet_write_wait();
383:
1.37 provos 384: return (authctxt);
1.1 markus 385: }