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