summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2014-07-18 15:04:10 +1000
committerDamien Miller <djm@mindrot.org>2014-07-18 15:04:10 +1000
commit357610d15946381ae90c271837dcdd0cdce7145f (patch)
treee94ba70af3b190aa205f06b8eedf4b910c5dc2e2
parentdad9a4a0b7c2b5d78605f8df28718f116524134e (diff)
- djm@cvs.openbsd.org 2014/07/17 07:22:19
[mux.c ssh.c] reflect stdio-forward ("ssh -W host:port ...") failures in exit status. previously we were always returning 0. bz#2255 reported by Brendan Germain; ok dtucker
-rw-r--r--ChangeLog5
-rw-r--r--mux.c66
-rw-r--r--ssh.c10
3 files changed, 73 insertions, 8 deletions
diff --git a/ChangeLog b/ChangeLog
index c2e52afcc..a7c402316 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -28,6 +28,11 @@
28 - djm@cvs.openbsd.org 2014/07/17 00:12:03 28 - djm@cvs.openbsd.org 2014/07/17 00:12:03
29 [key.c] 29 [key.c]
30 silence "incorrect passphrase" error spam; reported and ok dtucker@ 30 silence "incorrect passphrase" error spam; reported and ok dtucker@
31 - djm@cvs.openbsd.org 2014/07/17 07:22:19
32 [mux.c ssh.c]
33 reflect stdio-forward ("ssh -W host:port ...") failures in exit status.
34 previously we were always returning 0. bz#2255 reported by Brendan
35 Germain; ok dtucker
31 36
3220140717 3720140717
33 - (djm) [digest-openssl.c] Preserve array order when disabling digests. 38 - (djm) [digest-openssl.c] Preserve array order when disabling digests.
diff --git a/mux.c b/mux.c
index 8da2676b3..48f7a050f 100644
--- a/mux.c
+++ b/mux.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: mux.c,v 1.47 2014/07/17 00:10:18 djm Exp $ */ 1/* $OpenBSD: mux.c,v 1.48 2014/07/17 07:22:19 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 *
@@ -105,6 +105,11 @@ struct mux_session_confirm_ctx {
105 u_int rid; 105 u_int rid;
106}; 106};
107 107
108/* Context for stdio fwd open confirmation callback */
109struct mux_stdio_confirm_ctx {
110 u_int rid;
111};
112
108/* Context for global channel callback */ 113/* Context for global channel callback */
109struct mux_channel_confirm_ctx { 114struct mux_channel_confirm_ctx {
110 u_int cid; /* channel id */ 115 u_int cid; /* channel id */
@@ -157,6 +162,7 @@ struct mux_master_state {
157#define MUX_FWD_DYNAMIC 3 162#define MUX_FWD_DYNAMIC 3
158 163
159static void mux_session_confirm(int, int, void *); 164static void mux_session_confirm(int, int, void *);
165static void mux_stdio_confirm(int, int, void *);
160 166
161static int process_mux_master_hello(u_int, Channel *, Buffer *, Buffer *); 167static int process_mux_master_hello(u_int, Channel *, Buffer *, Buffer *);
162static int process_mux_new_session(u_int, Channel *, Buffer *, Buffer *); 168static int process_mux_new_session(u_int, Channel *, Buffer *, Buffer *);
@@ -923,6 +929,7 @@ process_mux_stdio_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
923 char *reserved, *chost; 929 char *reserved, *chost;
924 u_int cport, i, j; 930 u_int cport, i, j;
925 int new_fd[2]; 931 int new_fd[2];
932 struct mux_stdio_confirm_ctx *cctx;
926 933
927 chost = reserved = NULL; 934 chost = reserved = NULL;
928 if ((reserved = buffer_get_string_ret(m, NULL)) == NULL || 935 if ((reserved = buffer_get_string_ret(m, NULL)) == NULL ||
@@ -1002,15 +1009,60 @@ process_mux_stdio_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
1002 1009
1003 channel_register_cleanup(nc->self, mux_master_session_cleanup_cb, 1); 1010 channel_register_cleanup(nc->self, mux_master_session_cleanup_cb, 1);
1004 1011
1005 /* prepare reply */ 1012 cctx = xcalloc(1, sizeof(*cctx));
1006 /* XXX defer until channel confirmed */ 1013 cctx->rid = rid;
1007 buffer_put_int(r, MUX_S_SESSION_OPENED); 1014 channel_register_open_confirm(nc->self, mux_stdio_confirm, cctx);
1008 buffer_put_int(r, rid); 1015 c->mux_pause = 1; /* stop handling messages until open_confirm done */
1009 buffer_put_int(r, nc->self);
1010 1016
1017 /* reply is deferred, sent by mux_session_confirm */
1011 return 0; 1018 return 0;
1012} 1019}
1013 1020
1021/* Callback on open confirmation in mux master for a mux stdio fwd session. */
1022static void
1023mux_stdio_confirm(int id, int success, void *arg)
1024{
1025 struct mux_stdio_confirm_ctx *cctx = arg;
1026 Channel *c, *cc;
1027 Buffer reply;
1028
1029 if (cctx == NULL)
1030 fatal("%s: cctx == NULL", __func__);
1031 if ((c = channel_by_id(id)) == NULL)
1032 fatal("%s: no channel for id %d", __func__, id);
1033 if ((cc = channel_by_id(c->ctl_chan)) == NULL)
1034 fatal("%s: channel %d lacks control channel %d", __func__,
1035 id, c->ctl_chan);
1036
1037 if (!success) {
1038 debug3("%s: sending failure reply", __func__);
1039 /* prepare reply */
1040 buffer_init(&reply);
1041 buffer_put_int(&reply, MUX_S_FAILURE);
1042 buffer_put_int(&reply, cctx->rid);
1043 buffer_put_cstring(&reply, "Session open refused by peer");
1044 goto done;
1045 }
1046
1047 debug3("%s: sending success reply", __func__);
1048 /* prepare reply */
1049 buffer_init(&reply);
1050 buffer_put_int(&reply, MUX_S_SESSION_OPENED);
1051 buffer_put_int(&reply, cctx->rid);
1052 buffer_put_int(&reply, c->self);
1053
1054 done:
1055 /* Send reply */
1056 buffer_put_string(&cc->output, buffer_ptr(&reply), buffer_len(&reply));
1057 buffer_free(&reply);
1058
1059 if (cc->mux_pause <= 0)
1060 fatal("%s: mux_pause %d", __func__, cc->mux_pause);
1061 cc->mux_pause = 0; /* start processing messages again */
1062 c->open_confirm_ctx = NULL;
1063 free(cctx);
1064}
1065
1014static int 1066static int
1015process_mux_stop_listening(u_int rid, Channel *c, Buffer *m, Buffer *r) 1067process_mux_stop_listening(u_int rid, Channel *c, Buffer *m, Buffer *r)
1016{ 1068{
@@ -1955,7 +2007,7 @@ mux_client_request_stdio_fwd(int fd)
1955 case MUX_S_FAILURE: 2007 case MUX_S_FAILURE:
1956 e = buffer_get_string(&m, NULL); 2008 e = buffer_get_string(&m, NULL);
1957 buffer_free(&m); 2009 buffer_free(&m);
1958 fatal("%s: stdio forwarding request failed: %s", __func__, e); 2010 fatal("Stdio forwarding request failed: %s", e);
1959 default: 2011 default:
1960 buffer_free(&m); 2012 buffer_free(&m);
1961 error("%s: unexpected response from master 0x%08x", 2013 error("%s: unexpected response from master 0x%08x",
diff --git a/ssh.c b/ssh.c
index 47375f5ea..26e9681b7 100644
--- a/ssh.c
+++ b/ssh.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh.c,v 1.406 2014/07/15 15:54:14 millert Exp $ */ 1/* $OpenBSD: ssh.c,v 1.407 2014/07/17 07:22:19 djm Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -1360,6 +1360,13 @@ client_cleanup_stdio_fwd(int id, void *arg)
1360} 1360}
1361 1361
1362static void 1362static void
1363ssh_stdio_confirm(int id, int success, void *arg)
1364{
1365 if (!success)
1366 fatal("stdio forwarding failed");
1367}
1368
1369static void
1363ssh_init_stdio_forwarding(void) 1370ssh_init_stdio_forwarding(void)
1364{ 1371{
1365 Channel *c; 1372 Channel *c;
@@ -1379,6 +1386,7 @@ ssh_init_stdio_forwarding(void)
1379 stdio_forward_port, in, out)) == NULL) 1386 stdio_forward_port, in, out)) == NULL)
1380 fatal("%s: channel_connect_stdio_fwd failed", __func__); 1387 fatal("%s: channel_connect_stdio_fwd failed", __func__);
1381 channel_register_cleanup(c->self, client_cleanup_stdio_fwd, 0); 1388 channel_register_cleanup(c->self, client_cleanup_stdio_fwd, 0);
1389 channel_register_open_confirm(c->self, ssh_stdio_confirm, NULL);
1382} 1390}
1383 1391
1384static void 1392static void