View | Details | Raw Unified | Return to bug 1672 | Differences between
and this patch

Collapse All | Expand All

(-)clean/openssh-5.3p1/configure.ac (-22 / +61 lines)
Lines 3289-3320 AC_ARG_WITH(sectok, Link Here
3289
	]
3289
	]
3290
)
3290
)
3291
3291
3292
# Check whether user wants OpenSC support
3292
LIBVAL_MSG="no"
3293
OPENSC_CONFIG="no"
3293
# Check whether user wants DNSSEC local validation support
3294
AC_ARG_WITH(opensc,
3294
AC_ARG_WITH(local-dnssec-validation,
3295
	[  --with-opensc[[=PFX]]     Enable smartcard support using OpenSC (optionally in PATH)],
3295
	[  --with-local-dnssec-validation Enable local DNSSEC validation using libval],
3296
	[
3296
	[ if test "x$withval" != "xno" ; then
3297
	    if test "x$withval" != "xno" ; then
3298
		if test "x$withval" != "xyes" ; then
3297
		if test "x$withval" != "xyes" ; then
3299
  			OPENSC_CONFIG=$withval/bin/opensc-config
3298
			CPPFLAGS="$CPPFLAGS -I${withval}"
3300
		else
3299
			LDFLAGS="$LDFLAGS -L${withval}"
3301
  			AC_PATH_PROG(OPENSC_CONFIG, opensc-config, no)
3300
			if test ! -z "$need_dash_r" ; then
3301
				LDFLAGS="$LDFLAGS -R${withval}"
3302
		fi
3302
		fi
3303
		if test "$OPENSC_CONFIG" != "no"; then
3303
			if test ! -z "$blibpath" ; then
3304
			LIBOPENSC_CFLAGS=`$OPENSC_CONFIG --cflags`
3304
				blibpath="$blibpath:${withval}"
3305
			LIBOPENSC_LIBS=`$OPENSC_CONFIG --libs`
3306
			CPPFLAGS="$CPPFLAGS $LIBOPENSC_CFLAGS"
3307
			LIBS="$LIBS $LIBOPENSC_LIBS"
3308
			AC_DEFINE(SMARTCARD)
3309
			AC_DEFINE(USE_OPENSC, 1,
3310
				[Define if you want smartcard support
3311
				using OpenSC])
3312
			SCARD_MSG="yes, using OpenSC"
3313
		fi
3305
		fi
3314
	    fi
3306
	    fi
3315
	]
3307
		AC_CHECK_HEADERS(validator/validator.h)
3316
)
3308
		if test "$ac_cv_header_validator_validator_h" != yes; then
3317
3309
			AC_MSG_ERROR(Can't find validator.h)
3310
		fi
3311
		AC_CHECK_LIB(sres, query_send)
3312
		if test "$ac_cv_lib_sres_query_send" != yes; then
3313
			AC_MSG_ERROR(Can't find libsres)
3314
		fi
3315
		LIBVAL_SUFFIX=""
3316
		AC_CHECK_LIB(val, p_val_status,LIBS="$LIBS -lval",
3317
			[ AC_CHECK_LIB(pthread, pthread_rwlock_init)
3318
			  AC_CHECK_LIB(val-threads, p_val_status,
3319
				[ LIBS="$LIBS -lval-threads -lpthread"
3320
				  LIBVAL_SUFFIX="-threads"],
3321
				AC_MSG_ERROR(Can't find libval or libval-threads))
3322
			])
3323
		AC_DEFINE(DNSSEC_LOCAL_VALIDATION, 1,
3324
			[Define if you want local DNSSEC validation support])
3325
		LIBVAL_MSG="yes, libval${LIBVAL_SUFFIX}"
3326
	else
3318
# Check libraries needed by DNS fingerprint support
3327
# Check libraries needed by DNS fingerprint support
3319
AC_SEARCH_LIBS(getrrsetbyname, resolv,
3328
AC_SEARCH_LIBS(getrrsetbyname, resolv,
3320
	[AC_DEFINE(HAVE_GETRRSETBYNAME, 1,
3329
	[AC_DEFINE(HAVE_GETRRSETBYNAME, 1,
Lines 3368-3373 int main() Link Here
3368
			    [Define if HEADER.ad exists in arpa/nameser.h])],,
3377
			    [Define if HEADER.ad exists in arpa/nameser.h])],,
3369
			[#include <arpa/nameser.h>])
3378
			[#include <arpa/nameser.h>])
3370
	])
3379
	])
3380
	 fi]
3381
)
3382
3383
# Check whether user wants OpenSC support
3384
OPENSC_CONFIG="no"
3385
AC_ARG_WITH(opensc,
3386
	[  --with-opensc[[=PFX]]     Enable smartcard support using OpenSC (optionally in PATH)],
3387
	[
3388
	    if test "x$withval" != "xno" ; then
3389
		if test "x$withval" != "xyes" ; then
3390
  			OPENSC_CONFIG=$withval/bin/opensc-config
3391
		else
3392
  			AC_PATH_PROG(OPENSC_CONFIG, opensc-config, no)
3393
		fi
3394
		if test "$OPENSC_CONFIG" != "no"; then
3395
			LIBOPENSC_CFLAGS=`$OPENSC_CONFIG --cflags`
3396
			LIBOPENSC_LIBS=`$OPENSC_CONFIG --libs`
3397
			CPPFLAGS="$CPPFLAGS $LIBOPENSC_CFLAGS"
3398
			LIBS="$LIBS $LIBOPENSC_LIBS"
3399
			AC_DEFINE(SMARTCARD)
3400
			AC_DEFINE(USE_OPENSC, 1,
3401
				[Define if you want smartcard support
3402
				using OpenSC])
3403
			SCARD_MSG="yes, using OpenSC"
3404
		fi
3405
	    fi
3406
	]
3407
)
3408
3371
3409
3372
AC_MSG_CHECKING(if struct __res_state _res is an extern)
3410
AC_MSG_CHECKING(if struct __res_state _res is an extern)
3373
AC_LINK_IFELSE([
3411
AC_LINK_IFELSE([
Lines 4232-4237 echo " TCP Wrappers support Link Here
4232
echo "              MD5 password support: $MD5_MSG"
4270
echo "              MD5 password support: $MD5_MSG"
4233
echo "                   libedit support: $LIBEDIT_MSG"
4271
echo "                   libedit support: $LIBEDIT_MSG"
4234
echo "  Solaris process contract support: $SPC_MSG"
4272
echo "  Solaris process contract support: $SPC_MSG"
4273
echo "   Local DNSSEC validation support: $LIBVAL_MSG"
4235
echo "       IP address in \$DISPLAY hack: $DISPLAY_HACK_MSG"
4274
echo "       IP address in \$DISPLAY hack: $DISPLAY_HACK_MSG"
4236
echo "           Translate v4 in v6 hack: $IPV4_IN6_HACK_MSG"
4275
echo "           Translate v4 in v6 hack: $IPV4_IN6_HACK_MSG"
4237
echo "                  BSD Auth support: $BSD_AUTH_MSG"
4276
echo "                  BSD Auth support: $BSD_AUTH_MSG"
(-)clean/openssh-5.3p1/dns.c (-2 / +101 lines)
Lines 35-40 Link Here
35
#include <stdio.h>
35
#include <stdio.h>
36
#include <string.h>
36
#include <string.h>
37
37
38
#ifdef DNSSEC_LOCAL_VALIDATION
39
# include <validator/validator.h>
40
#endif
41
38
#include "xmalloc.h"
42
#include "xmalloc.h"
39
#include "key.h"
43
#include "key.h"
40
#include "dns.h"
44
#include "dns.h"
Lines 176-188 verify_host_key_dns(const char *hostname Link Here
176
{
180
{
177
	u_int counter;
181
	u_int counter;
178
	int result;
182
	int result;
179
	struct rrsetinfo *fingerprints = NULL;
180
183
181
	u_int8_t hostkey_algorithm;
184
	u_int8_t hostkey_algorithm;
182
	u_int8_t hostkey_digest_type;
185
	u_int8_t hostkey_digest_type;
183
	u_char *hostkey_digest;
186
	u_char *hostkey_digest;
184
	u_int hostkey_digest_len;
187
	u_int hostkey_digest_len;
185
188
189
#ifndef DNSSEC_LOCAL_VALIDATION
190
	struct rrsetinfo *fingerprints = NULL;
191
#else
192
	struct val_result_chain *val_res, *val_results = NULL;
193
	
194
#endif
195
186
	u_int8_t dnskey_algorithm;
196
	u_int8_t dnskey_algorithm;
187
	u_int8_t dnskey_digest_type;
197
	u_int8_t dnskey_digest_type;
188
	u_char *dnskey_digest;
198
	u_char *dnskey_digest;
Lines 199-204 verify_host_key_dns(const char *hostname Link Here
199
		return -1;
209
		return -1;
200
	}
210
	}
201
211
212
#ifndef DNSSEC_LOCAL_VALIDATION
202
	result = getrrsetbyname(hostname, DNS_RDATACLASS_IN,
213
	result = getrrsetbyname(hostname, DNS_RDATACLASS_IN,
203
	    DNS_RDATATYPE_SSHFP, 0, &fingerprints);
214
	    DNS_RDATATYPE_SSHFP, 0, &fingerprints);
204
	if (result) {
215
	if (result) {
Lines 207-213 verify_host_key_dns(const char *hostname Link Here
207
	}
218
	}
208
219
209
	if (fingerprints->rri_flags & RRSET_VALIDATED) {
220
	if (fingerprints->rri_flags & RRSET_VALIDATED) {
210
		*flags |= DNS_VERIFY_SECURE;
221
		*flags |= (DNS_VERIFY_SECURE|DNS_VERIFY_TRUSTED);
211
		debug("found %d secure fingerprints in DNS",
222
		debug("found %d secure fingerprints in DNS",
212
		    fingerprints->rri_nrdatas);
223
		    fingerprints->rri_nrdatas);
213
	} else {
224
	} else {
Lines 255-260 verify_host_key_dns(const char *hostname Link Here
255
266
256
	xfree(hostkey_digest); /* from key_fingerprint_raw() */
267
	xfree(hostkey_digest); /* from key_fingerprint_raw() */
257
	freerrset(fingerprints);
268
	freerrset(fingerprints);
269
#else
270
271
	result = val_resolve_and_check(NULL, hostname, DNS_RDATACLASS_IN,
272
	    DNS_RDATATYPE_SSHFP, 0, &val_results);
273
	if (result != VAL_NO_ERROR){
274
		verbose("DNS lookup error: %s", p_ac_status(val_results->val_rc_status));
275
		return -1;
276
	}
277
278
	/* Initialize host key parameters */
279
	if (!dns_read_key(&hostkey_algorithm, &hostkey_digest_type,
280
	    &hostkey_digest, &hostkey_digest_len, hostkey)) {
281
		error("Error calculating host key fingerprint.");
282
		val_free_result_chain(val_results);
283
		return -1;
284
	}
285
286
	counter = 0;
287
	for (val_res = val_results; val_res; val_res = val_res->val_rc_next)  {
288
		struct val_rrset_rec *val_rrset;
289
		struct val_rr_rec *rr;
290
291
		val_rrset = val_res->val_rc_rrset;
292
		if ((NULL == val_rrset) || (NULL == val_rrset->val_rrset_data)) 
293
			continue;
294
295
		for(rr = val_rrset->val_rrset_data; rr;
296
		    rr = rr->rr_next) {
297
298
			if (NULL == rr->rr_rdata)
299
				continue;
300
301
			/*
302
			 * Extract the key from the answer. Ignore any badly
303
			 * formatted fingerprints.
304
			 */
305
			if (!dns_read_rdata(&dnskey_algorithm, &dnskey_digest_type,
306
			    &dnskey_digest, &dnskey_digest_len,
307
			    rr->rr_rdata,
308
			    rr->rr_rdata_length)) {
309
				verbose("Error parsing fingerprint from DNS.");
310
				continue;
311
			}
312
313
			++counter;
314
315
			/* Check if the current key is the same as the given key */
316
			if (hostkey_algorithm == dnskey_algorithm &&
317
			    hostkey_digest_type == dnskey_digest_type) {
318
319
				if (hostkey_digest_len == dnskey_digest_len &&
320
				    memcmp(hostkey_digest, dnskey_digest,
321
				    hostkey_digest_len) == 0) {
322
323
					debug("found matching fingerprints in DNS");
324
					*flags |= DNS_VERIFY_MATCH;
325
326
327
328
				}
329
			}
330
			xfree(dnskey_digest);
331
		}
332
	    if (val_istrusted(val_res->val_rc_status)) {
333
		    /*
334
		     * local validation can result in a non-secure, but trusted
335
		     * response. For example, in a corporate network the authoritative
336
		     * server for internal DNS may be on the internal network, behind
337
		     * a firewall. Local validation policy can be configured to trust
338
		     * these results without using DNSSEC to validate them.
339
		     */
340
		    *flags |= DNS_VERIFY_TRUSTED;
341
		    if (val_isvalidated(val_res->val_rc_status)) {
342
			    *flags |= DNS_VERIFY_SECURE;
343
			    debug("found %d trusted fingerprints in DNS", counter);
344
		    } else  {
345
			    debug("found %d trusted, but not validated, fingerprints in DNS", counter);
346
		    }
347
	    } else {
348
		    debug("found %d un-trusted fingerprints in DNS", counter);
349
	    }
350
	}
351
	if(counter)
352
		*flags |= DNS_VERIFY_FOUND;
353
354
	xfree(hostkey_digest); /* from key_fingerprint_raw() */
355
	val_free_result_chain(val_results);
356
#endif /* */
258
357
259
	if (*flags & DNS_VERIFY_FOUND)
358
	if (*flags & DNS_VERIFY_FOUND)
260
		if (*flags & DNS_VERIFY_MATCH)
359
		if (*flags & DNS_VERIFY_MATCH)
(-)clean/openssh-5.3p1/dns.h (+1 lines)
Lines 45-50 enum sshfp_hashes { Link Here
45
#define DNS_VERIFY_FOUND	0x00000001
45
#define DNS_VERIFY_FOUND	0x00000001
46
#define DNS_VERIFY_MATCH	0x00000002
46
#define DNS_VERIFY_MATCH	0x00000002
47
#define DNS_VERIFY_SECURE	0x00000004
47
#define DNS_VERIFY_SECURE	0x00000004
48
#define DNS_VERIFY_TRUSTED	0x00000008
48
49
49
int	verify_host_key_dns(const char *, struct sockaddr *, const Key *, int *);
50
int	verify_host_key_dns(const char *, struct sockaddr *, const Key *, int *);
50
int	export_dns_rr(const char *, const Key *, FILE *, int);
51
int	export_dns_rr(const char *, const Key *, FILE *, int);
(-)clean/openssh-5.3p1/readconf.c (+22 lines)
Lines 131-136 typedef enum { Link Here
131
	oSendEnv, oControlPath, oControlMaster, oHashKnownHosts,
131
	oSendEnv, oControlPath, oControlMaster, oHashKnownHosts,
132
	oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand,
132
	oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand,
133
	oVisualHostKey, oUseRoaming, oZeroKnowledgePasswordAuthentication,
133
	oVisualHostKey, oUseRoaming, oZeroKnowledgePasswordAuthentication,
134
        oStrictDnssecChecking,oAutoAnswerValidatedKeys,
134
	oDeprecated, oUnsupported
135
	oDeprecated, oUnsupported
135
} OpCodes;
136
} OpCodes;
136
137
Lines 235-240 static struct { Link Here
235
#else
236
#else
236
	{ "zeroknowledgepasswordauthentication", oUnsupported },
237
	{ "zeroknowledgepasswordauthentication", oUnsupported },
237
#endif
238
#endif
239
#ifdef DNSSEC_LOCAL_VALIDATION
240
        { "strictdnssecchecking", oStrictDnssecChecking },
241
        { "autoanswervalidatedkeys", oAutoAnswerValidatedKeys },
242
#else
243
        { "strictdnssecchecking", oUnsupported },
244
        { "autoanswervalidatedkeys", oUnsupported },
245
#endif
238
246
239
	{ NULL, oBadOption }
247
	{ NULL, oBadOption }
240
};
248
};
Lines 490-495 parse_yesnoask: Link Here
490
			*intptr = value;
498
			*intptr = value;
491
		break;
499
		break;
492
500
501
	case oStrictDnssecChecking:
502
		intptr = &options->strict_dnssec_checking;
503
                goto parse_yesnoask;
504
505
	case oAutoAnswerValidatedKeys:
506
		intptr = &options->autoanswer_validated_keys;
507
                goto parse_yesnoask;
508
493
	case oCompression:
509
	case oCompression:
494
		intptr = &options->compression;
510
		intptr = &options->compression;
495
		goto parse_flag;
511
		goto parse_flag;
Lines 1022-1027 initialize_options(Options * options) Link Here
1022
	options->batch_mode = -1;
1038
	options->batch_mode = -1;
1023
	options->check_host_ip = -1;
1039
	options->check_host_ip = -1;
1024
	options->strict_host_key_checking = -1;
1040
	options->strict_host_key_checking = -1;
1041
	options->strict_dnssec_checking = -1;
1042
        options->autoanswer_validated_keys = -1;
1025
	options->compression = -1;
1043
	options->compression = -1;
1026
	options->tcp_keep_alive = -1;
1044
	options->tcp_keep_alive = -1;
1027
	options->compression_level = -1;
1045
	options->compression_level = -1;
Lines 1121-1126 fill_default_options(Options * options) Link Here
1121
		options->check_host_ip = 1;
1139
		options->check_host_ip = 1;
1122
	if (options->strict_host_key_checking == -1)
1140
	if (options->strict_host_key_checking == -1)
1123
		options->strict_host_key_checking = 2;	/* 2 is default */
1141
		options->strict_host_key_checking = 2;	/* 2 is default */
1142
	if (options->strict_dnssec_checking == -1)
1143
		options->strict_dnssec_checking = 2;	/* 2 is default */
1144
	if (options->autoanswer_validated_keys == -1)
1145
		options->autoanswer_validated_keys = 0;	/* 0 is default */
1124
	if (options->compression == -1)
1146
	if (options->compression == -1)
1125
		options->compression = 0;
1147
		options->compression = 0;
1126
	if (options->tcp_keep_alive == -1)
1148
	if (options->tcp_keep_alive == -1)
(-)clean/openssh-5.3p1/readconf.h (+3 lines)
Lines 125-130 typedef struct { Link Here
125
125
126
	int	use_roaming;
126
	int	use_roaming;
127
127
128
	int     strict_dnssec_checking;	/* Strict DNSSEC checking. */
129
	int     autoanswer_validated_keys;
130
128
}       Options;
131
}       Options;
129
132
130
#define SSHCTL_MASTER_NO	0
133
#define SSHCTL_MASTER_NO	0
(-)clean/openssh-5.3p1/sshconnect.c (-3 / +187 lines)
Lines 26-31 Link Here
26
#include <netinet/in.h>
26
#include <netinet/in.h>
27
#include <arpa/inet.h>
27
#include <arpa/inet.h>
28
28
29
#ifdef DNSSEC_LOCAL_VALIDATION
30
# include <validator/validator.h>
31
#endif
32
29
#include <ctype.h>
33
#include <ctype.h>
30
#include <errno.h>
34
#include <errno.h>
31
#include <netdb.h>
35
#include <netdb.h>
Lines 63-68 char *client_version_string = NULL; Link Here
63
char *server_version_string = NULL;
67
char *server_version_string = NULL;
64
68
65
static int matching_host_key_dns = 0;
69
static int matching_host_key_dns = 0;
70
#ifdef DNSSEC_LOCAL_VALIDATION
71
static int validated_host_key_dns = 0;
72
#endif
66
73
67
/* import */
74
/* import */
68
extern Options options;
75
extern Options options;
Lines 73-78 extern pid_t proxy_command_pid; Link Here
73
80
74
static int show_other_keys(const char *, Key *);
81
static int show_other_keys(const char *, Key *);
75
static void warn_changed_key(Key *);
82
static void warn_changed_key(Key *);
83
static int confirm(const char *prompt);
76
84
77
/*
85
/*
78
 * Connect to the given ssh server using a proxy command.
86
 * Connect to the given ssh server using a proxy command.
Lines 323-329 ssh_connect(const char *host, struct soc Link Here
323
	int on = 1;
331
	int on = 1;
324
	int sock = -1, attempt;
332
	int sock = -1, attempt;
325
	char ntop[NI_MAXHOST], strport[NI_MAXSERV];
333
	char ntop[NI_MAXHOST], strport[NI_MAXSERV];
326
	struct addrinfo hints, *ai, *aitop;
334
	struct addrinfo hints;
335
	struct addrinfo *ai, *aitop = NULL;
336
#ifdef DNSSEC_LOCAL_VALIDATION
337
	val_status_t val_status;
338
#endif
327
339
328
	debug2("ssh_connect: needpriv %d", needpriv);
340
	debug2("ssh_connect: needpriv %d", needpriv);
329
341
Lines 337-345 ssh_connect(const char *host, struct soc Link Here
337
	hints.ai_family = family;
349
	hints.ai_family = family;
338
	hints.ai_socktype = SOCK_STREAM;
350
	hints.ai_socktype = SOCK_STREAM;
339
	snprintf(strport, sizeof strport, "%u", port);
351
	snprintf(strport, sizeof strport, "%u", port);
352
#ifndef DNSSEC_LOCAL_VALIDATION
340
	if ((gaierr = getaddrinfo(host, strport, &hints, &aitop)) != 0)
353
	if ((gaierr = getaddrinfo(host, strport, &hints, &aitop)) != 0)
341
		fatal("%s: Could not resolve hostname %.100s: %s", __progname,
354
		fatal("%s: Could not resolve hostname %.100s: %s", __progname,
342
		    host, ssh_gai_strerror(gaierr));
355
		    host, ssh_gai_strerror(gaierr));
356
#else
357
	gaierr = val_getaddrinfo(NULL, host, strport, &hints, &aitop,
358
                                 &val_status);
359
        debug2("ssh_connect: gaierr %d, val_status %d / %s; trusted: %d",
360
               gaierr, val_status, p_val_status(val_status),
361
               val_istrusted(val_status));
362
	if (gaierr != 0) {
363
            if (VAL_GETADDRINFO_HAS_STATUS(gaierr) &&
364
                !val_istrusted(val_status)) {
365
                error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
366
                error("@ WARNING: UNTRUSTED ERROR IN DNS RESOLUTION FOR HOST!    @");
367
                error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
368
                error("The authenticity of DNS response is not trusted (%s).", 
369
                      p_val_status(val_status));
370
            }
371
		fatal("%s: Could not resolve hostname %.100s: %s", __progname,
372
		    host, ssh_gai_strerror(gaierr));
373
        }
374
 	if (!val_istrusted(val_status)) {
375
            error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
376
            error("@ WARNING: UNTRUSTED DNS RESOLUTION FOR HOST IP ADRRESS! @");
377
            error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
378
            error("The authenticity of DNS data for the host '%.200s' "
379
                  "can't be established.", host);
380
            if (options.strict_dnssec_checking == 1) {
381
                fatal("DNS resolution is not trusted (%s) "
382
                      "and you have requested strict checking",
383
                      p_val_status(val_status));
384
            } else if (options.strict_dnssec_checking == 2) {
385
                char msg[1024];
386
                for (ai = aitop; ai; ai = ai->ai_next) {
387
                    if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6)
388
                        continue;
389
                    if (getnameinfo(ai->ai_addr, ai->ai_addrlen,
390
                            ntop, sizeof(ntop), strport, sizeof(strport),
391
                            NI_NUMERICHOST|NI_NUMERICSERV) != 0) {
392
                        error("ssh_connect: getnameinfo failed");
393
                        continue;
394
                    }
395
                    error(" IP address %s port %s", ntop, strport);
396
                }
397
                snprintf(msg,sizeof(msg),
398
                         "Are you sure you want to attempt to connect "
399
                         "(yes/no)? ");
400
                if (!confirm(msg)) 
401
                    return (-1);
402
            }
403
 	}
404
#endif /* DNSSEC_LOCAL_VALIDATION */
343
405
344
	for (attempt = 0; attempt < connection_attempts; attempt++) {
406
	for (attempt = 0; attempt < connection_attempts; attempt++) {
345
		if (attempt > 0) {
407
		if (attempt > 0) {
Lines 736-741 check_host_key(char *hostname, struct so Link Here
736
		}
798
		}
737
		break;
799
		break;
738
	case HOST_NEW:
800
	case HOST_NEW:
801
		debug("Host '%.200s' new.", host);
739
		if (options.host_key_alias == NULL && port != 0 &&
802
		if (options.host_key_alias == NULL && port != 0 &&
740
		    port != SSH_DEFAULT_PORT) {
803
		    port != SSH_DEFAULT_PORT) {
741
			debug("checking without port identifier");
804
			debug("checking without port identifier");
Lines 781-786 check_host_key(char *hostname, struct so Link Here
781
					    "No matching host key fingerprint"
844
					    "No matching host key fingerprint"
782
					    " found in DNS.\n");
845
					    " found in DNS.\n");
783
			}
846
			}
847
#ifdef DNSSEC_LOCAL_VALIDATION
848
                        if (options.autoanswer_validated_keys &&
849
                            validated_host_key_dns && matching_host_key_dns) {
850
                            snprintf(msg, sizeof(msg),
851
                                     "The authenticity of host '%.200s (%s)' was "
852
                                     " validated via DNSSEC%s",
853
                                     host, ip, msg1);
854
                            logit(msg);
855
                            xfree(fp);
856
                        } else {
857
#endif
784
			snprintf(msg, sizeof(msg),
858
			snprintf(msg, sizeof(msg),
785
			    "The authenticity of host '%.200s (%s)' can't be "
859
			    "The authenticity of host '%.200s (%s)' can't be "
786
			    "established%s\n"
860
			    "established%s\n"
Lines 795-800 check_host_key(char *hostname, struct so Link Here
795
			xfree(fp);
869
			xfree(fp);
796
			if (!confirm(msg))
870
			if (!confirm(msg))
797
				goto fail;
871
				goto fail;
872
#ifdef DNSSEC_LOCAL_VALIDATION
873
                        }
874
#endif
798
		}
875
		}
799
		/*
876
		/*
800
		 * If not in strict mode, add the key automatically to the
877
		 * If not in strict mode, add the key automatically to the
Lines 830-835 check_host_key(char *hostname, struct so Link Here
830
			    "list of known hosts.", hostp, type);
907
			    "list of known hosts.", hostp, type);
831
		break;
908
		break;
832
	case HOST_CHANGED:
909
	case HOST_CHANGED:
910
		debug("Host '%.200s' changed.", host);
833
		if (readonly == ROQUIET)
911
		if (readonly == ROQUIET)
834
			goto fail;
912
			goto fail;
835
		if (options.check_host_ip && host_ip_differ) {
913
		if (options.check_host_ip && host_ip_differ) {
Lines 840-845 check_host_key(char *hostname, struct so Link Here
840
				key_msg = "is unchanged";
918
				key_msg = "is unchanged";
841
			else
919
			else
842
				key_msg = "has a different value";
920
				key_msg = "has a different value";
921
#ifdef DNSSEC_LOCAL_VALIDATION
922
                        if (!validated_host_key_dns) {
843
			error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
923
			error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
844
			error("@       WARNING: POSSIBLE DNS SPOOFING DETECTED!          @");
924
			error("@       WARNING: POSSIBLE DNS SPOOFING DETECTED!          @");
845
			error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
925
			error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
Lines 848-853 check_host_key(char *hostname, struct so Link Here
848
			error("%s. This could either mean that", key_msg);
928
			error("%s. This could either mean that", key_msg);
849
			error("DNS SPOOFING is happening or the IP address for the host");
929
			error("DNS SPOOFING is happening or the IP address for the host");
850
			error("and its host key have changed at the same time.");
930
			error("and its host key have changed at the same time.");
931
                        }
932
                        else {
933
#endif
934
			error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
935
			error("@       WARNING: HOST IP ADDRESS HAS CHANGED!             @");
936
			error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
937
                        error("The %s host key for %s has changed,", type, host);
938
			error("and the key for the according IP address %s", ip);
939
			error("%s. The IP address for the host", key_msg);
940
			error("and its host key have changed at the same time.");
941
#ifdef DNSSEC_LOCAL_VALIDATION
942
                        }
943
#endif
851
			if (ip_status != HOST_NEW)
944
			if (ip_status != HOST_NEW)
852
				error("Offending key for IP in %s:%d", ip_file, ip_line);
945
				error("Offending key for IP in %s:%d", ip_file, ip_line);
853
		}
946
		}
Lines 861-872 check_host_key(char *hostname, struct so Link Here
861
		 * If strict host key checking is in use, the user will have
954
		 * If strict host key checking is in use, the user will have
862
		 * to edit the key manually and we can only abort.
955
		 * to edit the key manually and we can only abort.
863
		 */
956
		 */
957
#ifdef DNSSEC_LOCAL_VALIDATION
958
		if ((options.strict_host_key_checking == 2) &&
959
                    options.autoanswer_validated_keys &&
960
                    matching_host_key_dns && validated_host_key_dns) {
961
                    logit("The authenticity of host '%.200s (%s)' was "
962
                          " validated via DNSSEC.",
963
                          host, ip);
964
                    /*
965
                     * If not in strict mode, add the key automatically to the
966
                     * local known_hosts file.
967
                     */
968
                    if (options.check_host_ip && ip_status == HOST_NEW) {
969
			snprintf(hostline, sizeof(hostline), "%s,%s",
970
                                 host, ip);
971
			hostp = hostline;
972
			if (options.hash_known_hosts) {
973
                            /* Add hash of host and IP separately */
974
                            r = add_host_to_hostfile(user_hostfile, host,
975
                                                     host_key, options.hash_known_hosts) &&
976
                                add_host_to_hostfile(user_hostfile, ip,
977
                                                     host_key, options.hash_known_hosts);
978
			} else {
979
                            /* Add unhashed "host,ip" */
980
                            r = add_host_to_hostfile(user_hostfile,
981
                                                     hostline, host_key,
982
                                                     options.hash_known_hosts);
983
			}
984
                    } else {
985
			r = add_host_to_hostfile(user_hostfile, host, host_key,
986
                                                 options.hash_known_hosts);
987
			hostp = host;
988
                    }
989
                    
990
                    if (!r)
991
			logit("Failed to add the host to the list of known "
992
                              "hosts (%.500s).", user_hostfile);
993
                    else
994
			logit("Warning: Permanently added '%.200s' (%s) to the "
995
                              "list of known hosts.", hostp, type);
996
                }
997
                else
998
#endif
864
		if (options.strict_host_key_checking) {
999
		if (options.strict_host_key_checking) {
865
			error("%s host key for %.200s has changed and you have "
1000
			error("%s host key for %.200s has changed and you have "
866
			    "requested strict checking.", type, host);
1001
			    "requested strict checking.", type, host);
867
			goto fail;
1002
			goto fail;
868
		}
1003
		}
869
1004
                else {
870
		/*
1005
		/*
871
		 * If strict host key checking has not been requested, allow
1006
		 * If strict host key checking has not been requested, allow
872
		 * the connection but without MITM-able authentication or
1007
		 * the connection but without MITM-able authentication or
Lines 925-933 check_host_key(char *hostname, struct so Link Here
925
		 * XXX Should permit the user to change to use the new id.
1060
		 * XXX Should permit the user to change to use the new id.
926
		 * This could be done by converting the host key to an
1061
		 * This could be done by converting the host key to an
927
		 * identifying sentence, tell that the host identifies itself
1062
		 * identifying sentence, tell that the host identifies itself
928
		 * by that sentence, and ask the user if he/she whishes to
1063
		 * by that sentence, and ask the user if he/she wishes to
929
		 * accept the authentication.
1064
		 * accept the authentication.
930
		 */
1065
		 */
1066
                }
931
		break;
1067
		break;
932
	case HOST_FOUND:
1068
	case HOST_FOUND:
933
		fatal("internal error");
1069
		fatal("internal error");
Lines 952-961 check_host_key(char *hostname, struct so Link Here
952
			error("Exiting, you have requested strict checking.");
1088
			error("Exiting, you have requested strict checking.");
953
			goto fail;
1089
			goto fail;
954
		} else if (options.strict_host_key_checking == 2) {
1090
		} else if (options.strict_host_key_checking == 2) {
1091
#ifdef DNSSEC_LOCAL_VALIDATION
1092
                    if (options.autoanswer_validated_keys &&
1093
                        matching_host_key_dns && validated_host_key_dns) {
1094
			logit("%s", msg);
1095
                    } else {
1096
#endif
955
			strlcat(msg, "\nAre you sure you want "
1097
			strlcat(msg, "\nAre you sure you want "
956
			    "to continue connecting (yes/no)? ", sizeof(msg));
1098
			    "to continue connecting (yes/no)? ", sizeof(msg));
957
			if (!confirm(msg))
1099
			if (!confirm(msg))
958
				goto fail;
1100
				goto fail;
1101
#ifdef DNSSEC_LOCAL_VALIDATION
1102
                    }
1103
#endif
959
		} else {
1104
		} else {
960
			logit("%s", msg);
1105
			logit("%s", msg);
961
		}
1106
		}
Lines 981-992 verify_host_key(char *host, struct socka Link Here
981
	if (options.verify_host_key_dns &&
1126
	if (options.verify_host_key_dns &&
982
	    verify_host_key_dns(host, hostaddr, host_key, &flags) == 0) {
1127
	    verify_host_key_dns(host, hostaddr, host_key, &flags) == 0) {
983
1128
1129
#ifdef DNSSEC_LOCAL_VALIDATION
1130
		/*
1131
		 * local validation can result in a non-secure, but trusted
1132
		 * response. For example, in a corporate network the authoritative
1133
		 * server for internal DNS may be on the internal network, behind
1134
		 * a firewall. Local validation policy can be configured to trust
1135
		 * these results without using DNSSEC to validate them.
1136
		 */
1137
		if (!(flags & DNS_VERIFY_TRUSTED)) {
1138
			error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
1139
			error("@  WARNING: UNTRUSTED DNS RESOLUTION FOR HOST KEY!       @");
1140
			error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
1141
		}
1142
                if (flags & DNS_VERIFY_SECURE)
1143
                    validated_host_key_dns = 1;
1144
#endif
984
		if (flags & DNS_VERIFY_FOUND) {
1145
		if (flags & DNS_VERIFY_FOUND) {
985
1146
986
			if (options.verify_host_key_dns == 1 &&
1147
			if (options.verify_host_key_dns == 1 &&
987
			    flags & DNS_VERIFY_MATCH &&
1148
			    flags & DNS_VERIFY_MATCH &&
988
			    flags & DNS_VERIFY_SECURE)
1149
			    flags & DNS_VERIFY_SECURE)
1150
#ifndef DNSSEC_LOCAL_VALIDATION
1151
				return 0;
1152
#else
1153
                        {
1154
                            if (flags & DNS_VERIFY_MATCH)
1155
				matching_host_key_dns = 1;
1156
                            if (options.autoanswer_validated_keys)
1157
                                return check_host_key(host, hostaddr, options.port,
1158
                                                      host_key, RDRW,
1159
                                                      options.user_hostfile,
1160
                                                      options.system_hostfile);
1161
                            else
989
				return 0;
1162
				return 0;
1163
                        }
1164
#endif
990
1165
991
			if (flags & DNS_VERIFY_MATCH) {
1166
			if (flags & DNS_VERIFY_MATCH) {
992
				matching_host_key_dns = 1;
1167
				matching_host_key_dns = 1;
Lines 1137-1145 warn_changed_key(Key *host_key) Link Here
1137
	error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
1312
	error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
1138
	error("@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @");
1313
	error("@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @");
1139
	error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
1314
	error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
1315
#ifdef DNSSEC_LOCAL_VALIDATION
1316
        if (matching_host_key_dns && validated_host_key_dns) {
1317
            error("Howerver, a matching host key, validated by DNSSEC, was found.");
1318
        }
1319
        else {
1320
#endif
1140
	error("IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!");
1321
	error("IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!");
1141
	error("Someone could be eavesdropping on you right now (man-in-the-middle attack)!");
1322
	error("Someone could be eavesdropping on you right now (man-in-the-middle attack)!");
1142
	error("It is also possible that the %s host key has just been changed.", type);
1323
	error("It is also possible that the %s host key has just been changed.", type);
1324
#ifdef DNSSEC_LOCAL_VALIDATION
1325
        }
1326
#endif
1143
	error("The fingerprint for the %s key sent by the remote host is\n%s.",
1327
	error("The fingerprint for the %s key sent by the remote host is\n%s.",
1144
	    type, fp);
1328
	    type, fp);
1145
	error("Please contact your system administrator.");
1329
	error("Please contact your system administrator.");

Return to bug 1672