summaryrefslogtreecommitdiff
path: root/ssh.c
diff options
context:
space:
mode:
Diffstat (limited to 'ssh.c')
-rw-r--r--ssh.c143
1 files changed, 107 insertions, 36 deletions
diff --git a/ssh.c b/ssh.c
index 3e63708da..5bce695d9 100644
--- a/ssh.c
+++ b/ssh.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh.c,v 1.401 2014/02/26 20:18:37 djm Exp $ */ 1/* $OpenBSD: ssh.c,v 1.407 2014/07/17 07:22:19 djm Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -71,8 +71,10 @@
71#include <netinet/in.h> 71#include <netinet/in.h>
72#include <arpa/inet.h> 72#include <arpa/inet.h>
73 73
74#ifdef WITH_OPENSSL
74#include <openssl/evp.h> 75#include <openssl/evp.h>
75#include <openssl/err.h> 76#include <openssl/err.h>
77#endif
76#include "openbsd-compat/openssl-compat.h" 78#include "openbsd-compat/openssl-compat.h"
77#include "openbsd-compat/sys-queue.h" 79#include "openbsd-compat/sys-queue.h"
78 80
@@ -83,6 +85,7 @@
83#include "canohost.h" 85#include "canohost.h"
84#include "compat.h" 86#include "compat.h"
85#include "cipher.h" 87#include "cipher.h"
88#include "digest.h"
86#include "packet.h" 89#include "packet.h"
87#include "buffer.h" 90#include "buffer.h"
88#include "channels.h" 91#include "channels.h"
@@ -93,9 +96,9 @@
93#include "dispatch.h" 96#include "dispatch.h"
94#include "clientloop.h" 97#include "clientloop.h"
95#include "log.h" 98#include "log.h"
99#include "misc.h"
96#include "readconf.h" 100#include "readconf.h"
97#include "sshconnect.h" 101#include "sshconnect.h"
98#include "misc.h"
99#include "kex.h" 102#include "kex.h"
100#include "mac.h" 103#include "mac.h"
101#include "sshpty.h" 104#include "sshpty.h"
@@ -420,8 +423,11 @@ main(int ac, char **av)
420 int timeout_ms; 423 int timeout_ms;
421 extern int optind, optreset; 424 extern int optind, optreset;
422 extern char *optarg; 425 extern char *optarg;
423 Forward fwd; 426 struct Forward fwd;
424 struct addrinfo *addrs = NULL; 427 struct addrinfo *addrs = NULL;
428 struct ssh_digest_ctx *md;
429 u_char conn_hash[SSH_DIGEST_MAX_LENGTH];
430 char *conn_hash_hex;
425 431
426 /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ 432 /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
427 sanitise_stdfd(); 433 sanitise_stdfd();
@@ -539,7 +545,7 @@ main(int ac, char **av)
539 options.forward_x11_trusted = 1; 545 options.forward_x11_trusted = 1;
540 break; 546 break;
541 case 'g': 547 case 'g':
542 options.gateway_ports = 1; 548 options.fwd_opts.gateway_ports = 1;
543 break; 549 break;
544 case 'O': 550 case 'O':
545 if (stdio_forward_host != NULL) 551 if (stdio_forward_host != NULL)
@@ -631,7 +637,13 @@ main(int ac, char **av)
631 break; 637 break;
632 case 'V': 638 case 'V':
633 fprintf(stderr, "%s, %s\n", 639 fprintf(stderr, "%s, %s\n",
634 SSH_RELEASE, SSLeay_version(SSLEAY_VERSION)); 640 SSH_RELEASE,
641#ifdef WITH_OPENSSL
642 SSLeay_version(SSLEAY_VERSION)
643#else
644 "without OpenSSL"
645#endif
646 );
635 if (opt == 'V') 647 if (opt == 'V')
636 exit(0); 648 exit(0);
637 break; 649 break;
@@ -828,8 +840,10 @@ main(int ac, char **av)
828 840
829 host_arg = xstrdup(host); 841 host_arg = xstrdup(host);
830 842
843#ifdef WITH_OPENSSL
831 OpenSSL_add_all_algorithms(); 844 OpenSSL_add_all_algorithms();
832 ERR_load_crypto_strings(); 845 ERR_load_crypto_strings();
846#endif
833 847
834 /* Initialize the command to execute on remote host. */ 848 /* Initialize the command to execute on remote host. */
835 buffer_init(&command); 849 buffer_init(&command);
@@ -876,7 +890,13 @@ main(int ac, char **av)
876 SYSLOG_FACILITY_USER, !use_syslog); 890 SYSLOG_FACILITY_USER, !use_syslog);
877 891
878 if (debug_flag) 892 if (debug_flag)
879 logit("%s, %s", SSH_VERSION, SSLeay_version(SSLEAY_VERSION)); 893 logit("%s, %s", SSH_RELEASE,
894#ifdef WITH_OPENSSL
895 SSLeay_version(SSLEAY_VERSION)
896#else
897 "without OpenSSL"
898#endif
899 );
880 900
881 /* Parse the configuration files */ 901 /* Parse the configuration files */
882 process_config_files(pw); 902 process_config_files(pw);
@@ -914,10 +934,14 @@ main(int ac, char **av)
914 if (addrs == NULL && options.num_permitted_cnames != 0 && 934 if (addrs == NULL && options.num_permitted_cnames != 0 &&
915 (option_clear_or_none(options.proxy_command) || 935 (option_clear_or_none(options.proxy_command) ||
916 options.canonicalize_hostname == SSH_CANONICALISE_ALWAYS)) { 936 options.canonicalize_hostname == SSH_CANONICALISE_ALWAYS)) {
917 if ((addrs = resolve_host(host, options.port, 1, 937 if ((addrs = resolve_host(host, options.port,
918 cname, sizeof(cname))) == NULL) 938 option_clear_or_none(options.proxy_command),
919 cleanup_exit(255); /* resolve_host logs the error */ 939 cname, sizeof(cname))) == NULL) {
920 check_follow_cname(&host, cname); 940 /* Don't fatal proxied host names not in the DNS */
941 if (option_clear_or_none(options.proxy_command))
942 cleanup_exit(255); /* logged in resolve_host */
943 } else
944 check_follow_cname(&host, cname);
921 } 945 }
922 946
923 /* 947 /*
@@ -982,12 +1006,29 @@ main(int ac, char **av)
982 shorthost[strcspn(thishost, ".")] = '\0'; 1006 shorthost[strcspn(thishost, ".")] = '\0';
983 snprintf(portstr, sizeof(portstr), "%d", options.port); 1007 snprintf(portstr, sizeof(portstr), "%d", options.port);
984 1008
1009 if ((md = ssh_digest_start(SSH_DIGEST_SHA1)) == NULL ||
1010 ssh_digest_update(md, thishost, strlen(thishost)) < 0 ||
1011 ssh_digest_update(md, host, strlen(host)) < 0 ||
1012 ssh_digest_update(md, portstr, strlen(portstr)) < 0 ||
1013 ssh_digest_update(md, options.user, strlen(options.user)) < 0 ||
1014 ssh_digest_final(md, conn_hash, sizeof(conn_hash)) < 0)
1015 fatal("%s: mux digest failed", __func__);
1016 ssh_digest_free(md);
1017 conn_hash_hex = tohex(conn_hash, ssh_digest_bytes(SSH_DIGEST_SHA1));
1018
985 if (options.local_command != NULL) { 1019 if (options.local_command != NULL) {
986 debug3("expanding LocalCommand: %s", options.local_command); 1020 debug3("expanding LocalCommand: %s", options.local_command);
987 cp = options.local_command; 1021 cp = options.local_command;
988 options.local_command = percent_expand(cp, "d", pw->pw_dir, 1022 options.local_command = percent_expand(cp,
989 "h", host, "l", thishost, "n", host_arg, "r", options.user, 1023 "C", conn_hash_hex,
990 "p", portstr, "u", pw->pw_name, "L", shorthost, 1024 "L", shorthost,
1025 "d", pw->pw_dir,
1026 "h", host,
1027 "l", thishost,
1028 "n", host_arg,
1029 "p", portstr,
1030 "r", options.user,
1031 "u", pw->pw_name,
991 (char *)NULL); 1032 (char *)NULL);
992 debug3("expanded LocalCommand: %s", options.local_command); 1033 debug3("expanded LocalCommand: %s", options.local_command);
993 free(cp); 1034 free(cp);
@@ -997,12 +1038,20 @@ main(int ac, char **av)
997 cp = tilde_expand_filename(options.control_path, 1038 cp = tilde_expand_filename(options.control_path,
998 original_real_uid); 1039 original_real_uid);
999 free(options.control_path); 1040 free(options.control_path);
1000 options.control_path = percent_expand(cp, "h", host, 1041 options.control_path = percent_expand(cp,
1001 "l", thishost, "n", host_arg, "r", options.user, 1042 "C", conn_hash_hex,
1002 "p", portstr, "u", pw->pw_name, "L", shorthost, 1043 "L", shorthost,
1044 "h", host,
1045 "l", thishost,
1046 "n", host_arg,
1047 "p", portstr,
1048 "r", options.user,
1049 "u", pw->pw_name,
1003 (char *)NULL); 1050 (char *)NULL);
1004 free(cp); 1051 free(cp);
1005 } 1052 }
1053 free(conn_hash_hex);
1054
1006 if (muxclient_command != 0 && options.control_path == NULL) 1055 if (muxclient_command != 0 && options.control_path == NULL)
1007 fatal("No ControlPath specified for \"-O\" command"); 1056 fatal("No ControlPath specified for \"-O\" command");
1008 if (options.control_path != NULL) 1057 if (options.control_path != NULL)
@@ -1256,13 +1305,17 @@ fork_postauth(void)
1256static void 1305static void
1257ssh_confirm_remote_forward(int type, u_int32_t seq, void *ctxt) 1306ssh_confirm_remote_forward(int type, u_int32_t seq, void *ctxt)
1258{ 1307{
1259 Forward *rfwd = (Forward *)ctxt; 1308 struct Forward *rfwd = (struct Forward *)ctxt;
1260 1309
1261 /* XXX verbose() on failure? */ 1310 /* XXX verbose() on failure? */
1262 debug("remote forward %s for: listen %d, connect %s:%d", 1311 debug("remote forward %s for: listen %s%s%d, connect %s:%d",
1263 type == SSH2_MSG_REQUEST_SUCCESS ? "success" : "failure", 1312 type == SSH2_MSG_REQUEST_SUCCESS ? "success" : "failure",
1264 rfwd->listen_port, rfwd->connect_host, rfwd->connect_port); 1313 rfwd->listen_path ? rfwd->listen_path :
1265 if (rfwd->listen_port == 0) { 1314 rfwd->listen_host ? rfwd->listen_host : "",
1315 (rfwd->listen_path || rfwd->listen_host) ? ":" : "",
1316 rfwd->listen_port, rfwd->connect_path ? rfwd->connect_path :
1317 rfwd->connect_host, rfwd->connect_port);
1318 if (rfwd->listen_path == NULL && rfwd->listen_port == 0) {
1266 if (type == SSH2_MSG_REQUEST_SUCCESS) { 1319 if (type == SSH2_MSG_REQUEST_SUCCESS) {
1267 rfwd->allocated_port = packet_get_int(); 1320 rfwd->allocated_port = packet_get_int();
1268 logit("Allocated port %u for remote forward to %s:%d", 1321 logit("Allocated port %u for remote forward to %s:%d",
@@ -1276,12 +1329,21 @@ ssh_confirm_remote_forward(int type, u_int32_t seq, void *ctxt)
1276 } 1329 }
1277 1330
1278 if (type == SSH2_MSG_REQUEST_FAILURE) { 1331 if (type == SSH2_MSG_REQUEST_FAILURE) {
1279 if (options.exit_on_forward_failure) 1332 if (options.exit_on_forward_failure) {
1280 fatal("Error: remote port forwarding failed for " 1333 if (rfwd->listen_path != NULL)
1281 "listen port %d", rfwd->listen_port); 1334 fatal("Error: remote port forwarding failed "
1282 else 1335 "for listen path %s", rfwd->listen_path);
1283 logit("Warning: remote port forwarding failed for " 1336 else
1284 "listen port %d", rfwd->listen_port); 1337 fatal("Error: remote port forwarding failed "
1338 "for listen port %d", rfwd->listen_port);
1339 } else {
1340 if (rfwd->listen_path != NULL)
1341 logit("Warning: remote port forwarding failed "
1342 "for listen path %s", rfwd->listen_path);
1343 else
1344 logit("Warning: remote port forwarding failed "
1345 "for listen port %d", rfwd->listen_port);
1346 }
1285 } 1347 }
1286 if (++remote_forward_confirms_received == options.num_remote_forwards) { 1348 if (++remote_forward_confirms_received == options.num_remote_forwards) {
1287 debug("All remote forwarding requests processed"); 1349 debug("All remote forwarding requests processed");
@@ -1298,6 +1360,13 @@ client_cleanup_stdio_fwd(int id, void *arg)
1298} 1360}
1299 1361
1300static void 1362static void
1363ssh_stdio_confirm(int id, int success, void *arg)
1364{
1365 if (!success)
1366 fatal("stdio forwarding failed");
1367}
1368
1369static void
1301ssh_init_stdio_forwarding(void) 1370ssh_init_stdio_forwarding(void)
1302{ 1371{
1303 Channel *c; 1372 Channel *c;
@@ -1317,6 +1386,7 @@ ssh_init_stdio_forwarding(void)
1317 stdio_forward_port, in, out)) == NULL) 1386 stdio_forward_port, in, out)) == NULL)
1318 fatal("%s: channel_connect_stdio_fwd failed", __func__); 1387 fatal("%s: channel_connect_stdio_fwd failed", __func__);
1319 channel_register_cleanup(c->self, client_cleanup_stdio_fwd, 0); 1388 channel_register_cleanup(c->self, client_cleanup_stdio_fwd, 0);
1389 channel_register_open_confirm(c->self, ssh_stdio_confirm, NULL);
1320} 1390}
1321 1391
1322static void 1392static void
@@ -1329,18 +1399,18 @@ ssh_init_forwarding(void)
1329 for (i = 0; i < options.num_local_forwards; i++) { 1399 for (i = 0; i < options.num_local_forwards; i++) {
1330 debug("Local connections to %.200s:%d forwarded to remote " 1400 debug("Local connections to %.200s:%d forwarded to remote "
1331 "address %.200s:%d", 1401 "address %.200s:%d",
1402 (options.local_forwards[i].listen_path != NULL) ?
1403 options.local_forwards[i].listen_path :
1332 (options.local_forwards[i].listen_host == NULL) ? 1404 (options.local_forwards[i].listen_host == NULL) ?
1333 (options.gateway_ports ? "*" : "LOCALHOST") : 1405 (options.fwd_opts.gateway_ports ? "*" : "LOCALHOST") :
1334 options.local_forwards[i].listen_host, 1406 options.local_forwards[i].listen_host,
1335 options.local_forwards[i].listen_port, 1407 options.local_forwards[i].listen_port,
1408 (options.local_forwards[i].connect_path != NULL) ?
1409 options.local_forwards[i].connect_path :
1336 options.local_forwards[i].connect_host, 1410 options.local_forwards[i].connect_host,
1337 options.local_forwards[i].connect_port); 1411 options.local_forwards[i].connect_port);
1338 success += channel_setup_local_fwd_listener( 1412 success += channel_setup_local_fwd_listener(
1339 options.local_forwards[i].listen_host, 1413 &options.local_forwards[i], &options.fwd_opts);
1340 options.local_forwards[i].listen_port,
1341 options.local_forwards[i].connect_host,
1342 options.local_forwards[i].connect_port,
1343 options.gateway_ports);
1344 } 1414 }
1345 if (i > 0 && success != i && options.exit_on_forward_failure) 1415 if (i > 0 && success != i && options.exit_on_forward_failure)
1346 fatal("Could not request local forwarding."); 1416 fatal("Could not request local forwarding.");
@@ -1351,17 +1421,18 @@ ssh_init_forwarding(void)
1351 for (i = 0; i < options.num_remote_forwards; i++) { 1421 for (i = 0; i < options.num_remote_forwards; i++) {
1352 debug("Remote connections from %.200s:%d forwarded to " 1422 debug("Remote connections from %.200s:%d forwarded to "
1353 "local address %.200s:%d", 1423 "local address %.200s:%d",
1424 (options.remote_forwards[i].listen_path != NULL) ?
1425 options.remote_forwards[i].listen_path :
1354 (options.remote_forwards[i].listen_host == NULL) ? 1426 (options.remote_forwards[i].listen_host == NULL) ?
1355 "LOCALHOST" : options.remote_forwards[i].listen_host, 1427 "LOCALHOST" : options.remote_forwards[i].listen_host,
1356 options.remote_forwards[i].listen_port, 1428 options.remote_forwards[i].listen_port,
1429 (options.remote_forwards[i].connect_path != NULL) ?
1430 options.remote_forwards[i].connect_path :
1357 options.remote_forwards[i].connect_host, 1431 options.remote_forwards[i].connect_host,
1358 options.remote_forwards[i].connect_port); 1432 options.remote_forwards[i].connect_port);
1359 options.remote_forwards[i].handle = 1433 options.remote_forwards[i].handle =
1360 channel_request_remote_forwarding( 1434 channel_request_remote_forwarding(
1361 options.remote_forwards[i].listen_host, 1435 &options.remote_forwards[i]);
1362 options.remote_forwards[i].listen_port,
1363 options.remote_forwards[i].connect_host,
1364 options.remote_forwards[i].connect_port);
1365 if (options.remote_forwards[i].handle < 0) { 1436 if (options.remote_forwards[i].handle < 0) {
1366 if (options.exit_on_forward_failure) 1437 if (options.exit_on_forward_failure)
1367 fatal("Could not request remote forwarding."); 1438 fatal("Could not request remote forwarding.");