auth-rh-rsa.c revision 63249
153642Sguido/*
2255332Scy *
353642Sguido * auth-rh-rsa.c
480482Sdarrenr *
553642Sguido * Author: Tatu Ylonen <ylo@cs.hut.fi>
653642Sguido *
757126Sguido * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
8172776Sdarrenr *                    All rights reserved
953642Sguido *
1053642Sguido * Created: Sun May  7 03:08:06 1995 ylo
1153642Sguido *
1253642Sguido * Rhosts or /etc/hosts.equiv authentication combined with RSA host
1353642Sguido * authentication.
14145562Sdarrenr *
15255332Scy * $FreeBSD: head/crypto/openssh/auth-rh-rsa.c 60576 2000-05-15 05:24:25Z kris $
16255332Scy */
17255332Scy
18255332Scy#include "includes.h"
19255332ScyRCSID("$Id: auth-rh-rsa.c,v 1.13 2000/04/14 10:30:29 markus Exp $");
20255332Scy
21255332Scy#include "packet.h"
22255332Scy#include "ssh.h"
23255332Scy#include "xmalloc.h"
24255332Scy#include "uidswap.h"
25255332Scy#include "servconf.h"
26145562Sdarrenr
27255332Scy#include <openssl/rsa.h>
28255332Scy#include <openssl/dsa.h>
29255332Scy#include "key.h"
30255332Scy#include "hostfile.h"
3153642Sguido
3253642Sguido/*
3353642Sguido * Tries to authenticate the user using the .rhosts file and the host using
3453642Sguido * its host key.  Returns true if authentication succeeds.
3553642Sguido */
3653642Sguido
3753642Sguidoint
3853642Sguidoauth_rhosts_rsa(struct passwd *pw, const char *client_user, RSA *client_host_key)
3953642Sguido{
4053642Sguido	extern ServerOptions options;
4153642Sguido	const char *canonical_hostname;
4253642Sguido	HostStatus host_status;
43153876Sguido	Key *client_key, *found;
44145522Sdarrenr
45145522Sdarrenr	debug("Trying rhosts with RSA host authentication for %.100s", client_user);
4653642Sguido
4753642Sguido	if (client_host_key == NULL)
48145522Sdarrenr		return 0;
4953642Sguido
5053642Sguido	/* Check if we would accept it using rhosts authentication. */
51145522Sdarrenr	if (!auth_rhosts(pw, client_user))
52145522Sdarrenr		return 0;
5353642Sguido
54145522Sdarrenr	canonical_hostname = get_canonical_hostname();
55145522Sdarrenr
5653642Sguido	debug("Rhosts RSA authentication: canonical host %.900s", canonical_hostname);
5753642Sguido
58145522Sdarrenr	/* wrap the RSA key into a 'generic' key */
59145522Sdarrenr	client_key = key_new(KEY_RSA);
60145522Sdarrenr	BN_copy(client_key->rsa->e, client_host_key->e);
61145522Sdarrenr	BN_copy(client_key->rsa->n, client_host_key->n);
62170268Sdarrenr	found = key_new(KEY_RSA);
6360851Sdarrenr
64145522Sdarrenr	/* Check if we know the host and its host key. */
65145522Sdarrenr	host_status = check_host_in_hostfile(SSH_SYSTEM_HOSTFILE, canonical_hostname,
66145522Sdarrenr	    client_key, found);
67170268Sdarrenr
68145522Sdarrenr	/* Check user host file unless ignored. */
69145522Sdarrenr	if (host_status != HOST_OK && !options.ignore_user_known_hosts) {
70145522Sdarrenr		struct stat st;
71145522Sdarrenr		char *user_hostfile = tilde_expand_filename(SSH_USER_HOSTFILE, pw->pw_uid);
72145522Sdarrenr		/*
73145522Sdarrenr		 * Check file permissions of SSH_USER_HOSTFILE, auth_rsa()
74145522Sdarrenr		 * did already check pw->pw_dir, but there is a race XXX
75170268Sdarrenr		 */
76170268Sdarrenr		if (options.strict_modes &&
77170268Sdarrenr		    (stat(user_hostfile, &st) == 0) &&
78170268Sdarrenr		    ((st.st_uid != 0 && st.st_uid != pw->pw_uid) ||
79170268Sdarrenr		     (st.st_mode & 022) != 0)) {
80170268Sdarrenr			log("Rhosts RSA authentication refused for %.100s: bad owner or modes for %.200s",
81255332Scy			    pw->pw_name, user_hostfile);
82255332Scy		} else {
8353642Sguido			/* XXX race between stat and the following open() */
84145522Sdarrenr			temporarily_use_uid(pw->pw_uid);
85145522Sdarrenr			host_status = check_host_in_hostfile(user_hostfile, canonical_hostname,
8653642Sguido			    client_key, found);
8753642Sguido			restore_uid();
88145522Sdarrenr		}
8953642Sguido		xfree(user_hostfile);
9053642Sguido	}
91145522Sdarrenr	key_free(client_key);
92145522Sdarrenr	key_free(found);
9353642Sguido
94145522Sdarrenr	if (host_status != HOST_OK) {
95145522Sdarrenr		debug("Rhosts with RSA host authentication denied: unknown or invalid host key");
9653642Sguido		packet_send_debug("Your host key cannot be verified: unknown or invalid host key.");
9753642Sguido		return 0;
98145522Sdarrenr	}
99145522Sdarrenr	/* A matching host key was found and is known. */
100145522Sdarrenr
101145522Sdarrenr	/* Perform the challenge-response dialog with the client for the host key. */
102170268Sdarrenr	if (!auth_rsa_challenge_dialog(client_host_key)) {
10360851Sdarrenr		log("Client on %.800s failed to respond correctly to host authentication.",
104145522Sdarrenr		    canonical_hostname);
105145522Sdarrenr		return 0;
106145522Sdarrenr	}
107170268Sdarrenr	/*
108145522Sdarrenr	 * We have authenticated the user using .rhosts or /etc/hosts.equiv,
109145522Sdarrenr	 * and the host using RSA. We accept the authentication.
110145522Sdarrenr	 */
111145522Sdarrenr
112145522Sdarrenr	verbose("Rhosts with RSA host authentication accepted for %.100s, %.100s on %.700s.",
113145522Sdarrenr	   pw->pw_name, client_user, canonical_hostname);
114145522Sdarrenr	packet_send_debug("Rhosts with RSA host authentication accepted.");
115170268Sdarrenr	return 1;
116170268Sdarrenr}
117170268Sdarrenr