|
Lines 31-36
Link Here
|
| 31 |
#include "readconf.h" |
31 |
#include "readconf.h" |
| 32 |
#include "atomicio.h" |
32 |
#include "atomicio.h" |
| 33 |
#include "misc.h" |
33 |
#include "misc.h" |
|
|
34 |
#include "readpass.h" |
| 34 |
|
35 |
|
| 35 |
char *client_version_string = NULL; |
36 |
char *client_version_string = NULL; |
| 36 |
char *server_version_string = NULL; |
37 |
char *server_version_string = NULL; |
|
Lines 480-519
Link Here
|
| 480 |
static int |
481 |
static int |
| 481 |
confirm(const char *prompt) |
482 |
confirm(const char *prompt) |
| 482 |
{ |
483 |
{ |
| 483 |
char buf[1024]; |
484 |
const char *msg, *again = "Please type 'yes' or 'no': "; |
| 484 |
FILE *f; |
485 |
char *p; |
| 485 |
int retval = -1; |
486 |
int ret = -1; |
| 486 |
|
487 |
|
| 487 |
if (options.batch_mode) |
488 |
if (options.batch_mode) |
| 488 |
return 0; |
489 |
return 0; |
| 489 |
if (isatty(STDIN_FILENO)) |
490 |
for (msg = prompt;;msg = again) { |
| 490 |
f = stdin; |
491 |
p = read_passphrase(msg, RP_ECHO); |
| 491 |
else |
492 |
if (p == NULL || |
| 492 |
f = fopen(_PATH_TTY, "rw"); |
493 |
(p[0] == '\0') || (p[0] == '\n') || |
| 493 |
if (f == NULL) |
494 |
strncasecmp(p, "no", 2) == 0) |
| 494 |
return 0; |
495 |
ret = 0; |
| 495 |
fflush(stdout); |
496 |
if (strncasecmp(p, "yes", 3) == 0) |
| 496 |
fprintf(stderr, "%s", prompt); |
497 |
ret = 1; |
| 497 |
while (1) { |
498 |
if (p) |
| 498 |
if (fgets(buf, sizeof(buf), f) == NULL) { |
499 |
xfree(p); |
| 499 |
fprintf(stderr, "\n"); |
500 |
if (ret != -1) |
| 500 |
strlcpy(buf, "no", sizeof buf); |
501 |
return ret; |
| 501 |
} |
|
|
| 502 |
/* Remove newline from response. */ |
| 503 |
if (strchr(buf, '\n')) |
| 504 |
*strchr(buf, '\n') = 0; |
| 505 |
if (strcmp(buf, "yes") == 0) |
| 506 |
retval = 1; |
| 507 |
else if (strcmp(buf, "no") == 0) |
| 508 |
retval = 0; |
| 509 |
else |
| 510 |
fprintf(stderr, "Please type 'yes' or 'no': "); |
| 511 |
|
| 512 |
if (retval != -1) { |
| 513 |
if (f != stdin) |
| 514 |
fclose(f); |
| 515 |
return retval; |
| 516 |
} |
| 517 |
} |
502 |
} |
| 518 |
} |
503 |
} |
| 519 |
|
504 |
|
|
Lines 534-540
Link Here
|
| 534 |
HostStatus ip_status; |
519 |
HostStatus ip_status; |
| 535 |
int local = 0, host_ip_differ = 0; |
520 |
int local = 0, host_ip_differ = 0; |
| 536 |
char ntop[NI_MAXHOST]; |
521 |
char ntop[NI_MAXHOST]; |
| 537 |
int host_line, ip_line; |
522 |
char msg[1024]; |
|
|
523 |
int len, host_line, ip_line; |
| 538 |
const char *host_file = NULL, *ip_file = NULL; |
524 |
const char *host_file = NULL, *ip_file = NULL; |
| 539 |
|
525 |
|
| 540 |
/* |
526 |
/* |
|
Lines 676-693
Link Here
|
| 676 |
goto fail; |
662 |
goto fail; |
| 677 |
} else if (options.strict_host_key_checking == 2) { |
663 |
} else if (options.strict_host_key_checking == 2) { |
| 678 |
/* The default */ |
664 |
/* The default */ |
| 679 |
char prompt[1024]; |
|
|
| 680 |
fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX); |
665 |
fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX); |
| 681 |
snprintf(prompt, sizeof(prompt), |
666 |
snprintf(msg, sizeof(msg), |
| 682 |
"The authenticity of host '%.200s (%s)' can't be " |
667 |
"The authenticity of host '%.200s (%s)' can't be " |
| 683 |
"established.\n" |
668 |
"established.\n" |
| 684 |
"%s key fingerprint is %s.\n" |
669 |
"%s key fingerprint is %s.\n" |
| 685 |
"Are you sure you want to continue connecting " |
670 |
"Are you sure you want to continue connecting " |
| 686 |
"(yes/no)? ", host, ip, type, fp); |
671 |
"(yes/no)? ", host, ip, type, fp); |
| 687 |
xfree(fp); |
672 |
xfree(fp); |
| 688 |
if (!confirm(prompt)) { |
673 |
if (!confirm(msg)) |
| 689 |
goto fail; |
674 |
goto fail; |
| 690 |
} |
|
|
| 691 |
} |
675 |
} |
| 692 |
if (options.check_host_ip && ip_status == HOST_NEW) { |
676 |
if (options.check_host_ip && ip_status == HOST_NEW) { |
| 693 |
snprintf(hostline, sizeof(hostline), "%s,%s", host, ip); |
677 |
snprintf(hostline, sizeof(hostline), "%s,%s", host, ip); |
|
Lines 791-810
Link Here
|
| 791 |
|
775 |
|
| 792 |
if (options.check_host_ip && host_status != HOST_CHANGED && |
776 |
if (options.check_host_ip && host_status != HOST_CHANGED && |
| 793 |
ip_status == HOST_CHANGED) { |
777 |
ip_status == HOST_CHANGED) { |
| 794 |
log("Warning: the %s host key for '%.200s' " |
778 |
snprintf(msg, sizeof(msg), |
| 795 |
"differs from the key for the IP address '%.128s'", |
779 |
"Warning: the %s host key for '%.200s' " |
| 796 |
type, host, ip); |
780 |
"differs from the key for the IP address '%.128s'" |
| 797 |
if (host_status == HOST_OK) |
781 |
"\nOffending key for IP in %s:%d", |
| 798 |
log("Matching host key in %s:%d", host_file, host_line); |
782 |
type, host, ip, ip_file, ip_line); |
| 799 |
log("Offending key for IP in %s:%d", ip_file, ip_line); |
783 |
if (host_status == HOST_OK) { |
|
|
784 |
len = strlen(msg); |
| 785 |
snprintf(msg + len, sizeof(msg) - len, |
| 786 |
"\nMatching host key in %s:%d", |
| 787 |
host_file, host_line); |
| 788 |
} |
| 800 |
if (options.strict_host_key_checking == 1) { |
789 |
if (options.strict_host_key_checking == 1) { |
|
|
790 |
log(msg); |
| 801 |
error("Exiting, you have requested strict checking."); |
791 |
error("Exiting, you have requested strict checking."); |
| 802 |
goto fail; |
792 |
goto fail; |
| 803 |
} else if (options.strict_host_key_checking == 2) { |
793 |
} else if (options.strict_host_key_checking == 2) { |
| 804 |
if (!confirm("Are you sure you want " |
794 |
strlcat(msg, "\nAre you sure you want " |
| 805 |
"to continue connecting (yes/no)? ")) { |
795 |
"to continue connecting (yes/no)? ", sizeof(msg)); |
|
|
796 |
if (!confirm(msg)) |
| 806 |
goto fail; |
797 |
goto fail; |
| 807 |
} |
798 |
} else { |
|
|
799 |
log(msg); |
| 808 |
} |
800 |
} |
| 809 |
} |
801 |
} |
| 810 |
|
802 |
|