summaryrefslogtreecommitdiff
path: root/mux.c
diff options
context:
space:
mode:
Diffstat (limited to 'mux.c')
-rw-r--r--mux.c152
1 files changed, 73 insertions, 79 deletions
diff --git a/mux.c b/mux.c
index 1ae0e0915..882fa61b5 100644
--- a/mux.c
+++ b/mux.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: mux.c,v 1.38 2013/01/02 00:32:07 djm Exp $ */ 1/* $OpenBSD: mux.c,v 1.44 2013/07/12 00:19:58 djm 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 *
@@ -184,7 +184,7 @@ static const struct {
184 184
185/* Cleanup callback fired on closure of mux slave _session_ channel */ 185/* Cleanup callback fired on closure of mux slave _session_ channel */
186/* ARGSUSED */ 186/* ARGSUSED */
187void 187static void
188mux_master_session_cleanup_cb(int cid, void *unused) 188mux_master_session_cleanup_cb(int cid, void *unused)
189{ 189{
190 Channel *cc, *c = channel_by_id(cid); 190 Channel *cc, *c = channel_by_id(cid);
@@ -219,7 +219,8 @@ mux_master_control_cleanup_cb(int cid, void *unused)
219 __func__, c->self, c->remote_id); 219 __func__, c->self, c->remote_id);
220 c->remote_id = -1; 220 c->remote_id = -1;
221 sc->ctl_chan = -1; 221 sc->ctl_chan = -1;
222 if (sc->type != SSH_CHANNEL_OPEN) { 222 if (sc->type != SSH_CHANNEL_OPEN &&
223 sc->type != SSH_CHANNEL_OPENING) {
223 debug2("%s: channel %d: not open", __func__, sc->self); 224 debug2("%s: channel %d: not open", __func__, sc->self);
224 chan_mark_dead(sc); 225 chan_mark_dead(sc);
225 } else { 226 } else {
@@ -286,13 +287,13 @@ process_mux_master_hello(u_int rid, Channel *c, Buffer *m, Buffer *r)
286 char *value = buffer_get_string_ret(m, NULL); 287 char *value = buffer_get_string_ret(m, NULL);
287 288
288 if (name == NULL || value == NULL) { 289 if (name == NULL || value == NULL) {
289 if (name != NULL) 290 free(name);
290 xfree(name); 291 free(value);
291 goto malf; 292 goto malf;
292 } 293 }
293 debug2("Unrecognised slave extension \"%s\"", name); 294 debug2("Unrecognised slave extension \"%s\"", name);
294 xfree(name); 295 free(name);
295 xfree(value); 296 free(value);
296 } 297 }
297 state->hello_rcvd = 1; 298 state->hello_rcvd = 1;
298 return 0; 299 return 0;
@@ -323,21 +324,17 @@ process_mux_new_session(u_int rid, Channel *c, Buffer *m, Buffer *r)
323 (cctx->term = buffer_get_string_ret(m, &len)) == NULL || 324 (cctx->term = buffer_get_string_ret(m, &len)) == NULL ||
324 (cmd = buffer_get_string_ret(m, &len)) == NULL) { 325 (cmd = buffer_get_string_ret(m, &len)) == NULL) {
325 malf: 326 malf:
326 if (cmd != NULL) 327 free(cmd);
327 xfree(cmd); 328 free(reserved);
328 if (reserved != NULL)
329 xfree(reserved);
330 for (j = 0; j < env_len; j++) 329 for (j = 0; j < env_len; j++)
331 xfree(cctx->env[j]); 330 free(cctx->env[j]);
332 if (env_len > 0) 331 free(cctx->env);
333 xfree(cctx->env); 332 free(cctx->term);
334 if (cctx->term != NULL) 333 free(cctx);
335 xfree(cctx->term);
336 xfree(cctx);
337 error("%s: malformed message", __func__); 334 error("%s: malformed message", __func__);
338 return -1; 335 return -1;
339 } 336 }
340 xfree(reserved); 337 free(reserved);
341 reserved = NULL; 338 reserved = NULL;
342 339
343 while (buffer_len(m) > 0) { 340 while (buffer_len(m) > 0) {
@@ -345,7 +342,7 @@ process_mux_new_session(u_int rid, Channel *c, Buffer *m, Buffer *r)
345 if ((cp = buffer_get_string_ret(m, &len)) == NULL) 342 if ((cp = buffer_get_string_ret(m, &len)) == NULL)
346 goto malf; 343 goto malf;
347 if (!env_permitted(cp)) { 344 if (!env_permitted(cp)) {
348 xfree(cp); 345 free(cp);
349 continue; 346 continue;
350 } 347 }
351 cctx->env = xrealloc(cctx->env, env_len + 2, 348 cctx->env = xrealloc(cctx->env, env_len + 2,
@@ -366,7 +363,7 @@ process_mux_new_session(u_int rid, Channel *c, Buffer *m, Buffer *r)
366 363
367 buffer_init(&cctx->cmd); 364 buffer_init(&cctx->cmd);
368 buffer_append(&cctx->cmd, cmd, strlen(cmd)); 365 buffer_append(&cctx->cmd, cmd, strlen(cmd));
369 xfree(cmd); 366 free(cmd);
370 cmd = NULL; 367 cmd = NULL;
371 368
372 /* Gather fds from client */ 369 /* Gather fds from client */
@@ -377,12 +374,11 @@ process_mux_new_session(u_int rid, Channel *c, Buffer *m, Buffer *r)
377 for (j = 0; j < i; j++) 374 for (j = 0; j < i; j++)
378 close(new_fd[j]); 375 close(new_fd[j]);
379 for (j = 0; j < env_len; j++) 376 for (j = 0; j < env_len; j++)
380 xfree(cctx->env[j]); 377 free(cctx->env[j]);
381 if (env_len > 0) 378 free(cctx->env);
382 xfree(cctx->env); 379 free(cctx->term);
383 xfree(cctx->term);
384 buffer_free(&cctx->cmd); 380 buffer_free(&cctx->cmd);
385 xfree(cctx); 381 free(cctx);
386 382
387 /* prepare reply */ 383 /* prepare reply */
388 buffer_put_int(r, MUX_S_FAILURE); 384 buffer_put_int(r, MUX_S_FAILURE);
@@ -407,14 +403,14 @@ process_mux_new_session(u_int rid, Channel *c, Buffer *m, Buffer *r)
407 close(new_fd[0]); 403 close(new_fd[0]);
408 close(new_fd[1]); 404 close(new_fd[1]);
409 close(new_fd[2]); 405 close(new_fd[2]);
410 xfree(cctx->term); 406 free(cctx->term);
411 if (env_len != 0) { 407 if (env_len != 0) {
412 for (i = 0; i < env_len; i++) 408 for (i = 0; i < env_len; i++)
413 xfree(cctx->env[i]); 409 free(cctx->env[i]);
414 xfree(cctx->env); 410 free(cctx->env);
415 } 411 }
416 buffer_free(&cctx->cmd); 412 buffer_free(&cctx->cmd);
417 xfree(cctx); 413 free(cctx);
418 return 0; 414 return 0;
419 } 415 }
420 416
@@ -619,7 +615,7 @@ mux_confirm_remote_forward(int type, u_int32_t seq, void *ctxt)
619 buffer_put_int(&out, MUX_S_FAILURE); 615 buffer_put_int(&out, MUX_S_FAILURE);
620 buffer_put_int(&out, fctx->rid); 616 buffer_put_int(&out, fctx->rid);
621 buffer_put_cstring(&out, failmsg); 617 buffer_put_cstring(&out, failmsg);
622 xfree(failmsg); 618 free(failmsg);
623 out: 619 out:
624 buffer_put_string(&c->output, buffer_ptr(&out), buffer_len(&out)); 620 buffer_put_string(&c->output, buffer_ptr(&out), buffer_len(&out));
625 buffer_free(&out); 621 buffer_free(&out);
@@ -634,25 +630,28 @@ process_mux_open_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
634 Forward fwd; 630 Forward fwd;
635 char *fwd_desc = NULL; 631 char *fwd_desc = NULL;
636 u_int ftype; 632 u_int ftype;
633 u_int lport, cport;
637 int i, ret = 0, freefwd = 1; 634 int i, ret = 0, freefwd = 1;
638 635
639 fwd.listen_host = fwd.connect_host = NULL; 636 fwd.listen_host = fwd.connect_host = NULL;
640 if (buffer_get_int_ret(&ftype, m) != 0 || 637 if (buffer_get_int_ret(&ftype, m) != 0 ||
641 (fwd.listen_host = buffer_get_string_ret(m, NULL)) == NULL || 638 (fwd.listen_host = buffer_get_string_ret(m, NULL)) == NULL ||
642 buffer_get_int_ret(&fwd.listen_port, m) != 0 || 639 buffer_get_int_ret(&lport, m) != 0 ||
643 (fwd.connect_host = buffer_get_string_ret(m, NULL)) == NULL || 640 (fwd.connect_host = buffer_get_string_ret(m, NULL)) == NULL ||
644 buffer_get_int_ret(&fwd.connect_port, m) != 0) { 641 buffer_get_int_ret(&cport, m) != 0 ||
642 lport > 65535 || cport > 65535) {
645 error("%s: malformed message", __func__); 643 error("%s: malformed message", __func__);
646 ret = -1; 644 ret = -1;
647 goto out; 645 goto out;
648 } 646 }
649 647 fwd.listen_port = lport;
648 fwd.connect_port = cport;
650 if (*fwd.listen_host == '\0') { 649 if (*fwd.listen_host == '\0') {
651 xfree(fwd.listen_host); 650 free(fwd.listen_host);
652 fwd.listen_host = NULL; 651 fwd.listen_host = NULL;
653 } 652 }
654 if (*fwd.connect_host == '\0') { 653 if (*fwd.connect_host == '\0') {
655 xfree(fwd.connect_host); 654 free(fwd.connect_host);
656 fwd.connect_host = NULL; 655 fwd.connect_host = NULL;
657 } 656 }
658 657
@@ -663,10 +662,8 @@ process_mux_open_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
663 ftype != MUX_FWD_DYNAMIC) { 662 ftype != MUX_FWD_DYNAMIC) {
664 logit("%s: invalid forwarding type %u", __func__, ftype); 663 logit("%s: invalid forwarding type %u", __func__, ftype);
665 invalid: 664 invalid:
666 if (fwd.listen_host) 665 free(fwd.listen_host);
667 xfree(fwd.listen_host); 666 free(fwd.connect_host);
668 if (fwd.connect_host)
669 xfree(fwd.connect_host);
670 buffer_put_int(r, MUX_S_FAILURE); 667 buffer_put_int(r, MUX_S_FAILURE);
671 buffer_put_int(r, rid); 668 buffer_put_int(r, rid);
672 buffer_put_cstring(r, "Invalid forwarding request"); 669 buffer_put_cstring(r, "Invalid forwarding request");
@@ -768,13 +765,10 @@ process_mux_open_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
768 buffer_put_int(r, MUX_S_OK); 765 buffer_put_int(r, MUX_S_OK);
769 buffer_put_int(r, rid); 766 buffer_put_int(r, rid);
770 out: 767 out:
771 if (fwd_desc != NULL) 768 free(fwd_desc);
772 xfree(fwd_desc);
773 if (freefwd) { 769 if (freefwd) {
774 if (fwd.listen_host != NULL) 770 free(fwd.listen_host);
775 xfree(fwd.listen_host); 771 free(fwd.connect_host);
776 if (fwd.connect_host != NULL)
777 xfree(fwd.connect_host);
778 } 772 }
779 return ret; 773 return ret;
780} 774}
@@ -787,24 +781,28 @@ process_mux_close_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
787 const char *error_reason = NULL; 781 const char *error_reason = NULL;
788 u_int ftype; 782 u_int ftype;
789 int i, listen_port, ret = 0; 783 int i, listen_port, ret = 0;
784 u_int lport, cport;
790 785
791 fwd.listen_host = fwd.connect_host = NULL; 786 fwd.listen_host = fwd.connect_host = NULL;
792 if (buffer_get_int_ret(&ftype, m) != 0 || 787 if (buffer_get_int_ret(&ftype, m) != 0 ||
793 (fwd.listen_host = buffer_get_string_ret(m, NULL)) == NULL || 788 (fwd.listen_host = buffer_get_string_ret(m, NULL)) == NULL ||
794 buffer_get_int_ret(&fwd.listen_port, m) != 0 || 789 buffer_get_int_ret(&lport, m) != 0 ||
795 (fwd.connect_host = buffer_get_string_ret(m, NULL)) == NULL || 790 (fwd.connect_host = buffer_get_string_ret(m, NULL)) == NULL ||
796 buffer_get_int_ret(&fwd.connect_port, m) != 0) { 791 buffer_get_int_ret(&cport, m) != 0 ||
792 lport > 65535 || cport > 65535) {
797 error("%s: malformed message", __func__); 793 error("%s: malformed message", __func__);
798 ret = -1; 794 ret = -1;
799 goto out; 795 goto out;
800 } 796 }
797 fwd.listen_port = lport;
798 fwd.connect_port = cport;
801 799
802 if (*fwd.listen_host == '\0') { 800 if (*fwd.listen_host == '\0') {
803 xfree(fwd.listen_host); 801 free(fwd.listen_host);
804 fwd.listen_host = NULL; 802 fwd.listen_host = NULL;
805 } 803 }
806 if (*fwd.connect_host == '\0') { 804 if (*fwd.connect_host == '\0') {
807 xfree(fwd.connect_host); 805 free(fwd.connect_host);
808 fwd.connect_host = NULL; 806 fwd.connect_host = NULL;
809 } 807 }
810 808
@@ -861,10 +859,8 @@ process_mux_close_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
861 buffer_put_int(r, MUX_S_OK); 859 buffer_put_int(r, MUX_S_OK);
862 buffer_put_int(r, rid); 860 buffer_put_int(r, rid);
863 861
864 if (found_fwd->listen_host != NULL) 862 free(found_fwd->listen_host);
865 xfree(found_fwd->listen_host); 863 free(found_fwd->connect_host);
866 if (found_fwd->connect_host != NULL)
867 xfree(found_fwd->connect_host);
868 found_fwd->listen_host = found_fwd->connect_host = NULL; 864 found_fwd->listen_host = found_fwd->connect_host = NULL;
869 found_fwd->listen_port = found_fwd->connect_port = 0; 865 found_fwd->listen_port = found_fwd->connect_port = 0;
870 } else { 866 } else {
@@ -873,12 +869,9 @@ process_mux_close_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
873 buffer_put_cstring(r, error_reason); 869 buffer_put_cstring(r, error_reason);
874 } 870 }
875 out: 871 out:
876 if (fwd_desc != NULL) 872 free(fwd_desc);
877 xfree(fwd_desc); 873 free(fwd.listen_host);
878 if (fwd.listen_host != NULL) 874 free(fwd.connect_host);
879 xfree(fwd.listen_host);
880 if (fwd.connect_host != NULL)
881 xfree(fwd.connect_host);
882 875
883 return ret; 876 return ret;
884} 877}
@@ -895,14 +888,12 @@ process_mux_stdio_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
895 if ((reserved = buffer_get_string_ret(m, NULL)) == NULL || 888 if ((reserved = buffer_get_string_ret(m, NULL)) == NULL ||
896 (chost = buffer_get_string_ret(m, NULL)) == NULL || 889 (chost = buffer_get_string_ret(m, NULL)) == NULL ||
897 buffer_get_int_ret(&cport, m) != 0) { 890 buffer_get_int_ret(&cport, m) != 0) {
898 if (reserved != NULL) 891 free(reserved);
899 xfree(reserved); 892 free(chost);
900 if (chost != NULL)
901 xfree(chost);
902 error("%s: malformed message", __func__); 893 error("%s: malformed message", __func__);
903 return -1; 894 return -1;
904 } 895 }
905 xfree(reserved); 896 free(reserved);
906 897
907 debug2("%s: channel %d: request stdio fwd to %s:%u", 898 debug2("%s: channel %d: request stdio fwd to %s:%u",
908 __func__, c->self, chost, cport); 899 __func__, c->self, chost, cport);
@@ -914,7 +905,7 @@ process_mux_stdio_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
914 __func__, i); 905 __func__, i);
915 for (j = 0; j < i; j++) 906 for (j = 0; j < i; j++)
916 close(new_fd[j]); 907 close(new_fd[j]);
917 xfree(chost); 908 free(chost);
918 909
919 /* prepare reply */ 910 /* prepare reply */
920 buffer_put_int(r, MUX_S_FAILURE); 911 buffer_put_int(r, MUX_S_FAILURE);
@@ -938,7 +929,7 @@ process_mux_stdio_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
938 cleanup: 929 cleanup:
939 close(new_fd[0]); 930 close(new_fd[0]);
940 close(new_fd[1]); 931 close(new_fd[1]);
941 xfree(chost); 932 free(chost);
942 return 0; 933 return 0;
943 } 934 }
944 935
@@ -1000,7 +991,7 @@ process_mux_stop_listening(u_int rid, Channel *c, Buffer *m, Buffer *r)
1000 if (mux_listener_channel != NULL) { 991 if (mux_listener_channel != NULL) {
1001 channel_free(mux_listener_channel); 992 channel_free(mux_listener_channel);
1002 client_stop_mux(); 993 client_stop_mux();
1003 xfree(options.control_path); 994 free(options.control_path);
1004 options.control_path = NULL; 995 options.control_path = NULL;
1005 mux_listener_channel = NULL; 996 mux_listener_channel = NULL;
1006 muxserver_sock = -1; 997 muxserver_sock = -1;
@@ -1100,7 +1091,7 @@ mux_exit_message(Channel *c, int exitval)
1100 Buffer m; 1091 Buffer m;
1101 Channel *mux_chan; 1092 Channel *mux_chan;
1102 1093
1103 debug3("%s: channel %d: exit message, evitval %d", __func__, c->self, 1094 debug3("%s: channel %d: exit message, exitval %d", __func__, c->self,
1104 exitval); 1095 exitval);
1105 1096
1106 if ((mux_chan = channel_by_id(c->ctl_chan)) == NULL) 1097 if ((mux_chan = channel_by_id(c->ctl_chan)) == NULL)
@@ -1197,8 +1188,8 @@ muxserver_listen(void)
1197 close(muxserver_sock); 1188 close(muxserver_sock);
1198 muxserver_sock = -1; 1189 muxserver_sock = -1;
1199 } 1190 }
1200 xfree(orig_control_path); 1191 free(orig_control_path);
1201 xfree(options.control_path); 1192 free(options.control_path);
1202 options.control_path = NULL; 1193 options.control_path = NULL;
1203 options.control_master = SSHCTL_MASTER_NO; 1194 options.control_master = SSHCTL_MASTER_NO;
1204 return; 1195 return;
@@ -1223,7 +1214,7 @@ muxserver_listen(void)
1223 goto disable_mux_master; 1214 goto disable_mux_master;
1224 } 1215 }
1225 unlink(options.control_path); 1216 unlink(options.control_path);
1226 xfree(options.control_path); 1217 free(options.control_path);
1227 options.control_path = orig_control_path; 1218 options.control_path = orig_control_path;
1228 1219
1229 set_nonblock(muxserver_sock); 1220 set_nonblock(muxserver_sock);
@@ -1308,13 +1299,13 @@ mux_session_confirm(int id, int success, void *arg)
1308 cc->mux_pause = 0; /* start processing messages again */ 1299 cc->mux_pause = 0; /* start processing messages again */
1309 c->open_confirm_ctx = NULL; 1300 c->open_confirm_ctx = NULL;
1310 buffer_free(&cctx->cmd); 1301 buffer_free(&cctx->cmd);
1311 xfree(cctx->term); 1302 free(cctx->term);
1312 if (cctx->env != NULL) { 1303 if (cctx->env != NULL) {
1313 for (i = 0; cctx->env[i] != NULL; i++) 1304 for (i = 0; cctx->env[i] != NULL; i++)
1314 xfree(cctx->env[i]); 1305 free(cctx->env[i]);
1315 xfree(cctx->env); 1306 free(cctx->env);
1316 } 1307 }
1317 xfree(cctx); 1308 free(cctx);
1318} 1309}
1319 1310
1320/* ** Multiplexing client support */ 1311/* ** Multiplexing client support */
@@ -1444,7 +1435,9 @@ mux_client_read_packet(int fd, Buffer *m)
1444 buffer_init(&queue); 1435 buffer_init(&queue);
1445 if (mux_client_read(fd, &queue, 4) != 0) { 1436 if (mux_client_read(fd, &queue, 4) != 0) {
1446 if ((oerrno = errno) == EPIPE) 1437 if ((oerrno = errno) == EPIPE)
1447 debug3("%s: read header failed: %s", __func__, strerror(errno)); 1438 debug3("%s: read header failed: %s", __func__,
1439 strerror(errno));
1440 buffer_free(&queue);
1448 errno = oerrno; 1441 errno = oerrno;
1449 return -1; 1442 return -1;
1450 } 1443 }
@@ -1452,6 +1445,7 @@ mux_client_read_packet(int fd, Buffer *m)
1452 if (mux_client_read(fd, &queue, need) != 0) { 1445 if (mux_client_read(fd, &queue, need) != 0) {
1453 oerrno = errno; 1446 oerrno = errno;
1454 debug3("%s: read body failed: %s", __func__, strerror(errno)); 1447 debug3("%s: read body failed: %s", __func__, strerror(errno));
1448 buffer_free(&queue);
1455 errno = oerrno; 1449 errno = oerrno;
1456 return -1; 1450 return -1;
1457 } 1451 }
@@ -1498,8 +1492,8 @@ mux_client_hello_exchange(int fd)
1498 char *value = buffer_get_string(&m, NULL); 1492 char *value = buffer_get_string(&m, NULL);
1499 1493
1500 debug2("Unrecognised master extension \"%s\"", name); 1494 debug2("Unrecognised master extension \"%s\"", name);
1501 xfree(name); 1495 free(name);
1502 xfree(value); 1496 free(value);
1503 } 1497 }
1504 buffer_free(&m); 1498 buffer_free(&m);
1505 return 0; 1499 return 0;
@@ -1608,7 +1602,7 @@ mux_client_forward(int fd, int cancel_flag, u_int ftype, Forward *fwd)
1608 fwd_desc = format_forward(ftype, fwd); 1602 fwd_desc = format_forward(ftype, fwd);
1609 debug("Requesting %s %s", 1603 debug("Requesting %s %s",
1610 cancel_flag ? "cancellation of" : "forwarding of", fwd_desc); 1604 cancel_flag ? "cancellation of" : "forwarding of", fwd_desc);
1611 xfree(fwd_desc); 1605 free(fwd_desc);
1612 1606
1613 buffer_init(&m); 1607 buffer_init(&m);
1614 buffer_put_int(&m, cancel_flag ? MUX_C_CLOSE_FWD : MUX_C_OPEN_FWD); 1608 buffer_put_int(&m, cancel_flag ? MUX_C_CLOSE_FWD : MUX_C_OPEN_FWD);