diff options
Diffstat (limited to 'ssh.c')
-rw-r--r-- | ssh.c | 66 |
1 files changed, 52 insertions, 14 deletions
@@ -40,7 +40,7 @@ | |||
40 | */ | 40 | */ |
41 | 41 | ||
42 | #include "includes.h" | 42 | #include "includes.h" |
43 | RCSID("$OpenBSD: ssh.c,v 1.228 2004/09/23 13:00:04 djm Exp $"); | 43 | RCSID("$OpenBSD: ssh.c,v 1.229 2004/11/07 00:01:46 djm Exp $"); |
44 | 44 | ||
45 | #include <openssl/evp.h> | 45 | #include <openssl/evp.h> |
46 | #include <openssl/err.h> | 46 | #include <openssl/err.h> |
@@ -144,6 +144,9 @@ pid_t proxy_command_pid = 0; | |||
144 | /* fd to control socket */ | 144 | /* fd to control socket */ |
145 | int control_fd = -1; | 145 | int control_fd = -1; |
146 | 146 | ||
147 | /* Multiplexing control command */ | ||
148 | static u_int mux_command = SSHMUX_COMMAND_OPEN; | ||
149 | |||
147 | /* Only used in control client mode */ | 150 | /* Only used in control client mode */ |
148 | volatile sig_atomic_t control_client_terminate = 0; | 151 | volatile sig_atomic_t control_client_terminate = 0; |
149 | u_int control_server_pid = 0; | 152 | u_int control_server_pid = 0; |
@@ -236,7 +239,7 @@ main(int ac, char **av) | |||
236 | 239 | ||
237 | again: | 240 | again: |
238 | while ((opt = getopt(ac, av, | 241 | while ((opt = getopt(ac, av, |
239 | "1246ab:c:e:fgi:kl:m:no:p:qstvxACD:F:I:L:MNPR:S:TVXY")) != -1) { | 242 | "1246ab:c:e:fgi:kl:m:no:p:qstvxACD:F:I:L:MNO:PR:S:TVXY")) != -1) { |
240 | switch (opt) { | 243 | switch (opt) { |
241 | case '1': | 244 | case '1': |
242 | options.protocol = SSH_PROTO_1; | 245 | options.protocol = SSH_PROTO_1; |
@@ -270,6 +273,14 @@ again: | |||
270 | case 'g': | 273 | case 'g': |
271 | options.gateway_ports = 1; | 274 | options.gateway_ports = 1; |
272 | break; | 275 | break; |
276 | case 'O': | ||
277 | if (strcmp(optarg, "check") == 0) | ||
278 | mux_command = SSHMUX_COMMAND_ALIVE_CHECK; | ||
279 | else if (strcmp(optarg, "exit") == 0) | ||
280 | mux_command = SSHMUX_COMMAND_TERMINATE; | ||
281 | else | ||
282 | fatal("Invalid multiplex command."); | ||
283 | break; | ||
273 | case 'P': /* deprecated */ | 284 | case 'P': /* deprecated */ |
274 | options.use_privileged_port = 0; | 285 | options.use_privileged_port = 0; |
275 | break; | 286 | break; |
@@ -1251,8 +1262,9 @@ control_client(const char *path) | |||
1251 | struct sockaddr_un addr; | 1262 | struct sockaddr_un addr; |
1252 | int i, r, fd, sock, exitval, num_env, addr_len; | 1263 | int i, r, fd, sock, exitval, num_env, addr_len; |
1253 | Buffer m; | 1264 | Buffer m; |
1254 | char *cp; | 1265 | char *term; |
1255 | extern char **environ; | 1266 | extern char **environ; |
1267 | u_int flags; | ||
1256 | 1268 | ||
1257 | if (stdin_null_flag) { | 1269 | if (stdin_null_flag) { |
1258 | if ((fd = open(_PATH_DEVNULL, O_RDONLY)) == -1) | 1270 | if ((fd = open(_PATH_DEVNULL, O_RDONLY)) == -1) |
@@ -1278,26 +1290,52 @@ control_client(const char *path) | |||
1278 | if (connect(sock, (struct sockaddr*)&addr, addr_len) == -1) | 1290 | if (connect(sock, (struct sockaddr*)&addr, addr_len) == -1) |
1279 | fatal("Couldn't connect to %s: %s", path, strerror(errno)); | 1291 | fatal("Couldn't connect to %s: %s", path, strerror(errno)); |
1280 | 1292 | ||
1281 | if ((cp = getenv("TERM")) == NULL) | 1293 | if ((term = getenv("TERM")) == NULL) |
1282 | cp = ""; | 1294 | term = ""; |
1295 | |||
1296 | flags = 0; | ||
1297 | if (tty_flag) | ||
1298 | flags |= SSHMUX_FLAG_TTY; | ||
1299 | if (subsystem_flag) | ||
1300 | flags |= SSHMUX_FLAG_SUBSYS; | ||
1283 | 1301 | ||
1284 | buffer_init(&m); | 1302 | buffer_init(&m); |
1285 | 1303 | ||
1286 | /* Get PID of controlee */ | 1304 | /* Send our command to server */ |
1305 | buffer_put_int(&m, mux_command); | ||
1306 | buffer_put_int(&m, flags); | ||
1307 | if (ssh_msg_send(sock, /* version */1, &m) == -1) | ||
1308 | fatal("%s: msg_send", __func__); | ||
1309 | buffer_clear(&m); | ||
1310 | |||
1311 | /* Get authorisation status and PID of controlee */ | ||
1287 | if (ssh_msg_recv(sock, &m) == -1) | 1312 | if (ssh_msg_recv(sock, &m) == -1) |
1288 | fatal("%s: msg_recv", __func__); | 1313 | fatal("%s: msg_recv", __func__); |
1289 | if (buffer_get_char(&m) != 0) | 1314 | if (buffer_get_char(&m) != 1) |
1290 | fatal("%s: wrong version", __func__); | 1315 | fatal("%s: wrong version", __func__); |
1291 | /* Connection allowed? */ | ||
1292 | if (buffer_get_int(&m) != 1) | 1316 | if (buffer_get_int(&m) != 1) |
1293 | fatal("Connection to master denied"); | 1317 | fatal("Connection to master denied"); |
1294 | control_server_pid = buffer_get_int(&m); | 1318 | control_server_pid = buffer_get_int(&m); |
1295 | 1319 | ||
1296 | buffer_clear(&m); | 1320 | buffer_clear(&m); |
1297 | buffer_put_int(&m, tty_flag); | ||
1298 | buffer_put_int(&m, subsystem_flag); | ||
1299 | buffer_put_cstring(&m, cp); | ||
1300 | 1321 | ||
1322 | switch (mux_command) { | ||
1323 | case SSHMUX_COMMAND_ALIVE_CHECK: | ||
1324 | fprintf(stderr, "Master running (pid=%d)\r\n", | ||
1325 | control_server_pid); | ||
1326 | exit(0); | ||
1327 | case SSHMUX_COMMAND_TERMINATE: | ||
1328 | fprintf(stderr, "Exit request sent.\r\n"); | ||
1329 | exit(0); | ||
1330 | case SSHMUX_COMMAND_OPEN: | ||
1331 | /* continue below */ | ||
1332 | break; | ||
1333 | default: | ||
1334 | fatal("silly mux_command %d", mux_command); | ||
1335 | } | ||
1336 | |||
1337 | /* SSHMUX_COMMAND_OPEN */ | ||
1338 | buffer_put_cstring(&m, term); | ||
1301 | buffer_append(&command, "\0", 1); | 1339 | buffer_append(&command, "\0", 1); |
1302 | buffer_put_cstring(&m, buffer_ptr(&command)); | 1340 | buffer_put_cstring(&m, buffer_ptr(&command)); |
1303 | 1341 | ||
@@ -1319,7 +1357,7 @@ control_client(const char *path) | |||
1319 | } | 1357 | } |
1320 | } | 1358 | } |
1321 | 1359 | ||
1322 | if (ssh_msg_send(sock, /* version */0, &m) == -1) | 1360 | if (ssh_msg_send(sock, /* version */1, &m) == -1) |
1323 | fatal("%s: msg_send", __func__); | 1361 | fatal("%s: msg_send", __func__); |
1324 | 1362 | ||
1325 | mm_send_fd(sock, STDIN_FILENO); | 1363 | mm_send_fd(sock, STDIN_FILENO); |
@@ -1330,8 +1368,8 @@ control_client(const char *path) | |||
1330 | buffer_clear(&m); | 1368 | buffer_clear(&m); |
1331 | if (ssh_msg_recv(sock, &m) == -1) | 1369 | if (ssh_msg_recv(sock, &m) == -1) |
1332 | fatal("%s: msg_recv", __func__); | 1370 | fatal("%s: msg_recv", __func__); |
1333 | if (buffer_get_char(&m) != 0) | 1371 | if (buffer_get_char(&m) != 1) |
1334 | fatal("%s: master returned error", __func__); | 1372 | fatal("%s: wrong version", __func__); |
1335 | buffer_free(&m); | 1373 | buffer_free(&m); |
1336 | 1374 | ||
1337 | signal(SIGHUP, control_client_sighandler); | 1375 | signal(SIGHUP, control_client_sighandler); |