auth-rh-rsa.c revision 65674
1/* 2 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * All rights reserved 5 * Rhosts or /etc/hosts.equiv authentication combined with RSA host 6 * authentication. 7 * 8 * As far as I am concerned, the code I have written for this software 9 * can be used freely for any purpose. Any derived versions of this 10 * software must be clearly marked as such, and if the derived work is 11 * incompatible with the protocol description in the RFC file, it must be 12 * called by a name other than "ssh" or "Secure Shell". 13 */ 14 15#include "includes.h" 16RCSID("$OpenBSD: auth-rh-rsa.c,v 1.16 2000/09/07 21:13:36 markus Exp $"); 17RCSID("$FreeBSD: head/crypto/openssh/auth-rh-rsa.c 65674 2000-09-10 09:35:38Z kris $"); 18 19#include "packet.h" 20#include "ssh.h" 21#include "xmalloc.h" 22#include "uidswap.h" 23#include "servconf.h" 24 25#include <openssl/rsa.h> 26#include <openssl/dsa.h> 27#include "key.h" 28#include "hostfile.h" 29 30/* 31 * Tries to authenticate the user using the .rhosts file and the host using 32 * its host key. Returns true if authentication succeeds. 33 */ 34 35int 36auth_rhosts_rsa(struct passwd *pw, const char *client_user, RSA *client_host_key) 37{ 38 extern ServerOptions options; 39 const char *canonical_hostname; 40 HostStatus host_status; 41 Key *client_key, *found; 42 43 debug("Trying rhosts with RSA host authentication for %.100s", client_user); 44 45 if (client_host_key == NULL) 46 return 0; 47 48 /* Check if we would accept it using rhosts authentication. */ 49 if (!auth_rhosts(pw, client_user)) 50 return 0; 51 52 canonical_hostname = get_canonical_hostname(); 53 54 debug("Rhosts RSA authentication: canonical host %.900s", canonical_hostname); 55 56 /* wrap the RSA key into a 'generic' key */ 57 client_key = key_new(KEY_RSA); 58 BN_copy(client_key->rsa->e, client_host_key->e); 59 BN_copy(client_key->rsa->n, client_host_key->n); 60 found = key_new(KEY_RSA); 61 62 /* Check if we know the host and its host key. */ 63 host_status = check_host_in_hostfile(SSH_SYSTEM_HOSTFILE, canonical_hostname, 64 client_key, found); 65 66 /* Check user host file unless ignored. */ 67 if (host_status != HOST_OK && !options.ignore_user_known_hosts) { 68 struct stat st; 69 char *user_hostfile = tilde_expand_filename(SSH_USER_HOSTFILE, pw->pw_uid); 70 /* 71 * Check file permissions of SSH_USER_HOSTFILE, auth_rsa() 72 * did already check pw->pw_dir, but there is a race XXX 73 */ 74 if (options.strict_modes && 75 (stat(user_hostfile, &st) == 0) && 76 ((st.st_uid != 0 && st.st_uid != pw->pw_uid) || 77 (st.st_mode & 022) != 0)) { 78 log("Rhosts RSA authentication refused for %.100s: bad owner or modes for %.200s", 79 pw->pw_name, user_hostfile); 80 } else { 81 /* XXX race between stat and the following open() */ 82 temporarily_use_uid(pw->pw_uid); 83 host_status = check_host_in_hostfile(user_hostfile, canonical_hostname, 84 client_key, found); 85 restore_uid(); 86 } 87 xfree(user_hostfile); 88 } 89 key_free(client_key); 90 key_free(found); 91 92 if (host_status != HOST_OK) { 93 debug("Rhosts with RSA host authentication denied: unknown or invalid host key"); 94 packet_send_debug("Your host key cannot be verified: unknown or invalid host key."); 95 return 0; 96 } 97 /* A matching host key was found and is known. */ 98 99 /* Perform the challenge-response dialog with the client for the host key. */ 100 if (!auth_rsa_challenge_dialog(client_host_key)) { 101 log("Client on %.800s failed to respond correctly to host authentication.", 102 canonical_hostname); 103 return 0; 104 } 105 /* 106 * We have authenticated the user using .rhosts or /etc/hosts.equiv, 107 * and the host using RSA. We accept the authentication. 108 */ 109 110 verbose("Rhosts with RSA host authentication accepted for %.100s, %.100s on %.700s.", 111 pw->pw_name, client_user, canonical_hostname); 112 packet_send_debug("Rhosts with RSA host authentication accepted."); 113 return 1; 114} 115