summaryrefslogtreecommitdiff
path: root/usr.bin
diff options
context:
space:
mode:
Diffstat (limited to 'usr.bin')
-rw-r--r--usr.bin/ssh/auth-rh-rsa.c27
-rw-r--r--usr.bin/ssh/hostfile.c14
-rw-r--r--usr.bin/ssh/readconf.c10
-rw-r--r--usr.bin/ssh/readconf.h3
-rw-r--r--usr.bin/ssh/ssh.111
-rw-r--r--usr.bin/ssh/ssh.c9
-rw-r--r--usr.bin/ssh/ssh.h15
-rw-r--r--usr.bin/ssh/sshconnect.c217
8 files changed, 200 insertions, 106 deletions
diff --git a/usr.bin/ssh/auth-rh-rsa.c b/usr.bin/ssh/auth-rh-rsa.c
index bcb43126488..5f3edfab75b 100644
--- a/usr.bin/ssh/auth-rh-rsa.c
+++ b/usr.bin/ssh/auth-rh-rsa.c
@@ -15,7 +15,7 @@ authentication.
*/
#include "includes.h"
-RCSID("$Id: auth-rh-rsa.c,v 1.1 1999/09/28 04:45:35 provos Exp $");
+RCSID("$Id: auth-rh-rsa.c,v 1.2 1999/10/03 21:50:03 provos Exp $");
#include "packet.h"
#include "ssh.h"
@@ -32,6 +32,8 @@ int auth_rhosts_rsa(struct passwd *pw, const char *client_user,
int ignore_rhosts, int strict_modes)
{
const char *canonical_hostname;
+ HostStatus host_status;
+ BIGNUM *ke, *kn;
debug("Trying rhosts with RSA host authentication for %.100s", client_user);
@@ -46,15 +48,20 @@ int auth_rhosts_rsa(struct passwd *pw, const char *client_user,
/* Check if we know the host and its host key. */
/* Check system-wide host file. */
- if (check_host_in_hostfile(SSH_SYSTEM_HOSTFILE, canonical_hostname,
- client_host_key_bits, client_host_key_e,
- client_host_key_n) != HOST_OK)
- {
- /* The host key was not found. */
- debug("Rhosts with RSA host authentication denied: unknown or invalid host key");
- packet_send_debug("Your host key cannot be verified: unknown or invalid host key.");
- return 0;
- }
+ ke = BN_new();
+ kn = BN_new();
+ host_status = check_host_in_hostfile(SSH_SYSTEM_HOSTFILE, canonical_hostname,
+ client_host_key_bits, client_host_key_e,
+ client_host_key_n, ke, kn);
+ BN_free(ke);
+ BN_free(kn);
+ if (host_status != HOST_OK) {
+ /* The host key was not found. */
+ debug("Rhosts with RSA host authentication denied: unknown or invalid host key");
+ packet_send_debug("Your host key cannot be verified: unknown or invalid host key.");
+ return 0;
+ }
+
/* A matching host key was found and is known. */
/* Perform the challenge-response dialog with the client for the host key. */
diff --git a/usr.bin/ssh/hostfile.c b/usr.bin/ssh/hostfile.c
index 9b36e39e828..6982899dec6 100644
--- a/usr.bin/ssh/hostfile.c
+++ b/usr.bin/ssh/hostfile.c
@@ -14,7 +14,7 @@ Functions for manipulating the known hosts files.
*/
#include "includes.h"
-RCSID("$Id: hostfile.c,v 1.2 1999/09/28 04:45:36 provos Exp $");
+RCSID("$Id: hostfile.c,v 1.3 1999/10/03 21:50:03 provos Exp $");
#include "packet.h"
#include "ssh.h"
@@ -168,7 +168,8 @@ match_hostname(const char *host, const char *pattern, unsigned int len)
HostStatus
check_host_in_hostfile(const char *filename,
const char *host, unsigned int bits,
- BIGNUM *e, BIGNUM *n)
+ BIGNUM *e, BIGNUM *n,
+ BIGNUM *ke, BIGNUM *kn)
{
FILE *f;
char line[8192];
@@ -176,7 +177,6 @@ check_host_in_hostfile(const char *filename,
char *cp, *cp2;
HostStatus end_return;
struct stat st;
- BIGNUM *ke, *kn;
/* Open the file containing the list of known hosts. */
f = fopen(filename, "r");
@@ -190,10 +190,6 @@ check_host_in_hostfile(const char *filename,
return HOST_NEW;
}
- /* Initialize mp-int variables. */
- ke = BN_new();
- kn = BN_new();
-
/* Cache the length of the host name. */
hostlen = strlen(host);
@@ -235,8 +231,6 @@ check_host_in_hostfile(const char *filename,
if (kbits == bits && BN_cmp(ke, e) == 0 && BN_cmp(kn, n) == 0)
{
/* Ok, they match. */
- BN_clear_free(ke);
- BN_clear_free(kn);
fclose(f);
return HOST_OK;
}
@@ -246,8 +240,6 @@ check_host_in_hostfile(const char *filename,
end_return = HOST_CHANGED;
}
/* Clear variables and close the file. */
- BN_clear_free(ke);
- BN_clear_free(kn);
fclose(f);
/* Return either HOST_NEW or HOST_CHANGED, depending on whether we saw a
diff --git a/usr.bin/ssh/readconf.c b/usr.bin/ssh/readconf.c
index 91cd876705f..3b98588c87f 100644
--- a/usr.bin/ssh/readconf.c
+++ b/usr.bin/ssh/readconf.c
@@ -14,7 +14,7 @@ Functions for reading the configuration files.
*/
#include "includes.h"
-RCSID("$Id: readconf.c,v 1.7 1999/09/30 08:03:39 deraadt Exp $");
+RCSID("$Id: readconf.c,v 1.8 1999/10/03 21:50:03 provos Exp $");
#include "ssh.h"
#include "cipher.h"
@@ -99,8 +99,8 @@ typedef enum
oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
oUser, oHost, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,
oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
- oBatchMode, oStrictHostKeyChecking, oCompression, oCompressionLevel,
- oKeepAlives, oTISAuthentication
+ oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
+ oCompressionLevel, oKeepAlives, oTISAuthentication
} OpCodes;
/* Textual representations of the tokens. */
@@ -141,6 +141,7 @@ static struct
{ "userknownhostsfile", oUserKnownHostsFile },
{ "connectionattempts", oConnectionAttempts },
{ "batchmode", oBatchMode },
+ { "checkhostip", oCheckHostIP },
{ "stricthostkeychecking", oStrictHostKeyChecking },
{ "compression", oCompression },
{ "compressionlevel", oCompressionLevel },
@@ -572,6 +573,7 @@ void initialize_options(Options *options)
options->fallback_to_rsh = -1;
options->use_rsh = -1;
options->batch_mode = -1;
+ options->check_host_ip = -1;
options->strict_host_key_checking = -1;
options->compression = -1;
options->keepalives = -1;
@@ -625,6 +627,8 @@ void fill_default_options(Options *options)
options->use_rsh = 0;
if (options->batch_mode == -1)
options->batch_mode = 0;
+ if (options->check_host_ip == -1)
+ options->check_host_ip = 1;
if (options->strict_host_key_checking == -1)
options->strict_host_key_checking = 2; /* 2 is default */
if (options->compression == -1)
diff --git a/usr.bin/ssh/readconf.h b/usr.bin/ssh/readconf.h
index 61e1ecf09a1..f0cff751511 100644
--- a/usr.bin/ssh/readconf.h
+++ b/usr.bin/ssh/readconf.h
@@ -13,7 +13,7 @@ Functions for reading the configuration file.
*/
-/* RCSID("$Id: readconf.h,v 1.4 1999/09/30 05:03:05 deraadt Exp $"); */
+/* RCSID("$Id: readconf.h,v 1.5 1999/10/03 21:50:03 provos Exp $"); */
#ifndef READCONF_H
#define READCONF_H
@@ -48,6 +48,7 @@ typedef struct
int fallback_to_rsh; /* Use rsh if cannot connect with ssh. */
int use_rsh; /* Always use rsh (don\'t try ssh). */
int batch_mode; /* Batch mode: do not ask for passwords. */
+ int check_host_ip; /* Also keep track of keys for IP address */
int strict_host_key_checking; /* Strict host key checking. */
int compression; /* Compress packets in both directions. */
int compression_level; /* Compression level 1 (fast) to 9 (best). */
diff --git a/usr.bin/ssh/ssh.1 b/usr.bin/ssh/ssh.1
index 064d1ed344f..ffff1050c82 100644
--- a/usr.bin/ssh/ssh.1
+++ b/usr.bin/ssh/ssh.1
@@ -9,7 +9,7 @@
.\"
.\" Created: Sat Apr 22 21:55:14 1995 ylo
.\"
-.\" $Id: ssh.1,v 1.12 1999/10/03 18:46:12 aaron Exp $
+.\" $Id: ssh.1,v 1.13 1999/10/03 21:50:04 provos Exp $
.\"
.Dd September 25, 1999
.Dt SSH 1
@@ -640,6 +640,15 @@ or
RSA authentication will only be
attempted if the identity file exists, or an authentication agent is
running.
+.It Cm CheckHostIP
+If this flag is set to
+.Dq yes ,
+ssh will additionally check the host ip address in the
+.Pa known_hosts
+file. This allows ssh to detect if a host key changed due to DNS spoofing.
+If the option is set to
+.Dq no ,
+the check will not be executed.
.It Cm StrictHostKeyChecking
If this flag is set to
.Dq yes ,
diff --git a/usr.bin/ssh/ssh.c b/usr.bin/ssh/ssh.c
index 21f96348c54..bf9dc850276 100644
--- a/usr.bin/ssh/ssh.c
+++ b/usr.bin/ssh/ssh.c
@@ -18,7 +18,7 @@ Modified to work with SSL by Niels Provos <provos@citi.umich.edu> in Canada.
*/
#include "includes.h"
-RCSID("$Id: ssh.c,v 1.21 1999/09/30 20:39:08 deraadt Exp $");
+RCSID("$Id: ssh.c,v 1.22 1999/10/03 21:50:04 provos Exp $");
#include "xmalloc.h"
#include "ssh.h"
@@ -58,6 +58,9 @@ Options options;
in a configuration file. */
char *host;
+/* socket address the host resolves to */
+struct sockaddr_in hostaddr;
+
/* Flag to indicate that we have received a window change signal which has
not yet been processed. This will cause a message indicating the new
window size to be sent to the server a little later. This is volatile
@@ -520,7 +523,7 @@ main(int ac, char **av)
/* Open a connection to the remote host. This needs root privileges if
rhosts_authentication is true. */
- ok = ssh_connect(host, options.port, options.connection_attempts,
+ ok = ssh_connect(host, &hostaddr, options.port, options.connection_attempts,
!options.rhosts_authentication &&
!options.rhosts_rsa_authentication,
original_real_uid, options.proxy_command);
@@ -581,7 +584,7 @@ main(int ac, char **av)
/* Log into the remote system. This never returns if the login fails. */
ssh_login(host_private_key_loaded, host_private_key,
- host, &options, original_real_uid);
+ host, &hostaddr, &options, original_real_uid);
/* We no longer need the host private key. Clear it now. */
if (host_private_key_loaded)
diff --git a/usr.bin/ssh/ssh.h b/usr.bin/ssh/ssh.h
index 05812fc2761..10b04bfb213 100644
--- a/usr.bin/ssh/ssh.h
+++ b/usr.bin/ssh/ssh.h
@@ -13,7 +13,7 @@ Generic header file for ssh.
*/
-/* RCSID("$Id: ssh.h,v 1.5 1999/10/01 02:38:10 provos Exp $"); */
+/* RCSID("$Id: ssh.h,v 1.6 1999/10/03 21:50:04 provos Exp $"); */
#ifndef SSH_H
#define SSH_H
@@ -244,7 +244,8 @@ void record_logout(int pid, const char *ttyname);
second. This returns true on success, and zero on failure. If the
connection is successful, this calls packet_set_connection for the
connection. */
-int ssh_connect(const char *host, int port, int connection_attempts,
+int ssh_connect(const char *host, struct sockaddr_in *hostaddr,
+ int port, int connection_attempts,
int anonymous, uid_t original_real_uid,
const char *proxy_command);
@@ -254,8 +255,9 @@ int ssh_connect(const char *host, int port, int connection_attempts,
If login fails, this function prints an error and never returns.
This initializes the random state, and leaves it initialized (it will also
have references from the packet module). */
-void ssh_login(int host_key_valid, RSA *host_key,
- const char *host, Options *options, uid_t original_real_uid);
+void ssh_login(int host_key_valid, RSA *host_key, const char *host,
+ struct sockaddr_in *hostaddr, Options *options,
+ uid_t original_real_uid);
/*------------ Definitions for various authentication methods. -------*/
@@ -315,10 +317,11 @@ int match_hostname(const char *host, const char *pattern, unsigned int len);
Returns HOST_OK if the host is known and has the specified key,
HOST_NEW if the host is not known, and HOST_CHANGED if the host is known
but used to have a different host key. The host must be in all lowercase. */
-typedef enum { HOST_OK, HOST_NEW, HOST_CHANGED } HostStatus;
+typedef enum { HOST_OK, HOST_NEW, HOST_CHANGED, HOST_DIFFER } HostStatus;
HostStatus check_host_in_hostfile(const char *filename,
const char *host, unsigned int bits,
- BIGNUM *e, BIGNUM *n);
+ BIGNUM *e, BIGNUM *n,
+ BIGNUM *ke, BIGNUM *kn);
/* Appends an entry to the host file. Returns false if the entry
could not be appended. */
diff --git a/usr.bin/ssh/sshconnect.c b/usr.bin/ssh/sshconnect.c
index 5159da41ced..fcb8dd15320 100644
--- a/usr.bin/ssh/sshconnect.c
+++ b/usr.bin/ssh/sshconnect.c
@@ -15,7 +15,7 @@ login (authentication) dialog.
*/
#include "includes.h"
-RCSID("$Id: sshconnect.c,v 1.11 1999/10/03 19:22:39 deraadt Exp $");
+RCSID("$Id: sshconnect.c,v 1.12 1999/10/03 21:50:04 provos Exp $");
#include <ssl/bn.h>
#include "xmalloc.h"
@@ -175,7 +175,8 @@ int ssh_create_socket(uid_t original_real_uid, int privileged)
and %p substituted for host and port, respectively) to use to contact
the daemon. */
-int ssh_connect(const char *host, int port, int connection_attempts,
+int ssh_connect(const char *host, struct sockaddr_in *hostaddr,
+ int port, int connection_attempts,
int anonymous, uid_t original_real_uid,
const char *proxy_command)
{
@@ -183,7 +184,6 @@ int ssh_connect(const char *host, int port, int connection_attempts,
int on = 1;
struct servent *sp;
struct hostent *hp;
- struct sockaddr_in hostaddr;
struct linger linger;
debug("ssh_connect: getuid %d geteuid %d anon %d",
@@ -217,15 +217,15 @@ int ssh_connect(const char *host, int port, int connection_attempts,
debug("Trying again...");
/* Try to parse the host name as a numeric inet address. */
- memset(&hostaddr, 0, sizeof(hostaddr));
- hostaddr.sin_family = AF_INET;
- hostaddr.sin_port = htons(port);
- hostaddr.sin_addr.s_addr = inet_addr(host);
- if ((hostaddr.sin_addr.s_addr & 0xffffffff) != 0xffffffff)
+ memset(hostaddr, 0, sizeof(hostaddr));
+ hostaddr->sin_family = AF_INET;
+ hostaddr->sin_port = htons(port);
+ hostaddr->sin_addr.s_addr = inet_addr(host);
+ if ((hostaddr->sin_addr.s_addr & 0xffffffff) != 0xffffffff)
{
/* Valid numeric IP address */
debug("Connecting to %.100s port %d.",
- inet_ntoa(hostaddr.sin_addr), port);
+ inet_ntoa(hostaddr->sin_addr), port);
/* Create a socket. */
sock = ssh_create_socket(original_real_uid,
@@ -236,7 +236,7 @@ int ssh_connect(const char *host, int port, int connection_attempts,
it will help with the problems of tcp_wrappers showing the
remote uid as root. */
temporarily_use_uid(original_real_uid);
- if (connect(sock, (struct sockaddr *)&hostaddr, sizeof(hostaddr))
+ if (connect(sock, (struct sockaddr *)hostaddr, sizeof(*hostaddr))
>= 0)
{
/* Successful connect. */
@@ -266,12 +266,12 @@ int ssh_connect(const char *host, int port, int connection_attempts,
for (i = 0; hp->h_addr_list[i]; i++)
{
/* Set the address to connect to. */
- hostaddr.sin_family = hp->h_addrtype;
- memcpy(&hostaddr.sin_addr, hp->h_addr_list[i],
- sizeof(hostaddr.sin_addr));
+ hostaddr->sin_family = hp->h_addrtype;
+ memcpy(&hostaddr->sin_addr, hp->h_addr_list[i],
+ sizeof(hostaddr->sin_addr));
debug("Connecting to %.200s [%.100s] port %d.",
- host, inet_ntoa(hostaddr.sin_addr), port);
+ host, inet_ntoa(hostaddr->sin_addr), port);
/* Create a socket for connecting. */
sock = ssh_create_socket(original_real_uid,
@@ -282,8 +282,8 @@ int ssh_connect(const char *host, int port, int connection_attempts,
it will help with tcp_wrappers showing the remote uid as
root. */
temporarily_use_uid(original_real_uid);
- if (connect(sock, (struct sockaddr *)&hostaddr,
- sizeof(hostaddr)) >= 0)
+ if (connect(sock, (struct sockaddr *)hostaddr,
+ sizeof(*hostaddr)) >= 0)
{
/* Successful connection. */
restore_uid();
@@ -990,13 +990,14 @@ int read_yes_or_no(const char *prompt, int defval)
void ssh_login(int host_key_valid,
RSA *own_host_key,
const char *orighost,
+ struct sockaddr_in *hostaddr,
Options *options, uid_t original_real_uid)
{
int i, type;
char *password;
struct passwd *pw;
BIGNUM *key;
- RSA *host_key;
+ RSA *host_key, *file_key;
RSA *public_key;
unsigned char session_key[SSH_SESSION_KEY_LENGTH];
const char *server_user, *local_user;
@@ -1004,6 +1005,7 @@ void ssh_login(int host_key_valid,
unsigned char check_bytes[8];
unsigned int supported_ciphers, supported_authentications, protocol_flags;
HostStatus host_status;
+ HostStatus ip_status;
int payload_len, clen, sum_len = 0;
u_int32_t rand = 0;
@@ -1056,6 +1058,15 @@ void ssh_login(int host_key_valid,
packet_get_bignum(host_key->n, &clen);
sum_len += clen;
+ if (options->check_host_ip && strcmp(host, inet_ntoa(hostaddr->sin_addr))) {
+ /* Store the host key from the known host file in here
+ * so that we can compare it with the key for the IP
+ * address. */
+ file_key = RSA_new();
+ file_key->n = BN_new();
+ file_key->e = BN_new();
+ }
+
/* Get protocol flags. */
protocol_flags = packet_get_int();
packet_set_protocol_flags(protocol_flags);
@@ -1082,12 +1093,13 @@ void ssh_login(int host_key_valid,
or in the systemwide list. */
host_status = check_host_in_hostfile(options->user_hostfile,
host, BN_num_bits(host_key->n),
- host_key->e, host_key->n);
+ host_key->e, host_key->n,
+ file_key->e, file_key->n);
if (host_status == HOST_NEW)
host_status = check_host_in_hostfile(options->system_hostfile, host,
BN_num_bits(host_key->n),
- host_key->e, host_key->n);
-
+ host_key->e, host_key->n,
+ file_key->e, file_key->n);
/* Force accepting of the host key for localhost and 127.0.0.1.
The problem is that if the home directory is NFS-mounted to multiple
machines, localhost will refer to a different machine in each of them,
@@ -1101,68 +1113,131 @@ void ssh_login(int host_key_valid,
host_status = HOST_OK;
}
- switch (host_status)
+ /* Also perform check for the ip address */
+ if (options->check_host_ip && strcmp(host, inet_ntoa(hostaddr->sin_addr))) {
+ RSA *ip_key = RSA_new();
+ ip_key->n = BN_new();
+ ip_key->e = BN_new();
+ ip_status = check_host_in_hostfile(options->user_hostfile,
+ inet_ntoa(hostaddr->sin_addr),
+ BN_num_bits(host_key->n),
+ host_key->e, host_key->n,
+ ip_key->e, ip_key->n);
+
+ if (ip_status == HOST_NEW)
+ ip_status = check_host_in_hostfile(options->system_hostfile,
+ inet_ntoa(hostaddr->sin_addr),
+ BN_num_bits(host_key->n),
+ host_key->e, host_key->n,
+ ip_key->e, ip_key->n);
+ if (ip_status == HOST_CHANGED && host_status == HOST_CHANGED &&
+ (BN_cmp(ip_key->e, file_key->e) || BN_cmp(ip_key->n, file_key->n)))
+ ip_status = HOST_DIFFER;
+
+ RSA_free(ip_key);
+ RSA_free(file_key);
+ } else
+ ip_status = host_status;
+
+ switch (host_status) {
+ case HOST_OK:
+ /* The host is known and the key matches. */
+ debug("Host '%.200s' is known and matches the host key.", host);
+ if (options->check_host_ip) {
+ if (ip_status == HOST_NEW) {
+ if (!add_host_to_hostfile(options->user_hostfile,
+ inet_ntoa(hostaddr->sin_addr),
+ BN_num_bits(host_key->n),
+ host_key->e, host_key->n))
+ log("Failed to add the host ip to the list of known hosts (%.30s).",
+ options->user_hostfile);
+ else
+ log("Warning: Permanently added host ip '%.30s' to the list of known hosts.", inet_ntoa(hostaddr->sin_addr));
+ } else if (ip_status != HOST_OK)
+ log("Warning: the host key differ from the key of the ip address '%.30s' differs", inet_ntoa(hostaddr->sin_addr));
+ }
+
+ break;
+ case HOST_NEW:
{
- case HOST_OK:
- /* The host is known and the key matches. */
- debug("Host '%.200s' is known and matches the host key.", host);
- break;
- case HOST_NEW:
+ char hostline[1000], *hostp = hostline;
/* The host is new. */
- if (options->strict_host_key_checking == 1)
- { /* User has requested strict host key checking. We will not
- add the host key automatically. The only alternative left
- is to abort. */
- fatal("No host key is known for %.200s and you have requested strict checking.", host);
- }
- else if (options->strict_host_key_checking == 2) /* The default */
- {
- char prompt[1024];
- sprintf(prompt,
- "The authenticity of host '%.200s' can't be established.\n"
- "Are you sure you want to continue connecting (yes/no)? ",
- host);
- if (!read_yes_or_no(prompt, -1))
- fatal("Aborted by user!\n");
- }
+ if (options->strict_host_key_checking == 1) {
+ /* User has requested strict host key checking. We will not
+ add the host key automatically. The only alternative left
+ is to abort. */
+ fatal("No host key is known for %.200s and you have requested strict checking.", host);
+ } else if (options->strict_host_key_checking == 2) { /* The default */
+ char prompt[1024];
+ snprintf(prompt, sizeof(prompt),
+ "The authenticity of host '%.200s' can't be established.\n"
+ "Are you sure you want to continue connecting (yes/no)? ",
+ host);
+ if (!read_yes_or_no(prompt, -1))
+ fatal("Aborted by user!\n");
+ }
+
+ if (options->check_host_ip && ip_status == HOST_NEW &&
+ strcmp(host, inet_ntoa(hostaddr->sin_addr)))
+ snprintf(hostline, sizeof(hostline), "%s,%s",
+ host, inet_ntoa(hostaddr->sin_addr));
+ else
+ hostp = host;
+
/* If not in strict mode, add the key automatically to the local
known_hosts file. */
- if (!add_host_to_hostfile(options->user_hostfile, host,
+ if (!add_host_to_hostfile(options->user_hostfile, hostp,
BN_num_bits(host_key->n),
host_key->e, host_key->n))
log("Failed to add the host to the list of known hosts (%.500s).",
options->user_hostfile);
else
- log("Warning: Permanently added host '%.200s' to the list of known hosts.", host);
- break;
- case HOST_CHANGED:
- /* The host key has changed. */
- error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
- error("@ WARNING: HOST IDENTIFICATION HAS CHANGED! @");
- error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
- error("IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!");
- error("Someone could be eavesdropping on you right now (man-in-the-middle attack)!");
- error("It is also possible that the host key has just been changed.");
- error("Please contact your system administrator.");
- error("Add correct host key in %.100s to get rid of this message.",
- options->user_hostfile);
-
- /* If strict host key checking is in use, the user will have to edit
- the key manually and we can only abort. */
- if (options->strict_host_key_checking)
- fatal("Host key for %.200s has changed and you have requested strict checking.", host);
-
- /* If strict host key checking has not been requested, allow the
- connection but without password authentication. */
- error("Password authentication is disabled to avoid trojan horses.");
- options->password_authentication = 0;
- /* XXX Should permit the user to change to use the new id. This could
- be done by converting the host key to an identifying sentence, tell
- that the host identifies itself by that sentence, and ask the user
- if he/she whishes to accept the authentication. */
+ log("Warning: Permanently added '%.200s' to the list of known hosts.",
+ hostp);
break;
}
-
+ case HOST_CHANGED:
+ if (options->check_host_ip) {
+ if (ip_status != HOST_CHANGED) {
+ error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
+ error("@ WARNING: POSSIBLE DNS SPOOFNG DETECTED! @");
+ error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
+ error("The host key for %s has changed,", host);
+ error("but the key for the according IP address %s has",
+ inet_ntoa(hostaddr->sin_addr));
+ error("a different status. This could either mean that DNS");
+ error("SPOOFING is happening or the IP address for the host");
+ error("and its host key have changed at the same time");
+ }
+ }
+
+ /* The host key has changed. */
+ error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
+ error("@ WARNING: HOST IDENTIFICATION HAS CHANGED! @");
+ error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
+ error("IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!");
+ error("Someone could be eavesdropping on you right now (man-in-the-middle attack)!");
+ error("It is also possible that the host key has just been changed.");
+ error("Please contact your system administrator.");
+ error("Add correct host key in %.100s to get rid of this message.",
+ options->user_hostfile);
+
+ /* If strict host key checking is in use, the user will have to edit
+ the key manually and we can only abort. */
+ if (options->strict_host_key_checking)
+ fatal("Host key for %.200s has changed and you have requested strict checking.", host);
+
+ /* If strict host key checking has not been requested, allow the
+ connection but without password authentication. */
+ error("Password authentication is disabled to avoid trojan horses.");
+ options->password_authentication = 0;
+ /* XXX Should permit the user to change to use the new id. This could
+ be done by converting the host key to an identifying sentence, tell
+ that the host identifies itself by that sentence, and ask the user
+ if he/she whishes to accept the authentication. */
+ break;
+ }
+
/* Generate a session key. */
arc4random_stir();