2 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
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".
13 RCSID("$OpenBSD: auth1.c,v 1.4 2000/09/07 20:27:49 deraadt Exp $");
33 extern ServerOptions options;
34 extern char *forced_command;
36 extern int saved_argc;
37 extern char **saved_argv;
38 #endif /* HAVE_OSF_SIA */
41 * convert ssh auth msg type into description
44 get_authname(int type)
46 static char buf[1024];
48 case SSH_CMSG_AUTH_PASSWORD:
50 case SSH_CMSG_AUTH_RSA:
52 case SSH_CMSG_AUTH_RHOSTS_RSA:
54 case SSH_CMSG_AUTH_RHOSTS:
57 case SSH_CMSG_AUTH_KERBEROS:
61 case SSH_CMSG_AUTH_TIS_RESPONSE:
65 snprintf(buf, sizeof buf, "bad-auth-msg-%d", type);
70 * The user does not exist or access is denied,
71 * but fake indication that authentication is needed.
74 do_fake_authloop1(char *user)
78 log("Faking authloop for illegal user %.200s from %.200s port %d",
83 #ifdef WITH_AIXAUTHENTICATE
84 loginfailed(user,get_canonical_hostname(),"ssh");
85 #endif /* WITH_AIXAUTHENTICATE */
87 /* Indicate that authentication is needed. */
88 packet_start(SSH_SMSG_FAILURE);
93 * Keep reading packets, and always respond with a failure. This is
94 * to avoid disclosing whether such a user really exists.
96 for (attempt = 1;; attempt++) {
97 /* Read a packet. This will not return if the client disconnects. */
100 (void)packet_read(&plen);
102 int type = packet_read(&plen);
104 char *password, *skeyinfo;
106 /* Try to send a fake s/key challenge. */
107 if (options.skey_authentication == 1 &&
108 (skeyinfo = skey_fake_keyinfo(user)) != NULL) {
109 if (type == SSH_CMSG_AUTH_TIS) {
110 packet_start(SSH_SMSG_AUTH_TIS_CHALLENGE);
111 packet_put_string(skeyinfo, strlen(skeyinfo));
115 } else if (type == SSH_CMSG_AUTH_PASSWORD &&
116 options.password_authentication &&
117 (password = packet_get_string(&dlen)) != NULL &&
119 strncasecmp(password, "s/key", 5) == 0 ) {
120 packet_send_debug(skeyinfo);
123 if (password != NULL)
126 if (attempt > AUTH_FAIL_MAX)
127 packet_disconnect(AUTH_FAIL_MSG, user);
130 * Send failure. This should be indistinguishable from a
131 * failed authentication.
133 packet_start(SSH_SMSG_FAILURE);
142 * read packets and try to authenticate local user *pw.
143 * return if authentication is successfull
146 do_authloop(struct passwd * pw)
150 RSA *client_host_key;
152 char *client_user = NULL, *password = NULL;
155 int plen, nlen, elen;
158 void (*authlog) (const char *fmt,...) = verbose;
160 /* Indicate that authentication is needed. */
161 packet_start(SSH_SMSG_FAILURE);
165 for (attempt = 1;; attempt++) {
166 int authenticated = 0;
167 strlcpy(user, "", sizeof user);
169 /* Get a packet from the client. */
170 type = packet_read(&plen);
172 /* Process the packet. */
175 case SSH_CMSG_HAVE_KERBEROS_TGT:
176 if (!options.kerberos_tgt_passing) {
177 /* packet_get_all(); */
178 verbose("Kerberos tgt passing disabled.");
181 /* Accept Kerberos tgt. */
182 char *tgt = packet_get_string(&dlen);
183 packet_integrity_check(plen, 4 + dlen, type);
184 if (!auth_kerberos_tgt(pw, tgt))
185 verbose("Kerberos tgt REFUSED for %s", pw->pw_name);
190 case SSH_CMSG_HAVE_AFS_TOKEN:
191 if (!options.afs_token_passing || !k_hasafs()) {
192 /* packet_get_all(); */
193 verbose("AFS token passing disabled.");
196 /* Accept AFS token. */
197 char *token_string = packet_get_string(&dlen);
198 packet_integrity_check(plen, 4 + dlen, type);
199 if (!auth_afs_token(pw, token_string))
200 verbose("AFS token REFUSED for %s", pw->pw_name);
206 case SSH_CMSG_AUTH_KERBEROS:
207 if (!options.kerberos_authentication) {
208 /* packet_get_all(); */
209 verbose("Kerberos authentication disabled.");
212 /* Try Kerberos v4 authentication. */
214 char *tkt_user = NULL;
215 char *kdata = packet_get_string((unsigned int *) &auth.length);
216 packet_integrity_check(plen, 4 + auth.length, type);
218 if (auth.length < MAX_KTXT_LEN)
219 memcpy(auth.dat, kdata, auth.length);
222 authenticated = auth_krb4(pw->pw_name, &auth, &tkt_user);
225 snprintf(user, sizeof user, " tktuser %s", tkt_user);
232 case SSH_CMSG_AUTH_RHOSTS:
233 if (!options.rhosts_authentication) {
234 verbose("Rhosts authentication disabled.");
238 * Get client user name. Note that we just have to
239 * trust the client; this is one reason why rhosts
240 * authentication is insecure. (Another is
241 * IP-spoofing on a local network.)
243 client_user = packet_get_string(&ulen);
244 packet_integrity_check(plen, 4 + ulen, type);
246 /* Try to authenticate using /etc/hosts.equiv and
248 authenticated = auth_rhosts(pw, client_user);
250 snprintf(user, sizeof user, " ruser %s", client_user);
253 case SSH_CMSG_AUTH_RHOSTS_RSA:
254 if (!options.rhosts_rsa_authentication) {
255 verbose("Rhosts with RSA authentication disabled.");
259 * Get client user name. Note that we just have to
260 * trust the client; root on the client machine can
261 * claim to be any user.
263 client_user = packet_get_string(&ulen);
265 /* Get the client host key. */
266 client_host_key = RSA_new();
267 if (client_host_key == NULL)
268 fatal("RSA_new failed");
269 client_host_key->e = BN_new();
270 client_host_key->n = BN_new();
271 if (client_host_key->e == NULL || client_host_key->n == NULL)
272 fatal("BN_new failed");
273 bits = packet_get_int();
274 packet_get_bignum(client_host_key->e, &elen);
275 packet_get_bignum(client_host_key->n, &nlen);
277 if (bits != BN_num_bits(client_host_key->n))
278 log("Warning: keysize mismatch for client_host_key: "
279 "actual %d, announced %d", BN_num_bits(client_host_key->n), bits);
280 packet_integrity_check(plen, (4 + ulen) + 4 + elen + nlen, type);
282 authenticated = auth_rhosts_rsa(pw, client_user, client_host_key);
283 RSA_free(client_host_key);
285 snprintf(user, sizeof user, " ruser %s", client_user);
288 case SSH_CMSG_AUTH_RSA:
289 if (!options.rsa_authentication) {
290 verbose("RSA authentication disabled.");
293 /* RSA authentication requested. */
295 packet_get_bignum(n, &nlen);
296 packet_integrity_check(plen, nlen, type);
297 authenticated = auth_rsa(pw, n);
301 case SSH_CMSG_AUTH_PASSWORD:
302 if (!options.password_authentication) {
303 verbose("Password authentication disabled.");
307 * Read user password. It is in plain text, but was
308 * transmitted over the encrypted channel so it is
309 * not visible to an outside observer.
311 password = packet_get_string(&dlen);
312 packet_integrity_check(plen, 4 + dlen, type);
315 /* Do PAM auth with password */
316 authenticated = auth_pam_password(pw, password);
317 #elif defined(HAVE_OSF_SIA)
318 /* Do SIA auth with password */
319 if (sia_validate_user(NULL, saved_argc, saved_argv,
320 get_canonical_hostname(), pw->pw_name, NULL, 0,
321 NULL, password) == SIASUCCESS) {
324 #else /* !USE_PAM && !HAVE_OSF_SIA */
325 /* Try authentication with the password. */
326 authenticated = auth_password(pw, password);
329 memset(password, 0, strlen(password));
334 case SSH_CMSG_AUTH_TIS:
335 debug("rcvd SSH_CMSG_AUTH_TIS");
336 if (options.skey_authentication == 1) {
337 char *skeyinfo = skey_keyinfo(pw->pw_name);
338 if (skeyinfo == NULL) {
339 debug("generating fake skeyinfo for %.100s.", pw->pw_name);
340 skeyinfo = skey_fake_keyinfo(pw->pw_name);
342 if (skeyinfo != NULL) {
343 /* we send our s/key- in tis-challenge messages */
344 debug("sending challenge '%s'", skeyinfo);
345 packet_start(SSH_SMSG_AUTH_TIS_CHALLENGE);
346 packet_put_string(skeyinfo, strlen(skeyinfo));
353 case SSH_CMSG_AUTH_TIS_RESPONSE:
354 debug("rcvd SSH_CMSG_AUTH_TIS_RESPONSE");
355 if (options.skey_authentication == 1) {
356 char *response = packet_get_string(&dlen);
357 debug("skey response == '%s'", response);
358 packet_integrity_check(plen, 4 + dlen, type);
359 authenticated = (skey_haskey(pw->pw_name) == 0 &&
360 skey_passcheck(pw->pw_name, response) != -1);
365 case SSH_CMSG_AUTH_TIS:
366 /* TIS Authentication is unsupported */
367 log("TIS authentication unsupported.");
373 * Any unknown messages will be ignored (and failure
374 * returned) during authentication.
376 log("Unknown message during authentication: type %d", type);
382 !check_nt_auth(type == SSH_CMSG_AUTH_PASSWORD,pw->pw_uid)) {
383 packet_disconnect("Authentication rejected for uid %d.",
390 * Check if the user is logging in as root and root logins
392 * Note that root login is allowed for forced commands.
394 if (authenticated && pw->pw_uid == 0 && !options.permit_root_login) {
395 if (forced_command) {
396 log("Root login accepted for forced command.");
399 log("ROOT LOGIN REFUSED FROM %.200s",
400 get_canonical_hostname());
404 /* Raise logging level */
406 attempt == AUTH_FAIL_LOG ||
407 type == SSH_CMSG_AUTH_PASSWORD)
410 authlog("%s %s for %.200s from %.200s port %d%s",
411 authenticated ? "Accepted" : "Failed",
413 pw->pw_uid == 0 ? "ROOT" : pw->pw_name,
420 if (!do_pam_account(pw->pw_name, client_user)) {
421 if (client_user != NULL) {
425 do_fake_authloop1(pw->pw_name);
435 if (client_user != NULL) {
440 if (attempt > AUTH_FAIL_MAX) {
441 #ifdef WITH_AIXAUTHENTICATE
442 loginfailed(pw->pw_name,get_canonical_hostname(),"ssh");
443 #endif /* WITH_AIXAUTHENTICATE */
444 packet_disconnect(AUTH_FAIL_MSG, pw->pw_name);
447 /* Send a message indicating that the authentication attempt failed. */
448 packet_start(SSH_SMSG_FAILURE);
455 * Performs authentication of an incoming connection. Session key has already
456 * been exchanged and encryption is enabled.
461 struct passwd *pw, pwcopy;
465 #ifdef WITH_AIXAUTHENTICATE
466 extern char *aixloginmsg;
467 #endif /* WITH_AIXAUTHENTICATE */
469 /* Get the name of the user that we wish to log in as. */
470 packet_read_expect(&plen, SSH_CMSG_USER);
472 /* Get the user name. */
473 user = packet_get_string(&ulen);
474 packet_integrity_check(plen, (4 + ulen), SSH_CMSG_USER);
476 setproctitle("%s", user);
479 /* If machine has AFS, set process authentication group. */
486 /* Verify that the user is a valid user. */
488 if (!pw || !allowed_user(pw))
489 do_fake_authloop1(user);
492 /* Take a copy of the returned structure. */
493 memset(&pwcopy, 0, sizeof(pwcopy));
494 pwcopy.pw_name = xstrdup(pw->pw_name);
495 pwcopy.pw_passwd = xstrdup(pw->pw_passwd);
496 pwcopy.pw_uid = pw->pw_uid;
497 pwcopy.pw_gid = pw->pw_gid;
498 #ifdef HAVE_PW_CLASS_IN_PASSWD
499 pwcopy.pw_class = xstrdup(pw->pw_class);
501 pwcopy.pw_dir = xstrdup(pw->pw_dir);
502 pwcopy.pw_shell = xstrdup(pw->pw_shell);
511 * If we are not running as root, the user must have the same uid as
513 * Rule not valid on Windows systems.
515 if (getuid() != 0 && pw->pw_uid != getuid())
516 packet_disconnect("Cannot change user when server not running as root.");
519 debug("Attempting authentication for %.100s.", pw->pw_name);
521 /* If the user has no password, accept authentication immediately. */
522 if (options.password_authentication &&
524 (!options.kerberos_authentication || options.kerberos_or_local_passwd) &&
527 auth_pam_password(pw, "")) {
528 #elif defined(HAVE_OSF_SIA)
529 (sia_validate_user(NULL, saved_argc, saved_argv,
530 get_canonical_hostname(), pw->pw_name, NULL, 0, NULL,
531 "") == SIASUCCESS)) {
532 #else /* !HAVE_OSF_SIA && !USE_PAM */
533 auth_password(pw, "")) {
535 /* Authentication with empty password succeeded. */
536 log("Login for user %s from %.100s, accepted without authentication.",
537 pw->pw_name, get_remote_ipaddr());
539 /* Loop until the user has been authenticated or the
540 connection is closed, do_authloop() returns only if
541 authentication is successfull */
545 /* The user has been authenticated and accepted. */
546 #ifdef WITH_AIXAUTHENTICATE
547 /* We don't have a pty yet, so just label the line as "ssh" */
548 if (loginsuccess(user,get_canonical_hostname(),"ssh",&aixloginmsg) < 0)
550 #endif /* WITH_AIXAUTHENTICATE */
551 packet_start(SSH_SMSG_SUCCESS);
555 /* Perform session preparation. */
556 do_authenticated(pw);