Commit 403463ce authored by Konstantin Artyushkin's avatar Konstantin Artyushkin

Added nx channels with new ssh API

parent 68530f0f
...@@ -86,6 +86,7 @@ ...@@ -86,6 +86,7 @@
#include "authfd.h" #include "authfd.h"
#include "pathnames.h" #include "pathnames.h"
#include "match.h" #include "match.h"
#include "proxy.h"
/* XXX remove once we're satisfied there's no lurking bugs */ /* XXX remove once we're satisfied there's no lurking bugs */
/* #define DEBUG_CHANNEL_POLL 1 */ /* #define DEBUG_CHANNEL_POLL 1 */
...@@ -482,7 +483,8 @@ channel_new(struct ssh *ssh, char *ctype, int type, int rfd, int wfd, int efd, ...@@ -482,7 +483,8 @@ channel_new(struct ssh *ssh, char *ctype, int type, int rfd, int wfd, int efd,
c = sc->channels[found] = xcalloc(1, sizeof(Channel)); c = sc->channels[found] = xcalloc(1, sizeof(Channel));
if ((c->input = sshbuf_new()) == NULL || if ((c->input = sshbuf_new()) == NULL ||
(c->output = sshbuf_new()) == NULL || (c->output = sshbuf_new()) == NULL ||
(c->extended = sshbuf_new()) == NULL) (c->extended = sshbuf_new()) == NULL ||
(c->nx_buffer = sshbuf_new()) == NULL)
fatal_f("sshbuf_new failed"); fatal_f("sshbuf_new failed");
if ((r = sshbuf_set_max_size(c->input, CHAN_INPUT_MAX)) != 0) if ((r = sshbuf_set_max_size(c->input, CHAN_INPUT_MAX)) != 0)
fatal_fr(r, "sshbuf_set_max_size"); fatal_fr(r, "sshbuf_set_max_size");
...@@ -740,7 +742,8 @@ channel_free(struct ssh *ssh, Channel *c) ...@@ -740,7 +742,8 @@ channel_free(struct ssh *ssh, Channel *c)
sshbuf_free(c->input); sshbuf_free(c->input);
sshbuf_free(c->output); sshbuf_free(c->output);
sshbuf_free(c->extended); sshbuf_free(c->extended);
c->input = c->output = c->extended = NULL; sshbuf_free(c->nx_buffer);
c->input = c->output = c->extended = c->nx_buffer = NULL;
free(c->remote_name); free(c->remote_name);
c->remote_name = NULL; c->remote_name = NULL;
free(c->path); free(c->path);
...@@ -2088,8 +2091,11 @@ channel_handle_rfd(struct ssh *ssh, Channel *c) ...@@ -2088,8 +2091,11 @@ channel_handle_rfd(struct ssh *ssh, Channel *c)
/* /*
* For "simple" channels (i.e. not datagram or filtered), we can * For "simple" channels (i.e. not datagram or filtered), we can
* read directly to the channel buffer. * read directly to the channel buffer.
* When NX switch checking is active, we use the buf/read path
* below to allow interception of the NX switch command.
*/ */
if (!pty_zeroread && c->input_filter == NULL && !c->datagram) { if (!pty_zeroread && c->input_filter == NULL && !c->datagram &&
!nx_check_switch) {
/* Only OPEN channels have valid rwin */ /* Only OPEN channels have valid rwin */
if (c->type == SSH_CHANNEL_OPEN) { if (c->type == SSH_CHANNEL_OPEN) {
if ((have = sshbuf_len(c->input)) >= c->remote_window) if ((have = sshbuf_len(c->input)) >= c->remote_window)
...@@ -2135,6 +2141,15 @@ channel_handle_rfd(struct ssh *ssh, Channel *c) ...@@ -2135,6 +2141,15 @@ channel_handle_rfd(struct ssh *ssh, Channel *c)
return -1; return -1;
} }
c->lastused = monotime(); c->lastused = monotime();
/*
* If NX switch checking is active, intercept the data
* to look for the NX switch command.
*/
if (nx_check_switch) {
int intlen = (int)len;
nx_check_channel_input(c, buf, &intlen, sizeof(buf) - 1);
len = intlen;
}
if (c->input_filter != NULL) { if (c->input_filter != NULL) {
if (c->input_filter(ssh, c, buf, len) == -1) { if (c->input_filter(ssh, c, buf, len) == -1) {
debug2("channel %d: filter stops", c->self); debug2("channel %d: filter stops", c->self);
...@@ -2351,6 +2366,29 @@ channel_post_open(struct ssh *ssh, Channel *c) ...@@ -2351,6 +2366,29 @@ channel_post_open(struct ssh *ssh, Channel *c)
channel_handle_wfd(ssh, c); channel_handle_wfd(ssh, c);
channel_handle_efd(ssh, c); channel_handle_efd(ssh, c);
channel_check_window(ssh, c); channel_check_window(ssh, c);
/*
* If we received the NX switch command then
* tie the channel to the running proxy or
* to descriptors inherited from nxserver.
*/
if (nx_check_switch && nx_switch_received) {
if (nx_switch_forward == 1) {
if (nx_switch_forward_descriptors(c) < 0)
fatal("NX> 290 Error while switching communication");
} else if (nx_switch_forward == 2) {
if (nx_switch_forward_port(c) < 0)
fatal("NX> 290 Error while switching communication");
} else {
int proxy_fd;
proxy_fd = nx_open_proxy_connection();
if (proxy_fd < 0)
fatal("NX> 290 Error while switching communication");
nx_check_proxy_authentication(proxy_fd);
if (nx_switch_client_side_descriptors(c, proxy_fd) < 0)
fatal("NX> 290 Error while switching communication");
}
}
} }
static u_int static u_int
...@@ -3497,7 +3535,11 @@ channel_input_ieof(int type, u_int32_t seq, struct ssh *ssh) ...@@ -3497,7 +3535,11 @@ channel_input_ieof(int type, u_int32_t seq, struct ssh *ssh)
if (channel_proxy_upstream(c, type, seq, ssh)) if (channel_proxy_upstream(c, type, seq, ssh))
return 0; return 0;
chan_rcvd_ieof(ssh, c); if (nx_check_switch && !nx_switch_received) {
debug("NX> 280 Ignoring EOF on the monitored channel");
} else {
chan_rcvd_ieof(ssh, c);
}
/* XXX force input close */ /* XXX force input close */
if (c->force_drain && c->istate == CHAN_INPUT_OPEN) { if (c->force_drain && c->istate == CHAN_INPUT_OPEN) {
...@@ -3521,7 +3563,11 @@ channel_input_oclose(int type, u_int32_t seq, struct ssh *ssh) ...@@ -3521,7 +3563,11 @@ channel_input_oclose(int type, u_int32_t seq, struct ssh *ssh)
error_fr(r, "parse data"); error_fr(r, "parse data");
ssh_packet_disconnect(ssh, "Invalid oclose message"); ssh_packet_disconnect(ssh, "Invalid oclose message");
} }
chan_rcvd_oclose(ssh, c); if (nx_check_switch && !nx_switch_received) {
debug("NX> 280 Ignoring CLOSE on the monitored channel");
} else {
chan_rcvd_oclose(ssh, c);
}
return 0; return 0;
} }
......
...@@ -212,6 +212,12 @@ struct Channel { ...@@ -212,6 +212,12 @@ struct Channel {
time_t lastused; time_t lastused;
/* Inactivity timeout deadline in seconds (0 = no timeout) */ /* Inactivity timeout deadline in seconds (0 = no timeout) */
int inactive_deadline; int inactive_deadline;
/*
* Enqueue data read from the local side
* to intercept the NX switch command.
*/
struct sshbuf *nx_buffer;
}; };
#define CHAN_EXTENDED_IGNORE 0 #define CHAN_EXTENDED_IGNORE 0
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment