summaryrefslogtreecommitdiff
path: root/mux.c
diff options
context:
space:
mode:
authormarkus@openbsd.org <markus@openbsd.org>2018-07-09 21:18:10 +0000
committerDamien Miller <djm@mindrot.org>2018-07-10 15:14:26 +1000
commitf4608a7065480516ab46214f554e5f853fb7870f (patch)
tree6e084f7cc4dbbc358b063c4e366d1da3d8a6e9a7 /mux.c
parentcecee2d607099a7bba0a84803e2325d15be4277b (diff)
upstream: client: switch mux to sshbuf API; with & ok djm@
OpenBSD-Commit-ID: 5948fb98d704f9c4e075b92edda64e0290b5feb2
Diffstat (limited to 'mux.c')
-rw-r--r--mux.c921
1 files changed, 507 insertions, 414 deletions
diff --git a/mux.c b/mux.c
index 474d610a3..95d74b62e 100644
--- a/mux.c
+++ b/mux.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: mux.c,v 1.72 2018/07/09 21:03:30 markus Exp $ */ 1/* $OpenBSD: mux.c,v 1.73 2018/07/09 21:18:10 markus Exp $ */
2/* 2/*
3 * Copyright (c) 2002-2008 Damien Miller <djm@openbsd.org> 3 * Copyright (c) 2002-2008 Damien Miller <djm@openbsd.org>
4 * 4 *
@@ -70,7 +70,7 @@
70#include "pathnames.h" 70#include "pathnames.h"
71#include "misc.h" 71#include "misc.h"
72#include "match.h" 72#include "match.h"
73#include "buffer.h" 73#include "sshbuf.h"
74#include "channels.h" 74#include "channels.h"
75#include "msg.h" 75#include "msg.h"
76#include "packet.h" 76#include "packet.h"
@@ -96,7 +96,7 @@ struct mux_session_confirm_ctx {
96 u_int want_subsys; 96 u_int want_subsys;
97 u_int want_x_fwd; 97 u_int want_x_fwd;
98 u_int want_agent_fwd; 98 u_int want_agent_fwd;
99 Buffer cmd; 99 struct sshbuf *cmd;
100 char *term; 100 char *term;
101 struct termios tio; 101 struct termios tio;
102 char **env; 102 char **env;
@@ -279,10 +279,11 @@ env_permitted(char *env)
279 279
280static int 280static int
281process_mux_master_hello(struct ssh *ssh, u_int rid, 281process_mux_master_hello(struct ssh *ssh, u_int rid,
282 Channel *c, Buffer *m, Buffer *r) 282 Channel *c, struct sshbuf *m, struct sshbuf *reply)
283{ 283{
284 u_int ver; 284 u_int ver;
285 struct mux_master_state *state = (struct mux_master_state *)c->mux_ctx; 285 struct mux_master_state *state = (struct mux_master_state *)c->mux_ctx;
286 int r;
286 287
287 if (state == NULL) 288 if (state == NULL)
288 fatal("%s: channel %d: c->mux_ctx == NULL", __func__, c->self); 289 fatal("%s: channel %d: c->mux_ctx == NULL", __func__, c->self);
@@ -290,9 +291,8 @@ process_mux_master_hello(struct ssh *ssh, u_int rid,
290 error("%s: HELLO received twice", __func__); 291 error("%s: HELLO received twice", __func__);
291 return -1; 292 return -1;
292 } 293 }
293 if (buffer_get_int_ret(&ver, m) != 0) { 294 if ((r = sshbuf_get_u32(m, &ver)) != 0) {
294 malf: 295 error("%s: malformed message: %s", __func__, ssh_err(r));
295 error("%s: malformed message", __func__);
296 return -1; 296 return -1;
297 } 297 }
298 if (ver != SSHMUX_VER) { 298 if (ver != SSHMUX_VER) {
@@ -303,51 +303,72 @@ process_mux_master_hello(struct ssh *ssh, u_int rid,
303 debug2("%s: channel %d slave version %u", __func__, c->self, ver); 303 debug2("%s: channel %d slave version %u", __func__, c->self, ver);
304 304
305 /* No extensions are presently defined */ 305 /* No extensions are presently defined */
306 while (buffer_len(m) > 0) { 306 while (sshbuf_len(m) > 0) {
307 char *name = buffer_get_string_ret(m, NULL); 307 char *name = NULL;
308 char *value = buffer_get_string_ret(m, NULL);
309 308
310 if (name == NULL || value == NULL) { 309 if ((r = sshbuf_get_cstring(m, &name, NULL)) != 0 ||
311 free(name); 310 (r = sshbuf_skip_string(m)) != 0) { /* value */
312 free(value); 311 error("%s: malformed extension: %s",
313 goto malf; 312 __func__, ssh_err(r));
313 return -1;
314 } 314 }
315 debug2("Unrecognised slave extension \"%s\"", name); 315 debug2("Unrecognised slave extension \"%s\"", name);
316 free(name); 316 free(name);
317 free(value);
318 } 317 }
319 state->hello_rcvd = 1; 318 state->hello_rcvd = 1;
320 return 0; 319 return 0;
321} 320}
322 321
322/* Enqueue a "ok" response to the reply buffer */
323static void
324reply_ok(struct sshbuf *reply, u_int rid)
325{
326 int r;
327
328 if ((r = sshbuf_put_u32(reply, MUX_S_OK)) != 0 ||
329 (r = sshbuf_put_u32(reply, rid)) != 0)
330 fatal("%s: reply: %s", __func__, ssh_err(r));
331}
332
333/* Enqueue an error response to the reply buffer */
334static void
335reply_error(struct sshbuf *reply, u_int type, u_int rid, const char *msg)
336{
337 int r;
338
339 if ((r = sshbuf_put_u32(reply, type)) != 0 ||
340 (r = sshbuf_put_u32(reply, rid)) != 0 ||
341 (r = sshbuf_put_cstring(reply, msg)) != 0)
342 fatal("%s: reply: %s", __func__, ssh_err(r));
343}
344
323static int 345static int
324process_mux_new_session(struct ssh *ssh, u_int rid, 346process_mux_new_session(struct ssh *ssh, u_int rid,
325 Channel *c, Buffer *m, Buffer *r) 347 Channel *c, struct sshbuf *m, struct sshbuf *reply)
326{ 348{
327 Channel *nc; 349 Channel *nc;
328 struct mux_session_confirm_ctx *cctx; 350 struct mux_session_confirm_ctx *cctx;
329 char *reserved, *cmd, *cp; 351 char *cmd, *cp;
330 u_int i, j, len, env_len, escape_char, window, packetmax; 352 u_int i, j, env_len, escape_char, window, packetmax;
331 int new_fd[3]; 353 int r, new_fd[3];
332 354
333 /* Reply for SSHMUX_COMMAND_OPEN */ 355 /* Reply for SSHMUX_COMMAND_OPEN */
334 cctx = xcalloc(1, sizeof(*cctx)); 356 cctx = xcalloc(1, sizeof(*cctx));
335 cctx->term = NULL; 357 cctx->term = NULL;
336 cctx->rid = rid; 358 cctx->rid = rid;
337 cmd = reserved = NULL; 359 cmd = NULL;
338 cctx->env = NULL; 360 cctx->env = NULL;
339 env_len = 0; 361 env_len = 0;
340 if ((reserved = buffer_get_string_ret(m, NULL)) == NULL || 362 if ((r = sshbuf_skip_string(m)) != 0 || /* reserved */
341 buffer_get_int_ret(&cctx->want_tty, m) != 0 || 363 (r = sshbuf_get_u32(m, &cctx->want_tty)) != 0 ||
342 buffer_get_int_ret(&cctx->want_x_fwd, m) != 0 || 364 (r = sshbuf_get_u32(m, &cctx->want_x_fwd)) != 0 ||
343 buffer_get_int_ret(&cctx->want_agent_fwd, m) != 0 || 365 (r = sshbuf_get_u32(m, &cctx->want_agent_fwd)) != 0 ||
344 buffer_get_int_ret(&cctx->want_subsys, m) != 0 || 366 (r = sshbuf_get_u32(m, &cctx->want_subsys)) != 0 ||
345 buffer_get_int_ret(&escape_char, m) != 0 || 367 (r = sshbuf_get_u32(m, &escape_char)) != 0 ||
346 (cctx->term = buffer_get_string_ret(m, &len)) == NULL || 368 (r = sshbuf_get_cstring(m, &cctx->term, NULL)) != 0 ||
347 (cmd = buffer_get_string_ret(m, &len)) == NULL) { 369 (r = sshbuf_get_cstring(m, &cmd, NULL)) != 0) {
348 malf: 370 malf:
349 free(cmd); 371 free(cmd);
350 free(reserved);
351 for (j = 0; j < env_len; j++) 372 for (j = 0; j < env_len; j++)
352 free(cctx->env[j]); 373 free(cctx->env[j]);
353 free(cctx->env); 374 free(cctx->env);
@@ -356,12 +377,10 @@ process_mux_new_session(struct ssh *ssh, u_int rid,
356 error("%s: malformed message", __func__); 377 error("%s: malformed message", __func__);
357 return -1; 378 return -1;
358 } 379 }
359 free(reserved);
360 reserved = NULL;
361 380
362 while (buffer_len(m) > 0) {
363#define MUX_MAX_ENV_VARS 4096 381#define MUX_MAX_ENV_VARS 4096
364 if ((cp = buffer_get_string_ret(m, &len)) == NULL) 382 while (sshbuf_len(m) > 0) {
383 if ((r = sshbuf_get_cstring(m, &cp, NULL)) != 0)
365 goto malf; 384 goto malf;
366 if (!env_permitted(cp)) { 385 if (!env_permitted(cp)) {
367 free(cp); 386 free(cp);
@@ -383,8 +402,10 @@ process_mux_new_session(struct ssh *ssh, u_int rid,
383 cctx->want_tty, cctx->want_x_fwd, cctx->want_agent_fwd, 402 cctx->want_tty, cctx->want_x_fwd, cctx->want_agent_fwd,
384 cctx->want_subsys, cctx->term, cmd, env_len); 403 cctx->want_subsys, cctx->term, cmd, env_len);
385 404
386 buffer_init(&cctx->cmd); 405 if ((cctx->cmd = sshbuf_new()) == NULL)
387 buffer_append(&cctx->cmd, cmd, strlen(cmd)); 406 fatal("%s: sshbuf_new", __func__);
407 if ((r = sshbuf_put(cctx->cmd, cmd, strlen(cmd))) != 0)
408 fatal("%s: sshbuf_put: %s", __func__, ssh_err(r));
388 free(cmd); 409 free(cmd);
389 cmd = NULL; 410 cmd = NULL;
390 411
@@ -399,13 +420,9 @@ process_mux_new_session(struct ssh *ssh, u_int rid,
399 free(cctx->env[j]); 420 free(cctx->env[j]);
400 free(cctx->env); 421 free(cctx->env);
401 free(cctx->term); 422 free(cctx->term);
402 buffer_free(&cctx->cmd); 423 sshbuf_free(cctx->cmd);
403 free(cctx); 424 free(cctx);
404 425 reply_error(reply, MUX_S_FAILURE, rid,
405 /* prepare reply */
406 buffer_put_int(r, MUX_S_FAILURE);
407 buffer_put_int(r, rid);
408 buffer_put_cstring(r,
409 "did not receive file descriptors"); 426 "did not receive file descriptors");
410 return -1; 427 return -1;
411 } 428 }
@@ -417,10 +434,8 @@ process_mux_new_session(struct ssh *ssh, u_int rid,
417 /* XXX support multiple child sessions in future */ 434 /* XXX support multiple child sessions in future */
418 if (c->have_remote_id) { 435 if (c->have_remote_id) {
419 debug2("%s: session already open", __func__); 436 debug2("%s: session already open", __func__);
420 /* prepare reply */ 437 reply_error(reply, MUX_S_FAILURE, rid,
421 buffer_put_int(r, MUX_S_FAILURE); 438 "Multiple sessions not supported");
422 buffer_put_int(r, rid);
423 buffer_put_cstring(r, "Multiple sessions not supported");
424 cleanup: 439 cleanup:
425 close(new_fd[0]); 440 close(new_fd[0]);
426 close(new_fd[1]); 441 close(new_fd[1]);
@@ -431,7 +446,7 @@ process_mux_new_session(struct ssh *ssh, u_int rid,
431 free(cctx->env[i]); 446 free(cctx->env[i]);
432 free(cctx->env); 447 free(cctx->env);
433 } 448 }
434 buffer_free(&cctx->cmd); 449 sshbuf_free(cctx->cmd);
435 free(cctx); 450 free(cctx);
436 return 0; 451 return 0;
437 } 452 }
@@ -440,10 +455,8 @@ process_mux_new_session(struct ssh *ssh, u_int rid,
440 options.control_master == SSHCTL_MASTER_AUTO_ASK) { 455 options.control_master == SSHCTL_MASTER_AUTO_ASK) {
441 if (!ask_permission("Allow shared connection to %s? ", host)) { 456 if (!ask_permission("Allow shared connection to %s? ", host)) {
442 debug2("%s: session refused by user", __func__); 457 debug2("%s: session refused by user", __func__);
443 /* prepare reply */ 458 reply_error(reply, MUX_S_PERMISSION_DENIED, rid,
444 buffer_put_int(r, MUX_S_PERMISSION_DENIED); 459 "Permission denied");
445 buffer_put_int(r, rid);
446 buffer_put_cstring(r, "Permission denied");
447 goto cleanup; 460 goto cleanup;
448 } 461 }
449 } 462 }
@@ -497,21 +510,24 @@ process_mux_new_session(struct ssh *ssh, u_int rid,
497 510
498static int 511static int
499process_mux_alive_check(struct ssh *ssh, u_int rid, 512process_mux_alive_check(struct ssh *ssh, u_int rid,
500 Channel *c, Buffer *m, Buffer *r) 513 Channel *c, struct sshbuf *m, struct sshbuf *reply)
501{ 514{
515 int r;
516
502 debug2("%s: channel %d: alive check", __func__, c->self); 517 debug2("%s: channel %d: alive check", __func__, c->self);
503 518
504 /* prepare reply */ 519 /* prepare reply */
505 buffer_put_int(r, MUX_S_ALIVE); 520 if ((r = sshbuf_put_u32(reply, MUX_S_ALIVE)) != 0 ||
506 buffer_put_int(r, rid); 521 (r = sshbuf_put_u32(reply, rid)) != 0 ||
507 buffer_put_int(r, (u_int)getpid()); 522 (r = sshbuf_put_u32(reply, (u_int)getpid())) != 0)
523 fatal("%s: reply: %s", __func__, ssh_err(r));
508 524
509 return 0; 525 return 0;
510} 526}
511 527
512static int 528static int
513process_mux_terminate(struct ssh *ssh, u_int rid, 529process_mux_terminate(struct ssh *ssh, u_int rid,
514 Channel *c, Buffer *m, Buffer *r) 530 Channel *c, struct sshbuf *m, struct sshbuf *reply)
515{ 531{
516 debug2("%s: channel %d: terminate request", __func__, c->self); 532 debug2("%s: channel %d: terminate request", __func__, c->self);
517 533
@@ -520,16 +536,14 @@ process_mux_terminate(struct ssh *ssh, u_int rid,
520 if (!ask_permission("Terminate shared connection to %s? ", 536 if (!ask_permission("Terminate shared connection to %s? ",
521 host)) { 537 host)) {
522 debug2("%s: termination refused by user", __func__); 538 debug2("%s: termination refused by user", __func__);
523 buffer_put_int(r, MUX_S_PERMISSION_DENIED); 539 reply_error(reply, MUX_S_PERMISSION_DENIED, rid,
524 buffer_put_int(r, rid); 540 "Permission denied");
525 buffer_put_cstring(r, "Permission denied");
526 return 0; 541 return 0;
527 } 542 }
528 } 543 }
529 544
530 quit_pending = 1; 545 quit_pending = 1;
531 buffer_put_int(r, MUX_S_OK); 546 reply_ok(reply, rid);
532 buffer_put_int(r, rid);
533 /* XXX exit happens too soon - message never makes it to client */ 547 /* XXX exit happens too soon - message never makes it to client */
534 return 0; 548 return 0;
535} 549}
@@ -606,14 +620,16 @@ mux_confirm_remote_forward(struct ssh *ssh, int type, u_int32_t seq, void *ctxt)
606 char *failmsg = NULL; 620 char *failmsg = NULL;
607 struct Forward *rfwd; 621 struct Forward *rfwd;
608 Channel *c; 622 Channel *c;
609 Buffer out; 623 struct sshbuf *out;
624 int r;
610 625
611 if ((c = channel_by_id(ssh, fctx->cid)) == NULL) { 626 if ((c = channel_by_id(ssh, fctx->cid)) == NULL) {
612 /* no channel for reply */ 627 /* no channel for reply */
613 error("%s: unknown channel", __func__); 628 error("%s: unknown channel", __func__);
614 return; 629 return;
615 } 630 }
616 buffer_init(&out); 631 if ((out = sshbuf_new()) == NULL)
632 fatal("%s: sshbuf_new", __func__);
617 if (fctx->fid >= options.num_remote_forwards || 633 if (fctx->fid >= options.num_remote_forwards ||
618 (options.remote_forwards[fctx->fid].connect_path == NULL && 634 (options.remote_forwards[fctx->fid].connect_path == NULL &&
619 options.remote_forwards[fctx->fid].connect_host == NULL)) { 635 options.remote_forwards[fctx->fid].connect_host == NULL)) {
@@ -631,14 +647,16 @@ mux_confirm_remote_forward(struct ssh *ssh, int type, u_int32_t seq, void *ctxt)
631 debug("Allocated port %u for mux remote forward" 647 debug("Allocated port %u for mux remote forward"
632 " to %s:%d", rfwd->allocated_port, 648 " to %s:%d", rfwd->allocated_port,
633 rfwd->connect_host, rfwd->connect_port); 649 rfwd->connect_host, rfwd->connect_port);
634 buffer_put_int(&out, MUX_S_REMOTE_PORT); 650 if ((r = sshbuf_put_u32(out,
635 buffer_put_int(&out, fctx->rid); 651 MUX_S_REMOTE_PORT)) != 0 ||
636 buffer_put_int(&out, rfwd->allocated_port); 652 (r = sshbuf_put_u32(out, fctx->rid)) != 0 ||
653 (r = sshbuf_put_u32(out,
654 rfwd->allocated_port)) != 0)
655 fatal("%s: reply: %s", __func__, ssh_err(r));
637 channel_update_permission(ssh, rfwd->handle, 656 channel_update_permission(ssh, rfwd->handle,
638 rfwd->allocated_port); 657 rfwd->allocated_port);
639 } else { 658 } else {
640 buffer_put_int(&out, MUX_S_OK); 659 reply_ok(out, fctx->rid);
641 buffer_put_int(&out, fctx->rid);
642 } 660 }
643 goto out; 661 goto out;
644 } else { 662 } else {
@@ -664,13 +682,12 @@ mux_confirm_remote_forward(struct ssh *ssh, int type, u_int32_t seq, void *ctxt)
664 } 682 }
665 fail: 683 fail:
666 error("%s: %s", __func__, failmsg); 684 error("%s: %s", __func__, failmsg);
667 buffer_put_int(&out, MUX_S_FAILURE); 685 reply_error(out, MUX_S_FAILURE, fctx->rid, failmsg);
668 buffer_put_int(&out, fctx->rid);
669 buffer_put_cstring(&out, failmsg);
670 free(failmsg); 686 free(failmsg);
671 out: 687 out:
672 buffer_put_string(c->output, buffer_ptr(&out), buffer_len(&out)); 688 if ((r = sshbuf_put_stringb(c->output, out)) != 0)
673 buffer_free(&out); 689 fatal("%s: sshbuf_put_stringb: %s", __func__, ssh_err(r));
690 sshbuf_free(out);
674 if (c->mux_pause <= 0) 691 if (c->mux_pause <= 0)
675 fatal("%s: mux_pause %d", __func__, c->mux_pause); 692 fatal("%s: mux_pause %d", __func__, c->mux_pause);
676 c->mux_pause = 0; /* start processing messages again */ 693 c->mux_pause = 0; /* start processing messages again */
@@ -678,23 +695,23 @@ mux_confirm_remote_forward(struct ssh *ssh, int type, u_int32_t seq, void *ctxt)
678 695
679static int 696static int
680process_mux_open_fwd(struct ssh *ssh, u_int rid, 697process_mux_open_fwd(struct ssh *ssh, u_int rid,
681 Channel *c, Buffer *m, Buffer *r) 698 Channel *c, struct sshbuf *m, struct sshbuf *reply)
682{ 699{
683 struct Forward fwd; 700 struct Forward fwd;
684 char *fwd_desc = NULL; 701 char *fwd_desc = NULL;
685 char *listen_addr, *connect_addr; 702 char *listen_addr, *connect_addr;
686 u_int ftype; 703 u_int ftype;
687 u_int lport, cport; 704 u_int lport, cport;
688 int i, ret = 0, freefwd = 1; 705 int r, i, ret = 0, freefwd = 1;
689 706
690 memset(&fwd, 0, sizeof(fwd)); 707 memset(&fwd, 0, sizeof(fwd));
691 708
692 /* XXX - lport/cport check redundant */ 709 /* XXX - lport/cport check redundant */
693 if (buffer_get_int_ret(&ftype, m) != 0 || 710 if ((r = sshbuf_get_u32(m, &ftype)) != 0 ||
694 (listen_addr = buffer_get_string_ret(m, NULL)) == NULL || 711 (r = sshbuf_get_cstring(m, &listen_addr, NULL)) != 0 ||
695 buffer_get_int_ret(&lport, m) != 0 || 712 (r = sshbuf_get_u32(m, &lport)) != 0 ||
696 (connect_addr = buffer_get_string_ret(m, NULL)) == NULL || 713 (r = sshbuf_get_cstring(m, &connect_addr, NULL)) != 0 ||
697 buffer_get_int_ret(&cport, m) != 0 || 714 (r = sshbuf_get_u32(m, &cport)) != 0 ||
698 (lport != (u_int)PORT_STREAMLOCAL && lport > 65535) || 715 (lport != (u_int)PORT_STREAMLOCAL && lport > 65535) ||
699 (cport != (u_int)PORT_STREAMLOCAL && cport > 65535)) { 716 (cport != (u_int)PORT_STREAMLOCAL && cport > 65535)) {
700 error("%s: malformed message", __func__); 717 error("%s: malformed message", __func__);
@@ -731,9 +748,8 @@ process_mux_open_fwd(struct ssh *ssh, u_int rid,
731 invalid: 748 invalid:
732 free(listen_addr); 749 free(listen_addr);
733 free(connect_addr); 750 free(connect_addr);
734 buffer_put_int(r, MUX_S_FAILURE); 751 reply_error(reply, MUX_S_FAILURE, rid,
735 buffer_put_int(r, rid); 752 "Invalid forwarding request");
736 buffer_put_cstring(r, "Invalid forwarding request");
737 return 0; 753 return 0;
738 } 754 }
739 if (ftype == MUX_FWD_DYNAMIC && fwd.listen_path) { 755 if (ftype == MUX_FWD_DYNAMIC && fwd.listen_path) {
@@ -770,26 +786,25 @@ process_mux_open_fwd(struct ssh *ssh, u_int rid,
770 exists: 786 exists:
771 debug2("%s: found existing forwarding", 787 debug2("%s: found existing forwarding",
772 __func__); 788 __func__);
773 buffer_put_int(r, MUX_S_OK); 789 reply_ok(reply, rid);
774 buffer_put_int(r, rid);
775 goto out; 790 goto out;
776 } 791 }
777 } 792 }
778 break; 793 break;
779 case MUX_FWD_REMOTE: 794 case MUX_FWD_REMOTE:
780 for (i = 0; i < options.num_remote_forwards; i++) { 795 for (i = 0; i < options.num_remote_forwards; i++) {
781 if (compare_forward(&fwd, 796 if (!compare_forward(&fwd, options.remote_forwards + i))
782 options.remote_forwards + i)) { 797 continue;
783 if (fwd.listen_port != 0) 798 if (fwd.listen_port != 0)
784 goto exists; 799 goto exists;
785 debug2("%s: found allocated port", 800 debug2("%s: found allocated port", __func__);
786 __func__); 801 if ((r = sshbuf_put_u32(reply,
787 buffer_put_int(r, MUX_S_REMOTE_PORT); 802 MUX_S_REMOTE_PORT)) != 0 ||
788 buffer_put_int(r, rid); 803 (r = sshbuf_put_u32(reply, rid)) != 0 ||
789 buffer_put_int(r, 804 (r = sshbuf_put_u32(reply,
790 options.remote_forwards[i].allocated_port); 805 options.remote_forwards[i].allocated_port)) != 0)
791 goto out; 806 fatal("%s: reply: %s", __func__, ssh_err(r));
792 } 807 goto out;
793 } 808 }
794 break; 809 break;
795 } 810 }
@@ -798,9 +813,8 @@ process_mux_open_fwd(struct ssh *ssh, u_int rid,
798 options.control_master == SSHCTL_MASTER_AUTO_ASK) { 813 options.control_master == SSHCTL_MASTER_AUTO_ASK) {
799 if (!ask_permission("Open %s on %s?", fwd_desc, host)) { 814 if (!ask_permission("Open %s on %s?", fwd_desc, host)) {
800 debug2("%s: forwarding refused by user", __func__); 815 debug2("%s: forwarding refused by user", __func__);
801 buffer_put_int(r, MUX_S_PERMISSION_DENIED); 816 reply_error(reply, MUX_S_PERMISSION_DENIED, rid,
802 buffer_put_int(r, rid); 817 "Permission denied");
803 buffer_put_cstring(r, "Permission denied");
804 goto out; 818 goto out;
805 } 819 }
806 } 820 }
@@ -810,9 +824,8 @@ process_mux_open_fwd(struct ssh *ssh, u_int rid,
810 &options.fwd_opts)) { 824 &options.fwd_opts)) {
811 fail: 825 fail:
812 logit("slave-requested %s failed", fwd_desc); 826 logit("slave-requested %s failed", fwd_desc);
813 buffer_put_int(r, MUX_S_FAILURE); 827 reply_error(reply, MUX_S_FAILURE, rid,
814 buffer_put_int(r, rid); 828 "Port forwarding failed");
815 buffer_put_cstring(r, "Port forwarding failed");
816 goto out; 829 goto out;
817 } 830 }
818 add_local_forward(&options, &fwd); 831 add_local_forward(&options, &fwd);
@@ -835,8 +848,7 @@ process_mux_open_fwd(struct ssh *ssh, u_int rid,
835 /* delayed reply in mux_confirm_remote_forward */ 848 /* delayed reply in mux_confirm_remote_forward */
836 goto out; 849 goto out;
837 } 850 }
838 buffer_put_int(r, MUX_S_OK); 851 reply_ok(reply, rid);
839 buffer_put_int(r, rid);
840 out: 852 out:
841 free(fwd_desc); 853 free(fwd_desc);
842 if (freefwd) { 854 if (freefwd) {
@@ -850,23 +862,23 @@ process_mux_open_fwd(struct ssh *ssh, u_int rid,
850 862
851static int 863static int
852process_mux_close_fwd(struct ssh *ssh, u_int rid, 864process_mux_close_fwd(struct ssh *ssh, u_int rid,
853 Channel *c, Buffer *m, Buffer *r) 865 Channel *c, struct sshbuf *m, struct sshbuf *reply)
854{ 866{
855 struct Forward fwd, *found_fwd; 867 struct Forward fwd, *found_fwd;
856 char *fwd_desc = NULL; 868 char *fwd_desc = NULL;
857 const char *error_reason = NULL; 869 const char *error_reason = NULL;
858 char *listen_addr = NULL, *connect_addr = NULL; 870 char *listen_addr = NULL, *connect_addr = NULL;
859 u_int ftype; 871 u_int ftype;
860 int i, ret = 0; 872 int r, i, ret = 0;
861 u_int lport, cport; 873 u_int lport, cport;
862 874
863 memset(&fwd, 0, sizeof(fwd)); 875 memset(&fwd, 0, sizeof(fwd));
864 876
865 if (buffer_get_int_ret(&ftype, m) != 0 || 877 if ((r = sshbuf_get_u32(m, &ftype)) != 0 ||
866 (listen_addr = buffer_get_string_ret(m, NULL)) == NULL || 878 (r = sshbuf_get_cstring(m, &listen_addr, NULL)) != 0 ||
867 buffer_get_int_ret(&lport, m) != 0 || 879 (r = sshbuf_get_u32(m, &lport)) != 0 ||
868 (connect_addr = buffer_get_string_ret(m, NULL)) == NULL || 880 (r = sshbuf_get_cstring(m, &connect_addr, NULL)) != 0 ||
869 buffer_get_int_ret(&cport, m) != 0 || 881 (r = sshbuf_get_u32(m, &cport)) != 0 ||
870 (lport != (u_int)PORT_STREAMLOCAL && lport > 65535) || 882 (lport != (u_int)PORT_STREAMLOCAL && lport > 65535) ||
871 (cport != (u_int)PORT_STREAMLOCAL && cport > 65535)) { 883 (cport != (u_int)PORT_STREAMLOCAL && cport > 65535)) {
872 error("%s: malformed message", __func__); 884 error("%s: malformed message", __func__);
@@ -940,10 +952,10 @@ process_mux_close_fwd(struct ssh *ssh, u_int rid,
940 error_reason = "port not found"; 952 error_reason = "port not found";
941 } 953 }
942 954
943 if (error_reason == NULL) { 955 if (error_reason != NULL)
944 buffer_put_int(r, MUX_S_OK); 956 reply_error(reply, MUX_S_FAILURE, rid, error_reason);
945 buffer_put_int(r, rid); 957 else {
946 958 reply_ok(reply, rid);
947 free(found_fwd->listen_host); 959 free(found_fwd->listen_host);
948 free(found_fwd->listen_path); 960 free(found_fwd->listen_path);
949 free(found_fwd->connect_host); 961 free(found_fwd->connect_host);
@@ -951,10 +963,6 @@ process_mux_close_fwd(struct ssh *ssh, u_int rid,
951 found_fwd->listen_host = found_fwd->connect_host = NULL; 963 found_fwd->listen_host = found_fwd->connect_host = NULL;
952 found_fwd->listen_path = found_fwd->connect_path = NULL; 964 found_fwd->listen_path = found_fwd->connect_path = NULL;
953 found_fwd->listen_port = found_fwd->connect_port = 0; 965 found_fwd->listen_port = found_fwd->connect_port = 0;
954 } else {
955 buffer_put_int(r, MUX_S_FAILURE);
956 buffer_put_int(r, rid);
957 buffer_put_cstring(r, error_reason);
958 } 966 }
959 out: 967 out:
960 free(fwd_desc); 968 free(fwd_desc);
@@ -966,24 +974,21 @@ process_mux_close_fwd(struct ssh *ssh, u_int rid,
966 974
967static int 975static int
968process_mux_stdio_fwd(struct ssh *ssh, u_int rid, 976process_mux_stdio_fwd(struct ssh *ssh, u_int rid,
969 Channel *c, Buffer *m, Buffer *r) 977 Channel *c, struct sshbuf *m, struct sshbuf *reply)
970{ 978{
971 Channel *nc; 979 Channel *nc;
972 char *reserved, *chost; 980 char *chost = NULL;
973 u_int cport, i, j; 981 u_int cport, i, j;
974 int new_fd[2]; 982 int r, new_fd[2];
975 struct mux_stdio_confirm_ctx *cctx; 983 struct mux_stdio_confirm_ctx *cctx;
976 984
977 chost = reserved = NULL; 985 if ((r = sshbuf_skip_string(m)) != 0 || /* reserved */
978 if ((reserved = buffer_get_string_ret(m, NULL)) == NULL || 986 (r = sshbuf_get_cstring(m, &chost, NULL)) != 0 ||
979 (chost = buffer_get_string_ret(m, NULL)) == NULL || 987 (r = sshbuf_get_u32(m, &cport)) != 0) {
980 buffer_get_int_ret(&cport, m) != 0) {
981 free(reserved);
982 free(chost); 988 free(chost);
983 error("%s: malformed message", __func__); 989 error("%s: malformed message", __func__);
984 return -1; 990 return -1;
985 } 991 }
986 free(reserved);
987 992
988 debug2("%s: channel %d: request stdio fwd to %s:%u", 993 debug2("%s: channel %d: request stdio fwd to %s:%u",
989 __func__, c->self, chost, cport); 994 __func__, c->self, chost, cport);
@@ -998,9 +1003,7 @@ process_mux_stdio_fwd(struct ssh *ssh, u_int rid,
998 free(chost); 1003 free(chost);
999 1004
1000 /* prepare reply */ 1005 /* prepare reply */
1001 buffer_put_int(r, MUX_S_FAILURE); 1006 reply_error(reply, MUX_S_FAILURE, rid,
1002 buffer_put_int(r, rid);
1003 buffer_put_cstring(r,
1004 "did not receive file descriptors"); 1007 "did not receive file descriptors");
1005 return -1; 1008 return -1;
1006 } 1009 }
@@ -1012,10 +1015,8 @@ process_mux_stdio_fwd(struct ssh *ssh, u_int rid,
1012 /* XXX support multiple child sessions in future */ 1015 /* XXX support multiple child sessions in future */
1013 if (c->have_remote_id) { 1016 if (c->have_remote_id) {
1014 debug2("%s: session already open", __func__); 1017 debug2("%s: session already open", __func__);
1015 /* prepare reply */ 1018 reply_error(reply, MUX_S_FAILURE, rid,
1016 buffer_put_int(r, MUX_S_FAILURE); 1019 "Multiple sessions not supported");
1017 buffer_put_int(r, rid);
1018 buffer_put_cstring(r, "Multiple sessions not supported");
1019 cleanup: 1020 cleanup:
1020 close(new_fd[0]); 1021 close(new_fd[0]);
1021 close(new_fd[1]); 1022 close(new_fd[1]);
@@ -1028,10 +1029,8 @@ process_mux_stdio_fwd(struct ssh *ssh, u_int rid,
1028 if (!ask_permission("Allow forward to %s:%u? ", 1029 if (!ask_permission("Allow forward to %s:%u? ",
1029 chost, cport)) { 1030 chost, cport)) {
1030 debug2("%s: stdio fwd refused by user", __func__); 1031 debug2("%s: stdio fwd refused by user", __func__);
1031 /* prepare reply */ 1032 reply_error(reply, MUX_S_PERMISSION_DENIED, rid,
1032 buffer_put_int(r, MUX_S_PERMISSION_DENIED); 1033 "Permission denied");
1033 buffer_put_int(r, rid);
1034 buffer_put_cstring(r, "Permission denied");
1035 goto cleanup; 1034 goto cleanup;
1036 } 1035 }
1037 } 1036 }
@@ -1069,7 +1068,8 @@ mux_stdio_confirm(struct ssh *ssh, int id, int success, void *arg)
1069{ 1068{
1070 struct mux_stdio_confirm_ctx *cctx = arg; 1069 struct mux_stdio_confirm_ctx *cctx = arg;
1071 Channel *c, *cc; 1070 Channel *c, *cc;
1072 Buffer reply; 1071 struct sshbuf *reply;
1072 int r;
1073 1073
1074 if (cctx == NULL) 1074 if (cctx == NULL)
1075 fatal("%s: cctx == NULL", __func__); 1075 fatal("%s: cctx == NULL", __func__);
@@ -1078,28 +1078,29 @@ mux_stdio_confirm(struct ssh *ssh, int id, int success, void *arg)
1078 if ((cc = channel_by_id(ssh, c->ctl_chan)) == NULL) 1078 if ((cc = channel_by_id(ssh, c->ctl_chan)) == NULL)
1079 fatal("%s: channel %d lacks control channel %d", __func__, 1079 fatal("%s: channel %d lacks control channel %d", __func__,
1080 id, c->ctl_chan); 1080 id, c->ctl_chan);
1081 if ((reply = sshbuf_new()) == NULL)
1082 fatal("%s: sshbuf_new", __func__);
1081 1083
1082 if (!success) { 1084 if (!success) {
1083 debug3("%s: sending failure reply", __func__); 1085 debug3("%s: sending failure reply", __func__);
1086 reply_error(reply, MUX_S_FAILURE, cctx->rid,
1087 "Session open refused by peer");
1084 /* prepare reply */ 1088 /* prepare reply */
1085 buffer_init(&reply);
1086 buffer_put_int(&reply, MUX_S_FAILURE);
1087 buffer_put_int(&reply, cctx->rid);
1088 buffer_put_cstring(&reply, "Session open refused by peer");
1089 goto done; 1089 goto done;
1090 } 1090 }
1091 1091
1092 debug3("%s: sending success reply", __func__); 1092 debug3("%s: sending success reply", __func__);
1093 /* prepare reply */ 1093 /* prepare reply */
1094 buffer_init(&reply); 1094 if ((r = sshbuf_put_u32(reply, MUX_S_SESSION_OPENED)) != 0 ||
1095 buffer_put_int(&reply, MUX_S_SESSION_OPENED); 1095 (r = sshbuf_put_u32(reply, cctx->rid)) != 0 ||
1096 buffer_put_int(&reply, cctx->rid); 1096 (r = sshbuf_put_u32(reply, c->self)) != 0)
1097 buffer_put_int(&reply, c->self); 1097 fatal("%s: reply: %s", __func__, ssh_err(r));
1098 1098
1099 done: 1099 done:
1100 /* Send reply */ 1100 /* Send reply */
1101 buffer_put_string(cc->output, buffer_ptr(&reply), buffer_len(&reply)); 1101 if ((r = sshbuf_put_stringb(cc->output, reply)) != 0)
1102 buffer_free(&reply); 1102 fatal("%s: sshbuf_put_stringb: %s", __func__, ssh_err(r));
1103 sshbuf_free(reply);
1103 1104
1104 if (cc->mux_pause <= 0) 1105 if (cc->mux_pause <= 0)
1105 fatal("%s: mux_pause %d", __func__, cc->mux_pause); 1106 fatal("%s: mux_pause %d", __func__, cc->mux_pause);
@@ -1110,7 +1111,7 @@ mux_stdio_confirm(struct ssh *ssh, int id, int success, void *arg)
1110 1111
1111static int 1112static int
1112process_mux_stop_listening(struct ssh *ssh, u_int rid, 1113process_mux_stop_listening(struct ssh *ssh, u_int rid,
1113 Channel *c, Buffer *m, Buffer *r) 1114 Channel *c, struct sshbuf *m, struct sshbuf *reply)
1114{ 1115{
1115 debug("%s: channel %d: stop listening", __func__, c->self); 1116 debug("%s: channel %d: stop listening", __func__, c->self);
1116 1117
@@ -1119,9 +1120,8 @@ process_mux_stop_listening(struct ssh *ssh, u_int rid,
1119 if (!ask_permission("Disable further multiplexing on shared " 1120 if (!ask_permission("Disable further multiplexing on shared "
1120 "connection to %s? ", host)) { 1121 "connection to %s? ", host)) {
1121 debug2("%s: stop listen refused by user", __func__); 1122 debug2("%s: stop listen refused by user", __func__);
1122 buffer_put_int(r, MUX_S_PERMISSION_DENIED); 1123 reply_error(reply, MUX_S_PERMISSION_DENIED, rid,
1123 buffer_put_int(r, rid); 1124 "Permission denied");
1124 buffer_put_cstring(r, "Permission denied");
1125 return 0; 1125 return 0;
1126 } 1126 }
1127 } 1127 }
@@ -1135,22 +1135,22 @@ process_mux_stop_listening(struct ssh *ssh, u_int rid,
1135 muxserver_sock = -1; 1135 muxserver_sock = -1;
1136 } 1136 }
1137 1137
1138 /* prepare reply */ 1138 reply_ok(reply, rid);
1139 buffer_put_int(r, MUX_S_OK);
1140 buffer_put_int(r, rid);
1141
1142 return 0; 1139 return 0;
1143} 1140}
1144 1141
1145static int 1142static int
1146process_mux_proxy(struct ssh *ssh, u_int rid, 1143process_mux_proxy(struct ssh *ssh, u_int rid,
1147 Channel *c, Buffer *m, Buffer *r) 1144 Channel *c, struct sshbuf *m, struct sshbuf *reply)
1148{ 1145{
1146 int r;
1147
1149 debug("%s: channel %d: proxy request", __func__, c->self); 1148 debug("%s: channel %d: proxy request", __func__, c->self);
1150 1149
1151 c->mux_rcb = channel_proxy_downstream; 1150 c->mux_rcb = channel_proxy_downstream;
1152 buffer_put_int(r, MUX_S_PROXY); 1151 if ((r = sshbuf_put_u32(reply, MUX_S_PROXY)) != 0 ||
1153 buffer_put_int(r, rid); 1152 (r = sshbuf_put_u32(reply, rid)) != 0)
1153 fatal("%s: reply: %s", __func__, ssh_err(r));
1154 1154
1155 return 0; 1155 return 0;
1156} 1156}
@@ -1160,10 +1160,12 @@ static int
1160mux_master_read_cb(struct ssh *ssh, Channel *c) 1160mux_master_read_cb(struct ssh *ssh, Channel *c)
1161{ 1161{
1162 struct mux_master_state *state = (struct mux_master_state *)c->mux_ctx; 1162 struct mux_master_state *state = (struct mux_master_state *)c->mux_ctx;
1163 Buffer in, out; 1163 struct sshbuf *in = NULL, *out = NULL;
1164 const u_char *ptr; 1164 u_int type, rid, i;
1165 u_int type, rid, have, i; 1165 int r, ret = -1;
1166 int ret = -1; 1166
1167 if ((out = sshbuf_new()) == NULL)
1168 fatal("%s: sshbuf_new", __func__);
1167 1169
1168 /* Setup ctx and */ 1170 /* Setup ctx and */
1169 if (c->mux_ctx == NULL) { 1171 if (c->mux_ctx == NULL) {
@@ -1173,32 +1175,29 @@ mux_master_read_cb(struct ssh *ssh, Channel *c)
1173 mux_master_control_cleanup_cb, 0); 1175 mux_master_control_cleanup_cb, 0);
1174 1176
1175 /* Send hello */ 1177 /* Send hello */
1176 buffer_init(&out); 1178 if ((r = sshbuf_put_u32(out, MUX_MSG_HELLO)) != 0 ||
1177 buffer_put_int(&out, MUX_MSG_HELLO); 1179 (r = sshbuf_put_u32(out, SSHMUX_VER)) != 0)
1178 buffer_put_int(&out, SSHMUX_VER); 1180 fatal("%s: reply: %s", __func__, ssh_err(r));
1179 /* no extensions */ 1181 /* no extensions */
1180 buffer_put_string(c->output, buffer_ptr(&out), 1182 if ((r = sshbuf_put_stringb(c->output, out)) != 0)
1181 buffer_len(&out)); 1183 fatal("%s: sshbuf_put_stringb: %s",
1182 buffer_free(&out); 1184 __func__, ssh_err(r));
1183 debug3("%s: channel %d: hello sent", __func__, c->self); 1185 debug3("%s: channel %d: hello sent", __func__, c->self);
1184 return 0; 1186 ret = 0;
1187 goto out;
1185 } 1188 }
1186 1189
1187 buffer_init(&in);
1188 buffer_init(&out);
1189
1190 /* Channel code ensures that we receive whole packets */ 1190 /* Channel code ensures that we receive whole packets */
1191 if ((ptr = buffer_get_string_ptr_ret(c->input, &have)) == NULL) { 1191 if ((r = sshbuf_froms(c->input, &in)) != 0) {
1192 malf: 1192 malf:
1193 error("%s: malformed message", __func__); 1193 error("%s: malformed message", __func__);
1194 goto out; 1194 goto out;
1195 } 1195 }
1196 buffer_append(&in, ptr, have);
1197 1196
1198 if (buffer_get_int_ret(&type, &in) != 0) 1197 if ((r = sshbuf_get_u32(in, &type)) != 0)
1199 goto malf; 1198 goto malf;
1200 debug3("%s: channel %d packet type 0x%08x len %u", 1199 debug3("%s: channel %d packet type 0x%08x len %zu",
1201 __func__, c->self, type, buffer_len(&in)); 1200 __func__, c->self, type, sshbuf_len(in));
1202 1201
1203 if (type == MUX_MSG_HELLO) 1202 if (type == MUX_MSG_HELLO)
1204 rid = 0; 1203 rid = 0;
@@ -1208,40 +1207,40 @@ mux_master_read_cb(struct ssh *ssh, Channel *c)
1208 "received 0x%08x", __func__, MUX_MSG_HELLO, type); 1207 "received 0x%08x", __func__, MUX_MSG_HELLO, type);
1209 goto out; 1208 goto out;
1210 } 1209 }
1211 if (buffer_get_int_ret(&rid, &in) != 0) 1210 if ((r = sshbuf_get_u32(in, &rid)) != 0)
1212 goto malf; 1211 goto malf;
1213 } 1212 }
1214 1213
1215 for (i = 0; mux_master_handlers[i].handler != NULL; i++) { 1214 for (i = 0; mux_master_handlers[i].handler != NULL; i++) {
1216 if (type == mux_master_handlers[i].type) { 1215 if (type == mux_master_handlers[i].type) {
1217 ret = mux_master_handlers[i].handler(ssh, rid, 1216 ret = mux_master_handlers[i].handler(ssh, rid,
1218 c, &in, &out); 1217 c, in, out);
1219 break; 1218 break;
1220 } 1219 }
1221 } 1220 }
1222 if (mux_master_handlers[i].handler == NULL) { 1221 if (mux_master_handlers[i].handler == NULL) {
1223 error("%s: unsupported mux message 0x%08x", __func__, type); 1222 error("%s: unsupported mux message 0x%08x", __func__, type);
1224 buffer_put_int(&out, MUX_S_FAILURE); 1223 reply_error(out, MUX_S_FAILURE, rid, "unsupported request");
1225 buffer_put_int(&out, rid);
1226 buffer_put_cstring(&out, "unsupported request");
1227 ret = 0; 1224 ret = 0;
1228 } 1225 }
1229 /* Enqueue reply packet */ 1226 /* Enqueue reply packet */
1230 if (buffer_len(&out) != 0) { 1227 if (sshbuf_len(out) != 0) {
1231 buffer_put_string(c->output, buffer_ptr(&out), 1228 if ((r = sshbuf_put_stringb(c->output, out)) != 0)
1232 buffer_len(&out)); 1229 fatal("%s: sshbuf_put_stringb: %s",
1230 __func__, ssh_err(r));
1233 } 1231 }
1234 out: 1232 out:
1235 buffer_free(&in); 1233 sshbuf_free(in);
1236 buffer_free(&out); 1234 sshbuf_free(out);
1237 return ret; 1235 return ret;
1238} 1236}
1239 1237
1240void 1238void
1241mux_exit_message(struct ssh *ssh, Channel *c, int exitval) 1239mux_exit_message(struct ssh *ssh, Channel *c, int exitval)
1242{ 1240{
1243 Buffer m; 1241 struct sshbuf *m;
1244 Channel *mux_chan; 1242 Channel *mux_chan;
1243 int r;
1245 1244
1246 debug3("%s: channel %d: exit message, exitval %d", __func__, c->self, 1245 debug3("%s: channel %d: exit message, exitval %d", __func__, c->self,
1247 exitval); 1246 exitval);
@@ -1251,20 +1250,22 @@ mux_exit_message(struct ssh *ssh, Channel *c, int exitval)
1251 __func__, c->self, c->ctl_chan); 1250 __func__, c->self, c->ctl_chan);
1252 1251
1253 /* Append exit message packet to control socket output queue */ 1252 /* Append exit message packet to control socket output queue */
1254 buffer_init(&m); 1253 if ((m = sshbuf_new()) == NULL)
1255 buffer_put_int(&m, MUX_S_EXIT_MESSAGE); 1254 fatal("%s: sshbuf_new", __func__);
1256 buffer_put_int(&m, c->self); 1255 if ((r = sshbuf_put_u32(m, MUX_S_EXIT_MESSAGE)) != 0 ||
1257 buffer_put_int(&m, exitval); 1256 (r = sshbuf_put_u32(m, c->self)) != 0 ||
1258 1257 (r = sshbuf_put_u32(m, exitval)) != 0 ||
1259 buffer_put_string(mux_chan->output, buffer_ptr(&m), buffer_len(&m)); 1258 (r = sshbuf_put_stringb(mux_chan->output, m)) != 0)
1260 buffer_free(&m); 1259 fatal("%s: reply: %s", __func__, ssh_err(r));
1260 sshbuf_free(m);
1261} 1261}
1262 1262
1263void 1263void
1264mux_tty_alloc_failed(struct ssh *ssh, Channel *c) 1264mux_tty_alloc_failed(struct ssh *ssh, Channel *c)
1265{ 1265{
1266 Buffer m; 1266 struct sshbuf *m;
1267 Channel *mux_chan; 1267 Channel *mux_chan;
1268 int r;
1268 1269
1269 debug3("%s: channel %d: TTY alloc failed", __func__, c->self); 1270 debug3("%s: channel %d: TTY alloc failed", __func__, c->self);
1270 1271
@@ -1273,12 +1274,13 @@ mux_tty_alloc_failed(struct ssh *ssh, Channel *c)
1273 __func__, c->self, c->ctl_chan); 1274 __func__, c->self, c->ctl_chan);
1274 1275
1275 /* Append exit message packet to control socket output queue */ 1276 /* Append exit message packet to control socket output queue */
1276 buffer_init(&m); 1277 if ((m = sshbuf_new()) == NULL)
1277 buffer_put_int(&m, MUX_S_TTY_ALLOC_FAIL); 1278 fatal("%s: sshbuf_new", __func__);
1278 buffer_put_int(&m, c->self); 1279 if ((r = sshbuf_put_u32(m, MUX_S_TTY_ALLOC_FAIL)) != 0 ||
1279 1280 (r = sshbuf_put_u32(m, c->self)) != 0 ||
1280 buffer_put_string(mux_chan->output, buffer_ptr(&m), buffer_len(&m)); 1281 (r = sshbuf_put_stringb(mux_chan->output, m)) != 0)
1281 buffer_free(&m); 1282 fatal("%s: reply: %s", __func__, ssh_err(r));
1283 sshbuf_free(m);
1282} 1284}
1283 1285
1284/* Prepare a mux master to listen on a Unix domain socket. */ 1286/* Prepare a mux master to listen on a Unix domain socket. */
@@ -1372,8 +1374,8 @@ mux_session_confirm(struct ssh *ssh, int id, int success, void *arg)
1372 struct mux_session_confirm_ctx *cctx = arg; 1374 struct mux_session_confirm_ctx *cctx = arg;
1373 const char *display; 1375 const char *display;
1374 Channel *c, *cc; 1376 Channel *c, *cc;
1375 int i; 1377 int i, r;
1376 Buffer reply; 1378 struct sshbuf *reply;
1377 1379
1378 if (cctx == NULL) 1380 if (cctx == NULL)
1379 fatal("%s: cctx == NULL", __func__); 1381 fatal("%s: cctx == NULL", __func__);
@@ -1382,14 +1384,13 @@ mux_session_confirm(struct ssh *ssh, int id, int success, void *arg)
1382 if ((cc = channel_by_id(ssh, c->ctl_chan)) == NULL) 1384 if ((cc = channel_by_id(ssh, c->ctl_chan)) == NULL)
1383 fatal("%s: channel %d lacks control channel %d", __func__, 1385 fatal("%s: channel %d lacks control channel %d", __func__,
1384 id, c->ctl_chan); 1386 id, c->ctl_chan);
1387 if ((reply = sshbuf_new()) == NULL)
1388 fatal("%s: sshbuf_new", __func__);
1385 1389
1386 if (!success) { 1390 if (!success) {
1387 debug3("%s: sending failure reply", __func__); 1391 debug3("%s: sending failure reply", __func__);
1388 /* prepare reply */ 1392 reply_error(reply, MUX_S_FAILURE, cctx->rid,
1389 buffer_init(&reply); 1393 "Session open refused by peer");
1390 buffer_put_int(&reply, MUX_S_FAILURE);
1391 buffer_put_int(&reply, cctx->rid);
1392 buffer_put_cstring(&reply, "Session open refused by peer");
1393 goto done; 1394 goto done;
1394 } 1395 }
1395 1396
@@ -1419,25 +1420,26 @@ mux_session_confirm(struct ssh *ssh, int id, int success, void *arg)
1419 } 1420 }
1420 1421
1421 client_session2_setup(ssh, id, cctx->want_tty, cctx->want_subsys, 1422 client_session2_setup(ssh, id, cctx->want_tty, cctx->want_subsys,
1422 cctx->term, &cctx->tio, c->rfd, &cctx->cmd, cctx->env); 1423 cctx->term, &cctx->tio, c->rfd, cctx->cmd, cctx->env);
1423 1424
1424 debug3("%s: sending success reply", __func__); 1425 debug3("%s: sending success reply", __func__);
1425 /* prepare reply */ 1426 /* prepare reply */
1426 buffer_init(&reply); 1427 if ((r = sshbuf_put_u32(reply, MUX_S_SESSION_OPENED)) != 0 ||
1427 buffer_put_int(&reply, MUX_S_SESSION_OPENED); 1428 (r = sshbuf_put_u32(reply, cctx->rid)) != 0 ||
1428 buffer_put_int(&reply, cctx->rid); 1429 (r = sshbuf_put_u32(reply, c->self)) != 0)
1429 buffer_put_int(&reply, c->self); 1430 fatal("%s: reply: %s", __func__, ssh_err(r));
1430 1431
1431 done: 1432 done:
1432 /* Send reply */ 1433 /* Send reply */
1433 buffer_put_string(cc->output, buffer_ptr(&reply), buffer_len(&reply)); 1434 if ((r = sshbuf_put_stringb(cc->output, reply)) != 0)
1434 buffer_free(&reply); 1435 fatal("%s: sshbuf_put_stringb: %s", __func__, ssh_err(r));
1436 sshbuf_free(reply);
1435 1437
1436 if (cc->mux_pause <= 0) 1438 if (cc->mux_pause <= 0)
1437 fatal("%s: mux_pause %d", __func__, cc->mux_pause); 1439 fatal("%s: mux_pause %d", __func__, cc->mux_pause);
1438 cc->mux_pause = 0; /* start processing messages again */ 1440 cc->mux_pause = 0; /* start processing messages again */
1439 c->open_confirm_ctx = NULL; 1441 c->open_confirm_ctx = NULL;
1440 buffer_free(&cctx->cmd); 1442 sshbuf_free(cctx->cmd);
1441 free(cctx->term); 1443 free(cctx->term);
1442 if (cctx->env != NULL) { 1444 if (cctx->env != NULL) {
1443 for (i = 0; cctx->env[i] != NULL; i++) 1445 for (i = 0; cctx->env[i] != NULL; i++)
@@ -1472,16 +1474,18 @@ control_client_sigrelay(int signo)
1472} 1474}
1473 1475
1474static int 1476static int
1475mux_client_read(int fd, Buffer *b, u_int need) 1477mux_client_read(int fd, struct sshbuf *b, size_t need)
1476{ 1478{
1477 u_int have; 1479 size_t have;
1478 ssize_t len; 1480 ssize_t len;
1479 u_char *p; 1481 u_char *p;
1480 struct pollfd pfd; 1482 struct pollfd pfd;
1483 int r;
1481 1484
1482 pfd.fd = fd; 1485 pfd.fd = fd;
1483 pfd.events = POLLIN; 1486 pfd.events = POLLIN;
1484 p = buffer_append_space(b, need); 1487 if ((r = sshbuf_reserve(b, need, &p)) != 0)
1488 fatal("%s: reserve: %s", __func__, ssh_err(r));
1485 for (have = 0; have < need; ) { 1489 for (have = 0; have < need; ) {
1486 if (muxclient_terminate) { 1490 if (muxclient_terminate) {
1487 errno = EINTR; 1491 errno = EINTR;
@@ -1506,31 +1510,33 @@ mux_client_read(int fd, Buffer *b, u_int need)
1506 errno = EPIPE; 1510 errno = EPIPE;
1507 return -1; 1511 return -1;
1508 } 1512 }
1509 have += (u_int)len; 1513 have += (size_t)len;
1510 } 1514 }
1511 return 0; 1515 return 0;
1512} 1516}
1513 1517
1514static int 1518static int
1515mux_client_write_packet(int fd, Buffer *m) 1519mux_client_write_packet(int fd, struct sshbuf *m)
1516{ 1520{
1517 Buffer queue; 1521 struct sshbuf *queue;
1518 u_int have, need; 1522 u_int have, need;
1519 int oerrno, len; 1523 int r, oerrno, len;
1520 u_char *ptr; 1524 const u_char *ptr;
1521 struct pollfd pfd; 1525 struct pollfd pfd;
1522 1526
1523 pfd.fd = fd; 1527 pfd.fd = fd;
1524 pfd.events = POLLOUT; 1528 pfd.events = POLLOUT;
1525 buffer_init(&queue); 1529 if ((queue = sshbuf_new()) == NULL)
1526 buffer_put_string(&queue, buffer_ptr(m), buffer_len(m)); 1530 fatal("%s: sshbuf_new", __func__);
1531 if ((r = sshbuf_put_stringb(queue, m)) != 0)
1532 fatal("%s: sshbuf_put_stringb: %s", __func__, ssh_err(r));
1527 1533
1528 need = buffer_len(&queue); 1534 need = sshbuf_len(queue);
1529 ptr = buffer_ptr(&queue); 1535 ptr = sshbuf_ptr(queue);
1530 1536
1531 for (have = 0; have < need; ) { 1537 for (have = 0; have < need; ) {
1532 if (muxclient_terminate) { 1538 if (muxclient_terminate) {
1533 buffer_free(&queue); 1539 sshbuf_free(queue);
1534 errno = EINTR; 1540 errno = EINTR;
1535 return -1; 1541 return -1;
1536 } 1542 }
@@ -1547,85 +1553,91 @@ mux_client_write_packet(int fd, Buffer *m)
1547 continue; 1553 continue;
1548 default: 1554 default:
1549 oerrno = errno; 1555 oerrno = errno;
1550 buffer_free(&queue); 1556 sshbuf_free(queue);
1551 errno = oerrno; 1557 errno = oerrno;
1552 return -1; 1558 return -1;
1553 } 1559 }
1554 } 1560 }
1555 if (len == 0) { 1561 if (len == 0) {
1556 buffer_free(&queue); 1562 sshbuf_free(queue);
1557 errno = EPIPE; 1563 errno = EPIPE;
1558 return -1; 1564 return -1;
1559 } 1565 }
1560 have += (u_int)len; 1566 have += (u_int)len;
1561 } 1567 }
1562 buffer_free(&queue); 1568 sshbuf_free(queue);
1563 return 0; 1569 return 0;
1564} 1570}
1565 1571
1566static int 1572static int
1567mux_client_read_packet(int fd, Buffer *m) 1573mux_client_read_packet(int fd, struct sshbuf *m)
1568{ 1574{
1569 Buffer queue; 1575 struct sshbuf *queue;
1570 u_int need, have; 1576 size_t need, have;
1571 const u_char *ptr; 1577 const u_char *ptr;
1572 int oerrno; 1578 int r, oerrno;
1573 1579
1574 buffer_init(&queue); 1580 if ((queue = sshbuf_new()) == NULL)
1575 if (mux_client_read(fd, &queue, 4) != 0) { 1581 fatal("%s: sshbuf_new", __func__);
1582 if (mux_client_read(fd, queue, 4) != 0) {
1576 if ((oerrno = errno) == EPIPE) 1583 if ((oerrno = errno) == EPIPE)
1577 debug3("%s: read header failed: %s", __func__, 1584 debug3("%s: read header failed: %s", __func__,
1578 strerror(errno)); 1585 strerror(errno));
1579 buffer_free(&queue); 1586 sshbuf_free(queue);
1580 errno = oerrno; 1587 errno = oerrno;
1581 return -1; 1588 return -1;
1582 } 1589 }
1583 need = get_u32(buffer_ptr(&queue)); 1590 need = PEEK_U32(sshbuf_ptr(queue));
1584 if (mux_client_read(fd, &queue, need) != 0) { 1591 if (mux_client_read(fd, queue, need) != 0) {
1585 oerrno = errno; 1592 oerrno = errno;
1586 debug3("%s: read body failed: %s", __func__, strerror(errno)); 1593 debug3("%s: read body failed: %s", __func__, strerror(errno));
1587 buffer_free(&queue); 1594 sshbuf_free(queue);
1588 errno = oerrno; 1595 errno = oerrno;
1589 return -1; 1596 return -1;
1590 } 1597 }
1591 ptr = buffer_get_string_ptr(&queue, &have); 1598 if ((r = sshbuf_get_string_direct(queue, &ptr, &have)) != 0 ||
1592 buffer_append(m, ptr, have); 1599 (r = sshbuf_put(m, ptr, have)) != 0)
1593 buffer_free(&queue); 1600 fatal("%s: buffer error: %s", __func__, ssh_err(r));
1601 sshbuf_free(queue);
1594 return 0; 1602 return 0;
1595} 1603}
1596 1604
1597static int 1605static int
1598mux_client_hello_exchange(int fd) 1606mux_client_hello_exchange(int fd)
1599{ 1607{
1600 Buffer m; 1608 struct sshbuf *m;
1601 u_int type, ver; 1609 u_int type, ver;
1602 int ret = -1; 1610 int r, ret = -1;
1603 1611
1604 buffer_init(&m); 1612 if ((m = sshbuf_new()) == NULL)
1605 buffer_put_int(&m, MUX_MSG_HELLO); 1613 fatal("%s: sshbuf_new", __func__);
1606 buffer_put_int(&m, SSHMUX_VER); 1614 if ((r = sshbuf_put_u32(m, MUX_MSG_HELLO)) != 0 ||
1615 (r = sshbuf_put_u32(m, SSHMUX_VER)) != 0)
1616 fatal("%s: hello: %s", __func__, ssh_err(r));
1607 /* no extensions */ 1617 /* no extensions */
1608 1618
1609 if (mux_client_write_packet(fd, &m) != 0) { 1619 if (mux_client_write_packet(fd, m) != 0) {
1610 debug("%s: write packet: %s", __func__, strerror(errno)); 1620 debug("%s: write packet: %s", __func__, strerror(errno));
1611 goto out; 1621 goto out;
1612 } 1622 }
1613 1623
1614 buffer_clear(&m); 1624 sshbuf_reset(m);
1615 1625
1616 /* Read their HELLO */ 1626 /* Read their HELLO */
1617 if (mux_client_read_packet(fd, &m) != 0) { 1627 if (mux_client_read_packet(fd, m) != 0) {
1618 debug("%s: read packet failed", __func__); 1628 debug("%s: read packet failed", __func__);
1619 goto out; 1629 goto out;
1620 } 1630 }
1621 1631
1622 type = buffer_get_int(&m); 1632 if ((r = sshbuf_get_u32(m, &type)) != 0)
1633 fatal("%s: decode type: %s", __func__, ssh_err(r));
1623 if (type != MUX_MSG_HELLO) { 1634 if (type != MUX_MSG_HELLO) {
1624 error("%s: expected HELLO (%u) received %u", 1635 error("%s: expected HELLO (%u) received %u",
1625 __func__, MUX_MSG_HELLO, type); 1636 __func__, MUX_MSG_HELLO, type);
1626 goto out; 1637 goto out;
1627 } 1638 }
1628 ver = buffer_get_int(&m); 1639 if ((r = sshbuf_get_u32(m, &ver)) != 0)
1640 fatal("%s: decode version: %s", __func__, ssh_err(r));
1629 if (ver != SSHMUX_VER) { 1641 if (ver != SSHMUX_VER) {
1630 error("Unsupported multiplexing protocol version %d " 1642 error("Unsupported multiplexing protocol version %d "
1631 "(expected %d)", ver, SSHMUX_VER); 1643 "(expected %d)", ver, SSHMUX_VER);
@@ -1633,56 +1645,68 @@ mux_client_hello_exchange(int fd)
1633 } 1645 }
1634 debug2("%s: master version %u", __func__, ver); 1646 debug2("%s: master version %u", __func__, ver);
1635 /* No extensions are presently defined */ 1647 /* No extensions are presently defined */
1636 while (buffer_len(&m) > 0) { 1648 while (sshbuf_len(m) > 0) {
1637 char *name = buffer_get_string(&m, NULL); 1649 char *name = NULL;
1638 char *value = buffer_get_string(&m, NULL);
1639 1650
1651 if ((r = sshbuf_get_cstring(m, &name, NULL)) != 0 ||
1652 (r = sshbuf_skip_string(m)) != 0) { /* value */
1653 error("%s: malformed extension: %s",
1654 __func__, ssh_err(r));
1655 goto out;
1656 }
1640 debug2("Unrecognised master extension \"%s\"", name); 1657 debug2("Unrecognised master extension \"%s\"", name);
1641 free(name); 1658 free(name);
1642 free(value);
1643 } 1659 }
1644 /* success */ 1660 /* success */
1645 ret = 0; 1661 ret = 0;
1646 out: 1662 out:
1647 buffer_free(&m); 1663 sshbuf_free(m);
1648 return ret; 1664 return ret;
1649} 1665}
1650 1666
1651static u_int 1667static u_int
1652mux_client_request_alive(int fd) 1668mux_client_request_alive(int fd)
1653{ 1669{
1654 Buffer m; 1670 struct sshbuf *m;
1655 char *e; 1671 char *e;
1656 u_int pid, type, rid; 1672 u_int pid, type, rid;
1673 int r;
1657 1674
1658 debug3("%s: entering", __func__); 1675 debug3("%s: entering", __func__);
1659 1676
1660 buffer_init(&m); 1677 if ((m = sshbuf_new()) == NULL)
1661 buffer_put_int(&m, MUX_C_ALIVE_CHECK); 1678 fatal("%s: sshbuf_new", __func__);
1662 buffer_put_int(&m, muxclient_request_id); 1679 if ((r = sshbuf_put_u32(m, MUX_C_ALIVE_CHECK)) != 0 ||
1680 (r = sshbuf_put_u32(m, muxclient_request_id)) != 0)
1681 fatal("%s: request: %s", __func__, ssh_err(r));
1663 1682
1664 if (mux_client_write_packet(fd, &m) != 0) 1683 if (mux_client_write_packet(fd, m) != 0)
1665 fatal("%s: write packet: %s", __func__, strerror(errno)); 1684 fatal("%s: write packet: %s", __func__, strerror(errno));
1666 1685
1667 buffer_clear(&m); 1686 sshbuf_reset(m);
1668 1687
1669 /* Read their reply */ 1688 /* Read their reply */
1670 if (mux_client_read_packet(fd, &m) != 0) { 1689 if (mux_client_read_packet(fd, m) != 0) {
1671 buffer_free(&m); 1690 sshbuf_free(m);
1672 return 0; 1691 return 0;
1673 } 1692 }
1674 1693
1675 type = buffer_get_int(&m); 1694 if ((r = sshbuf_get_u32(m, &type)) != 0)
1695 fatal("%s: decode type: %s", __func__, ssh_err(r));
1676 if (type != MUX_S_ALIVE) { 1696 if (type != MUX_S_ALIVE) {
1677 e = buffer_get_string(&m, NULL); 1697 if ((r = sshbuf_get_cstring(m, &e, NULL)) != 0)
1698 fatal("%s: decode error: %s", __func__, ssh_err(r));
1678 fatal("%s: master returned error: %s", __func__, e); 1699 fatal("%s: master returned error: %s", __func__, e);
1679 } 1700 }
1680 1701
1681 if ((rid = buffer_get_int(&m)) != muxclient_request_id) 1702 if ((r = sshbuf_get_u32(m, &rid)) != 0)
1703 fatal("%s: decode remote ID: %s", __func__, ssh_err(r));
1704 if (rid != muxclient_request_id)
1682 fatal("%s: out of sequence reply: my id %u theirs %u", 1705 fatal("%s: out of sequence reply: my id %u theirs %u",
1683 __func__, muxclient_request_id, rid); 1706 __func__, muxclient_request_id, rid);
1684 pid = buffer_get_int(&m); 1707 if ((r = sshbuf_get_u32(m, &pid)) != 0)
1685 buffer_free(&m); 1708 fatal("%s: decode PID: %s", __func__, ssh_err(r));
1709 sshbuf_free(m);
1686 1710
1687 debug3("%s: done pid = %u", __func__, pid); 1711 debug3("%s: done pid = %u", __func__, pid);
1688 1712
@@ -1694,107 +1718,128 @@ mux_client_request_alive(int fd)
1694static void 1718static void
1695mux_client_request_terminate(int fd) 1719mux_client_request_terminate(int fd)
1696{ 1720{
1697 Buffer m; 1721 struct sshbuf *m;
1698 char *e; 1722 char *e;
1699 u_int type, rid; 1723 u_int type, rid;
1724 int r;
1700 1725
1701 debug3("%s: entering", __func__); 1726 debug3("%s: entering", __func__);
1702 1727
1703 buffer_init(&m); 1728 if ((m = sshbuf_new()) == NULL)
1704 buffer_put_int(&m, MUX_C_TERMINATE); 1729 fatal("%s: sshbuf_new", __func__);
1705 buffer_put_int(&m, muxclient_request_id); 1730 if ((r = sshbuf_put_u32(m, MUX_C_TERMINATE)) != 0 ||
1731 (r = sshbuf_put_u32(m, muxclient_request_id)) != 0)
1732 fatal("%s: request: %s", __func__, ssh_err(r));
1706 1733
1707 if (mux_client_write_packet(fd, &m) != 0) 1734 if (mux_client_write_packet(fd, m) != 0)
1708 fatal("%s: write packet: %s", __func__, strerror(errno)); 1735 fatal("%s: write packet: %s", __func__, strerror(errno));
1709 1736
1710 buffer_clear(&m); 1737 sshbuf_reset(m);
1711 1738
1712 /* Read their reply */ 1739 /* Read their reply */
1713 if (mux_client_read_packet(fd, &m) != 0) { 1740 if (mux_client_read_packet(fd, m) != 0) {
1714 /* Remote end exited already */ 1741 /* Remote end exited already */
1715 if (errno == EPIPE) { 1742 if (errno == EPIPE) {
1716 buffer_free(&m); 1743 sshbuf_free(m);
1717 return; 1744 return;
1718 } 1745 }
1719 fatal("%s: read from master failed: %s", 1746 fatal("%s: read from master failed: %s",
1720 __func__, strerror(errno)); 1747 __func__, strerror(errno));
1721 } 1748 }
1722 1749
1723 type = buffer_get_int(&m); 1750 if ((r = sshbuf_get_u32(m, &type)) != 0 ||
1724 if ((rid = buffer_get_int(&m)) != muxclient_request_id) 1751 (r = sshbuf_get_u32(m, &rid)) != 0)
1752 fatal("%s: decode: %s", __func__, ssh_err(r));
1753 if (rid != muxclient_request_id)
1725 fatal("%s: out of sequence reply: my id %u theirs %u", 1754 fatal("%s: out of sequence reply: my id %u theirs %u",
1726 __func__, muxclient_request_id, rid); 1755 __func__, muxclient_request_id, rid);
1727 switch (type) { 1756 switch (type) {
1728 case MUX_S_OK: 1757 case MUX_S_OK:
1729 break; 1758 break;
1730 case MUX_S_PERMISSION_DENIED: 1759 case MUX_S_PERMISSION_DENIED:
1731 e = buffer_get_string(&m, NULL); 1760 if ((r = sshbuf_get_cstring(m, &e, NULL)) != 0)
1761 fatal("%s: decode error: %s", __func__, ssh_err(r));
1732 fatal("Master refused termination request: %s", e); 1762 fatal("Master refused termination request: %s", e);
1733 case MUX_S_FAILURE: 1763 case MUX_S_FAILURE:
1734 e = buffer_get_string(&m, NULL); 1764 if ((r = sshbuf_get_cstring(m, &e, NULL)) != 0)
1765 fatal("%s: decode error: %s", __func__, ssh_err(r));
1735 fatal("%s: termination request failed: %s", __func__, e); 1766 fatal("%s: termination request failed: %s", __func__, e);
1736 default: 1767 default:
1737 fatal("%s: unexpected response from master 0x%08x", 1768 fatal("%s: unexpected response from master 0x%08x",
1738 __func__, type); 1769 __func__, type);
1739 } 1770 }
1740 buffer_free(&m); 1771 sshbuf_free(m);
1741 muxclient_request_id++; 1772 muxclient_request_id++;
1742} 1773}
1743 1774
1744static int 1775static int
1745mux_client_forward(int fd, int cancel_flag, u_int ftype, struct Forward *fwd) 1776mux_client_forward(int fd, int cancel_flag, u_int ftype, struct Forward *fwd)
1746{ 1777{
1747 Buffer m; 1778 struct sshbuf *m;
1748 char *e, *fwd_desc; 1779 char *e, *fwd_desc;
1780 const char *lhost, *chost;
1749 u_int type, rid; 1781 u_int type, rid;
1782 int r;
1750 1783
1751 fwd_desc = format_forward(ftype, fwd); 1784 fwd_desc = format_forward(ftype, fwd);
1752 debug("Requesting %s %s", 1785 debug("Requesting %s %s",
1753 cancel_flag ? "cancellation of" : "forwarding of", fwd_desc); 1786 cancel_flag ? "cancellation of" : "forwarding of", fwd_desc);
1754 free(fwd_desc); 1787 free(fwd_desc);
1755 1788
1756 buffer_init(&m); 1789 type = cancel_flag ? MUX_C_CLOSE_FWD : MUX_C_OPEN_FWD;
1757 buffer_put_int(&m, cancel_flag ? MUX_C_CLOSE_FWD : MUX_C_OPEN_FWD); 1790 if (fwd->listen_path != NULL)
1758 buffer_put_int(&m, muxclient_request_id); 1791 lhost = fwd->listen_path;
1759 buffer_put_int(&m, ftype); 1792 else if (fwd->listen_host == NULL)
1760 if (fwd->listen_path != NULL) { 1793 lhost = "";
1761 buffer_put_cstring(&m, fwd->listen_path); 1794 else if (*fwd->listen_host == '\0')
1762 } else { 1795 lhost = "*";
1763 buffer_put_cstring(&m, 1796 else
1764 fwd->listen_host == NULL ? "" : 1797 lhost = fwd->listen_host;
1765 (*fwd->listen_host == '\0' ? "*" : fwd->listen_host));
1766 }
1767 buffer_put_int(&m, fwd->listen_port);
1768 if (fwd->connect_path != NULL) {
1769 buffer_put_cstring(&m, fwd->connect_path);
1770 } else {
1771 buffer_put_cstring(&m,
1772 fwd->connect_host == NULL ? "" : fwd->connect_host);
1773 }
1774 buffer_put_int(&m, fwd->connect_port);
1775 1798
1776 if (mux_client_write_packet(fd, &m) != 0) 1799 if (fwd->connect_path != NULL)
1800 chost = fwd->connect_path;
1801 else if (fwd->connect_host == NULL)
1802 chost = "";
1803 else
1804 chost = fwd->connect_host;
1805
1806 if ((m = sshbuf_new()) == NULL)
1807 fatal("%s: sshbuf_new", __func__);
1808 if ((r = sshbuf_put_u32(m, type)) != 0 ||
1809 (r = sshbuf_put_u32(m, muxclient_request_id)) != 0 ||
1810 (r = sshbuf_put_u32(m, ftype)) != 0 ||
1811 (r = sshbuf_put_cstring(m, lhost)) != 0 ||
1812 (r = sshbuf_put_u32(m, fwd->listen_port)) != 0 ||
1813 (r = sshbuf_put_cstring(m, chost)) != 0 ||
1814 (r = sshbuf_put_u32(m, fwd->connect_port)) != 0)
1815 fatal("%s: request: %s", __func__, ssh_err(r));
1816
1817 if (mux_client_write_packet(fd, m) != 0)
1777 fatal("%s: write packet: %s", __func__, strerror(errno)); 1818 fatal("%s: write packet: %s", __func__, strerror(errno));
1778 1819
1779 buffer_clear(&m); 1820 sshbuf_reset(m);
1780 1821
1781 /* Read their reply */ 1822 /* Read their reply */
1782 if (mux_client_read_packet(fd, &m) != 0) { 1823 if (mux_client_read_packet(fd, m) != 0) {
1783 buffer_free(&m); 1824 sshbuf_free(m);
1784 return -1; 1825 return -1;
1785 } 1826 }
1786 1827
1787 type = buffer_get_int(&m); 1828 if ((r = sshbuf_get_u32(m, &type)) != 0 ||
1788 if ((rid = buffer_get_int(&m)) != muxclient_request_id) 1829 (r = sshbuf_get_u32(m, &rid)) != 0)
1830 fatal("%s: decode: %s", __func__, ssh_err(r));
1831 if (rid != muxclient_request_id)
1789 fatal("%s: out of sequence reply: my id %u theirs %u", 1832 fatal("%s: out of sequence reply: my id %u theirs %u",
1790 __func__, muxclient_request_id, rid); 1833 __func__, muxclient_request_id, rid);
1834
1791 switch (type) { 1835 switch (type) {
1792 case MUX_S_OK: 1836 case MUX_S_OK:
1793 break; 1837 break;
1794 case MUX_S_REMOTE_PORT: 1838 case MUX_S_REMOTE_PORT:
1795 if (cancel_flag) 1839 if (cancel_flag)
1796 fatal("%s: got MUX_S_REMOTE_PORT for cancel", __func__); 1840 fatal("%s: got MUX_S_REMOTE_PORT for cancel", __func__);
1797 fwd->allocated_port = buffer_get_int(&m); 1841 if ((r = sshbuf_get_u32(m, &fwd->allocated_port)) != 0)
1842 fatal("%s: decode port: %s", __func__, ssh_err(r));
1798 verbose("Allocated port %u for remote forward to %s:%d", 1843 verbose("Allocated port %u for remote forward to %s:%d",
1799 fwd->allocated_port, 1844 fwd->allocated_port,
1800 fwd->connect_host ? fwd->connect_host : "", 1845 fwd->connect_host ? fwd->connect_host : "",
@@ -1803,20 +1848,22 @@ mux_client_forward(int fd, int cancel_flag, u_int ftype, struct Forward *fwd)
1803 fprintf(stdout, "%i\n", fwd->allocated_port); 1848 fprintf(stdout, "%i\n", fwd->allocated_port);
1804 break; 1849 break;
1805 case MUX_S_PERMISSION_DENIED: 1850 case MUX_S_PERMISSION_DENIED:
1806 e = buffer_get_string(&m, NULL); 1851 if ((r = sshbuf_get_cstring(m, &e, NULL)) != 0)
1807 buffer_free(&m); 1852 fatal("%s: decode error: %s", __func__, ssh_err(r));
1853 sshbuf_free(m);
1808 error("Master refused forwarding request: %s", e); 1854 error("Master refused forwarding request: %s", e);
1809 return -1; 1855 return -1;
1810 case MUX_S_FAILURE: 1856 case MUX_S_FAILURE:
1811 e = buffer_get_string(&m, NULL); 1857 if ((r = sshbuf_get_cstring(m, &e, NULL)) != 0)
1812 buffer_free(&m); 1858 fatal("%s: decode error: %s", __func__, ssh_err(r));
1859 sshbuf_free(m);
1813 error("%s: forwarding request failed: %s", __func__, e); 1860 error("%s: forwarding request failed: %s", __func__, e);
1814 return -1; 1861 return -1;
1815 default: 1862 default:
1816 fatal("%s: unexpected response from master 0x%08x", 1863 fatal("%s: unexpected response from master 0x%08x",
1817 __func__, type); 1864 __func__, type);
1818 } 1865 }
1819 buffer_free(&m); 1866 sshbuf_free(m);
1820 1867
1821 muxclient_request_id++; 1868 muxclient_request_id++;
1822 return 0; 1869 return 0;
@@ -1850,11 +1897,12 @@ mux_client_forwards(int fd, int cancel_flag)
1850static int 1897static int
1851mux_client_request_session(int fd) 1898mux_client_request_session(int fd)
1852{ 1899{
1853 Buffer m; 1900 struct sshbuf *m;
1854 char *e, *term; 1901 char *e;
1855 u_int rid, sid, esid, exitval, type, exitval_seen; 1902 const char *term;
1903 u_int echar, rid, sid, esid, exitval, type, exitval_seen;
1856 extern char **environ; 1904 extern char **environ;
1857 int i, devnull, rawmode; 1905 int r, i, devnull, rawmode;
1858 1906
1859 debug3("%s: entering", __func__); 1907 debug3("%s: entering", __func__);
1860 1908
@@ -1874,33 +1922,41 @@ mux_client_request_session(int fd)
1874 close(devnull); 1922 close(devnull);
1875 } 1923 }
1876 1924
1877 term = getenv("TERM"); 1925 if ((term = getenv("TERM")) == NULL)
1878 1926 term = "";
1879 buffer_init(&m); 1927 echar = 0xffffffff;
1880 buffer_put_int(&m, MUX_C_NEW_SESSION); 1928 if (options.escape_char != SSH_ESCAPECHAR_NONE)
1881 buffer_put_int(&m, muxclient_request_id); 1929 echar = (u_int)options.escape_char;
1882 buffer_put_cstring(&m, ""); /* reserved */ 1930
1883 buffer_put_int(&m, tty_flag); 1931 if ((m = sshbuf_new()) == NULL)
1884 buffer_put_int(&m, options.forward_x11); 1932 fatal("%s: sshbuf_new", __func__);
1885 buffer_put_int(&m, options.forward_agent); 1933 if ((r = sshbuf_put_u32(m, MUX_C_NEW_SESSION)) != 0 ||
1886 buffer_put_int(&m, subsystem_flag); 1934 (r = sshbuf_put_u32(m, muxclient_request_id)) != 0 ||
1887 buffer_put_int(&m, options.escape_char == SSH_ESCAPECHAR_NONE ? 1935 (r = sshbuf_put_string(m, NULL, 0)) != 0 || /* reserved */
1888 0xffffffff : (u_int)options.escape_char); 1936 (r = sshbuf_put_u32(m, tty_flag)) != 0 ||
1889 buffer_put_cstring(&m, term == NULL ? "" : term); 1937 (r = sshbuf_put_u32(m, options.forward_x11)) != 0 ||
1890 buffer_put_string(&m, buffer_ptr(command), buffer_len(command)); 1938 (r = sshbuf_put_u32(m, options.forward_agent)) != 0 ||
1939 (r = sshbuf_put_u32(m, subsystem_flag)) != 0 ||
1940 (r = sshbuf_put_u32(m, echar)) != 0 ||
1941 (r = sshbuf_put_cstring(m, term)) != 0 ||
1942 (r = sshbuf_put_stringb(m, command)) != 0)
1943 fatal("%s: request: %s", __func__, ssh_err(r));
1891 1944
1892 /* Pass environment */ 1945 /* Pass environment */
1893 if (options.num_send_env > 0 && environ != NULL) { 1946 if (options.num_send_env > 0 && environ != NULL) {
1894 for (i = 0; environ[i] != NULL; i++) { 1947 for (i = 0; environ[i] != NULL; i++) {
1895 if (env_permitted(environ[i])) { 1948 if (!env_permitted(environ[i]))
1896 buffer_put_cstring(&m, environ[i]); 1949 continue;
1897 } 1950 if ((r = sshbuf_put_cstring(m, environ[i])) != 0)
1951 fatal("%s: request: %s", __func__, ssh_err(r));
1898 } 1952 }
1899 } 1953 }
1900 for (i = 0; i < options.num_setenv; i++) 1954 for (i = 0; i < options.num_setenv; i++) {
1901 buffer_put_cstring(&m, options.setenv[i]); 1955 if ((r = sshbuf_put_cstring(m, options.setenv[i])) != 0)
1956 fatal("%s: request: %s", __func__, ssh_err(r));
1957 }
1902 1958
1903 if (mux_client_write_packet(fd, &m) != 0) 1959 if (mux_client_write_packet(fd, m) != 0)
1904 fatal("%s: write packet: %s", __func__, strerror(errno)); 1960 fatal("%s: write packet: %s", __func__, strerror(errno));
1905 1961
1906 /* Send the stdio file descriptors */ 1962 /* Send the stdio file descriptors */
@@ -1912,35 +1968,40 @@ mux_client_request_session(int fd)
1912 debug3("%s: session request sent", __func__); 1968 debug3("%s: session request sent", __func__);
1913 1969
1914 /* Read their reply */ 1970 /* Read their reply */
1915 buffer_clear(&m); 1971 sshbuf_reset(m);
1916 if (mux_client_read_packet(fd, &m) != 0) { 1972 if (mux_client_read_packet(fd, m) != 0) {
1917 error("%s: read from master failed: %s", 1973 error("%s: read from master failed: %s",
1918 __func__, strerror(errno)); 1974 __func__, strerror(errno));
1919 buffer_free(&m); 1975 sshbuf_free(m);
1920 return -1; 1976 return -1;
1921 } 1977 }
1922 1978
1923 type = buffer_get_int(&m); 1979 if ((r = sshbuf_get_u32(m, &type)) != 0 ||
1924 if ((rid = buffer_get_int(&m)) != muxclient_request_id) 1980 (r = sshbuf_get_u32(m, &rid)) != 0)
1981 fatal("%s: decode: %s", __func__, ssh_err(r));
1982 if (rid != muxclient_request_id)
1925 fatal("%s: out of sequence reply: my id %u theirs %u", 1983 fatal("%s: out of sequence reply: my id %u theirs %u",
1926 __func__, muxclient_request_id, rid); 1984 __func__, muxclient_request_id, rid);
1985
1927 switch (type) { 1986 switch (type) {
1928 case MUX_S_SESSION_OPENED: 1987 case MUX_S_SESSION_OPENED:
1929 sid = buffer_get_int(&m); 1988 if ((r = sshbuf_get_u32(m, &sid)) != 0)
1930 debug("%s: master session id: %u", __func__, sid); 1989 fatal("%s: decode ID: %s", __func__, ssh_err(r));
1931 break; 1990 break;
1932 case MUX_S_PERMISSION_DENIED: 1991 case MUX_S_PERMISSION_DENIED:
1933 e = buffer_get_string(&m, NULL); 1992 if ((r = sshbuf_get_cstring(m, &e, NULL)) != 0)
1934 buffer_free(&m); 1993 fatal("%s: decode error: %s", __func__, ssh_err(r));
1935 error("Master refused session request: %s", e); 1994 error("Master refused session request: %s", e);
1995 sshbuf_free(m);
1936 return -1; 1996 return -1;
1937 case MUX_S_FAILURE: 1997 case MUX_S_FAILURE:
1938 e = buffer_get_string(&m, NULL); 1998 if ((r = sshbuf_get_cstring(m, &e, NULL)) != 0)
1939 buffer_free(&m); 1999 fatal("%s: decode error: %s", __func__, ssh_err(r));
1940 error("%s: session request failed: %s", __func__, e); 2000 error("%s: session request failed: %s", __func__, e);
2001 sshbuf_free(m);
1941 return -1; 2002 return -1;
1942 default: 2003 default:
1943 buffer_free(&m); 2004 sshbuf_free(m);
1944 error("%s: unexpected response from master 0x%08x", 2005 error("%s: unexpected response from master 0x%08x",
1945 __func__, type); 2006 __func__, type);
1946 return -1; 2007 return -1;
@@ -1968,13 +2029,17 @@ mux_client_request_session(int fd)
1968 * terminate early too (possibly losing data). 2029 * terminate early too (possibly losing data).
1969 */ 2030 */
1970 for (exitval = 255, exitval_seen = 0;;) { 2031 for (exitval = 255, exitval_seen = 0;;) {
1971 buffer_clear(&m); 2032 sshbuf_reset(m);
1972 if (mux_client_read_packet(fd, &m) != 0) 2033 if (mux_client_read_packet(fd, m) != 0)
1973 break; 2034 break;
1974 type = buffer_get_int(&m); 2035 if ((r = sshbuf_get_u32(m, &type)) != 0)
2036 fatal("%s: decode type: %s", __func__, ssh_err(r));
1975 switch (type) { 2037 switch (type) {
1976 case MUX_S_TTY_ALLOC_FAIL: 2038 case MUX_S_TTY_ALLOC_FAIL:
1977 if ((esid = buffer_get_int(&m)) != sid) 2039 if ((r = sshbuf_get_u32(m, &esid)) != 0)
2040 fatal("%s: decode ID: %s",
2041 __func__, ssh_err(r));
2042 if (esid != sid)
1978 fatal("%s: tty alloc fail on unknown session: " 2043 fatal("%s: tty alloc fail on unknown session: "
1979 "my id %u theirs %u", 2044 "my id %u theirs %u",
1980 __func__, sid, esid); 2045 __func__, sid, esid);
@@ -1983,17 +2048,24 @@ mux_client_request_session(int fd)
1983 rawmode = 0; 2048 rawmode = 0;
1984 continue; 2049 continue;
1985 case MUX_S_EXIT_MESSAGE: 2050 case MUX_S_EXIT_MESSAGE:
1986 if ((esid = buffer_get_int(&m)) != sid) 2051 if ((r = sshbuf_get_u32(m, &esid)) != 0)
2052 fatal("%s: decode ID: %s",
2053 __func__, ssh_err(r));
2054 if (esid != sid)
1987 fatal("%s: exit on unknown session: " 2055 fatal("%s: exit on unknown session: "
1988 "my id %u theirs %u", 2056 "my id %u theirs %u",
1989 __func__, sid, esid); 2057 __func__, sid, esid);
1990 if (exitval_seen) 2058 if (exitval_seen)
1991 fatal("%s: exitval sent twice", __func__); 2059 fatal("%s: exitval sent twice", __func__);
1992 exitval = buffer_get_int(&m); 2060 if ((r = sshbuf_get_u32(m, &exitval)) != 0)
2061 fatal("%s: decode exit value: %s",
2062 __func__, ssh_err(r));
1993 exitval_seen = 1; 2063 exitval_seen = 1;
1994 continue; 2064 continue;
1995 default: 2065 default:
1996 e = buffer_get_string(&m, NULL); 2066 if ((r = sshbuf_get_cstring(m, &e, NULL)) != 0)
2067 fatal("%s: decode error: %s",
2068 __func__, ssh_err(r));
1997 fatal("%s: master returned error: %s", __func__, e); 2069 fatal("%s: master returned error: %s", __func__, e);
1998 } 2070 }
1999 } 2071 }
@@ -2020,32 +2092,38 @@ mux_client_request_session(int fd)
2020static int 2092static int
2021mux_client_proxy(int fd) 2093mux_client_proxy(int fd)
2022{ 2094{
2023 Buffer m; 2095 struct sshbuf *m;
2024 char *e; 2096 char *e;
2025 u_int type, rid; 2097 u_int type, rid;
2026 2098 int r;
2027 buffer_init(&m); 2099
2028 buffer_put_int(&m, MUX_C_PROXY); 2100 if ((m = sshbuf_new()) == NULL)
2029 buffer_put_int(&m, muxclient_request_id); 2101 fatal("%s: sshbuf_new", __func__);
2030 if (mux_client_write_packet(fd, &m) != 0) 2102 if ((r = sshbuf_put_u32(m, MUX_C_PROXY)) != 0 ||
2103 (r = sshbuf_put_u32(m, muxclient_request_id)) != 0)
2104 fatal("%s: request: %s", __func__, ssh_err(r));
2105 if (mux_client_write_packet(fd, m) != 0)
2031 fatal("%s: write packet: %s", __func__, strerror(errno)); 2106 fatal("%s: write packet: %s", __func__, strerror(errno));
2032 2107
2033 buffer_clear(&m); 2108 sshbuf_reset(m);
2034 2109
2035 /* Read their reply */ 2110 /* Read their reply */
2036 if (mux_client_read_packet(fd, &m) != 0) { 2111 if (mux_client_read_packet(fd, m) != 0) {
2037 buffer_free(&m); 2112 sshbuf_free(m);
2038 return 0; 2113 return 0;
2039 } 2114 }
2040 type = buffer_get_int(&m); 2115 if ((r = sshbuf_get_u32(m, &type)) != 0 ||
2116 (r = sshbuf_get_u32(m, &rid)) != 0)
2117 fatal("%s: decode: %s", __func__, ssh_err(r));
2118 if (rid != muxclient_request_id)
2119 fatal("%s: out of sequence reply: my id %u theirs %u",
2120 __func__, muxclient_request_id, rid);
2041 if (type != MUX_S_PROXY) { 2121 if (type != MUX_S_PROXY) {
2042 e = buffer_get_string(&m, NULL); 2122 if ((r = sshbuf_get_cstring(m, &e, NULL)) != 0)
2123 fatal("%s: decode error: %s", __func__, ssh_err(r));
2043 fatal("%s: master returned error: %s", __func__, e); 2124 fatal("%s: master returned error: %s", __func__, e);
2044 } 2125 }
2045 if ((rid = buffer_get_int(&m)) != muxclient_request_id) 2126 sshbuf_free(m);
2046 fatal("%s: out of sequence reply: my id %u theirs %u",
2047 __func__, muxclient_request_id, rid);
2048 buffer_free(&m);
2049 2127
2050 debug3("%s: done", __func__); 2128 debug3("%s: done", __func__);
2051 muxclient_request_id++; 2129 muxclient_request_id++;
@@ -2055,10 +2133,10 @@ mux_client_proxy(int fd)
2055static int 2133static int
2056mux_client_request_stdio_fwd(int fd) 2134mux_client_request_stdio_fwd(int fd)
2057{ 2135{
2058 Buffer m; 2136 struct sshbuf *m;
2059 char *e; 2137 char *e;
2060 u_int type, rid, sid; 2138 u_int type, rid, sid;
2061 int devnull; 2139 int r, devnull;
2062 2140
2063 debug3("%s: entering", __func__); 2141 debug3("%s: entering", __func__);
2064 2142
@@ -2078,14 +2156,16 @@ mux_client_request_stdio_fwd(int fd)
2078 close(devnull); 2156 close(devnull);
2079 } 2157 }
2080 2158
2081 buffer_init(&m); 2159 if ((m = sshbuf_new()) == NULL)
2082 buffer_put_int(&m, MUX_C_NEW_STDIO_FWD); 2160 fatal("%s: sshbuf_new", __func__);
2083 buffer_put_int(&m, muxclient_request_id); 2161 if ((r = sshbuf_put_u32(m, MUX_C_NEW_STDIO_FWD)) != 0 ||
2084 buffer_put_cstring(&m, ""); /* reserved */ 2162 (r = sshbuf_put_u32(m, muxclient_request_id)) != 0 ||
2085 buffer_put_cstring(&m, options.stdio_forward_host); 2163 (r = sshbuf_put_string(m, NULL, 0)) != 0 || /* reserved */
2086 buffer_put_int(&m, options.stdio_forward_port); 2164 (r = sshbuf_put_cstring(m, options.stdio_forward_host)) != 0 ||
2165 (r = sshbuf_put_u32(m, options.stdio_forward_port)) != 0)
2166 fatal("%s: request: %s", __func__, ssh_err(r));
2087 2167
2088 if (mux_client_write_packet(fd, &m) != 0) 2168 if (mux_client_write_packet(fd, m) != 0)
2089 fatal("%s: write packet: %s", __func__, strerror(errno)); 2169 fatal("%s: write packet: %s", __func__, strerror(errno));
2090 2170
2091 /* Send the stdio file descriptors */ 2171 /* Send the stdio file descriptors */
@@ -2100,34 +2180,39 @@ mux_client_request_stdio_fwd(int fd)
2100 debug3("%s: stdio forward request sent", __func__); 2180 debug3("%s: stdio forward request sent", __func__);
2101 2181
2102 /* Read their reply */ 2182 /* Read their reply */
2103 buffer_clear(&m); 2183 sshbuf_reset(m);
2104 2184
2105 if (mux_client_read_packet(fd, &m) != 0) { 2185 if (mux_client_read_packet(fd, m) != 0) {
2106 error("%s: read from master failed: %s", 2186 error("%s: read from master failed: %s",
2107 __func__, strerror(errno)); 2187 __func__, strerror(errno));
2108 buffer_free(&m); 2188 sshbuf_free(m);
2109 return -1; 2189 return -1;
2110 } 2190 }
2111 2191
2112 type = buffer_get_int(&m); 2192 if ((r = sshbuf_get_u32(m, &type)) != 0 ||
2113 if ((rid = buffer_get_int(&m)) != muxclient_request_id) 2193 (r = sshbuf_get_u32(m, &rid)) != 0)
2194 fatal("%s: decode: %s", __func__, ssh_err(r));
2195 if (rid != muxclient_request_id)
2114 fatal("%s: out of sequence reply: my id %u theirs %u", 2196 fatal("%s: out of sequence reply: my id %u theirs %u",
2115 __func__, muxclient_request_id, rid); 2197 __func__, muxclient_request_id, rid);
2116 switch (type) { 2198 switch (type) {
2117 case MUX_S_SESSION_OPENED: 2199 case MUX_S_SESSION_OPENED:
2118 sid = buffer_get_int(&m); 2200 if ((r = sshbuf_get_u32(m, &sid)) != 0)
2201 fatal("%s: decode ID: %s", __func__, ssh_err(r));
2119 debug("%s: master session id: %u", __func__, sid); 2202 debug("%s: master session id: %u", __func__, sid);
2120 break; 2203 break;
2121 case MUX_S_PERMISSION_DENIED: 2204 case MUX_S_PERMISSION_DENIED:
2122 e = buffer_get_string(&m, NULL); 2205 if ((r = sshbuf_get_cstring(m, &e, NULL)) != 0)
2123 buffer_free(&m); 2206 fatal("%s: decode error: %s", __func__, ssh_err(r));
2207 sshbuf_free(m);
2124 fatal("Master refused stdio forwarding request: %s", e); 2208 fatal("Master refused stdio forwarding request: %s", e);
2125 case MUX_S_FAILURE: 2209 case MUX_S_FAILURE:
2126 e = buffer_get_string(&m, NULL); 2210 if ((r = sshbuf_get_cstring(m, &e, NULL)) != 0)
2127 buffer_free(&m); 2211 fatal("%s: decode error: %s", __func__, ssh_err(r));
2212 sshbuf_free(m);
2128 fatal("Stdio forwarding request failed: %s", e); 2213 fatal("Stdio forwarding request failed: %s", e);
2129 default: 2214 default:
2130 buffer_free(&m); 2215 sshbuf_free(m);
2131 error("%s: unexpected response from master 0x%08x", 2216 error("%s: unexpected response from master 0x%08x",
2132 __func__, type); 2217 __func__, type);
2133 return -1; 2218 return -1;
@@ -2142,8 +2227,8 @@ mux_client_request_stdio_fwd(int fd)
2142 /* 2227 /*
2143 * Stick around until the controlee closes the client_fd. 2228 * Stick around until the controlee closes the client_fd.
2144 */ 2229 */
2145 buffer_clear(&m); 2230 sshbuf_reset(m);
2146 if (mux_client_read_packet(fd, &m) != 0) { 2231 if (mux_client_read_packet(fd, m) != 0) {
2147 if (errno == EPIPE || 2232 if (errno == EPIPE ||
2148 (errno == EINTR && muxclient_terminate != 0)) 2233 (errno == EINTR && muxclient_terminate != 0))
2149 return 0; 2234 return 0;
@@ -2156,44 +2241,52 @@ mux_client_request_stdio_fwd(int fd)
2156static void 2241static void
2157mux_client_request_stop_listening(int fd) 2242mux_client_request_stop_listening(int fd)
2158{ 2243{
2159 Buffer m; 2244 struct sshbuf *m;
2160 char *e; 2245 char *e;
2161 u_int type, rid; 2246 u_int type, rid;
2247 int r;
2162 2248
2163 debug3("%s: entering", __func__); 2249 debug3("%s: entering", __func__);
2164 2250
2165 buffer_init(&m); 2251 if ((m = sshbuf_new()) == NULL)
2166 buffer_put_int(&m, MUX_C_STOP_LISTENING); 2252 fatal("%s: sshbuf_new", __func__);
2167 buffer_put_int(&m, muxclient_request_id); 2253 if ((r = sshbuf_put_u32(m, MUX_C_STOP_LISTENING)) != 0 ||
2254 (r = sshbuf_put_u32(m, muxclient_request_id)) != 0)
2255 fatal("%s: request: %s", __func__, ssh_err(r));
2168 2256
2169 if (mux_client_write_packet(fd, &m) != 0) 2257 if (mux_client_write_packet(fd, m) != 0)
2170 fatal("%s: write packet: %s", __func__, strerror(errno)); 2258 fatal("%s: write packet: %s", __func__, strerror(errno));
2171 2259
2172 buffer_clear(&m); 2260 sshbuf_reset(m);
2173 2261
2174 /* Read their reply */ 2262 /* Read their reply */
2175 if (mux_client_read_packet(fd, &m) != 0) 2263 if (mux_client_read_packet(fd, m) != 0)
2176 fatal("%s: read from master failed: %s", 2264 fatal("%s: read from master failed: %s",
2177 __func__, strerror(errno)); 2265 __func__, strerror(errno));
2178 2266
2179 type = buffer_get_int(&m); 2267 if ((r = sshbuf_get_u32(m, &type)) != 0 ||
2180 if ((rid = buffer_get_int(&m)) != muxclient_request_id) 2268 (r = sshbuf_get_u32(m, &rid)) != 0)
2269 fatal("%s: decode: %s", __func__, ssh_err(r));
2270 if (rid != muxclient_request_id)
2181 fatal("%s: out of sequence reply: my id %u theirs %u", 2271 fatal("%s: out of sequence reply: my id %u theirs %u",
2182 __func__, muxclient_request_id, rid); 2272 __func__, muxclient_request_id, rid);
2273
2183 switch (type) { 2274 switch (type) {
2184 case MUX_S_OK: 2275 case MUX_S_OK:
2185 break; 2276 break;
2186 case MUX_S_PERMISSION_DENIED: 2277 case MUX_S_PERMISSION_DENIED:
2187 e = buffer_get_string(&m, NULL); 2278 if ((r = sshbuf_get_cstring(m, &e, NULL)) != 0)
2279 fatal("%s: decode error: %s", __func__, ssh_err(r));
2188 fatal("Master refused stop listening request: %s", e); 2280 fatal("Master refused stop listening request: %s", e);
2189 case MUX_S_FAILURE: 2281 case MUX_S_FAILURE:
2190 e = buffer_get_string(&m, NULL); 2282 if ((r = sshbuf_get_cstring(m, &e, NULL)) != 0)
2283 fatal("%s: decode error: %s", __func__, ssh_err(r));
2191 fatal("%s: stop listening request failed: %s", __func__, e); 2284 fatal("%s: stop listening request failed: %s", __func__, e);
2192 default: 2285 default:
2193 fatal("%s: unexpected response from master 0x%08x", 2286 fatal("%s: unexpected response from master 0x%08x",
2194 __func__, type); 2287 __func__, type);
2195 } 2288 }
2196 buffer_free(&m); 2289 sshbuf_free(m);
2197 muxclient_request_id++; 2290 muxclient_request_id++;
2198} 2291}
2199 2292