version 1.61, 2016/08/08 22:40:57 |
version 1.62, 2016/09/30 09:19:13 |
|
|
#include "key.h" |
#include "key.h" |
#include "readconf.h" |
#include "readconf.h" |
#include "clientloop.h" |
#include "clientloop.h" |
|
#include "ssherr.h" |
|
|
/* from ssh.c */ |
/* from ssh.c */ |
extern int tty_flag; |
extern int tty_flag; |
|
|
#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_C_STOP_LISTENING 0x10000009 |
|
#define MUX_C_PROXY 0x1000000f |
#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 |
|
|
#define MUX_S_SESSION_OPENED 0x80000006 |
#define MUX_S_SESSION_OPENED 0x80000006 |
#define MUX_S_REMOTE_PORT 0x80000007 |
#define MUX_S_REMOTE_PORT 0x80000007 |
#define MUX_S_TTY_ALLOC_FAIL 0x80000008 |
#define MUX_S_TTY_ALLOC_FAIL 0x80000008 |
|
#define MUX_S_PROXY 0x8000000f |
|
|
/* type codes for MUX_C_OPEN_FWD and MUX_C_CLOSE_FWD */ |
/* type codes for MUX_C_OPEN_FWD and MUX_C_CLOSE_FWD */ |
#define MUX_FWD_LOCAL 1 |
#define MUX_FWD_LOCAL 1 |
|
|
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 int process_mux_stop_listening(u_int, Channel *, Buffer *, Buffer *); |
|
static int process_mux_proxy(u_int, Channel *, Buffer *, Buffer *); |
|
|
static const struct { |
static const struct { |
u_int type; |
u_int type; |
|
|
{ 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 }, |
{ MUX_C_STOP_LISTENING, process_mux_stop_listening }, |
|
{ MUX_C_PROXY, process_mux_proxy }, |
{ 0, NULL } |
{ 0, NULL } |
}; |
}; |
|
|
|
|
return 0; |
return 0; |
} |
} |
|
|
|
static int |
|
process_mux_proxy(u_int rid, Channel *c, Buffer *m, Buffer *r) |
|
{ |
|
debug("%s: channel %d: proxy request", __func__, c->self); |
|
|
|
c->mux_rcb = channel_proxy_downstream; |
|
buffer_put_int(r, MUX_S_PROXY); |
|
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) |
|
|
} |
} |
|
|
static int |
static int |
|
mux_client_proxy(int fd) |
|
{ |
|
Buffer m; |
|
char *e; |
|
u_int type, rid; |
|
|
|
buffer_init(&m); |
|
buffer_put_int(&m, MUX_C_PROXY); |
|
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) { |
|
buffer_free(&m); |
|
return 0; |
|
} |
|
type = buffer_get_int(&m); |
|
if (type != MUX_S_PROXY) { |
|
e = buffer_get_string(&m, NULL); |
|
fatal("%s: master returned error: %s", __func__, e); |
|
} |
|
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); |
|
buffer_free(&m); |
|
|
|
debug3("%s: done", __func__); |
|
muxclient_request_id++; |
|
return 0; |
|
} |
|
|
|
static int |
mux_client_request_stdio_fwd(int fd) |
mux_client_request_stdio_fwd(int fd) |
{ |
{ |
Buffer m; |
Buffer m; |
|
|
} |
} |
|
|
/* Multiplex client main loop. */ |
/* Multiplex client main loop. */ |
void |
int |
muxclient(const char *path) |
muxclient(const char *path) |
{ |
{ |
struct sockaddr_un addr; |
struct sockaddr_un addr; |
|
|
case SSHCTL_MASTER_NO: |
case SSHCTL_MASTER_NO: |
break; |
break; |
default: |
default: |
return; |
return -1; |
} |
} |
|
|
memset(&addr, '\0', sizeof(addr)); |
memset(&addr, '\0', sizeof(addr)); |
|
|
strerror(errno)); |
strerror(errno)); |
} |
} |
close(sock); |
close(sock); |
return; |
return -1; |
} |
} |
set_nonblock(sock); |
set_nonblock(sock); |
|
|
if (mux_client_hello_exchange(sock) != 0) { |
if (mux_client_hello_exchange(sock) != 0) { |
error("%s: master hello exchange failed", __func__); |
error("%s: master hello exchange failed", __func__); |
close(sock); |
close(sock); |
return; |
return -1; |
} |
} |
|
|
switch (muxclient_command) { |
switch (muxclient_command) { |
|
|
case SSHMUX_COMMAND_OPEN: |
case SSHMUX_COMMAND_OPEN: |
if (mux_client_forwards(sock, 0) != 0) { |
if (mux_client_forwards(sock, 0) != 0) { |
error("%s: master forward request failed", __func__); |
error("%s: master forward request failed", __func__); |
return; |
return -1; |
} |
} |
mux_client_request_session(sock); |
mux_client_request_session(sock); |
return; |
return -1; |
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); |
|
|
error("%s: master cancel forward request failed", |
error("%s: master cancel forward request failed", |
__func__); |
__func__); |
exit(0); |
exit(0); |
|
case SSHMUX_COMMAND_PROXY: |
|
mux_client_proxy(sock); |
|
return (sock); |
default: |
default: |
fatal("unrecognised muxclient_command %d", muxclient_command); |
fatal("unrecognised muxclient_command %d", muxclient_command); |
} |
} |