|
Lines 520-526
check_host_key(char *host, struct sockad
Link Here
|
| 520 |
{ |
520 |
{ |
| 521 |
Key *file_key; |
521 |
Key *file_key; |
| 522 |
const char *type = key_type(host_key); |
522 |
const char *type = key_type(host_key); |
| 523 |
char *ip = NULL; |
523 |
char *ip = NULL, *hoststr = NULL, *ipstr = NULL; |
| 524 |
char hostline[1000], *hostp, *fp; |
524 |
char hostline[1000], *hostp, *fp; |
| 525 |
HostStatus host_status; |
525 |
HostStatus host_status; |
| 526 |
HostStatus ip_status; |
526 |
HostStatus ip_status; |
|
Lines 580-593
check_host_key(char *host, struct sockad
Link Here
|
| 580 |
options.check_host_ip = 0; |
580 |
options.check_host_ip = 0; |
| 581 |
|
581 |
|
| 582 |
/* |
582 |
/* |
| 583 |
* Allow the user to record the key under a different name. This is |
583 |
* Allow the user to record the key under a different name or |
| 584 |
* useful for ssh tunneling over forwarded connections or if you run |
584 |
* differentiate a non-standard port. This is useful for ssh |
| 585 |
* multiple sshd's on different ports on the same machine. |
585 |
* tunneling over forwarded connections or if you run multiple |
|
|
586 |
* sshd's on different ports on the same machine. |
| 586 |
*/ |
587 |
*/ |
| 587 |
if (options.host_key_alias != NULL) { |
588 |
if (options.host_key_alias != NULL) { |
| 588 |
host = options.host_key_alias; |
589 |
host = options.host_key_alias; |
| 589 |
debug("using hostkeyalias: %s", host); |
590 |
debug("using hostkeyalias: %s", host); |
|
|
591 |
hoststr = xstrdup(host); |
| 592 |
} else { |
| 593 |
hoststr = put_host_port(host, options.port); |
| 590 |
} |
594 |
} |
|
|
595 |
ipstr = put_host_port(ip, options.port); |
| 591 |
|
596 |
|
| 592 |
/* |
597 |
/* |
| 593 |
* Store the host key from the known host file in here so that we can |
598 |
* Store the host key from the known host file in here so that we can |
|
Lines 600-611
check_host_key(char *host, struct sockad
Link Here
|
| 600 |
* hosts or in the systemwide list. |
605 |
* hosts or in the systemwide list. |
| 601 |
*/ |
606 |
*/ |
| 602 |
host_file = user_hostfile; |
607 |
host_file = user_hostfile; |
| 603 |
host_status = check_host_in_hostfile(host_file, host, host_key, |
608 |
host_status = check_host_in_hostfile(host_file, hoststr, host_key, |
| 604 |
file_key, &host_line); |
609 |
file_key, &host_line); |
| 605 |
if (host_status == HOST_NEW) { |
610 |
if (host_status == HOST_NEW) { |
| 606 |
host_file = system_hostfile; |
611 |
host_file = system_hostfile; |
| 607 |
host_status = check_host_in_hostfile(host_file, host, host_key, |
612 |
host_status = check_host_in_hostfile(host_file, hoststr, |
| 608 |
file_key, &host_line); |
613 |
host_key, file_key, &host_line); |
| 609 |
} |
614 |
} |
| 610 |
/* |
615 |
/* |
| 611 |
* Also perform check for the ip address, skip the check if we are |
616 |
* Also perform check for the ip address, skip the check if we are |
|
Lines 615-625
check_host_key(char *host, struct sockad
Link Here
|
| 615 |
Key *ip_key = key_new(host_key->type); |
620 |
Key *ip_key = key_new(host_key->type); |
| 616 |
|
621 |
|
| 617 |
ip_file = user_hostfile; |
622 |
ip_file = user_hostfile; |
| 618 |
ip_status = check_host_in_hostfile(ip_file, ip, host_key, |
623 |
ip_status = check_host_in_hostfile(ip_file, ipstr, host_key, |
| 619 |
ip_key, &ip_line); |
624 |
ip_key, &ip_line); |
| 620 |
if (ip_status == HOST_NEW) { |
625 |
if (ip_status == HOST_NEW) { |
| 621 |
ip_file = system_hostfile; |
626 |
ip_file = system_hostfile; |
| 622 |
ip_status = check_host_in_hostfile(ip_file, ip, |
627 |
ip_status = check_host_in_hostfile(ip_file, ipstr, |
| 623 |
host_key, ip_key, &ip_line); |
628 |
host_key, ip_key, &ip_line); |
| 624 |
} |
629 |
} |
| 625 |
if (host_status == HOST_CHANGED && |
630 |
if (host_status == HOST_CHANGED && |
|
Lines 636-657
check_host_key(char *host, struct sockad
Link Here
|
| 636 |
case HOST_OK: |
641 |
case HOST_OK: |
| 637 |
/* The host is known and the key matches. */ |
642 |
/* The host is known and the key matches. */ |
| 638 |
debug("Host '%.200s' is known and matches the %s host key.", |
643 |
debug("Host '%.200s' is known and matches the %s host key.", |
| 639 |
host, type); |
644 |
hoststr, type); |
| 640 |
debug("Found key in %s:%d", host_file, host_line); |
645 |
debug("Found key in %s:%d", host_file, host_line); |
| 641 |
if (options.check_host_ip && ip_status == HOST_NEW) { |
646 |
if (options.check_host_ip && ip_status == HOST_NEW) { |
| 642 |
if (readonly) |
647 |
if (readonly) |
| 643 |
logit("%s host key for IP address " |
648 |
logit("%s host key for IP address " |
| 644 |
"'%.128s' not in list of known hosts.", |
649 |
"'%.128s' not in list of known hosts.", |
| 645 |
type, ip); |
650 |
type, ipstr); |
| 646 |
else if (!add_host_to_hostfile(user_hostfile, ip, |
651 |
else if (!add_host_to_hostfile(user_hostfile, ip, |
| 647 |
host_key, options.hash_known_hosts)) |
652 |
host_key, options.hash_known_hosts)) |
| 648 |
logit("Failed to add the %s host key for IP " |
653 |
logit("Failed to add the %s host key for IP " |
| 649 |
"address '%.128s' to the list of known " |
654 |
"address '%.128s' to the list of known " |
| 650 |
"hosts (%.30s).", type, ip, user_hostfile); |
655 |
"hosts (%.30s).", type, ipstr, |
|
|
656 |
user_hostfile); |
| 651 |
else |
657 |
else |
| 652 |
logit("Warning: Permanently added the %s host " |
658 |
logit("Warning: Permanently added the %s host " |
| 653 |
"key for IP address '%.128s' to the list " |
659 |
"key for IP address '%.128s' to the list " |
| 654 |
"of known hosts.", type, ip); |
660 |
"of known hosts.", type, ipstr); |
| 655 |
} |
661 |
} |
| 656 |
break; |
662 |
break; |
| 657 |
case HOST_NEW: |
663 |
case HOST_NEW: |
|
Lines 665-676
check_host_key(char *host, struct sockad
Link Here
|
| 665 |
* alternative left is to abort. |
671 |
* alternative left is to abort. |
| 666 |
*/ |
672 |
*/ |
| 667 |
error("No %s host key is known for %.200s and you " |
673 |
error("No %s host key is known for %.200s and you " |
| 668 |
"have requested strict checking.", type, host); |
674 |
"have requested strict checking.", type, hoststr); |
| 669 |
goto fail; |
675 |
goto fail; |
| 670 |
} else if (options.strict_host_key_checking == 2) { |
676 |
} else if (options.strict_host_key_checking == 2) { |
| 671 |
char msg1[1024], msg2[1024]; |
677 |
char msg1[1024], msg2[1024]; |
| 672 |
|
678 |
|
| 673 |
if (show_other_keys(host, host_key)) |
679 |
if (show_other_keys(hoststr, host_key)) |
| 674 |
snprintf(msg1, sizeof(msg1), |
680 |
snprintf(msg1, sizeof(msg1), |
| 675 |
"\nbut keys of different type are already" |
681 |
"\nbut keys of different type are already" |
| 676 |
" known for this host."); |
682 |
" known for this host."); |
|
Lines 695-701
check_host_key(char *host, struct sockad
Link Here
|
| 695 |
"%s key fingerprint is %s.\n%s" |
701 |
"%s key fingerprint is %s.\n%s" |
| 696 |
"Are you sure you want to continue connecting " |
702 |
"Are you sure you want to continue connecting " |
| 697 |
"(yes/no)? ", |
703 |
"(yes/no)? ", |
| 698 |
host, ip, msg1, type, fp, msg2); |
704 |
hoststr, ipstr, msg1, type, fp, msg2); |
| 699 |
xfree(fp); |
705 |
xfree(fp); |
| 700 |
if (!confirm(msg)) |
706 |
if (!confirm(msg)) |
| 701 |
goto fail; |
707 |
goto fail; |
|
Lines 706-718
check_host_key(char *host, struct sockad
Link Here
|
| 706 |
*/ |
712 |
*/ |
| 707 |
if (options.check_host_ip && ip_status == HOST_NEW) { |
713 |
if (options.check_host_ip && ip_status == HOST_NEW) { |
| 708 |
snprintf(hostline, sizeof(hostline), "%s,%s", |
714 |
snprintf(hostline, sizeof(hostline), "%s,%s", |
| 709 |
host, ip); |
715 |
hoststr, ipstr); |
| 710 |
hostp = hostline; |
716 |
hostp = hostline; |
| 711 |
if (options.hash_known_hosts) { |
717 |
if (options.hash_known_hosts) { |
| 712 |
/* Add hash of host and IP separately */ |
718 |
/* Add hash of host and IP separately */ |
| 713 |
r = add_host_to_hostfile(user_hostfile, host, |
719 |
r = add_host_to_hostfile(user_hostfile, hoststr, |
| 714 |
host_key, options.hash_known_hosts) && |
720 |
host_key, options.hash_known_hosts) && |
| 715 |
add_host_to_hostfile(user_hostfile, ip, |
721 |
add_host_to_hostfile(user_hostfile, ipstr, |
| 716 |
host_key, options.hash_known_hosts); |
722 |
host_key, options.hash_known_hosts); |
| 717 |
} else { |
723 |
} else { |
| 718 |
/* Add unhashed "host,ip" */ |
724 |
/* Add unhashed "host,ip" */ |
|
Lines 721-729
check_host_key(char *host, struct sockad
Link Here
|
| 721 |
options.hash_known_hosts); |
727 |
options.hash_known_hosts); |
| 722 |
} |
728 |
} |
| 723 |
} else { |
729 |
} else { |
| 724 |
r = add_host_to_hostfile(user_hostfile, host, host_key, |
730 |
r = add_host_to_hostfile(user_hostfile, hoststr, |
| 725 |
options.hash_known_hosts); |
731 |
host_key, options.hash_known_hosts); |
| 726 |
hostp = host; |
732 |
hostp = hoststr; |
| 727 |
} |
733 |
} |
| 728 |
|
734 |
|
| 729 |
if (!r) |
735 |
if (!r) |
|
Lines 745-752
check_host_key(char *host, struct sockad
Link Here
|
| 745 |
error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); |
751 |
error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); |
| 746 |
error("@ WARNING: POSSIBLE DNS SPOOFING DETECTED! @"); |
752 |
error("@ WARNING: POSSIBLE DNS SPOOFING DETECTED! @"); |
| 747 |
error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); |
753 |
error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); |
| 748 |
error("The %s host key for %s has changed,", type, host); |
754 |
error("The %s host key for %s has changed,", type, hoststr); |
| 749 |
error("and the key for the according IP address %s", ip); |
755 |
error("and the key for the according IP address %s", ipstr); |
| 750 |
error("%s. This could either mean that", key_msg); |
756 |
error("%s. This could either mean that", key_msg); |
| 751 |
error("DNS SPOOFING is happening or the IP address for the host"); |
757 |
error("DNS SPOOFING is happening or the IP address for the host"); |
| 752 |
error("and its host key have changed at the same time."); |
758 |
error("and its host key have changed at the same time."); |
|
Lines 765-771
check_host_key(char *host, struct sockad
Link Here
|
| 765 |
*/ |
771 |
*/ |
| 766 |
if (options.strict_host_key_checking) { |
772 |
if (options.strict_host_key_checking) { |
| 767 |
error("%s host key for %.200s has changed and you have " |
773 |
error("%s host key for %.200s has changed and you have " |
| 768 |
"requested strict checking.", type, host); |
774 |
"requested strict checking.", type, hoststr); |
| 769 |
goto fail; |
775 |
goto fail; |
| 770 |
} |
776 |
} |
| 771 |
|
777 |
|
|
Lines 826-832
check_host_key(char *host, struct sockad
Link Here
|
| 826 |
"Warning: the %s host key for '%.200s' " |
832 |
"Warning: the %s host key for '%.200s' " |
| 827 |
"differs from the key for the IP address '%.128s'" |
833 |
"differs from the key for the IP address '%.128s'" |
| 828 |
"\nOffending key for IP in %s:%d", |
834 |
"\nOffending key for IP in %s:%d", |
| 829 |
type, host, ip, ip_file, ip_line); |
835 |
type, hoststr, ipstr, ip_file, ip_line); |
| 830 |
if (host_status == HOST_OK) { |
836 |
if (host_status == HOST_OK) { |
| 831 |
len = strlen(msg); |
837 |
len = strlen(msg); |
| 832 |
snprintf(msg + len, sizeof(msg) - len, |
838 |
snprintf(msg + len, sizeof(msg) - len, |
|
Lines 848-857
check_host_key(char *host, struct sockad
Link Here
|
| 848 |
} |
854 |
} |
| 849 |
|
855 |
|
| 850 |
xfree(ip); |
856 |
xfree(ip); |
|
|
857 |
xfree(hoststr); |
| 858 |
xfree(ipstr); |
| 851 |
return 0; |
859 |
return 0; |
| 852 |
|
860 |
|
| 853 |
fail: |
861 |
fail: |
| 854 |
xfree(ip); |
862 |
xfree(ip); |
|
|
863 |
xfree(hoststr); |
| 864 |
xfree(ipstr); |
| 855 |
return -1; |
865 |
return -1; |
| 856 |
} |
866 |
} |
| 857 |
|
867 |
|