diff options
author | Damien Miller <djm@mindrot.org> | 2014-07-18 15:04:10 +1000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2014-07-18 15:04:10 +1000 |
commit | 357610d15946381ae90c271837dcdd0cdce7145f (patch) | |
tree | e94ba70af3b190aa205f06b8eedf4b910c5dc2e2 | |
parent | dad9a4a0b7c2b5d78605f8df28718f116524134e (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-- | ChangeLog | 5 | ||||
-rw-r--r-- | mux.c | 66 | ||||
-rw-r--r-- | ssh.c | 10 |
3 files changed, 73 insertions, 8 deletions
@@ -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 | ||
32 | 20140717 | 37 | 20140717 |
33 | - (djm) [digest-openssl.c] Preserve array order when disabling digests. | 38 | - (djm) [digest-openssl.c] Preserve array order when disabling digests. |
@@ -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 */ | ||
109 | struct mux_stdio_confirm_ctx { | ||
110 | u_int rid; | ||
111 | }; | ||
112 | |||
108 | /* Context for global channel callback */ | 113 | /* Context for global channel callback */ |
109 | struct mux_channel_confirm_ctx { | 114 | struct 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 | ||
159 | static void mux_session_confirm(int, int, void *); | 164 | static void mux_session_confirm(int, int, void *); |
165 | static void mux_stdio_confirm(int, int, void *); | ||
160 | 166 | ||
161 | static int process_mux_master_hello(u_int, Channel *, Buffer *, Buffer *); | 167 | static int process_mux_master_hello(u_int, Channel *, Buffer *, Buffer *); |
162 | static int process_mux_new_session(u_int, Channel *, Buffer *, Buffer *); | 168 | static 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. */ | ||
1022 | static void | ||
1023 | mux_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 | |||
1014 | static int | 1066 | static int |
1015 | process_mux_stop_listening(u_int rid, Channel *c, Buffer *m, Buffer *r) | 1067 | process_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", |
@@ -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 | ||
1362 | static void | 1362 | static void |
1363 | ssh_stdio_confirm(int id, int success, void *arg) | ||
1364 | { | ||
1365 | if (!success) | ||
1366 | fatal("stdio forwarding failed"); | ||
1367 | } | ||
1368 | |||
1369 | static void | ||
1363 | ssh_init_stdio_forwarding(void) | 1370 | ssh_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 | ||
1384 | static void | 1392 | static void |