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

Collapse All | Expand All

(-)sshconnect.c (-24 / +49 lines)
Lines 550-556 check_host_key(char *host, struct sockad Link Here
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, *hoststr = NULL, *ipstr = NULL;
554
	char hostline[1000], *hostp, *fp;
554
	char hostline[1000], *hostp, *fp;
555
	HostStatus host_status;
555
	HostStatus host_status;
556
	HostStatus ip_status;
556
	HostStatus ip_status;
Lines 614-626 check_host_key(char *host, struct sockad Link Here
614
		options.check_host_ip = 0;
614
		options.check_host_ip = 0;
615
615
616
	/*
616
	/*
617
	 * Allow the user to record the key under a different name. This is
617
	 * Allow the user to record the key under a different name or
618
	 * useful for ssh tunneling over forwarded connections or if you run
618
	 * differentiate a non-standard port.  This is useful for ssh
619
	 * multiple sshd's on different ports on the same machine.
619
	 * tunneling over forwarded connections or if you run multiple
620
	 * sshd's on different ports on the same machine.
620
	 */
621
	 */
621
	if (options.host_key_alias != NULL) {
622
	if (options.host_key_alias != NULL) {
622
		host = options.host_key_alias;
623
		host = options.host_key_alias;
623
		debug("using hostkeyalias: %s", host);
624
		debug("using hostkeyalias: %s", host);
625
		hoststr = xstrdup(host);
626
		ipstr = xstrdup(ip);
627
	} else if (options.port == 0 || options.port == SSH_DEFAULT_PORT) {
628
		/* unspecified or default port */
629
		hoststr = xstrdup(host);
630
		ipstr = xstrdup(ip);
631
	} else {
632
		/* non-standard port, append port identifier */
633
		len = strlen(host) + sizeof(options.port) * 4 + 2;
634
		hoststr = xmalloc(len);
635
		r = snprintf(hoststr, len, "%s@%hu", host, options.port);
636
		if (r == -1 || r >= len)
637
			fatal("check_host_key: snprintf failed");
638
		len = strlen(ip) + sizeof(options.port) * 4 + 2;
639
		ipstr = xmalloc(len);
640
		r = snprintf(ipstr, len, "%s@%hu", ip, options.port);
641
		if (r == -1 || r >= len)
642
			fatal("check_host_key: snprintf failed");
624
	}
643
	}
625
644
626
	/*
645
	/*
Lines 634-646 check_host_key(char *host, struct sockad Link Here
634
	 * hosts or in the systemwide list.
653
	 * hosts or in the systemwide list.
635
	 */
654
	 */
636
	host_file = user_hostfile;
655
	host_file = user_hostfile;
637
	host_status = check_host_in_hostfile(host_file, host, host_key,
656
	host_status = check_host_in_hostfile(host_file, hoststr, host_key,
638
	    file_key, &host_line);
657
	    file_key, &host_line);
639
	if (host_status == HOST_NEW) {
658
	if (host_status == HOST_NEW) {
640
		host_file = system_hostfile;
659
		host_file = system_hostfile;
641
		host_status = check_host_in_hostfile(host_file, host, host_key,
660
		host_status = check_host_in_hostfile(host_file, hoststr,
642
		    file_key, &host_line);
661
		    host_key, file_key, &host_line);
643
	}
662
	}
663
644
	/*
664
	/*
645
	 * Also perform check for the ip address, skip the check if we are
665
	 * 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
666
	 * 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);
669
		Key *ip_key = key_new(host_key->type);
650
670
651
		ip_file = user_hostfile;
671
		ip_file = user_hostfile;
652
		ip_status = check_host_in_hostfile(ip_file, ip, host_key,
672
		ip_status = check_host_in_hostfile(ip_file, ipstr, host_key,
653
		    ip_key, &ip_line);
673
		    ip_key, &ip_line);
654
		if (ip_status == HOST_NEW) {
674
		if (ip_status == HOST_NEW) {
655
			ip_file = system_hostfile;
675
			ip_file = system_hostfile;
656
			ip_status = check_host_in_hostfile(ip_file, ip,
676
			ip_status = check_host_in_hostfile(ip_file, ipstr,
657
			    host_key, ip_key, &ip_line);
677
			    host_key, ip_key, &ip_line);
658
		}
678
		}
659
		if (host_status == HOST_CHANGED &&
679
		if (host_status == HOST_CHANGED &&
Lines 670-691 check_host_key(char *host, struct sockad Link Here
670
	case HOST_OK:
690
	case HOST_OK:
671
		/* The host is known and the key matches. */
691
		/* The host is known and the key matches. */
672
		debug("Host '%.200s' is known and matches the %s host key.",
692
		debug("Host '%.200s' is known and matches the %s host key.",
673
		    host, type);
693
		    hoststr, type);
674
		debug("Found key in %s:%d", host_file, host_line);
694
		debug("Found key in %s:%d", host_file, host_line);
675
		if (options.check_host_ip && ip_status == HOST_NEW) {
695
		if (options.check_host_ip && ip_status == HOST_NEW) {
676
			if (readonly)
696
			if (readonly)
677
				logit("%s host key for IP address "
697
				logit("%s host key for IP address "
678
				    "'%.128s' not in list of known hosts.",
698
				    "'%.128s' not in list of known hosts.",
679
				    type, ip);
699
				    type, ipstr);
680
			else if (!add_host_to_hostfile(user_hostfile, ip,
700
			else if (!add_host_to_hostfile(user_hostfile, ip,
681
			    host_key, options.hash_known_hosts))
701
			    host_key, options.hash_known_hosts))
682
				logit("Failed to add the %s host key for IP "
702
				logit("Failed to add the %s host key for IP "
683
				    "address '%.128s' to the list of known "
703
				    "address '%.128s' to the list of known "
684
				    "hosts (%.30s).", type, ip, user_hostfile);
704
				    "hosts (%.30s).", type, ipstr,
705
				    user_hostfile);
685
			else
706
			else
686
				logit("Warning: Permanently added the %s host "
707
				logit("Warning: Permanently added the %s host "
687
				    "key for IP address '%.128s' to the list "
708
				    "key for IP address '%.128s' to the list "
688
				    "of known hosts.", type, ip);
709
				    "of known hosts.", type, ipstr);
689
		}
710
		}
690
		break;
711
		break;
691
	case HOST_NEW:
712
	case HOST_NEW:
Lines 699-710 check_host_key(char *host, struct sockad Link Here
699
			 * alternative left is to abort.
720
			 * alternative left is to abort.
700
			 */
721
			 */
701
			error("No %s host key is known for %.200s and you "
722
			error("No %s host key is known for %.200s and you "
702
			    "have requested strict checking.", type, host);
723
			    "have requested strict checking.", type, hoststr);
703
			goto fail;
724
			goto fail;
704
		} else if (options.strict_host_key_checking == 2) {
725
		} else if (options.strict_host_key_checking == 2) {
705
			char msg1[1024], msg2[1024];
726
			char msg1[1024], msg2[1024];
706
727
707
			if (show_other_keys(host, host_key))
728
			if (show_other_keys(hoststr, host_key))
708
				snprintf(msg1, sizeof(msg1),
729
				snprintf(msg1, sizeof(msg1),
709
				   "\nbut keys of different type are already"
730
				   "\nbut keys of different type are already"
710
				   " known for this host.");
731
				   " known for this host.");
Lines 729-735 check_host_key(char *host, struct sockad Link Here
729
			    "%s key fingerprint is %s.\n%s"
750
			    "%s key fingerprint is %s.\n%s"
730
			    "Are you sure you want to continue connecting "
751
			    "Are you sure you want to continue connecting "
731
			    "(yes/no)? ",
752
			    "(yes/no)? ",
732
			    host, ip, msg1, type, fp, msg2);
753
			    hoststr, ipstr, msg1, type, fp, msg2);
733
			xfree(fp);
754
			xfree(fp);
734
			if (!confirm(msg))
755
			if (!confirm(msg))
735
				goto fail;
756
				goto fail;
Lines 740-752 check_host_key(char *host, struct sockad Link Here
740
		 */
761
		 */
741
		if (options.check_host_ip && ip_status == HOST_NEW) {
762
		if (options.check_host_ip && ip_status == HOST_NEW) {
742
			snprintf(hostline, sizeof(hostline), "%s,%s",
763
			snprintf(hostline, sizeof(hostline), "%s,%s",
743
			    host, ip);
764
			    hoststr, ipstr);
744
			hostp = hostline;
765
			hostp = hostline;
745
			if (options.hash_known_hosts) {
766
			if (options.hash_known_hosts) {
746
				/* Add hash of host and IP separately */
767
				/* Add hash of host and IP separately */
747
				r = add_host_to_hostfile(user_hostfile, host,
768
				r = add_host_to_hostfile(user_hostfile, hoststr,
748
				    host_key, options.hash_known_hosts) &&
769
				    host_key, options.hash_known_hosts) &&
749
				    add_host_to_hostfile(user_hostfile, ip,
770
				    add_host_to_hostfile(user_hostfile, ipstr,
750
				    host_key, options.hash_known_hosts);
771
				    host_key, options.hash_known_hosts);
751
			} else {
772
			} else {
752
				/* Add unhashed "host,ip" */
773
				/* Add unhashed "host,ip" */
Lines 757-763 check_host_key(char *host, struct sockad Link Here
757
		} else {
778
		} else {
758
			r = add_host_to_hostfile(user_hostfile, host, host_key,
779
			r = add_host_to_hostfile(user_hostfile, host, host_key,
759
			    options.hash_known_hosts);
780
			    options.hash_known_hosts);
760
			hostp = host;
781
			hostp = hoststr;
761
		}
782
		}
762
783
763
		if (!r)
784
		if (!r)
Lines 779-786 check_host_key(char *host, struct sockad Link Here
779
			error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
800
			error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
780
			error("@       WARNING: POSSIBLE DNS SPOOFING DETECTED!          @");
801
			error("@       WARNING: POSSIBLE DNS SPOOFING DETECTED!          @");
781
			error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
802
			error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
782
			error("The %s host key for %s has changed,", type, host);
803
			error("The %s host key for %s has changed,", type, hoststr);
783
			error("and the key for the according IP address %s", ip);
804
			error("and the key for the according IP address %s", ipstr);
784
			error("%s. This could either mean that", key_msg);
805
			error("%s. This could either mean that", key_msg);
785
			error("DNS SPOOFING is happening or the IP address for the host");
806
			error("DNS SPOOFING is happening or the IP address for the host");
786
			error("and its host key have changed at the same time.");
807
			error("and its host key have changed at the same time.");
Lines 799-805 check_host_key(char *host, struct sockad Link Here
799
		 */
820
		 */
800
		if (options.strict_host_key_checking) {
821
		if (options.strict_host_key_checking) {
801
			error("%s host key for %.200s has changed and you have "
822
			error("%s host key for %.200s has changed and you have "
802
			    "requested strict checking.", type, host);
823
			    "requested strict checking.", type, hoststr);
803
			goto fail;
824
			goto fail;
804
		}
825
		}
805
826
Lines 860-866 check_host_key(char *host, struct sockad Link Here
860
		    "Warning: the %s host key for '%.200s' "
881
		    "Warning: the %s host key for '%.200s' "
861
		    "differs from the key for the IP address '%.128s'"
882
		    "differs from the key for the IP address '%.128s'"
862
		    "\nOffending key for IP in %s:%d",
883
		    "\nOffending key for IP in %s:%d",
863
		    type, host, ip, ip_file, ip_line);
884
		    type, hoststr, ipstr, ip_file, ip_line);
864
		if (host_status == HOST_OK) {
885
		if (host_status == HOST_OK) {
865
			len = strlen(msg);
886
			len = strlen(msg);
866
			snprintf(msg + len, sizeof(msg) - len,
887
			snprintf(msg + len, sizeof(msg) - len,
Lines 882-891 check_host_key(char *host, struct sockad Link Here
882
	}
903
	}
883
904
884
	xfree(ip);
905
	xfree(ip);
906
	xfree(hoststr);
907
	xfree(ipstr);
885
	return 0;
908
	return 0;
886
909
887
fail:
910
fail:
888
	xfree(ip);
911
	xfree(ip);
912
	xfree(hoststr);
913
	xfree(ipstr);
889
	return -1;
914
	return -1;
890
}
915
}
891
916
(-)sshd.8 (+3 lines)
Lines 552-557 A pattern may also be preceded by Link Here
552
to indicate negation: if the host name matches a negated
552
to indicate negation: if the host name matches a negated
553
pattern, it is not accepted (by that line) even if it matched another
553
pattern, it is not accepted (by that line) even if it matched another
554
pattern on the line.
554
pattern on the line.
555
A hostname may optionally be followed by a
556
.Ql @
557
and then a non-standard port number.
555
.Pp
558
.Pp
556
Alternately, hostnames may be stored in a hashed form which hides host names
559
Alternately, hostnames may be stored in a hashed form which hides host names
557
and addresses should the file's contents be disclosed.
560
and addresses should the file's contents be disclosed.

Return to bug 910