93
86
char *command_string, *tmp;
94
87
int pin[2], pout[2];
96
char strport[NI_MAXSERV];
89
char *shell, strport[NI_MAXSERV];
91
if ((shell = getenv("SHELL")) == NULL)
98
94
/* Convert the port number into a string. */
99
95
snprintf(strport, sizeof strport, "%hu", port);
164
160
xfree(command_string);
166
162
/* Set the connection file descriptors. */
167
packet_set_connection(pout[0], pin[1], options.setuptimeout);
163
packet_set_connection(pout[0], pin[1]);
164
packet_set_timeout(options.server_alive_interval,
165
options.server_alive_count_max);
169
167
/* Indicate OK return */
208
206
hints.ai_socktype = ai->ai_socktype;
209
207
hints.ai_protocol = ai->ai_protocol;
210
208
hints.ai_flags = AI_PASSIVE;
211
gaierr = getaddrinfo(options.bind_address, "0", &hints, &res);
209
gaierr = getaddrinfo(options.bind_address, NULL, &hints, &res);
213
211
error("getaddrinfo: %s: %s", options.bind_address,
214
gai_strerror(gaierr));
212
ssh_gai_strerror(gaierr));
229
227
timeout_connect(int sockfd, const struct sockaddr *serv_addr,
230
socklen_t addrlen, int timeout)
228
socklen_t addrlen, int *timeoutp)
231
struct timeval tv, t_start;
234
232
socklen_t optlen;
235
233
int optval, rc, result = -1;
238
return (connect(sockfd, serv_addr, addrlen));
235
gettimeofday(&t_start, NULL);
237
if (*timeoutp <= 0) {
238
result = connect(sockfd, serv_addr, addrlen);
240
242
set_nonblock(sockfd);
241
243
rc = connect(sockfd, serv_addr, addrlen);
243
245
unset_nonblock(sockfd);
246
if (errno != EINPROGRESS)
249
if (errno != EINPROGRESS) {
249
254
fdset = (fd_set *)xcalloc(howmany(sockfd + 1, NFDBITS),
250
255
sizeof(fd_mask));
251
256
FD_SET(sockfd, fdset);
257
ms_to_timeval(&tv, *timeoutp);
256
260
rc = select(sockfd + 1, NULL, fdset, NULL, &tv);
307
321
ssh_connect(const char *host, struct sockaddr_storage * hostaddr,
308
u_short port, int family, int connection_attempts,
309
int needpriv, const char *proxy_command)
322
u_short port, int family, int connection_attempts, int *timeout_ms,
323
int want_keepalive, int needpriv, const char *proxy_command)
327
341
hints.ai_socktype = SOCK_STREAM;
328
342
snprintf(strport, sizeof strport, "%u", port);
329
343
if ((gaierr = getaddrinfo(host, strport, &hints, &aitop)) != 0)
330
fatal("%s: %.100s: %s", __progname, host,
331
gai_strerror(gaierr));
344
fatal("%s: Could not resolve hostname %.100s: %s", __progname,
345
host, ssh_gai_strerror(gaierr));
333
347
for (attempt = 0; attempt < connection_attempts; attempt++) {
334
348
if (attempt > 0) {
386
400
debug("Connection established.");
388
402
/* Set SO_KEEPALIVE if requested. */
389
if (options.tcp_keep_alive &&
403
if (want_keepalive &&
390
404
setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (void *)&on,
392
406
error("setsockopt SO_KEEPALIVE: %.100s", strerror(errno));
394
408
/* Set the connection. */
395
packet_set_connection(sock, sock, options.setuptimeout);
409
packet_set_connection(sock, sock);
410
packet_set_timeout(options.server_alive_interval,
411
options.server_alive_count_max);
410
426
int connection_out = packet_get_connection_out();
411
427
int minor1 = PROTOCOL_MINOR_1;
413
struct sigaction sa, osa;
415
/* Read other side's version identification.
416
* If SetupTimeOut has been set, give up after the specified amount
419
if (options.setuptimeout > 0) {
420
memset(&sa, 0, sizeof(sa));
421
sa.sa_handler = banner_alarm_catch;
422
/* throw away any pending alarms, since we'd block otherwise */
424
sigaction(SIGALRM, &sa, &osa);
425
alarm(options.setuptimeout);
430
int fdsetsz, remaining, rc;
431
struct timeval t_start, t_remaining;
434
fdsetsz = howmany(connection_in + 1, NFDBITS) * sizeof(fd_mask);
435
fdset = xcalloc(1, fdsetsz);
427
437
/* Read other side's version identification. */
438
remaining = timeout_ms;
429
for (i = 0; i < sizeof(buf) - 1; ) {
430
ssize_t len = read(connection_in, &buf[i], 1);
432
fatal("ssh_exchange_identification: Timeout waiting for version information.");
440
for (i = 0; i < sizeof(buf) - 1; i++) {
441
if (timeout_ms > 0) {
442
gettimeofday(&t_start, NULL);
443
ms_to_timeval(&t_remaining, remaining);
444
FD_SET(connection_in, fdset);
445
rc = select(connection_in + 1, fdset, NULL,
446
fdset, &t_remaining);
447
ms_subtract_diff(&t_start, &remaining);
448
if (rc == 0 || remaining <= 0)
449
fatal("Connection timed out during "
454
fatal("ssh_exchange_identification: "
455
"select: %s", strerror(errno));
459
len = atomicio(read, connection_in, &buf[i], 1);
436
461
if (len != 1 && errno == EPIPE)
437
fatal("ssh_exchange_identification: Connection closed by remote host");
440
if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK)
442
if (errno == EINTR || errno == EAGAIN)
445
fatal("ssh_exchange_identification: read: %.100s", strerror(errno));
462
fatal("ssh_exchange_identification: "
463
"Connection closed by remote host");
465
fatal("ssh_exchange_identification: "
466
"read: %.100s", strerror(errno));
447
467
if (buf[i] == '\r') {
467
483
debug("ssh_exchange_identification: %s", buf);
469
485
server_version_string = xstrdup(buf);
471
/* If SetupTimeOut has been set, unset the alarm now, and
472
* put the correct handler for SIGALRM back.
474
if (options.setuptimeout > 0) {
476
sigaction(SIGALRM, &osa, NULL);
480
489
* Check that the versions match. In future this might accept
528
537
(options.protocol & SSH_PROTO_2) ? PROTOCOL_MAJOR_2 : PROTOCOL_MAJOR_1,
530
539
/* Send our own protocol version identification. */
531
snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n",
540
snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s%s",
532
541
compat20 ? PROTOCOL_MAJOR_2 : PROTOCOL_MAJOR_1,
533
542
compat20 ? PROTOCOL_MINOR_2 : minor1,
543
SSH_RELEASE, compat20 ? "\r\n" : "\n");
535
544
if (atomicio(vwrite, connection_out, buf, strlen(buf)) != strlen(buf))
536
545
fatal("write: %.100s", strerror(errno));
537
546
client_version_string = xstrdup(buf);
581
590
const char *type = key_type(host_key);
582
591
char *ip = NULL, *host = NULL;
583
char hostline[1000], *hostp, *fp;
592
char hostline[1000], *hostp, *fp, *ra;
584
593
HostStatus host_status;
585
594
HostStatus ip_status;
586
595
int r, local = 0, host_ip_differ = 0;
588
597
char ntop[NI_MAXHOST];
590
int len, host_line, ip_line;
599
int len, host_line, ip_line, cancelled_forwarding = 0;
591
600
const char *host_file = NULL, *ip_file = NULL;
718
728
logit("Warning: Permanently added the %s host "
719
729
"key for IP address '%.128s' to the list "
720
730
"of known hosts.", type, ip);
731
} else if (options.visual_host_key) {
732
fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX);
733
ra = key_fingerprint(host_key, SSH_FP_MD5,
735
logit("Host key fingerprint is %s\n%s\n", fp, ra);
753
770
snprintf(msg1, sizeof(msg1), ".");
754
771
/* The default */
755
772
fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX);
773
ra = key_fingerprint(host_key, SSH_FP_MD5,
757
776
if (options.verify_host_key_dns) {
758
777
if (matching_host_key_dns)
767
786
snprintf(msg, sizeof(msg),
768
787
"The authenticity of host '%.200s (%s)' can't be "
769
788
"established%s\n"
770
"%s key fingerprint is %s.\n%s"
789
"%s key fingerprint is %s.%s%s\n%s"
771
790
"Are you sure you want to continue connecting "
773
host, ip, msg1, type, fp, msg2);
792
host, ip, msg1, type, fp,
793
options.visual_host_key ? "\n" : "",
794
options.visual_host_key ? ra : "",
775
798
if (!confirm(msg))
823
846
error("@ WARNING: POSSIBLE DNS SPOOFING DETECTED! @");
824
847
error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
825
848
error("The %s host key for %s has changed,", type, host);
826
error("and the key for the according IP address %s", ip);
849
error("and the key for the corresponding IP address %s", ip);
827
850
error("%s. This could either mean that", key_msg);
828
851
error("DNS SPOOFING is happening or the IP address for the host");
829
852
error("and its host key have changed at the same time.");
855
878
error("Password authentication is disabled to avoid "
856
879
"man-in-the-middle attacks.");
857
880
options.password_authentication = 0;
881
cancelled_forwarding = 1;
859
883
if (options.kbd_interactive_authentication) {
860
884
error("Keyboard-interactive authentication is disabled"
861
885
" to avoid man-in-the-middle attacks.");
862
886
options.kbd_interactive_authentication = 0;
863
887
options.challenge_response_authentication = 0;
888
cancelled_forwarding = 1;
865
890
if (options.challenge_response_authentication) {
866
891
error("Challenge/response authentication is disabled"
867
892
" to avoid man-in-the-middle attacks.");
868
893
options.challenge_response_authentication = 0;
894
cancelled_forwarding = 1;
870
896
if (options.forward_agent) {
871
897
error("Agent forwarding is disabled to avoid "
872
898
"man-in-the-middle attacks.");
873
899
options.forward_agent = 0;
900
cancelled_forwarding = 1;
875
902
if (options.forward_x11) {
876
903
error("X11 forwarding is disabled to avoid "
877
904
"man-in-the-middle attacks.");
878
905
options.forward_x11 = 0;
906
cancelled_forwarding = 1;
880
908
if (options.num_local_forwards > 0 ||
881
909
options.num_remote_forwards > 0) {
883
911
"man-in-the-middle attacks.");
884
912
options.num_local_forwards =
885
913
options.num_remote_forwards = 0;
914
cancelled_forwarding = 1;
887
916
if (options.tun_open != SSH_TUNMODE_NO) {
888
917
error("Tunnel forwarding is disabled to avoid "
889
918
"man-in-the-middle attacks.");
890
919
options.tun_open = SSH_TUNMODE_NO;
920
cancelled_forwarding = 1;
922
if (options.exit_on_forward_failure && cancelled_forwarding)
923
fatal("Error: forwarding disabled due to host key "
893
927
* XXX Should permit the user to change to use the new id.
894
928
* This could be done by converting the host key to an
1041
1075
show_key_from_file(const char *file, const char *host, int keytype)
1047
1081
found = key_new(keytype);
1048
1082
if ((ret = lookup_key_in_hostfile_by_type(file, host,
1049
1083
keytype, found, &line))) {
1050
1084
fp = key_fingerprint(found, SSH_FP_MD5, SSH_FP_HEX);
1085
ra = key_fingerprint(found, SSH_FP_MD5, SSH_FP_RANDOMART);
1051
1086
logit("WARNING: %s key found for host %s\n"
1053
"%s key fingerprint %s.",
1088
"%s key fingerprint %s.\n%s\n",
1054
1089
key_type(found), host, file, line,
1055
key_type(found), fp);
1090
key_type(found), fp, ra);
1058
1094
key_free(found);
1134
1170
if (pid == 0) {
1135
1171
debug3("Executing %s -c \"%s\"", shell, args);
1136
execl(shell, shell, "-c", args, (char *)NULL);
1172
execlp(shell, shell, "-c", args, (char *)NULL);
1137
1173
error("Couldn't execute %s -c \"%s\": %s",
1138
1174
shell, args, strerror(errno));