mirror of
https://github.com/PowerShell/openssh-portable.git
synced 2025-07-28 08:14:24 +02:00
- djm@cvs.openbsd.org 2011/04/17 22:42:42
[PROTOCOL.mux clientloop.c clientloop.h mux.c ssh.1 ssh.c] allow graceful shutdown of multiplexing: request that a mux server removes its listener socket and refuse future multiplexing requests; ok markus@
This commit is contained in:
parent
ad21032e65
commit
6c3eec7ab2
@ -55,6 +55,11 @@
|
|||||||
- djm@cvs.openbsd.org 2011/04/13 04:09:37
|
- djm@cvs.openbsd.org 2011/04/13 04:09:37
|
||||||
[ssh-keygen.1]
|
[ssh-keygen.1]
|
||||||
mention valid -b sizes for ECDSA keys; bz#1862
|
mention valid -b sizes for ECDSA keys; bz#1862
|
||||||
|
- djm@cvs.openbsd.org 2011/04/17 22:42:42
|
||||||
|
[PROTOCOL.mux clientloop.c clientloop.h mux.c ssh.1 ssh.c]
|
||||||
|
allow graceful shutdown of multiplexing: request that a mux server
|
||||||
|
removes its listener socket and refuse future multiplexing requests;
|
||||||
|
ok markus@
|
||||||
|
|
||||||
20110221
|
20110221
|
||||||
- (dtucker) [contrib/cygwin/ssh-host-config] From Corinna: revamp of the
|
- (dtucker) [contrib/cygwin/ssh-host-config] From Corinna: revamp of the
|
||||||
|
19
PROTOCOL.mux
19
PROTOCOL.mux
@ -149,10 +149,21 @@ The client then sends its standard input and output file descriptors
|
|||||||
|
|
||||||
The contents of "reserved" are currently ignored.
|
The contents of "reserved" are currently ignored.
|
||||||
|
|
||||||
A server may reply with a MUX_S_SESSION_OPEED, a MUX_S_PERMISSION_DENIED
|
A server may reply with a MUX_S_SESSION_OPENED, a MUX_S_PERMISSION_DENIED
|
||||||
or a MUX_S_FAILURE.
|
or a MUX_S_FAILURE.
|
||||||
|
|
||||||
8. Status messages
|
8. Requesting shutdown of mux listener
|
||||||
|
|
||||||
|
A client may request the master to stop accepting new multiplexing requests
|
||||||
|
and remove its listener socket.
|
||||||
|
|
||||||
|
uint32 MUX_C_STOP_LISTENING
|
||||||
|
uint32 request id
|
||||||
|
|
||||||
|
A server may reply with a MUX_S_OK, a MUX_S_PERMISSION_DENIED or a
|
||||||
|
MUX_S_FAILURE.
|
||||||
|
|
||||||
|
9. Status messages
|
||||||
|
|
||||||
The MUX_S_OK message is empty:
|
The MUX_S_OK message is empty:
|
||||||
|
|
||||||
@ -178,6 +189,7 @@ The MUX_S_PERMISSION_DENIED and MUX_S_FAILURE include a reason:
|
|||||||
#define MUX_C_OPEN_FWD 0x10000006
|
#define MUX_C_OPEN_FWD 0x10000006
|
||||||
#define MUX_C_CLOSE_FWD 0x10000007
|
#define MUX_C_CLOSE_FWD 0x10000007
|
||||||
#define MUX_C_NEW_STDIO_FWD 0x10000008
|
#define MUX_C_NEW_STDIO_FWD 0x10000008
|
||||||
|
#define MUX_C_STOP_LISTENING 0x10000009
|
||||||
#define MUX_S_OK 0x80000001
|
#define MUX_S_OK 0x80000001
|
||||||
#define MUX_S_PERMISSION_DENIED 0x80000002
|
#define MUX_S_PERMISSION_DENIED 0x80000002
|
||||||
#define MUX_S_FAILURE 0x80000003
|
#define MUX_S_FAILURE 0x80000003
|
||||||
@ -192,7 +204,6 @@ The MUX_S_PERMISSION_DENIED and MUX_S_FAILURE include a reason:
|
|||||||
|
|
||||||
XXX TODO
|
XXX TODO
|
||||||
XXX extended status (e.g. report open channels / forwards)
|
XXX extended status (e.g. report open channels / forwards)
|
||||||
XXX graceful close (delete listening socket, but keep existing sessions active)
|
|
||||||
XXX lock (maybe)
|
XXX lock (maybe)
|
||||||
XXX watch in/out traffic (pre/post crypto)
|
XXX watch in/out traffic (pre/post crypto)
|
||||||
XXX inject packet (what about replies)
|
XXX inject packet (what about replies)
|
||||||
@ -200,4 +211,4 @@ XXX server->client error/warning notifications
|
|||||||
XXX port0 rfwd (need custom response message)
|
XXX port0 rfwd (need custom response message)
|
||||||
XXX send signals via mux
|
XXX send signals via mux
|
||||||
|
|
||||||
$OpenBSD: PROTOCOL.mux,v 1.4 2011/01/31 21:42:15 djm Exp $
|
$OpenBSD: PROTOCOL.mux,v 1.5 2011/04/17 22:42:41 djm Exp $
|
||||||
|
34
clientloop.c
34
clientloop.c
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: clientloop.c,v 1.231 2011/01/16 12:05:59 djm Exp $ */
|
/* $OpenBSD: clientloop.c,v 1.232 2011/04/17 22:42:41 djm Exp $ */
|
||||||
/*
|
/*
|
||||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||||
@ -265,10 +265,10 @@ static void
|
|||||||
set_control_persist_exit_time(void)
|
set_control_persist_exit_time(void)
|
||||||
{
|
{
|
||||||
if (muxserver_sock == -1 || !options.control_persist
|
if (muxserver_sock == -1 || !options.control_persist
|
||||||
|| options.control_persist_timeout == 0)
|
|| options.control_persist_timeout == 0) {
|
||||||
/* not using a ControlPersist timeout */
|
/* not using a ControlPersist timeout */
|
||||||
control_persist_exit_time = 0;
|
control_persist_exit_time = 0;
|
||||||
else if (channel_still_open()) {
|
} else if (channel_still_open()) {
|
||||||
/* some client connections are still open */
|
/* some client connections are still open */
|
||||||
if (control_persist_exit_time > 0)
|
if (control_persist_exit_time > 0)
|
||||||
debug2("%s: cancel scheduled exit", __func__);
|
debug2("%s: cancel scheduled exit", __func__);
|
||||||
@ -1419,14 +1419,17 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
|
|||||||
|
|
||||||
if (compat20) {
|
if (compat20) {
|
||||||
session_ident = ssh2_chan_id;
|
session_ident = ssh2_chan_id;
|
||||||
if (escape_char_arg != SSH_ESCAPECHAR_NONE)
|
if (session_ident != -1) {
|
||||||
channel_register_filter(session_ident,
|
if (escape_char_arg != SSH_ESCAPECHAR_NONE) {
|
||||||
client_simple_escape_filter, NULL,
|
channel_register_filter(session_ident,
|
||||||
client_filter_cleanup,
|
client_simple_escape_filter, NULL,
|
||||||
client_new_escape_filter_ctx(escape_char_arg));
|
client_filter_cleanup,
|
||||||
if (session_ident != -1)
|
client_new_escape_filter_ctx(
|
||||||
|
escape_char_arg));
|
||||||
|
}
|
||||||
channel_register_cleanup(session_ident,
|
channel_register_cleanup(session_ident,
|
||||||
client_channel_closed, 0);
|
client_channel_closed, 0);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Check if we should immediately send eof on stdin. */
|
/* Check if we should immediately send eof on stdin. */
|
||||||
client_check_initial_eof_on_stdin();
|
client_check_initial_eof_on_stdin();
|
||||||
@ -2122,6 +2125,19 @@ client_init_dispatch(void)
|
|||||||
client_init_dispatch_15();
|
client_init_dispatch_15();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
client_stop_mux(void)
|
||||||
|
{
|
||||||
|
if (options.control_path != NULL && muxserver_sock != -1)
|
||||||
|
unlink(options.control_path);
|
||||||
|
/*
|
||||||
|
* If we are in persist mode, signal that we should close when all
|
||||||
|
* active channels are closed.
|
||||||
|
*/
|
||||||
|
if (options.control_persist)
|
||||||
|
session_closed = 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* client specific fatal cleanup */
|
/* client specific fatal cleanup */
|
||||||
void
|
void
|
||||||
cleanup_exit(int i)
|
cleanup_exit(int i)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: clientloop.h,v 1.25 2010/06/25 23:15:36 djm Exp $ */
|
/* $OpenBSD: clientloop.h,v 1.26 2011/04/17 22:42:41 djm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||||
@ -45,6 +45,7 @@ void client_global_request_reply_fwd(int, u_int32_t, void *);
|
|||||||
void client_session2_setup(int, int, int, const char *, struct termios *,
|
void client_session2_setup(int, int, int, const char *, struct termios *,
|
||||||
int, Buffer *, char **);
|
int, Buffer *, char **);
|
||||||
int client_request_tun_fwd(int, int, int);
|
int client_request_tun_fwd(int, int, int);
|
||||||
|
void client_stop_mux(void);
|
||||||
|
|
||||||
/* Escape filter for protocol 2 sessions */
|
/* Escape filter for protocol 2 sessions */
|
||||||
void *client_new_escape_filter_ctx(int);
|
void *client_new_escape_filter_ctx(int);
|
||||||
@ -64,6 +65,7 @@ void client_register_global_confirm(global_confirm_cb *, void *);
|
|||||||
#define SSHMUX_COMMAND_TERMINATE 3 /* Ask master to exit */
|
#define SSHMUX_COMMAND_TERMINATE 3 /* Ask master to exit */
|
||||||
#define SSHMUX_COMMAND_STDIO_FWD 4 /* Open stdio fwd (ssh -W) */
|
#define SSHMUX_COMMAND_STDIO_FWD 4 /* Open stdio fwd (ssh -W) */
|
||||||
#define SSHMUX_COMMAND_FORWARD 5 /* Forward only, no command */
|
#define SSHMUX_COMMAND_FORWARD 5 /* Forward only, no command */
|
||||||
|
#define SSHMUX_COMMAND_STOP 6 /* Disable mux but not conn */
|
||||||
|
|
||||||
void muxserver_listen(void);
|
void muxserver_listen(void);
|
||||||
void muxclient(const char *);
|
void muxclient(const char *);
|
||||||
|
86
mux.c
86
mux.c
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: mux.c,v 1.24 2011/01/13 21:54:53 djm Exp $ */
|
/* $OpenBSD: mux.c,v 1.25 2011/04/17 22:42:41 djm Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2002-2008 Damien Miller <djm@openbsd.org>
|
* Copyright (c) 2002-2008 Damien Miller <djm@openbsd.org>
|
||||||
*
|
*
|
||||||
@ -146,6 +146,7 @@ struct mux_master_state {
|
|||||||
#define MUX_C_OPEN_FWD 0x10000006
|
#define MUX_C_OPEN_FWD 0x10000006
|
||||||
#define MUX_C_CLOSE_FWD 0x10000007
|
#define MUX_C_CLOSE_FWD 0x10000007
|
||||||
#define MUX_C_NEW_STDIO_FWD 0x10000008
|
#define MUX_C_NEW_STDIO_FWD 0x10000008
|
||||||
|
#define MUX_C_STOP_LISTENING 0x10000009
|
||||||
#define MUX_S_OK 0x80000001
|
#define MUX_S_OK 0x80000001
|
||||||
#define MUX_S_PERMISSION_DENIED 0x80000002
|
#define MUX_S_PERMISSION_DENIED 0x80000002
|
||||||
#define MUX_S_FAILURE 0x80000003
|
#define MUX_S_FAILURE 0x80000003
|
||||||
@ -168,6 +169,7 @@ static int process_mux_terminate(u_int, Channel *, Buffer *, Buffer *);
|
|||||||
static int process_mux_open_fwd(u_int, Channel *, Buffer *, Buffer *);
|
static int process_mux_open_fwd(u_int, Channel *, Buffer *, Buffer *);
|
||||||
static int process_mux_close_fwd(u_int, Channel *, Buffer *, Buffer *);
|
static int process_mux_close_fwd(u_int, Channel *, Buffer *, Buffer *);
|
||||||
static int process_mux_stdio_fwd(u_int, Channel *, Buffer *, Buffer *);
|
static int process_mux_stdio_fwd(u_int, Channel *, Buffer *, Buffer *);
|
||||||
|
static int process_mux_stop_listening(u_int, Channel *, Buffer *, Buffer *);
|
||||||
|
|
||||||
static const struct {
|
static const struct {
|
||||||
u_int type;
|
u_int type;
|
||||||
@ -180,6 +182,7 @@ static const struct {
|
|||||||
{ MUX_C_OPEN_FWD, process_mux_open_fwd },
|
{ MUX_C_OPEN_FWD, process_mux_open_fwd },
|
||||||
{ MUX_C_CLOSE_FWD, process_mux_close_fwd },
|
{ MUX_C_CLOSE_FWD, process_mux_close_fwd },
|
||||||
{ MUX_C_NEW_STDIO_FWD, process_mux_stdio_fwd },
|
{ MUX_C_NEW_STDIO_FWD, process_mux_stdio_fwd },
|
||||||
|
{ MUX_C_STOP_LISTENING, process_mux_stop_listening },
|
||||||
{ 0, NULL }
|
{ 0, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -915,6 +918,39 @@ process_mux_stdio_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
process_mux_stop_listening(u_int rid, Channel *c, Buffer *m, Buffer *r)
|
||||||
|
{
|
||||||
|
debug("%s: channel %d: stop listening", __func__, c->self);
|
||||||
|
|
||||||
|
if (options.control_master == SSHCTL_MASTER_ASK ||
|
||||||
|
options.control_master == SSHCTL_MASTER_AUTO_ASK) {
|
||||||
|
if (!ask_permission("Disable further multiplexing on shared "
|
||||||
|
"connection to %s? ", host)) {
|
||||||
|
debug2("%s: stop listen refused by user", __func__);
|
||||||
|
buffer_put_int(r, MUX_S_PERMISSION_DENIED);
|
||||||
|
buffer_put_int(r, rid);
|
||||||
|
buffer_put_cstring(r, "Permission denied");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mux_listener_channel != NULL) {
|
||||||
|
channel_free(mux_listener_channel);
|
||||||
|
client_stop_mux();
|
||||||
|
xfree(options.control_path);
|
||||||
|
options.control_path = NULL;
|
||||||
|
mux_listener_channel = NULL;
|
||||||
|
muxserver_sock = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* prepare reply */
|
||||||
|
buffer_put_int(r, MUX_S_OK);
|
||||||
|
buffer_put_int(r, rid);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Channel callbacks fired on read/write from mux slave fd */
|
/* Channel callbacks fired on read/write from mux slave fd */
|
||||||
static int
|
static int
|
||||||
mux_master_read_cb(Channel *c)
|
mux_master_read_cb(Channel *c)
|
||||||
@ -1813,6 +1849,50 @@ mux_client_request_stdio_fwd(int fd)
|
|||||||
fatal("%s: master returned unexpected message %u", __func__, type);
|
fatal("%s: master returned unexpected message %u", __func__, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
mux_client_request_stop_listening(int fd)
|
||||||
|
{
|
||||||
|
Buffer m;
|
||||||
|
char *e;
|
||||||
|
u_int type, rid;
|
||||||
|
|
||||||
|
debug3("%s: entering", __func__);
|
||||||
|
|
||||||
|
buffer_init(&m);
|
||||||
|
buffer_put_int(&m, MUX_C_STOP_LISTENING);
|
||||||
|
buffer_put_int(&m, muxclient_request_id);
|
||||||
|
|
||||||
|
if (mux_client_write_packet(fd, &m) != 0)
|
||||||
|
fatal("%s: write packet: %s", __func__, strerror(errno));
|
||||||
|
|
||||||
|
buffer_clear(&m);
|
||||||
|
|
||||||
|
/* Read their reply */
|
||||||
|
if (mux_client_read_packet(fd, &m) != 0)
|
||||||
|
fatal("%s: read from master failed: %s",
|
||||||
|
__func__, strerror(errno));
|
||||||
|
|
||||||
|
type = buffer_get_int(&m);
|
||||||
|
if ((rid = buffer_get_int(&m)) != muxclient_request_id)
|
||||||
|
fatal("%s: out of sequence reply: my id %u theirs %u",
|
||||||
|
__func__, muxclient_request_id, rid);
|
||||||
|
switch (type) {
|
||||||
|
case MUX_S_OK:
|
||||||
|
break;
|
||||||
|
case MUX_S_PERMISSION_DENIED:
|
||||||
|
e = buffer_get_string(&m, NULL);
|
||||||
|
fatal("Master refused stop listening request: %s", e);
|
||||||
|
case MUX_S_FAILURE:
|
||||||
|
e = buffer_get_string(&m, NULL);
|
||||||
|
fatal("%s: stop listening request failed: %s", __func__, e);
|
||||||
|
default:
|
||||||
|
fatal("%s: unexpected response from master 0x%08x",
|
||||||
|
__func__, type);
|
||||||
|
}
|
||||||
|
buffer_free(&m);
|
||||||
|
muxclient_request_id++;
|
||||||
|
}
|
||||||
|
|
||||||
/* Multiplex client main loop. */
|
/* Multiplex client main loop. */
|
||||||
void
|
void
|
||||||
muxclient(const char *path)
|
muxclient(const char *path)
|
||||||
@ -1906,6 +1986,10 @@ muxclient(const char *path)
|
|||||||
case SSHMUX_COMMAND_STDIO_FWD:
|
case SSHMUX_COMMAND_STDIO_FWD:
|
||||||
mux_client_request_stdio_fwd(sock);
|
mux_client_request_stdio_fwd(sock);
|
||||||
exit(0);
|
exit(0);
|
||||||
|
case SSHMUX_COMMAND_STOP:
|
||||||
|
mux_client_request_stop_listening(sock);
|
||||||
|
fprintf(stderr, "Stop listening request sent.\r\n");
|
||||||
|
exit(0);
|
||||||
default:
|
default:
|
||||||
fatal("unrecognised muxclient_command %d", muxclient_command);
|
fatal("unrecognised muxclient_command %d", muxclient_command);
|
||||||
}
|
}
|
||||||
|
6
ssh.1
6
ssh.1
@ -33,8 +33,8 @@
|
|||||||
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
.\"
|
.\"
|
||||||
.\" $OpenBSD: ssh.1,v 1.316 2010/11/18 15:01:00 jmc Exp $
|
.\" $OpenBSD: ssh.1,v 1.317 2011/04/17 22:42:41 djm Exp $
|
||||||
.Dd $Mdocdate: November 18 2010 $
|
.Dd $Mdocdate: April 17 2011 $
|
||||||
.Dt SSH 1
|
.Dt SSH 1
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -395,6 +395,8 @@ Valid commands are:
|
|||||||
(request forwardings without command execution) and
|
(request forwardings without command execution) and
|
||||||
.Dq exit
|
.Dq exit
|
||||||
(request the master to exit).
|
(request the master to exit).
|
||||||
|
.Dq stop
|
||||||
|
(request the master to stop accepting further multiplexing requests).
|
||||||
.It Fl o Ar option
|
.It Fl o Ar option
|
||||||
Can be used to give options in the format used in the configuration file.
|
Can be used to give options in the format used in the configuration file.
|
||||||
This is useful for specifying options for which there is no separate
|
This is useful for specifying options for which there is no separate
|
||||||
|
4
ssh.c
4
ssh.c
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: ssh.c,v 1.356 2011/01/06 22:23:53 djm Exp $ */
|
/* $OpenBSD: ssh.c,v 1.357 2011/04/17 22:42:42 djm Exp $ */
|
||||||
/*
|
/*
|
||||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||||
@ -345,6 +345,8 @@ main(int ac, char **av)
|
|||||||
muxclient_command = SSHMUX_COMMAND_FORWARD;
|
muxclient_command = SSHMUX_COMMAND_FORWARD;
|
||||||
else if (strcmp(optarg, "exit") == 0)
|
else if (strcmp(optarg, "exit") == 0)
|
||||||
muxclient_command = SSHMUX_COMMAND_TERMINATE;
|
muxclient_command = SSHMUX_COMMAND_TERMINATE;
|
||||||
|
else if (strcmp(optarg, "stop") == 0)
|
||||||
|
muxclient_command = SSHMUX_COMMAND_STOP;
|
||||||
else
|
else
|
||||||
fatal("Invalid multiplex command.");
|
fatal("Invalid multiplex command.");
|
||||||
break;
|
break;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user