Commit cf8be0f6 authored by Balázs Scheidler's avatar Balázs Scheidler Committed by Niels Möller
Browse files

New files.

Rev: src/proxy_channel.c:1.1
Rev: src/proxy_channel.h:1.1
Rev: src/proxy_tcpforward.c:1.1
Rev: src/proxy_tcpforward.h:1.1
parent 23080cd0
/* proxy_channel.c
*
* $Id$ */
/* lsh, an implementation of the ssh protocol
*
* Copyright (C) 1999, 2000 Balzs Scheidler
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "proxy_channel.h"
#include "xalloc.h"
#include "ssh.h"
#include "werror.h"
#include "channel_commands.h"
#include "format.h"
#define GABA_DEFINE
#include "proxy_channel.h.x"
#undef GABA_DEFINE
#include "proxy_channel.c.x"
#define WINDOW_SIZE (SSH_MAX_PACKET << 3)
static void
do_receive(struct ssh_channel *c,
int type,
struct lsh_string *data)
{
CAST(proxy_channel, closure, c);
switch(type)
{
case CHANNEL_DATA:
A_WRITE(closure->chain->super.write, channel_transmit_data(&closure->chain->super, data));
break;
case CHANNEL_STDERR_DATA:
A_WRITE(closure->chain->super.write, channel_transmit_extended(&closure->chain->super, CHANNEL_STDERR_DATA, data));
break;
default:
fatal("Internal error!\n");
}
}
static void
do_eof(struct ssh_channel *c)
{
CAST(proxy_channel, channel, c);
channel_eof(&channel->chain->super);
}
static void
do_close(struct ssh_channel *c)
{
CAST(proxy_channel, channel, c);
channel_close(&channel->chain->super);
}
static void
do_init_io(struct proxy_channel *self)
{
/* self->super.send = do_send; */
self->super.receive = do_receive;
self->super.eof = do_eof;
self->super.close = do_close;
}
struct proxy_channel *
make_proxy_channel(UINT32 window_size,
struct alist *request_types,
int client_side)
{
NEW(proxy_channel, self);
init_channel(&self->super);
self->super.max_window = SSH_MAX_PACKET << 3;
self->super.rec_window_size = window_size;
self->super.rec_max_packet = SSH_MAX_PACKET;
self->super.request_types = request_types;
self->init_io = do_init_io;
if (client_side)
self->super.flags |= CHANNEL_CLOSE_AT_EOF;
return self;
}
/* proxy channel requests */
/* GABA:
(class
(name general_channel_request_command)
(super channel_request_command)
(vars
(request string)))
*/
static struct lsh_string *
do_format_channel_general(struct channel_request_command *s,
struct ssh_channel *ch UNUSED,
struct command_continuation **c UNUSED
/* , struct exception_handler **e UNUSED */)
{
CAST(general_channel_request_command, self, s);
struct lsh_string *r = self->request;
self->request = NULL;
return r;
}
static struct command *
make_general_channel_request_command(struct lsh_string *request)
{
NEW(general_channel_request_command, self);
self->super.super.call = do_channel_request_command;
self->super.format_request = do_format_channel_general;
self->request = request;
return &self->super.super;
}
static void
do_proxy_channel_request(struct channel_request *s UNUSED,
struct ssh_channel *ch,
struct ssh_connection *connection UNUSED,
UINT32 type,
int want_reply,
struct simple_buffer *args,
struct command_continuation *c,
struct exception_handler *e)
{
CAST(proxy_channel, channel, ch);
struct lsh_string *request =
format_channel_request(type, &channel->chain->super, want_reply,
"%ls",
args->capacity - args->pos, &args->data[args->pos]);
struct command *send;
send = make_general_channel_request_command(request);
COMMAND_CALL(send, channel->chain, c, e);
}
struct channel_request proxy_channel_request =
{ STATIC_HEADER, do_proxy_channel_request };
/* GABA:
(class
(name general_global_request_command)
(super global_request_command)
(vars
(request string)))
*/
static struct lsh_string *
do_format_general_global_request(struct global_request_command *s,
struct ssh_connection *connection UNUSED,
struct command_continuation **c UNUSED
/* , struct exception_handler **e UNUSED */)
{
CAST(general_global_request_command, self, s);
struct lsh_string *r = self->request;
self->request = NULL;
return r;
}
static struct command *
make_general_global_request_command(struct lsh_string *request)
{
NEW(general_global_request_command, self);
self->super.super.call = do_channel_global_command;
self->super.format_request = do_format_general_global_request;
self->request = request;
return &self->super.super;
}
static void
do_proxy_global_request(struct global_request *s UNUSED,
struct ssh_connection *connection,
UINT32 type,
int want_reply,
struct simple_buffer *args,
struct command_continuation *c,
struct exception_handler *e)
{
struct lsh_string *request =
ssh_format("%c%a%c%ls", SSH_MSG_GLOBAL_REQUEST, type,
want_reply, args->capacity - args->pos, &args->data[args->pos]);
struct command *send;
send = make_general_global_request_command(request);
COMMAND_CALL(send, connection->chain, c, e);
}
struct global_request proxy_global_request =
{ STATIC_HEADER, do_proxy_global_request };
/*
* continuation to handle the returned channel, and chain two channels
* together
*/
/* GABA:
(class
(name proxy_channel_open_continuation)
(super command_continuation)
(vars
(up object command_continuation)
(channel object proxy_channel)))
*/
static void
do_proxy_channel_open_continuation(struct command_continuation *c,
struct lsh_object *x)
{
CAST(proxy_channel_open_continuation, self, c);
CAST(proxy_channel, chain_channel, x);
self->channel->chain = chain_channel;
chain_channel->chain = self->channel;
PROXY_CHANNEL_INIT_IO(self->channel);
PROXY_CHANNEL_INIT_IO(chain_channel);
COMMAND_RETURN(self->up, self->channel);
}
struct command_continuation *
make_proxy_channel_open_continuation(struct command_continuation *up,
struct proxy_channel *channel)
{
NEW(proxy_channel_open_continuation, self);
self->super.c = do_proxy_channel_open_continuation;
self->channel = channel;
self->up = up;
return &self->super;
}
/* command to request a channel open */
/* GABA:
(class
(name proxy_channel_open_command)
(super channel_open_command)
(vars
; channel type
(type . UINT32)
(requests object alist)
(open_request string)))
*/
static struct ssh_channel *
do_proxy_channel_open(struct channel_open_command *c,
struct ssh_connection *connection,
UINT32 local_channel_number,
struct lsh_string **request)
{
CAST(proxy_channel_open_command, closure, c);
struct proxy_channel *client = make_proxy_channel(WINDOW_SIZE, closure->requests, 1);
client->super.write = connection->write;
if (closure->open_request)
*request = format_channel_open(closure->type, local_channel_number,
&client->super, "%lS", closure->open_request);
else
*request = format_channel_open(closure->type, local_channel_number,
&client->super, "");
return &client->super;
}
struct command *
make_proxy_channel_open_command(UINT32 type,
struct lsh_string *open_request,
struct alist *requests)
{
NEW(proxy_channel_open_command, self);
self->super.new_channel = do_proxy_channel_open;
self->super.super.call = do_channel_open_command;
self->type = type;
self->open_request = open_request;
self->requests = requests;
return &self->super.super;
}
/* proxy_channel.h
*
* $Id$ */
/* lsh, an implementation of the ssh protocol
*
* Copyright (C) 1999, 2000 Balázs Scheidler
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef LSH_PROXY_CHANNEL_H_INCLUDED
#define LSH_PROXY_CHANNEL_H_INCLUDED
#include "channel.h"
#define GABA_DECLARE
#include "proxy_channel.h.x"
#undef GABA_DECLARE
/* GABA:
(class
(name proxy_channel)
(super ssh_channel)
(vars
(chain object proxy_channel)
(init_io method void)))
*/
#define PROXY_CHANNEL_INIT_IO(c) ((c)->init_io(c))
struct proxy_channel *
make_proxy_channel(UINT32 window_size,
struct alist *request_types,
int client_side);
struct command *
make_proxy_channel_open_command(UINT32 type,
struct lsh_string *open_request,
struct alist *requests);
struct command_continuation *
make_proxy_channel_open_continuation(struct command_continuation *up,
struct proxy_channel *channel);
extern struct global_request proxy_global_request;
extern struct channel_request proxy_channel_request;
#endif
/* proxy_tcpforward.c
*
* $Id$ */
/* lsh, an implementation of the ssh protocol
*
* Copyright (C) 1999 Balzs Scheidler
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "proxy_tcpforward.h"
#include "proxy_channel.h"
#include "xalloc.h"
#include "ssh.h"
#include "werror.h"
#include "channel_commands.h"
#include "format.h"
#define WINDOW_SIZE (SSH_MAX_PACKET << 3)
static void
do_proxy_open_direct_tcpip(struct channel_open *s UNUSED,
struct ssh_connection *connection,
UINT32 type,
struct simple_buffer *args,
struct command_continuation *c,
struct exception_handler *e)
{
struct lsh_string *host = NULL, *orig_host = NULL;
UINT32 port, orig_port;
debug("server.c: do_proxy_open_direct_tcpip()\n");
if ((host = parse_string_copy(args)) &&
parse_uint32(args, &port) &&
(orig_host = parse_string_copy(args)) &&
parse_uint32(args, &orig_port) &&
parse_eod(args))
{
struct proxy_channel *server = make_proxy_channel(WINDOW_SIZE, NULL, 0);
struct command *o =
make_proxy_channel_open_command(type,
ssh_format("%S%i%S%i",
host, port,
orig_host, orig_port), NULL);
werror("direct-tcpip open request: host to connect=%S:%i, originator=%S:%i", host, port, orig_host, orig_port);
COMMAND_CALL(o,
connection->chain,
make_proxy_channel_open_continuation(c, server),
e);
}
else
{
PROTOCOL_ERROR(e, "Trailing garbage in open message");
}
lsh_string_free(host);
lsh_string_free(orig_host);
}
struct channel_open *
make_proxy_open_direct_tcpip(void)
{
NEW(channel_open, self);
self->handler = do_proxy_open_direct_tcpip;
return self;
}
static void
do_proxy_open_forwarded_tcpip(struct channel_open *s UNUSED,
struct ssh_connection *connection,
UINT32 type,
struct simple_buffer *args,
struct command_continuation *c,
struct exception_handler *e)
{
struct lsh_string *host = NULL, *orig_host = NULL;
UINT32 port, orig_port;
debug("server.c: do_proxy_open_forwarded_tcpip()\n");
if ((host = parse_string_copy(args)) &&
parse_uint32(args, &port) &&
(orig_host = parse_string_copy(args)) &&
parse_uint32(args, &orig_port) &&
parse_eod(args))
{
struct proxy_channel *server = make_proxy_channel(WINDOW_SIZE, NULL, 0);
struct command *o =
make_proxy_channel_open_command(type,
ssh_format("%S%i%S%i",
host, port,
orig_host, orig_port), NULL);
werror("direct-tcpip open request: address where connection was accepted=%S:%i, originator=%S:%i", host, port, orig_host, orig_port);
COMMAND_CALL(o,
connection->chain,
make_proxy_channel_open_continuation(c, server),
e);
}
else
{
PROTOCOL_ERROR(e, "Trailing garbage in open message");
}
lsh_string_free(host);
lsh_string_free(orig_host);
}
struct channel_open *
make_proxy_open_forwarded_tcpip(void)
{
NEW(channel_open, self);
self->handler = do_proxy_open_forwarded_tcpip;
return self;
}
/* proxy_tcpforward.h
*
* $Id$ */
/* lsh, an implementation of the ssh protocol
*
* Copyright (C) 1999 Balázs Scheidler
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef LSH_PROXY_TCPFORWARD_H_INCLUDED
#define LSH_PROXY_TCPFORWARD_H_INCLUDED
struct channel_open *
make_proxy_open_direct_tcpip(void);
struct channel_open *
make_proxy_open_forwarded_tcpip(void);
#endif
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