|
Lines 67-72
Link Here
|
| 67 |
#include "sshpty.h" |
67 |
#include "sshpty.h" |
| 68 |
#include "key.h" |
68 |
#include "key.h" |
| 69 |
#include "readconf.h" |
69 |
#include "readconf.h" |
|
|
70 |
#include "compat.h" |
| 70 |
#include "clientloop.h" |
71 |
#include "clientloop.h" |
| 71 |
|
72 |
|
| 72 |
/* from ssh.c */ |
73 |
/* from ssh.c */ |
|
Lines 208-218
muxserver_accept_control(void)
Link Here
|
| 208 |
{ |
209 |
{ |
| 209 |
Buffer m; |
210 |
Buffer m; |
| 210 |
Channel *c; |
211 |
Channel *c; |
| 211 |
int client_fd, new_fd[3], ver, allowed, window, packetmax; |
212 |
int client_fd, new_fd[3], ver, allowed, window, packetmax, count; |
| 212 |
socklen_t addrlen; |
213 |
socklen_t addrlen; |
| 213 |
struct sockaddr_storage addr; |
214 |
struct sockaddr_storage addr; |
| 214 |
struct mux_session_confirm_ctx *cctx; |
215 |
struct mux_session_confirm_ctx *cctx; |
| 215 |
char *cmd; |
216 |
char *cmd, *tag, *question, *signal; |
| 216 |
u_int i, j, len, env_len, mux_command, flags, escape_char; |
217 |
u_int i, j, len, env_len, mux_command, flags, escape_char; |
| 217 |
uid_t euid; |
218 |
uid_t euid; |
| 218 |
gid_t egid; |
219 |
gid_t egid; |
|
Lines 260-325
muxserver_accept_control(void)
Link Here
|
| 260 |
} |
261 |
} |
| 261 |
|
262 |
|
| 262 |
allowed = 1; |
263 |
allowed = 1; |
|
|
264 |
question = NULL; |
| 263 |
mux_command = buffer_get_int(&m); |
265 |
mux_command = buffer_get_int(&m); |
| 264 |
flags = buffer_get_int(&m); |
266 |
flags = buffer_get_int(&m); |
| 265 |
|
267 |
|
|
|
268 |
/* Process extra arguments and ask user for permission */ |
| 269 |
switch (mux_command) { |
| 270 |
case SSHMUX_COMMAND_OPEN: |
| 271 |
question = "Allow shared connection to %s? "; |
| 272 |
break; |
| 273 |
case SSHMUX_COMMAND_TERMINATE: |
| 274 |
question = "Terminate shared connection to %s? "; |
| 275 |
break; |
| 276 |
case SSHMUX_COMMAND_KILL: |
| 277 |
signal = buffer_get_string(&m, &len); |
| 278 |
tag = buffer_get_string(&m, &len); |
| 279 |
c = NULL; |
| 280 |
if (tag && signal && compat20) { |
| 281 |
/* channel lookup by tag */ |
| 282 |
while (c = channel_next(c)) { |
| 283 |
if (c->tag && (strcmp(tag, c->tag) == 0)) |
| 284 |
break; |
| 285 |
} |
| 286 |
if (c) { |
| 287 |
question = "Send signal to process in %s? "; |
| 288 |
break; |
| 289 |
} |
| 290 |
} |
| 291 |
allowed = 0; |
| 292 |
break; |
| 293 |
} |
| 294 |
|
| 295 |
if (question && (options.control_master == SSHCTL_MASTER_ASK || |
| 296 |
options.control_master == SSHCTL_MASTER_AUTO_ASK)) |
| 297 |
allowed = ask_permission(question, host); |
| 298 |
|
| 299 |
/* response header */ |
| 266 |
buffer_clear(&m); |
300 |
buffer_clear(&m); |
|
|
301 |
buffer_put_int(&m, allowed); |
| 302 |
buffer_put_int(&m, getpid()); |
| 267 |
|
303 |
|
| 268 |
switch (mux_command) { |
304 |
switch (mux_command) { |
| 269 |
case SSHMUX_COMMAND_OPEN: |
305 |
case SSHMUX_COMMAND_OPEN: |
| 270 |
if (options.control_master == SSHCTL_MASTER_ASK || |
306 |
case SSHMUX_COMMAND_ALIVE_CHECK: |
| 271 |
options.control_master == SSHCTL_MASTER_AUTO_ASK) |
|
|
| 272 |
allowed = ask_permission("Allow shared connection " |
| 273 |
"to %s? ", host); |
| 274 |
/* continue below */ |
| 275 |
break; |
307 |
break; |
|
|
308 |
|
| 276 |
case SSHMUX_COMMAND_TERMINATE: |
309 |
case SSHMUX_COMMAND_TERMINATE: |
| 277 |
if (options.control_master == SSHCTL_MASTER_ASK || |
|
|
| 278 |
options.control_master == SSHCTL_MASTER_AUTO_ASK) |
| 279 |
allowed = ask_permission("Terminate shared connection " |
| 280 |
"to %s? ", host); |
| 281 |
if (allowed) |
310 |
if (allowed) |
| 282 |
start_close = 1; |
311 |
start_close = 1; |
| 283 |
/* FALLTHROUGH */ |
312 |
break; |
| 284 |
case SSHMUX_COMMAND_ALIVE_CHECK: |
313 |
|
| 285 |
/* Reply for SSHMUX_COMMAND_TERMINATE and ALIVE_CHECK */ |
314 |
case SSHMUX_COMMAND_PS: |
| 286 |
buffer_clear(&m); |
315 |
count = 0; |
| 287 |
buffer_put_int(&m, allowed); |
316 |
c = NULL; |
| 288 |
buffer_put_int(&m, getpid()); |
317 |
while (c = channel_next(c)) |
| 289 |
if (ssh_msg_send(client_fd, SSHMUX_VER, &m) == -1) { |
318 |
if (c->tag) |
| 290 |
error("%s: client msg_send failed", __func__); |
319 |
count ++; |
| 291 |
close(client_fd); |
320 |
buffer_put_int(&m, count); |
| 292 |
buffer_free(&m); |
321 |
|
| 293 |
return start_close; |
322 |
while (c = channel_next(c)) |
|
|
323 |
if (c->tag) |
| 324 |
buffer_put_cstring(&m, c->tag); |
| 325 |
break; |
| 326 |
|
| 327 |
case SSHMUX_COMMAND_KILL: |
| 328 |
if (allowed) { |
| 329 |
int id = c->self; |
| 330 |
channel_request_start(id, "signal", 0); |
| 331 |
packet_put_cstring(signal); |
| 332 |
packet_send(); |
| 294 |
} |
333 |
} |
| 295 |
buffer_free(&m); |
334 |
break; |
| 296 |
close(client_fd); |
|
|
| 297 |
return start_close; |
| 298 |
default: |
335 |
default: |
| 299 |
error("Unsupported command %d", mux_command); |
336 |
error("Unsupported command %d", mux_command); |
| 300 |
buffer_free(&m); |
337 |
goto cleanup; |
| 301 |
close(client_fd); |
|
|
| 302 |
return 0; |
| 303 |
} |
338 |
} |
| 304 |
|
339 |
if (!allowed) |
| 305 |
/* Reply for SSHMUX_COMMAND_OPEN */ |
340 |
error("Refused control connection"); |
| 306 |
buffer_clear(&m); |
|
|
| 307 |
buffer_put_int(&m, allowed); |
| 308 |
buffer_put_int(&m, getpid()); |
| 309 |
if (ssh_msg_send(client_fd, SSHMUX_VER, &m) == -1) { |
341 |
if (ssh_msg_send(client_fd, SSHMUX_VER, &m) == -1) { |
| 310 |
error("%s: client msg_send failed", __func__); |
342 |
error("%s: client msg_send failed", __func__); |
| 311 |
close(client_fd); |
343 |
goto cleanup; |
| 312 |
buffer_free(&m); |
|
|
| 313 |
return 0; |
| 314 |
} |
344 |
} |
| 315 |
|
345 |
|
| 316 |
if (!allowed) { |
346 |
if ((mux_command != SSHMUX_COMMAND_OPEN) || !allowed) { |
| 317 |
error("Refused control connection"); |
347 |
cleanup: |
| 318 |
close(client_fd); |
|
|
| 319 |
buffer_free(&m); |
348 |
buffer_free(&m); |
| 320 |
return 0; |
349 |
close(client_fd); |
|
|
350 |
return start_close; |
| 321 |
} |
351 |
} |
| 322 |
|
352 |
|
|
|
353 |
/* Continue SSHMUX_COMMAND_OPEN processing */ |
| 354 |
|
| 323 |
buffer_clear(&m); |
355 |
buffer_clear(&m); |
| 324 |
if (ssh_msg_recv(client_fd, &m) == -1) { |
356 |
if (ssh_msg_recv(client_fd, &m) == -1) { |
| 325 |
error("%s: client msg_recv failed", __func__); |
357 |
error("%s: client msg_recv failed", __func__); |
|
Lines 341-346
muxserver_accept_control(void)
Link Here
|
| 341 |
cctx->want_agent_fwd = (flags & SSHMUX_FLAG_AGENT_FWD) != 0; |
373 |
cctx->want_agent_fwd = (flags & SSHMUX_FLAG_AGENT_FWD) != 0; |
| 342 |
cctx->term = buffer_get_string(&m, &len); |
374 |
cctx->term = buffer_get_string(&m, &len); |
| 343 |
escape_char = buffer_get_int(&m); |
375 |
escape_char = buffer_get_int(&m); |
|
|
376 |
tag = buffer_get_string(&m, &len); |
| 344 |
|
377 |
|
| 345 |
cmd = buffer_get_string(&m, &len); |
378 |
cmd = buffer_get_string(&m, &len); |
| 346 |
buffer_init(&cctx->cmd); |
379 |
buffer_init(&cctx->cmd); |
|
Lines 375-380
muxserver_accept_control(void)
Link Here
|
| 375 |
buffer_free(&cctx->cmd); |
408 |
buffer_free(&cctx->cmd); |
| 376 |
close(client_fd); |
409 |
close(client_fd); |
| 377 |
xfree(cctx); |
410 |
xfree(cctx); |
|
|
411 |
xfree(tag); |
| 378 |
return 0; |
412 |
return 0; |
| 379 |
} |
413 |
} |
| 380 |
} |
414 |
} |
|
Lines 401-406
muxserver_accept_control(void)
Link Here
|
| 401 |
xfree(cctx->env[i]); |
435 |
xfree(cctx->env[i]); |
| 402 |
xfree(cctx->env); |
436 |
xfree(cctx->env); |
| 403 |
} |
437 |
} |
|
|
438 |
xfree(cctx); |
| 439 |
xfree(tag); |
| 404 |
return 0; |
440 |
return 0; |
| 405 |
} |
441 |
} |
| 406 |
buffer_free(&m); |
442 |
buffer_free(&m); |
|
Lines 427-432
muxserver_accept_control(void)
Link Here
|
| 427 |
CHAN_EXTENDED_WRITE, "client-session", /*nonblock*/0); |
463 |
CHAN_EXTENDED_WRITE, "client-session", /*nonblock*/0); |
| 428 |
|
464 |
|
| 429 |
c->ctl_fd = client_fd; |
465 |
c->ctl_fd = client_fd; |
|
|
466 |
c->tag = tag; |
| 430 |
if (cctx->want_tty && escape_char != 0xffffffff) { |
467 |
if (cctx->want_tty && escape_char != 0xffffffff) { |
| 431 |
channel_register_filter(c->self, |
468 |
channel_register_filter(c->self, |
| 432 |
client_simple_escape_filter, NULL, |
469 |
client_simple_escape_filter, NULL, |
|
Lines 487-503
env_permitted(char *env)
Link Here
|
| 487 |
|
524 |
|
| 488 |
/* Multiplex client main loop. */ |
525 |
/* Multiplex client main loop. */ |
| 489 |
void |
526 |
void |
| 490 |
muxclient(const char *path) |
527 |
muxclient(const char *path, int ac, char **av) |
| 491 |
{ |
528 |
{ |
| 492 |
struct sockaddr_un addr; |
529 |
struct sockaddr_un addr; |
| 493 |
int i, r, fd, sock, exitval[2], num_env; |
530 |
int i, r, fd, sock, exitval[2], num_env, count, len; |
| 494 |
Buffer m; |
531 |
Buffer m; |
| 495 |
char *term; |
532 |
char *term, *tag = NULL; |
| 496 |
extern char **environ; |
533 |
extern char **environ; |
| 497 |
u_int allowed, flags; |
534 |
u_int allowed, flags; |
| 498 |
|
535 |
|
| 499 |
if (muxclient_command == 0) |
536 |
switch (muxclient_command) { |
|
|
537 |
case 0: |
| 500 |
muxclient_command = SSHMUX_COMMAND_OPEN; |
538 |
muxclient_command = SSHMUX_COMMAND_OPEN; |
|
|
539 |
break; |
| 540 |
case SSHMUX_COMMAND_KILL: |
| 541 |
if (ac != 2) |
| 542 |
fatal("Bad number of arguments for kill command"); |
| 543 |
break; |
| 544 |
} |
| 501 |
|
545 |
|
| 502 |
switch (options.control_master) { |
546 |
switch (options.control_master) { |
| 503 |
case SSHCTL_MASTER_AUTO: |
547 |
case SSHCTL_MASTER_AUTO: |
|
Lines 562-570
muxclient(const char *path)
Link Here
|
| 562 |
|
606 |
|
| 563 |
buffer_init(&m); |
607 |
buffer_init(&m); |
| 564 |
|
608 |
|
| 565 |
/* Send our command to server */ |
609 |
/* Build command header */ |
| 566 |
buffer_put_int(&m, muxclient_command); |
610 |
buffer_put_int(&m, muxclient_command); |
| 567 |
buffer_put_int(&m, flags); |
611 |
buffer_put_int(&m, flags); |
|
|
612 |
|
| 613 |
/* Add command specific data */ |
| 614 |
switch (muxclient_command) { |
| 615 |
case SSHMUX_COMMAND_KILL: |
| 616 |
buffer_put_cstring(&m, av[0]); |
| 617 |
buffer_put_cstring(&m, av[1]); |
| 618 |
break; |
| 619 |
} |
| 620 |
|
| 621 |
/* Send our command to server */ |
| 568 |
if (ssh_msg_send(sock, SSHMUX_VER, &m) == -1) { |
622 |
if (ssh_msg_send(sock, SSHMUX_VER, &m) == -1) { |
| 569 |
error("%s: msg_send", __func__); |
623 |
error("%s: msg_send", __func__); |
| 570 |
muxerr: |
624 |
muxerr: |
|
Lines 599-606
muxclient(const char *path)
Link Here
|
| 599 |
} |
653 |
} |
| 600 |
muxserver_pid = buffer_get_int(&m); |
654 |
muxserver_pid = buffer_get_int(&m); |
| 601 |
|
655 |
|
| 602 |
buffer_clear(&m); |
|
|
| 603 |
|
| 604 |
switch (muxclient_command) { |
656 |
switch (muxclient_command) { |
| 605 |
case SSHMUX_COMMAND_ALIVE_CHECK: |
657 |
case SSHMUX_COMMAND_ALIVE_CHECK: |
| 606 |
fprintf(stderr, "Master running (pid=%d)\r\n", |
658 |
fprintf(stderr, "Master running (pid=%d)\r\n", |
|
Lines 609-620
muxclient(const char *path)
Link Here
|
| 609 |
case SSHMUX_COMMAND_TERMINATE: |
661 |
case SSHMUX_COMMAND_TERMINATE: |
| 610 |
fprintf(stderr, "Exit request sent.\r\n"); |
662 |
fprintf(stderr, "Exit request sent.\r\n"); |
| 611 |
exit(0); |
663 |
exit(0); |
|
|
664 |
case SSHMUX_COMMAND_KILL: |
| 665 |
fprintf(stderr, "Signal request sent.\r\n"); |
| 666 |
exit(0); |
| 667 |
case SSHMUX_COMMAND_PS: |
| 668 |
if (buffer_get_int_ret(&count, &m) != 0) { |
| 669 |
error("%s: bad server reply", __func__); |
| 670 |
goto muxerr; |
| 671 |
} |
| 672 |
for (i = 0; i < count; i++) { |
| 673 |
char *tag = buffer_get_string(&m, &len); |
| 674 |
if (!tag) { |
| 675 |
error("%s: bad server reply", __func__); |
| 676 |
goto muxerr; |
| 677 |
} |
| 678 |
printf("%s\n", tag); |
| 679 |
xfree(tag); |
| 680 |
} |
| 681 |
exit(0); |
| 682 |
|
| 612 |
case SSHMUX_COMMAND_OPEN: |
683 |
case SSHMUX_COMMAND_OPEN: |
|
|
684 |
buffer_clear(&m); |
| 613 |
buffer_put_cstring(&m, term ? term : ""); |
685 |
buffer_put_cstring(&m, term ? term : ""); |
| 614 |
if (options.escape_char == SSH_ESCAPECHAR_NONE) |
686 |
if (options.escape_char == SSH_ESCAPECHAR_NONE) |
| 615 |
buffer_put_int(&m, 0xffffffff); |
687 |
buffer_put_int(&m, 0xffffffff); |
| 616 |
else |
688 |
else |
| 617 |
buffer_put_int(&m, options.escape_char); |
689 |
buffer_put_int(&m, options.escape_char); |
|
|
690 |
xasprintf(&tag, "%ld", (long)getpid()); |
| 691 |
buffer_put_cstring(&m, tag); |
| 618 |
buffer_append(&command, "\0", 1); |
692 |
buffer_append(&command, "\0", 1); |
| 619 |
buffer_put_cstring(&m, buffer_ptr(&command)); |
693 |
buffer_put_cstring(&m, buffer_ptr(&command)); |
| 620 |
|
694 |
|