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

Collapse All | Expand All

(-)sshconnect.c (-24 / +50 lines)
Lines 545-556 confirm(const char *prompt) Link Here
545
 * is not valid. the user_hostfile will not be updated if 'readonly' is true.
545
 * is not valid. the user_hostfile will not be updated if 'readonly' is true.
546
 */
546
 */
547
static int
547
static int
548
check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
548
check_host_key(char *host, char *port, struct sockaddr *hostaddr, Key *host_key,
549
    int readonly, const char *user_hostfile, const char *system_hostfile)
549
    int readonly, const char *user_hostfile, const char *system_hostfile)
550
{
550
{
551
	Key *file_key;
551
	Key *file_key;
552
	const char *type = key_type(host_key);
552
	const char *type = key_type(host_key);
553
	char *ip = NULL;
553
	char *ip = NULL;
554
	char *hoststr = NULL;
555
	char *ipstr = NULL;
554
	char hostline[1000], *hostp, *fp;
556
	char hostline[1000], *hostp, *fp;
555
	HostStatus host_status;
557
	HostStatus host_status;
556
	HostStatus ip_status;
558
	HostStatus ip_status;
Lines 620-626 check_host_key(char *host, struct sockad Link Here
620
	 */
622
	 */
621
	if (options.host_key_alias != NULL) {
623
	if (options.host_key_alias != NULL) {
622
		host = options.host_key_alias;
624
		host = options.host_key_alias;
623
		debug("using hostkeyalias: %s", host);
625
		hoststr = xstrdup(host);
626
		ipstr = xstrdup(ip);
627
		debug("using hostkeyalias: %s", hoststr);
628
	} else {
629
		/*
630
		 * Have no HostKeyAlias; make ssh client PortAware
631
		 */
632
		len = strlen(host) + strlen(port) + 2;
633
		hoststr = xmalloc(len);
634
		snprintf(hoststr, len, "%s@%s", host, port);
635
		len = strlen(ip) + strlen(port) + 2;
636
		ipstr = xmalloc(len);
637
		snprintf(ipstr, len, "%s@%s", ip, port);
624
	}
638
	}
625
639
626
	/*
640
	/*
Lines 634-646 check_host_key(char *host, struct sockad Link Here
634
	 * hosts or in the systemwide list.
648
	 * hosts or in the systemwide list.
635
	 */
649
	 */
636
	host_file = user_hostfile;
650
	host_file = user_hostfile;
637
	host_status = check_host_in_hostfile(host_file, host, host_key,
651
	host_status = check_host_in_hostfile(host_file, hoststr, host_key,
638
	    file_key, &host_line);
652
	    file_key, &host_line);
639
	if (host_status == HOST_NEW) {
653
	if (host_status == HOST_NEW) {
640
		host_file = system_hostfile;
654
		host_file = system_hostfile;
641
		host_status = check_host_in_hostfile(host_file, host, host_key,
655
		host_status = check_host_in_hostfile(host_file, hoststr, host_key,
642
		    file_key, &host_line);
656
		    file_key, &host_line);
643
	}
657
	}
658
644
	/*
659
	/*
645
	 * Also perform check for the ip address, skip the check if we are
660
	 * Also perform check for the ip address, skip the check if we are
646
	 * localhost or the hostname was an ip address to begin with
661
	 * localhost or the hostname was an ip address to begin with
Lines 649-659 check_host_key(char *host, struct sockad Link Here
649
		Key *ip_key = key_new(host_key->type);
664
		Key *ip_key = key_new(host_key->type);
650
665
651
		ip_file = user_hostfile;
666
		ip_file = user_hostfile;
652
		ip_status = check_host_in_hostfile(ip_file, ip, host_key,
667
		ip_status = check_host_in_hostfile(ip_file, ipstr, host_key,
653
		    ip_key, &ip_line);
668
		    ip_key, &ip_line);
654
		if (ip_status == HOST_NEW) {
669
		if (ip_status == HOST_NEW) {
655
			ip_file = system_hostfile;
670
			ip_file = system_hostfile;
656
			ip_status = check_host_in_hostfile(ip_file, ip,
671
			ip_status = check_host_in_hostfile(ip_file, ipstr,
657
			    host_key, ip_key, &ip_line);
672
			    host_key, ip_key, &ip_line);
658
		}
673
		}
659
		if (host_status == HOST_CHANGED &&
674
		if (host_status == HOST_CHANGED &&
Lines 670-691 check_host_key(char *host, struct sockad Link Here
670
	case HOST_OK:
685
	case HOST_OK:
671
		/* The host is known and the key matches. */
686
		/* The host is known and the key matches. */
672
		debug("Host '%.200s' is known and matches the %s host key.",
687
		debug("Host '%.200s' is known and matches the %s host key.",
673
		    host, type);
688
		    hoststr, type);
674
		debug("Found key in %s:%d", host_file, host_line);
689
		debug("Found key in %s:%d", host_file, host_line);
675
		if (options.check_host_ip && ip_status == HOST_NEW) {
690
		if (options.check_host_ip && ip_status == HOST_NEW) {
676
			if (readonly)
691
			if (readonly)
677
				logit("%s host key for IP address "
692
				logit("%s host key for IP address "
678
				    "'%.128s' not in list of known hosts.",
693
				    "'%.128s' not in list of known hosts.",
679
				    type, ip);
694
				    type, ipstr);
680
			else if (!add_host_to_hostfile(user_hostfile, ip,
695
			else if (!add_host_to_hostfile(user_hostfile, ip,
681
			    host_key, options.hash_known_hosts))
696
			    host_key, options.hash_known_hosts))
682
				logit("Failed to add the %s host key for IP "
697
				logit("Failed to add the %s host key for IP "
683
				    "address '%.128s' to the list of known "
698
				    "address '%.128s' to the list of known "
684
				    "hosts (%.30s).", type, ip, user_hostfile);
699
				    "hosts (%.30s).", type, ipstr,
700
				    user_hostfile);
685
			else
701
			else
686
				logit("Warning: Permanently added the %s host "
702
				logit("Warning: Permanently added the %s host "
687
				    "key for IP address '%.128s' to the list "
703
				    "key for IP address '%.128s' to the list "
688
				    "of known hosts.", type, ip);
704
				    "of known hosts.", type, ipstr);
689
		}
705
		}
690
		break;
706
		break;
691
	case HOST_NEW:
707
	case HOST_NEW:
Lines 699-710 check_host_key(char *host, struct sockad Link Here
699
			 * alternative left is to abort.
715
			 * alternative left is to abort.
700
			 */
716
			 */
701
			error("No %s host key is known for %.200s and you "
717
			error("No %s host key is known for %.200s and you "
702
			    "have requested strict checking.", type, host);
718
			    "have requested strict checking.", type, hoststr);
703
			goto fail;
719
			goto fail;
704
		} else if (options.strict_host_key_checking == 2) {
720
		} else if (options.strict_host_key_checking == 2) {
705
			char msg1[1024], msg2[1024];
721
			char msg1[1024], msg2[1024];
706
722
707
			if (show_other_keys(host, host_key))
723
			if (show_other_keys(hoststr, host_key))
708
				snprintf(msg1, sizeof(msg1),
724
				snprintf(msg1, sizeof(msg1),
709
				   "\nbut keys of different type are already"
725
				   "\nbut keys of different type are already"
710
				   " known for this host.");
726
				   " known for this host.");
Lines 729-735 check_host_key(char *host, struct sockad Link Here
729
			    "%s key fingerprint is %s.\n%s"
745
			    "%s key fingerprint is %s.\n%s"
730
			    "Are you sure you want to continue connecting "
746
			    "Are you sure you want to continue connecting "
731
			    "(yes/no)? ",
747
			    "(yes/no)? ",
732
			    host, ip, msg1, type, fp, msg2);
748
			    host, ipstr, msg1, type, fp, msg2);
733
			xfree(fp);
749
			xfree(fp);
734
			if (!confirm(msg))
750
			if (!confirm(msg))
735
				goto fail;
751
				goto fail;
Lines 740-746 check_host_key(char *host, struct sockad Link Here
740
		 */
756
		 */
741
		if (options.check_host_ip && ip_status == HOST_NEW) {
757
		if (options.check_host_ip && ip_status == HOST_NEW) {
742
			snprintf(hostline, sizeof(hostline), "%s,%s",
758
			snprintf(hostline, sizeof(hostline), "%s,%s",
743
			    host, ip);
759
			    hoststr, ipstr);
744
			hostp = hostline;
760
			hostp = hostline;
745
			if (options.hash_known_hosts) {
761
			if (options.hash_known_hosts) {
746
				/* Add hash of host and IP separately */
762
				/* Add hash of host and IP separately */
Lines 757-763 check_host_key(char *host, struct sockad Link Here
757
		} else {
773
		} else {
758
			r = add_host_to_hostfile(user_hostfile, host, host_key,
774
			r = add_host_to_hostfile(user_hostfile, host, host_key,
759
			    options.hash_known_hosts);
775
			    options.hash_known_hosts);
760
			hostp = host;
776
			hostp = hoststr;
761
		}
777
		}
762
778
763
		if (!r)
779
		if (!r)
Lines 779-786 check_host_key(char *host, struct sockad Link Here
779
			error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
795
			error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
780
			error("@       WARNING: POSSIBLE DNS SPOOFING DETECTED!          @");
796
			error("@       WARNING: POSSIBLE DNS SPOOFING DETECTED!          @");
781
			error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
797
			error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
782
			error("The %s host key for %s has changed,", type, host);
798
			error("The %s host key for %s has changed,", type, hoststr);
783
			error("and the key for the according IP address %s", ip);
799
			error("and the key for the according IP address %s", ipstr);
784
			error("%s. This could either mean that", key_msg);
800
			error("%s. This could either mean that", key_msg);
785
			error("DNS SPOOFING is happening or the IP address for the host");
801
			error("DNS SPOOFING is happening or the IP address for the host");
786
			error("and its host key have changed at the same time.");
802
			error("and its host key have changed at the same time.");
Lines 799-805 check_host_key(char *host, struct sockad Link Here
799
		 */
815
		 */
800
		if (options.strict_host_key_checking) {
816
		if (options.strict_host_key_checking) {
801
			error("%s host key for %.200s has changed and you have "
817
			error("%s host key for %.200s has changed and you have "
802
			    "requested strict checking.", type, host);
818
			    "requested strict checking.", type, hoststr);
803
			goto fail;
819
			goto fail;
804
		}
820
		}
805
821
Lines 860-866 check_host_key(char *host, struct sockad Link Here
860
		    "Warning: the %s host key for '%.200s' "
876
		    "Warning: the %s host key for '%.200s' "
861
		    "differs from the key for the IP address '%.128s'"
877
		    "differs from the key for the IP address '%.128s'"
862
		    "\nOffending key for IP in %s:%d",
878
		    "\nOffending key for IP in %s:%d",
863
		    type, host, ip, ip_file, ip_line);
879
		    type, hoststr, ipstr, ip_file, ip_line);
864
		if (host_status == HOST_OK) {
880
		if (host_status == HOST_OK) {
865
			len = strlen(msg);
881
			len = strlen(msg);
866
			snprintf(msg + len, sizeof(msg) - len,
882
			snprintf(msg + len, sizeof(msg) - len,
Lines 882-897 check_host_key(char *host, struct sockad Link Here
882
	}
898
	}
883
899
884
	xfree(ip);
900
	xfree(ip);
901
	xfree(hoststr);
902
	xfree(ipstr);
885
	return 0;
903
	return 0;
886
904
887
fail:
905
fail:
888
	xfree(ip);
906
	xfree(ip);
907
	xfree(hoststr);
908
	xfree(ipstr);
889
	return -1;
909
	return -1;
890
}
910
}
891
911
892
/* returns 0 if key verifies or -1 if key does NOT verify */
912
/* returns 0 if key verifies or -1 if key does NOT verify */
893
int
913
int
894
verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key)
914
verify_host_key(char *host, char *port, struct sockaddr *hostaddr, Key *host_key)
895
{
915
{
896
	struct stat st;
916
	struct stat st;
897
	int flags = 0;
917
	int flags = 0;
Lines 919-929 verify_host_key(char *host, struct socka Link Here
919
	/* return ok if the key can be found in an old keyfile */
939
	/* return ok if the key can be found in an old keyfile */
920
	if (stat(options.system_hostfile2, &st) == 0 ||
940
	if (stat(options.system_hostfile2, &st) == 0 ||
921
	    stat(options.user_hostfile2, &st) == 0) {
941
	    stat(options.user_hostfile2, &st) == 0) {
922
		if (check_host_key(host, hostaddr, host_key, /*readonly*/ 1,
942
		if (check_host_key(host, port, hostaddr, host_key, /*readonly*/ 1,
923
		    options.user_hostfile2, options.system_hostfile2) == 0)
943
		    options.user_hostfile2, options.system_hostfile2) == 0)
924
			return 0;
944
			return 0;
925
	}
945
	}
926
	return check_host_key(host, hostaddr, host_key, /*readonly*/ 0,
946
	return check_host_key(host, port, hostaddr, host_key, /*readonly*/ 0,
927
	    options.user_hostfile, options.system_hostfile);
947
	    options.user_hostfile, options.system_hostfile);
928
}
948
}
929
949
Lines 940-949 ssh_login(Sensitive *sensitive, const ch Link Here
940
{
960
{
941
	char *host, *cp;
961
	char *host, *cp;
942
	char *server_user, *local_user;
962
	char *server_user, *local_user;
963
	u_short port;
964
	char strport[NI_MAXSERV];
943
965
944
	local_user = xstrdup(pw->pw_name);
966
	local_user = xstrdup(pw->pw_name);
945
	server_user = options.user ? options.user : local_user;
967
	server_user = options.user ? options.user : local_user;
946
968
969
	/* Set default port */
970
	port = options.port ? options.port : 22;
971
	snprintf(strport, sizeof strport, "%hu", port);
972
947
	/* Convert the user-supplied hostname into all lowercase. */
973
	/* Convert the user-supplied hostname into all lowercase. */
948
	host = xstrdup(orighost);
974
	host = xstrdup(orighost);
949
	for (cp = host; *cp; cp++)
975
	for (cp = host; *cp; cp++)
Lines 959-968 ssh_login(Sensitive *sensitive, const ch Link Here
959
	/* key exchange */
985
	/* key exchange */
960
	/* authenticate user */
986
	/* authenticate user */
961
	if (compat20) {
987
	if (compat20) {
962
		ssh_kex2(host, hostaddr);
988
		ssh_kex2(host, strport, hostaddr);
963
		ssh_userauth2(local_user, server_user, host, sensitive);
989
		ssh_userauth2(local_user, server_user, host, sensitive);
964
	} else {
990
	} else {
965
		ssh_kex(host, hostaddr);
991
		ssh_kex(host, strport, hostaddr);
966
		ssh_userauth1(local_user, server_user, host, sensitive);
992
		ssh_userauth1(local_user, server_user, host, sensitive);
967
	}
993
	}
968
}
994
}
(-)sshconnect.h (-3 / +3 lines)
Lines 40-49 ssh_connect(const char *, struct sockadd Link Here
40
void
40
void
41
ssh_login(Sensitive *, const char *, struct sockaddr *, struct passwd *);
41
ssh_login(Sensitive *, const char *, struct sockaddr *, struct passwd *);
42
42
43
int	 verify_host_key(char *, struct sockaddr *, Key *);
43
int	 verify_host_key(char *, char *, struct sockaddr *, Key *);
44
44
45
void	 ssh_kex(char *, struct sockaddr *);
45
void	 ssh_kex(char *, char *, struct sockaddr *);
46
void	 ssh_kex2(char *, struct sockaddr *);
46
void	 ssh_kex2(char *, char *, struct sockaddr *);
47
47
48
void	 ssh_userauth1(const char *, const char *, char *, Sensitive *);
48
void	 ssh_userauth1(const char *, const char *, char *, Sensitive *);
49
void	 ssh_userauth2(const char *, const char *, char *, Sensitive *);
49
void	 ssh_userauth2(const char *, const char *, char *, Sensitive *);
(-)sshconnect1.c (-2 / +2 lines)
Lines 465-471 try_password_authentication(char *prompt Link Here
465
 * SSH1 key exchange
465
 * SSH1 key exchange
466
 */
466
 */
467
void
467
void
468
ssh_kex(char *host, struct sockaddr *hostaddr)
468
ssh_kex(char *host, char *port, struct sockaddr *hostaddr)
469
{
469
{
470
	int i;
470
	int i;
471
	BIGNUM *key;
471
	BIGNUM *key;
Lines 523-529 ssh_kex(char *host, struct sockaddr *hos Link Here
523
	debug("Received server public key (%d bits) and host key (%d bits).",
523
	debug("Received server public key (%d bits) and host key (%d bits).",
524
	    BN_num_bits(server_key->rsa->n), BN_num_bits(host_key->rsa->n));
524
	    BN_num_bits(server_key->rsa->n), BN_num_bits(host_key->rsa->n));
525
525
526
	if (verify_host_key(host, hostaddr, host_key) == -1)
526
	if (verify_host_key(host, port, hostaddr, host_key) == -1)
527
		fatal("Host key verification failed.");
527
		fatal("Host key verification failed.");
528
528
529
	client_flags = SSH_PROTOFLAG_SCREEN_NUMBER | SSH_PROTOFLAG_HOST_IN_FWD_OPEN;
529
	client_flags = SSH_PROTOFLAG_SCREEN_NUMBER | SSH_PROTOFLAG_HOST_IN_FWD_OPEN;
(-)sshconnect2.c (-2 / +4 lines)
Lines 68-90 u_int session_id2_len = 0; Link Here
68
68
69
char *xxx_host;
69
char *xxx_host;
70
struct sockaddr *xxx_hostaddr;
70
struct sockaddr *xxx_hostaddr;
71
char *xxx_port;
71
72
72
Kex *xxx_kex = NULL;
73
Kex *xxx_kex = NULL;
73
74
74
static int
75
static int
75
verify_host_key_callback(Key *hostkey)
76
verify_host_key_callback(Key *hostkey)
76
{
77
{
77
	if (verify_host_key(xxx_host, xxx_hostaddr, hostkey) == -1)
78
	if (verify_host_key(xxx_host, xxx_port, xxx_hostaddr, hostkey) == -1)
78
		fatal("Host key verification failed.");
79
		fatal("Host key verification failed.");
79
	return 0;
80
	return 0;
80
}
81
}
81
82
82
void
83
void
83
ssh_kex2(char *host, struct sockaddr *hostaddr)
84
ssh_kex2(char *host, char *port, struct sockaddr *hostaddr)
84
{
85
{
85
	Kex *kex;
86
	Kex *kex;
86
87
87
	xxx_host = host;
88
	xxx_host = host;
89
	xxx_port = port;
88
	xxx_hostaddr = hostaddr;
90
	xxx_hostaddr = hostaddr;
89
91
90
	if (options.ciphers == (char *)-1) {
92
	if (options.ciphers == (char *)-1) {

Return to bug 910