mirror of
https://github.com/clearml/dropbear
synced 2025-04-02 12:06:15 +00:00
TCP forwarding works.
--HG-- extra : convert_revision : 57dfb36d0d482ad84f31506904eb67863bd303ab
This commit is contained in:
parent
453261a042
commit
e1057cd477
@ -46,8 +46,8 @@ HEADERS=options.h dbutil.h session.h packet.h algo.h ssh.h buffer.h kex.h \
|
||||
dss.h bignum.h signkey.h rsa.h random.h service.h auth.h authpasswd.h \
|
||||
debug.h channel.h chansession.h config.h queue.h sshpty.h \
|
||||
termcodes.h gendss.h genrsa.h authpubkey.h runopts.h includes.h \
|
||||
loginrec.h atomicio.h x11fwd.h agentfwd.h tcp-accept.h compat.h \
|
||||
tcp-connect.h listener.h
|
||||
loginrec.h atomicio.h x11fwd.h agentfwd.h tcpfwd.h compat.h \
|
||||
listener.h
|
||||
|
||||
dropbearobjs=$(COMMONOBJS) $(CLISVROBJS) $(SVROBJS)
|
||||
dbclientobjs=$(COMMONOBJS) $(CLISVROBJS) $(CLIOBJS)
|
||||
|
134
cli-runopts.c
134
cli-runopts.c
@ -28,6 +28,7 @@
|
||||
#include "buffer.h"
|
||||
#include "dbutil.h"
|
||||
#include "algo.h"
|
||||
#include "tcpfwd.h"
|
||||
|
||||
cli_runopts cli_opts; /* GLOBAL */
|
||||
|
||||
@ -36,6 +37,9 @@ static void parsehostname(char* userhostarg);
|
||||
#ifdef DROPBEAR_PUBKEY_AUTH
|
||||
static void loadidentityfile(const char* filename);
|
||||
#endif
|
||||
#ifdef ENABLE_CLI_ANYTCPFWD
|
||||
static void addforward(char* str, struct TCPFwdList** fwdlist);
|
||||
#endif
|
||||
|
||||
static void printhelp() {
|
||||
|
||||
@ -48,10 +52,10 @@ static void printhelp() {
|
||||
#ifdef DROPBEAR_PUBKEY_AUTH
|
||||
"-i <identityfile> (multiple allowed)\n"
|
||||
#endif
|
||||
#ifndef DISABLE_REMOTETCPFWD
|
||||
#ifdef ENABLE_CLI_LOCALTCPFWD
|
||||
"-L <listenport:remotehsot:reportport> Local port forwarding\n"
|
||||
#endif
|
||||
#ifndef DISABLE_TCPFWD_DIRECT
|
||||
#ifdef ENABLE_CLI_REMOTETCPFWD
|
||||
"-R <listenport:remotehost:remoteport> Remote port forwarding\n"
|
||||
#endif
|
||||
,DROPBEAR_VERSION, cli_opts.progname);
|
||||
@ -65,15 +69,13 @@ void cli_getopts(int argc, char ** argv) {
|
||||
#ifdef DROPBEAR_PUBKEY_AUTH
|
||||
int nextiskey = 0; /* A flag if the next argument is a keyfile */
|
||||
#endif
|
||||
#ifdef DROPBEAR_CLI_LOCALTCP
|
||||
#ifdef ENABLE_CLI_LOCALTCPFWD
|
||||
int nextislocal = 0;
|
||||
#endif
|
||||
#ifdef DROPBEAR_CLI_REMOTETCP
|
||||
#ifdef ENABLE_CLI_REMOTETCPFWD
|
||||
int nextisremote = 0;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* see printhelp() for options */
|
||||
cli_opts.progname = argv[0];
|
||||
cli_opts.remotehost = NULL;
|
||||
@ -84,11 +86,11 @@ void cli_getopts(int argc, char ** argv) {
|
||||
#ifdef DROPBEAR_PUBKEY_AUTH
|
||||
cli_opts.pubkeys = NULL;
|
||||
#endif
|
||||
#ifdef DROPBEAR_CLI_LOCALTCP
|
||||
cli_opts.localports = NULL;
|
||||
#ifdef ENABLE_CLI_LOCALTCPFWD
|
||||
cli_opts.localfwds = NULL;
|
||||
#endif
|
||||
#ifdef DROPBEAR_CLI_REMOTETCP
|
||||
cli_opts.remoteports = NULL;
|
||||
#ifdef ENABLE_CLI_REMOTETCPFWD
|
||||
cli_opts.remotefwds = NULL;
|
||||
#endif
|
||||
opts.nolocaltcp = 0;
|
||||
opts.noremotetcp = 0;
|
||||
@ -106,6 +108,22 @@ void cli_getopts(int argc, char ** argv) {
|
||||
nextiskey = 0;
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
#ifdef ENABLE_CLI_REMOTETCPFWD
|
||||
if (nextisremote) {
|
||||
TRACE(("nextisremote true"));
|
||||
addforward(argv[i], &cli_opts.remotefwds);
|
||||
nextisremote = 0;
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
#ifdef ENABLE_CLI_LOCALTCPFWD
|
||||
if (nextislocal) {
|
||||
TRACE(("nextislocal true"));
|
||||
addforward(argv[i], &cli_opts.localfwds);
|
||||
nextislocal = 0;
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
if (next) {
|
||||
/* The previous flag set a value to assign */
|
||||
@ -135,6 +153,16 @@ void cli_getopts(int argc, char ** argv) {
|
||||
case 'T': /* don't want a pty */
|
||||
cli_opts.wantpty = 0;
|
||||
break;
|
||||
#ifdef ENABLE_CLI_LOCALTCPFWD
|
||||
case 'L':
|
||||
nextislocal = 1;
|
||||
break;
|
||||
#endif
|
||||
#ifdef ENABLE_CLI_REMOTETCPFWD
|
||||
case 'R':
|
||||
nextisremote = 1;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
fprintf(stderr, "Unknown argument '%s'\n", argv[i]);
|
||||
printhelp();
|
||||
@ -145,7 +173,7 @@ void cli_getopts(int argc, char ** argv) {
|
||||
continue; /* next argument */
|
||||
|
||||
} else {
|
||||
TRACE(("non-flag arg"));
|
||||
TRACE(("non-flag arg: '%s'", argv[i]));
|
||||
|
||||
/* Either the hostname or commands */
|
||||
|
||||
@ -226,10 +254,14 @@ static void loadidentityfile(const char* filename) {
|
||||
|
||||
/* Parses a [user@]hostname argument. userhostarg is the argv[i] corresponding
|
||||
* - note that it will be modified */
|
||||
static void parsehostname(char* userhostarg) {
|
||||
static void parsehostname(char* orighostarg) {
|
||||
|
||||
uid_t uid;
|
||||
struct passwd *pw = NULL;
|
||||
char *userhostarg = NULL;
|
||||
|
||||
/* We probably don't want to be editing argvs */
|
||||
userhostarg = m_strdup(orighostarg);
|
||||
|
||||
cli_opts.remotehost = strchr(userhostarg, '@');
|
||||
if (cli_opts.remotehost == NULL) {
|
||||
@ -257,3 +289,81 @@ static void parsehostname(char* userhostarg) {
|
||||
dropbear_exit("Bad hostname");
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef ENABLE_CLI_ANYTCPFWD
|
||||
/* Turn a "listenport:remoteaddr:remoteport" string into into a forwarding
|
||||
* set, and add it to the forwarding list */
|
||||
static void addforward(char* origstr, struct TCPFwdList** fwdlist) {
|
||||
|
||||
char * listenport = NULL;
|
||||
char * connectport = NULL;
|
||||
char * connectaddr = NULL;
|
||||
struct TCPFwdList* newfwd = NULL;
|
||||
char * str = NULL;
|
||||
|
||||
TRACE(("enter addforward"));
|
||||
|
||||
/* We probably don't want to be editing argvs */
|
||||
str = m_strdup(origstr);
|
||||
|
||||
listenport = str;
|
||||
|
||||
connectaddr = strchr(str, ':');
|
||||
if (connectaddr == NULL) {
|
||||
TRACE(("connectaddr == NULL"));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
connectaddr[0] = '\0';
|
||||
connectaddr++;
|
||||
|
||||
connectport = strchr(connectaddr, ':');
|
||||
if (connectport == NULL) {
|
||||
TRACE(("connectport == NULL"));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
connectport[0] = '\0';
|
||||
connectport++;
|
||||
|
||||
newfwd = (struct TCPFwdList*)m_malloc(sizeof(struct TCPFwdList));
|
||||
|
||||
/* Now we check the ports - note that the port ints are unsigned,
|
||||
* the check later only checks for >= MAX_PORT */
|
||||
newfwd->listenport = strtol(listenport, NULL, 10);
|
||||
if (errno != 0) {
|
||||
TRACE(("bad listenport strtol"));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
newfwd->connectport = strtol(connectport, NULL, 10);
|
||||
if (errno != 0) {
|
||||
TRACE(("bad connectport strtol"));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
newfwd->connectaddr = connectaddr;
|
||||
|
||||
if (newfwd->listenport > 65535) {
|
||||
TRACE(("listenport > 65535"));
|
||||
goto badport;
|
||||
}
|
||||
|
||||
if (newfwd->connectport > 65535) {
|
||||
TRACE(("connectport > 65535"));
|
||||
goto badport;
|
||||
}
|
||||
|
||||
newfwd->next = *fwdlist;
|
||||
*fwdlist = newfwd;
|
||||
|
||||
TRACE(("leave addforward: done"));
|
||||
return;
|
||||
|
||||
fail:
|
||||
dropbear_exit("Bad TCP forward '%s'", origstr);
|
||||
|
||||
badport:
|
||||
dropbear_exit("Bad TCP port in '%s'", origstr);
|
||||
}
|
||||
#endif
|
||||
|
@ -4,8 +4,7 @@
|
||||
#include "kex.h"
|
||||
#include "ssh.h"
|
||||
#include "packet.h"
|
||||
#include "tcp-accept.h"
|
||||
#include "tcp-connect.h"
|
||||
#include "tcpfwd.h"
|
||||
#include "channel.h"
|
||||
#include "random.h"
|
||||
#include "service.h"
|
||||
@ -45,8 +44,9 @@ static const packettype cli_packettypes[] = {
|
||||
};
|
||||
|
||||
static const struct ChanType *cli_chantypes[] = {
|
||||
/* &chan_tcpdirect etc, though need to only allow if we've requested
|
||||
* that forwarding */
|
||||
#ifdef ENABLE_CLI_REMOTETCPFWD
|
||||
&cli_chan_tcpremote,
|
||||
#endif
|
||||
NULL /* Null termination */
|
||||
};
|
||||
|
||||
@ -178,6 +178,10 @@ static void cli_sessionloop() {
|
||||
*/
|
||||
|
||||
case USERAUTH_SUCCESS_RCVD:
|
||||
#ifdef ENABLE_CLI_LOCALTCPFWD
|
||||
TRACE(("recvd USERAUTH_SUCCESS_RCVD"));
|
||||
setup_localtcp();
|
||||
#endif
|
||||
cli_send_chansess_request();
|
||||
TRACE(("leave cli_sessionloop: cli_send_chansess_request"));
|
||||
cli_ses.state = SESSION_RUNNING;
|
||||
@ -223,7 +227,6 @@ static void cli_finished() {
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* called when the remote side closes the connection */
|
||||
static void cli_remoteclosed() {
|
||||
|
||||
|
130
cli-tcpfwd.c
130
cli-tcpfwd.c
@ -1,20 +1,54 @@
|
||||
#include "includes.h"
|
||||
#include "options.h"
|
||||
#include "tcp-accept.h"
|
||||
#include "tcp-connect.h"
|
||||
#include "dbutil.h"
|
||||
#include "tcpfwd.h"
|
||||
#include "channel.h"
|
||||
#include "runopts.h"
|
||||
#include "session.h"
|
||||
#include "ssh.h"
|
||||
|
||||
static int cli_localtcp(unsigned int listenport, const char* remoteaddr,
|
||||
unsigned int remoteport);
|
||||
static int newtcpforwarded(struct Channel * channel);
|
||||
|
||||
const struct ChanType cli_chan_tcpremote = {
|
||||
1, /* sepfds */
|
||||
"forwarded-tcpip",
|
||||
newtcpforwarded,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
static const struct ChanType cli_chan_tcplocal = {
|
||||
1, /* sepfds */
|
||||
"direct-tcpip",
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
void setup_localtcp() {
|
||||
|
||||
qv
|
||||
int ret;
|
||||
|
||||
if (cli_opts.localfwds == NULL) {
|
||||
TRACE(("cli_opts.localfwds == NULL"));
|
||||
}
|
||||
|
||||
while (cli_opts.localfwds != NULL) {
|
||||
ret = cli_localtcp(cli_opts.localfwds->listenport,
|
||||
cli_opts.localfwds->connectaddr,
|
||||
cli_opts.localfwds->connectport);
|
||||
if (ret == DROPBEAR_FAILURE) {
|
||||
dropbear_log(LOG_WARNING, "Failed local port forward %d:%s:%d",
|
||||
cli_opts.localfwds->listenport,
|
||||
cli_opts.localfwds->connectaddr,
|
||||
cli_opts.localfwds->connectport);
|
||||
}
|
||||
|
||||
cli_opts.localfwds = cli_opts.localfwds->next;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -22,6 +56,10 @@ static int cli_localtcp(unsigned int listenport, const char* remoteaddr,
|
||||
unsigned int remoteport) {
|
||||
|
||||
struct TCPListener* tcpinfo = NULL;
|
||||
int ret;
|
||||
|
||||
TRACE(("enter cli_localtcp: %d %s %d", listenport, remoteaddr,
|
||||
remoteport));
|
||||
|
||||
tcpinfo = (struct TCPListener*)m_malloc(sizeof(struct TCPListener*));
|
||||
tcpinfo->sendaddr = remoteaddr;
|
||||
@ -34,5 +72,91 @@ static int cli_localtcp(unsigned int listenport, const char* remoteaddr,
|
||||
if (ret == DROPBEAR_FAILURE) {
|
||||
m_free(tcpinfo);
|
||||
}
|
||||
TRACE(("leave cli_localtcp: %d", ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void send_msg_global_request_remotetcp(int port) {
|
||||
|
||||
TRACE(("enter send_msg_global_request_remotetcp"));
|
||||
|
||||
CHECKCLEARTOWRITE();
|
||||
buf_putbyte(ses.writepayload, SSH_MSG_GLOBAL_REQUEST);
|
||||
buf_putstring(ses.writepayload, "tcpip-forward", 13);
|
||||
buf_putbyte(ses.writepayload, 0);
|
||||
buf_putstring(ses.writepayload, "0.0.0.0", 7); /* TODO: IPv6? */
|
||||
buf_putint(ses.writepayload, port);
|
||||
|
||||
encrypt_packet();
|
||||
|
||||
TRACE(("leave send_msg_global_request_remotetcp"));
|
||||
}
|
||||
|
||||
void setup_remotetcp() {
|
||||
|
||||
struct TCPFwdList * iter = NULL;
|
||||
|
||||
if (cli_opts.remotefwds == NULL) {
|
||||
TRACE(("cli_opts.remotefwds == NULL"));
|
||||
}
|
||||
|
||||
iter = cli_opts.remotefwds;
|
||||
|
||||
while (iter != NULL) {
|
||||
send_msg_global_request_remotetcp(iter->listenport);
|
||||
iter = iter->next;
|
||||
}
|
||||
}
|
||||
|
||||
static int newtcpforwarded(struct Channel * channel) {
|
||||
|
||||
unsigned int origport;
|
||||
struct TCPFwdList * iter = NULL;
|
||||
char portstring[NI_MAXSERV];
|
||||
int sock;
|
||||
int ret = DROPBEAR_FAILURE;
|
||||
|
||||
/* We don't care what address they connected to */
|
||||
buf_eatstring(ses.payload);
|
||||
|
||||
origport = buf_getint(ses.payload);
|
||||
|
||||
/* Find which port corresponds */
|
||||
iter = cli_opts.remotefwds;
|
||||
|
||||
while (iter != NULL) {
|
||||
if (origport == iter->listenport) {
|
||||
break;
|
||||
}
|
||||
iter = iter->next;
|
||||
}
|
||||
|
||||
if (iter == NULL) {
|
||||
/* We didn't request forwarding on that port */
|
||||
dropbear_log(LOG_INFO, "Server send unrequested port, from port %d",
|
||||
origport);
|
||||
goto out;
|
||||
}
|
||||
|
||||
snprintf(portstring, sizeof(portstring), "%d", iter->connectport);
|
||||
sock = connect_remote(iter->connectaddr, portstring, 1, NULL);
|
||||
if (sock < 0) {
|
||||
TRACE(("leave newtcpdirect: sock failed"));
|
||||
goto out;
|
||||
}
|
||||
|
||||
ses.maxfd = MAX(ses.maxfd, sock);
|
||||
|
||||
/* Note that infd is actually the "outgoing" direction on the
|
||||
* tcp connection, vice versa for outfd.
|
||||
* We don't set outfd, that will get set after the connection's
|
||||
* progress succeeds */
|
||||
channel->infd = sock;
|
||||
channel->initconn = 1;
|
||||
|
||||
ret = DROPBEAR_SUCCESS;
|
||||
|
||||
out:
|
||||
TRACE(("leave newtcpdirect: ret %d", ret));
|
||||
return ret;
|
||||
}
|
||||
|
4
dbutil.c
4
dbutil.c
@ -185,7 +185,7 @@ int dropbear_listen(const char* address, const char* port,
|
||||
if (bind(sock, res->ai_addr, res->ai_addrlen) < 0) {
|
||||
err = errno;
|
||||
close(sock);
|
||||
TRACE(("bind() failed"));
|
||||
TRACE(("bind(%s) failed", port));
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -206,7 +206,7 @@ int dropbear_listen(const char* address, const char* port,
|
||||
int len;
|
||||
len = 20 + strlen(strerror(err));
|
||||
*errstring = (char*)m_malloc(len);
|
||||
snprintf(*errstring, len, "Error connecting: %s", strerror(err));
|
||||
snprintf(*errstring, len, "Error listening: %s", strerror(err));
|
||||
TRACE(("leave dropbear_listen: failure, %s", strerror(err)));
|
||||
return -1;
|
||||
}
|
||||
|
224
fake-rfc2553.c
Normal file
224
fake-rfc2553.c
Normal file
@ -0,0 +1,224 @@
|
||||
/*
|
||||
* Copyright (C) 2000-2003 Damien Miller. All rights reserved.
|
||||
* Copyright (C) 1999 WIDE Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the project nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Pseudo-implementation of RFC2553 name / address resolution functions
|
||||
*
|
||||
* But these functions are not implemented correctly. The minimum subset
|
||||
* is implemented for ssh use only. For example, this routine assumes
|
||||
* that ai_family is AF_INET. Don't use it for another purpose.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
RCSID("$Id: fake-rfc2553.c,v 1.5 2003/09/22 02:08:23 dtucker Exp $");
|
||||
|
||||
#ifndef HAVE_GETNAMEINFO
|
||||
int getnameinfo(const struct sockaddr *sa, size_t salen, char *host,
|
||||
size_t hostlen, char *serv, size_t servlen, int flags)
|
||||
{
|
||||
struct sockaddr_in *sin = (struct sockaddr_in *)sa;
|
||||
struct hostent *hp;
|
||||
char tmpserv[16];
|
||||
|
||||
if (serv != NULL) {
|
||||
snprintf(tmpserv, sizeof(tmpserv), "%d", ntohs(sin->sin_port));
|
||||
if (strlcpy(serv, tmpserv, servlen) >= servlen)
|
||||
return (EAI_MEMORY);
|
||||
}
|
||||
|
||||
if (host != NULL) {
|
||||
if (flags & NI_NUMERICHOST) {
|
||||
if (strlcpy(host, inet_ntoa(sin->sin_addr),
|
||||
hostlen) >= hostlen)
|
||||
return (EAI_MEMORY);
|
||||
else
|
||||
return (0);
|
||||
} else {
|
||||
hp = gethostbyaddr((char *)&sin->sin_addr,
|
||||
sizeof(struct in_addr), AF_INET);
|
||||
if (hp == NULL)
|
||||
return (EAI_NODATA);
|
||||
|
||||
if (strlcpy(host, hp->h_name, hostlen) >= hostlen)
|
||||
return (EAI_MEMORY);
|
||||
else
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
#endif /* !HAVE_GETNAMEINFO */
|
||||
|
||||
#ifndef HAVE_GAI_STRERROR
|
||||
#ifdef HAVE_CONST_GAI_STRERROR_PROTO
|
||||
const char *
|
||||
#else
|
||||
char *
|
||||
#endif
|
||||
gai_strerror(int err)
|
||||
{
|
||||
switch (err) {
|
||||
case EAI_NODATA:
|
||||
return ("no address associated with name");
|
||||
case EAI_MEMORY:
|
||||
return ("memory allocation failure.");
|
||||
case EAI_NONAME:
|
||||
return ("nodename nor servname provided, or not known");
|
||||
default:
|
||||
return ("unknown/invalid error.");
|
||||
}
|
||||
}
|
||||
#endif /* !HAVE_GAI_STRERROR */
|
||||
|
||||
#ifndef HAVE_FREEADDRINFO
|
||||
void
|
||||
freeaddrinfo(struct addrinfo *ai)
|
||||
{
|
||||
struct addrinfo *next;
|
||||
|
||||
for(; ai != NULL;) {
|
||||
next = ai->ai_next;
|
||||
free(ai);
|
||||
ai = next;
|
||||
}
|
||||
}
|
||||
#endif /* !HAVE_FREEADDRINFO */
|
||||
|
||||
#ifndef HAVE_GETADDRINFO
|
||||
static struct
|
||||
addrinfo *malloc_ai(int port, u_long addr, const struct addrinfo *hints)
|
||||
{
|
||||
struct addrinfo *ai;
|
||||
|
||||
ai = malloc(sizeof(*ai) + sizeof(struct sockaddr_in));
|
||||
if (ai == NULL)
|
||||
return (NULL);
|
||||
|
||||
memset(ai, '\0', sizeof(*ai) + sizeof(struct sockaddr_in));
|
||||
|
||||
ai->ai_addr = (struct sockaddr *)(ai + 1);
|
||||
/* XXX -- ssh doesn't use sa_len */
|
||||
ai->ai_addrlen = sizeof(struct sockaddr_in);
|
||||
ai->ai_addr->sa_family = ai->ai_family = AF_INET;
|
||||
|
||||
((struct sockaddr_in *)(ai)->ai_addr)->sin_port = port;
|
||||
((struct sockaddr_in *)(ai)->ai_addr)->sin_addr.s_addr = addr;
|
||||
|
||||
/* XXX: the following is not generally correct, but does what we want */
|
||||
if (hints->ai_socktype)
|
||||
ai->ai_socktype = hints->ai_socktype;
|
||||
else
|
||||
ai->ai_socktype = SOCK_STREAM;
|
||||
|
||||
if (hints->ai_protocol)
|
||||
ai->ai_protocol = hints->ai_protocol;
|
||||
|
||||
return (ai);
|
||||
}
|
||||
|
||||
int
|
||||
getaddrinfo(const char *hostname, const char *servname,
|
||||
const struct addrinfo *hints, struct addrinfo **res)
|
||||
{
|
||||
struct hostent *hp;
|
||||
struct servent *sp;
|
||||
struct in_addr in;
|
||||
int i;
|
||||
long int port;
|
||||
u_long addr;
|
||||
|
||||
port = 0;
|
||||
if (servname != NULL) {
|
||||
char *cp;
|
||||
|
||||
port = strtol(servname, &cp, 10);
|
||||
if (port > 0 && port <= 65535 && *cp == '\0')
|
||||
port = htons(port);
|
||||
else if ((sp = getservbyname(servname, NULL)) != NULL)
|
||||
port = sp->s_port;
|
||||
else
|
||||
port = 0;
|
||||
}
|
||||
|
||||
if (hints && hints->ai_flags & AI_PASSIVE) {
|
||||
addr = htonl(0x00000000);
|
||||
if (hostname && inet_aton(hostname, &in) != 0)
|
||||
addr = in.s_addr;
|
||||
*res = malloc_ai(port, addr, hints);
|
||||
if (*res == NULL)
|
||||
return (EAI_MEMORY);
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (!hostname) {
|
||||
*res = malloc_ai(port, htonl(0x7f000001), hints);
|
||||
if (*res == NULL)
|
||||
return (EAI_MEMORY);
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (inet_aton(hostname, &in)) {
|
||||
*res = malloc_ai(port, in.s_addr, hints);
|
||||
if (*res == NULL)
|
||||
return (EAI_MEMORY);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Don't try DNS if AI_NUMERICHOST is set */
|
||||
if (hints && hints->ai_flags & AI_NUMERICHOST)
|
||||
return (EAI_NONAME);
|
||||
|
||||
hp = gethostbyname(hostname);
|
||||
if (hp && hp->h_name && hp->h_name[0] && hp->h_addr_list[0]) {
|
||||
struct addrinfo *cur, *prev;
|
||||
|
||||
cur = prev = *res = NULL;
|
||||
for (i = 0; hp->h_addr_list[i]; i++) {
|
||||
struct in_addr *in = (struct in_addr *)hp->h_addr_list[i];
|
||||
|
||||
cur = malloc_ai(port, in->s_addr, hints);
|
||||
if (cur == NULL) {
|
||||
if (*res != NULL)
|
||||
freeaddrinfo(*res);
|
||||
return (EAI_MEMORY);
|
||||
}
|
||||
if (prev)
|
||||
prev->ai_next = cur;
|
||||
else
|
||||
*res = cur;
|
||||
|
||||
prev = cur;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
return (EAI_NODATA);
|
||||
}
|
||||
#endif /* !HAVE_GETADDRINFO */
|
161
fake-rfc2553.h
Normal file
161
fake-rfc2553.h
Normal file
@ -0,0 +1,161 @@
|
||||
/* $Id: fake-rfc2553.h,v 1.9 2004/03/10 10:06:33 dtucker Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2000-2003 Damien Miller. All rights reserved.
|
||||
* Copyright (C) 1999 WIDE Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the project nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Pseudo-implementation of RFC2553 name / address resolution functions
|
||||
*
|
||||
* But these functions are not implemented correctly. The minimum subset
|
||||
* is implemented for ssh use only. For example, this routine assumes
|
||||
* that ai_family is AF_INET. Don't use it for another purpose.
|
||||
*/
|
||||
|
||||
#ifndef _FAKE_RFC2553_H
|
||||
#define _FAKE_RFC2553_H
|
||||
|
||||
#include "includes.h"
|
||||
#include "sys/types.h"
|
||||
|
||||
/*
|
||||
* First, socket and INET6 related definitions
|
||||
*/
|
||||
#ifndef HAVE_STRUCT_SOCKADDR_STORAGE
|
||||
# define _SS_MAXSIZE 128 /* Implementation specific max size */
|
||||
# define _SS_PADSIZE (_SS_MAXSIZE - sizeof (struct sockaddr))
|
||||
struct sockaddr_storage {
|
||||
struct sockaddr ss_sa;
|
||||
char __ss_pad2[_SS_PADSIZE];
|
||||
};
|
||||
# define ss_family ss_sa.sa_family
|
||||
#endif /* !HAVE_STRUCT_SOCKADDR_STORAGE */
|
||||
|
||||
#ifndef IN6_IS_ADDR_LOOPBACK
|
||||
# define IN6_IS_ADDR_LOOPBACK(a) \
|
||||
(((u_int32_t *)(a))[0] == 0 && ((u_int32_t *)(a))[1] == 0 && \
|
||||
((u_int32_t *)(a))[2] == 0 && ((u_int32_t *)(a))[3] == htonl(1))
|
||||
#endif /* !IN6_IS_ADDR_LOOPBACK */
|
||||
|
||||
#ifndef HAVE_STRUCT_IN6_ADDR
|
||||
struct in6_addr {
|
||||
u_int8_t s6_addr[16];
|
||||
};
|
||||
#endif /* !HAVE_STRUCT_IN6_ADDR */
|
||||
|
||||
#ifndef HAVE_STRUCT_SOCKADDR_IN6
|
||||
struct sockaddr_in6 {
|
||||
unsigned short sin6_family;
|
||||
u_int16_t sin6_port;
|
||||
u_int32_t sin6_flowinfo;
|
||||
struct in6_addr sin6_addr;
|
||||
};
|
||||
#endif /* !HAVE_STRUCT_SOCKADDR_IN6 */
|
||||
|
||||
#ifndef AF_INET6
|
||||
/* Define it to something that should never appear */
|
||||
#define AF_INET6 AF_MAX
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Next, RFC2553 name / address resolution API
|
||||
*/
|
||||
|
||||
#ifndef NI_NUMERICHOST
|
||||
# define NI_NUMERICHOST (1)
|
||||
#endif
|
||||
#ifndef NI_NAMEREQD
|
||||
# define NI_NAMEREQD (1<<1)
|
||||
#endif
|
||||
#ifndef NI_NUMERICSERV
|
||||
# define NI_NUMERICSERV (1<<2)
|
||||
#endif
|
||||
|
||||
#ifndef AI_PASSIVE
|
||||
# define AI_PASSIVE (1)
|
||||
#endif
|
||||
#ifndef AI_CANONNAME
|
||||
# define AI_CANONNAME (1<<1)
|
||||
#endif
|
||||
#ifndef AI_NUMERICHOST
|
||||
# define AI_NUMERICHOST (1<<2)
|
||||
#endif
|
||||
|
||||
#ifndef NI_MAXSERV
|
||||
# define NI_MAXSERV 32
|
||||
#endif /* !NI_MAXSERV */
|
||||
#ifndef NI_MAXHOST
|
||||
# define NI_MAXHOST 1025
|
||||
#endif /* !NI_MAXHOST */
|
||||
|
||||
#ifndef EAI_NODATA
|
||||
# define EAI_NODATA 1
|
||||
# define EAI_MEMORY 2
|
||||
# define EAI_NONAME 3
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRUCT_ADDRINFO
|
||||
struct addrinfo {
|
||||
int ai_flags; /* AI_PASSIVE, AI_CANONNAME */
|
||||
int ai_family; /* PF_xxx */
|
||||
int ai_socktype; /* SOCK_xxx */
|
||||
int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
|
||||
size_t ai_addrlen; /* length of ai_addr */
|
||||
char *ai_canonname; /* canonical name for hostname */
|
||||
struct sockaddr *ai_addr; /* binary address */
|
||||
struct addrinfo *ai_next; /* next structure in linked list */
|
||||
};
|
||||
#endif /* !HAVE_STRUCT_ADDRINFO */
|
||||
|
||||
#ifndef HAVE_GETADDRINFO
|
||||
#ifdef getaddrinfo
|
||||
# undef getaddrinfo
|
||||
#endif
|
||||
#define getaddrinfo(a,b,c,d) (ssh_getaddrinfo(a,b,c,d))
|
||||
int getaddrinfo(const char *, const char *,
|
||||
const struct addrinfo *, struct addrinfo **);
|
||||
#endif /* !HAVE_GETADDRINFO */
|
||||
|
||||
#if !defined(HAVE_GAI_STRERROR) && !defined(HAVE_CONST_GAI_STRERROR_PROTO)
|
||||
#define gai_strerror(a) (ssh_gai_strerror(a))
|
||||
char *gai_strerror(int);
|
||||
#endif /* !HAVE_GAI_STRERROR */
|
||||
|
||||
#ifndef HAVE_FREEADDRINFO
|
||||
#define freeaddrinfo(a) (ssh_freeaddrinfo(a))
|
||||
void freeaddrinfo(struct addrinfo *);
|
||||
#endif /* !HAVE_FREEADDRINFO */
|
||||
|
||||
#ifndef HAVE_GETNAMEINFO
|
||||
#define getnameinfo(a,b,c,d,e,f,g) (ssh_getnameinfo(a,b,c,d,e,f,g))
|
||||
int getnameinfo(const struct sockaddr *, size_t, char *, size_t,
|
||||
char *, size_t, int);
|
||||
#endif /* !HAVE_GETNAMEINFO */
|
||||
|
||||
#endif /* !_FAKE_RFC2553_H */
|
||||
|
15
options.h
15
options.h
@ -51,10 +51,13 @@
|
||||
#define ENABLE_X11FWD
|
||||
|
||||
/* Enable TCP Fowarding */
|
||||
/* OpenSSH's "-L" style forwarding (client port forwarded via server) */
|
||||
#define ENABLE_LOCALTCPFWD
|
||||
/* OpenSSH's "-R" style forwarding (server port forwarded via client) */
|
||||
#define ENABLE_REMOTETCPFWD
|
||||
/* "-L" style forwarding (client listening port forwarded via server) */
|
||||
#define ENABLE_CLI_LOCALTCPFWD
|
||||
/* "-R" style forwarding (server listening port forwarded via client) */
|
||||
#define ENABLE_CLI_REMOTETCPFWD
|
||||
|
||||
#define ENABLE_SVR_LOCALTCPFWD
|
||||
#define ENABLE_SVR_REMOTETCPFWD
|
||||
|
||||
/* Enable Authentication Agent Forwarding */
|
||||
#define ENABLE_AGENTFWD
|
||||
@ -299,6 +302,10 @@
|
||||
#define DISABLE_REMOTETCPFWD
|
||||
#endif
|
||||
|
||||
#if defined(ENABLE_CLI_REMOTETCPFWD) || defined(ENABLE_CLI_LOCALTCPFWD)
|
||||
#define ENABLE_CLI_ANYTCPFWD
|
||||
#endif
|
||||
|
||||
#if defined(ENABLE_REMOTETCPFWD) || defined(ENABLE_LOCALTCPFWD) || \
|
||||
defined(ENABLE_AGENTFWD) || defined(ENABLE_X11FWD)
|
||||
#define USING_LISTENERS
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "signkey.h"
|
||||
#include "buffer.h"
|
||||
#include "auth.h"
|
||||
#include "tcpfwd.h"
|
||||
|
||||
typedef struct runopts {
|
||||
|
||||
@ -90,8 +91,14 @@ typedef struct cli_runopts {
|
||||
|
||||
char *cmd;
|
||||
int wantpty;
|
||||
struct PubkeyList *pubkeys; /* Keys to use for public-key auth */
|
||||
#ifdef DROPBEAR_PUBKEY_AUTH
|
||||
struct PubkeyList *pubkeys; /* Keys to use for public-key auth */
|
||||
#endif
|
||||
#ifdef ENABLE_CLI_REMOTETCPFWD
|
||||
struct TCPFwdList * remotefwds;
|
||||
#endif
|
||||
#ifdef ENABLE_CLI_LOCALTCPFWD
|
||||
struct TCPFwdList * localfwds;
|
||||
#endif
|
||||
/* XXX TODO */
|
||||
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include "queue.h"
|
||||
#include "listener.h"
|
||||
#include "packet.h"
|
||||
#include "tcpfwd.h"
|
||||
|
||||
extern int sessinitdone; /* Is set to 0 somewhere */
|
||||
extern int exitflag;
|
||||
|
72
svr-tcpfwd.c
72
svr-tcpfwd.c
@ -1,7 +1,6 @@
|
||||
#include "includes.h"
|
||||
#include "ssh.h"
|
||||
#include "tcp-accept.h"
|
||||
#include "tcp-connect.h"
|
||||
#include "tcpfwd.h"
|
||||
#include "dbutil.h"
|
||||
#include "session.h"
|
||||
#include "buffer.h"
|
||||
@ -15,6 +14,7 @@ static void send_msg_request_success();
|
||||
static void send_msg_request_failure();
|
||||
static int svr_cancelremotetcp();
|
||||
static int svr_remotetcpreq();
|
||||
static int newtcpdirect(struct Channel * channel);
|
||||
|
||||
|
||||
const struct ChanType svr_chan_tcpdirect = {
|
||||
@ -178,8 +178,8 @@ static int svr_remotetcpreq() {
|
||||
|
||||
tcpinfo = (struct TCPListener*)m_malloc(sizeof(struct TCPListener));
|
||||
tcpinfo->sendaddr = bindaddr;
|
||||
TRACE(("sendport = %d", port));
|
||||
tcpinfo->sendport = port;
|
||||
tcpinfo->listenport = port;
|
||||
tcpinfo->chantype = &svr_chan_tcpremote;
|
||||
|
||||
/* Note: bindaddr is actually ignored by listen_tcpfwd, since
|
||||
@ -196,4 +196,70 @@ out:
|
||||
TRACE(("leave remotetcpreq"));
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Called upon creating a new direct tcp channel (ie we connect out to an
|
||||
* address */
|
||||
static int newtcpdirect(struct Channel * channel) {
|
||||
|
||||
unsigned char* desthost = NULL;
|
||||
unsigned int destport;
|
||||
unsigned char* orighost = NULL;
|
||||
unsigned int origport;
|
||||
char portstring[NI_MAXSERV];
|
||||
int sock;
|
||||
int len;
|
||||
int ret = DROPBEAR_FAILURE;
|
||||
|
||||
if (opts.nolocaltcp) {
|
||||
TRACE(("leave newtcpdirect: local tcp forwarding disabled"));
|
||||
goto out;
|
||||
}
|
||||
|
||||
desthost = buf_getstring(ses.payload, &len);
|
||||
if (len > MAX_HOST_LEN) {
|
||||
TRACE(("leave newtcpdirect: desthost too long"));
|
||||
goto out;
|
||||
}
|
||||
|
||||
destport = buf_getint(ses.payload);
|
||||
|
||||
orighost = buf_getstring(ses.payload, &len);
|
||||
if (len > MAX_HOST_LEN) {
|
||||
TRACE(("leave newtcpdirect: orighost too long"));
|
||||
goto out;
|
||||
}
|
||||
|
||||
origport = buf_getint(ses.payload);
|
||||
|
||||
/* best be sure */
|
||||
if (origport > 65535 || destport > 65535) {
|
||||
TRACE(("leave newtcpdirect: port > 65535"));
|
||||
goto out;
|
||||
}
|
||||
|
||||
snprintf(portstring, sizeof(portstring), "%d", destport);
|
||||
sock = connect_remote(desthost, portstring, 1, NULL);
|
||||
if (sock < 0) {
|
||||
TRACE(("leave newtcpdirect: sock failed"));
|
||||
goto out;
|
||||
}
|
||||
|
||||
ses.maxfd = MAX(ses.maxfd, sock);
|
||||
|
||||
/* Note that infd is actually the "outgoing" direction on the
|
||||
* tcp connection, vice versa for outfd.
|
||||
* We don't set outfd, that will get set after the connection's
|
||||
* progress succeeds */
|
||||
channel->infd = sock;
|
||||
channel->initconn = 1;
|
||||
|
||||
ret = DROPBEAR_SUCCESS;
|
||||
|
||||
out:
|
||||
m_free(desthost);
|
||||
m_free(orighost);
|
||||
TRACE(("leave newtcpdirect: ret %d", ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include "includes.h"
|
||||
#include "ssh.h"
|
||||
#include "tcp-accept.h"
|
||||
#include "tcpfwd.h"
|
||||
#include "dbutil.h"
|
||||
#include "session.h"
|
||||
#include "buffer.h"
|
||||
@ -67,7 +67,7 @@ int listen_tcpfwd(struct TCPListener* tcpinfo) {
|
||||
TRACE(("enter listen_tcpfwd"));
|
||||
|
||||
/* first we try to bind, so don't need to do so much cleanup on failure */
|
||||
snprintf(portstring, sizeof(portstring), "%d", tcpinfo->sendport);
|
||||
snprintf(portstring, sizeof(portstring), "%d", tcpinfo->listenport);
|
||||
|
||||
/* XXX Note: we're just listening on localhost, no matter what they tell
|
||||
* us. If someone wants to make it listen otherways, then change
|
||||
|
25
tcp-accept.h
25
tcp-accept.h
@ -1,25 +0,0 @@
|
||||
#ifndef _REMOTETCPFWD_H
|
||||
#define _REMOTETCPFWD_H
|
||||
|
||||
struct TCPListener {
|
||||
|
||||
/* sendaddr/sendport are what we send in the channel init request. For a
|
||||
* forwarded-tcpip request, it's the addr/port we were binding to.
|
||||
* For a direct-tcpip request, it's the addr/port we want the other
|
||||
* end to connect to */
|
||||
|
||||
unsigned char *sendaddr;
|
||||
unsigned int sendport;
|
||||
|
||||
/* This is for direct-tcpip (ie the client listening), and specifies the
|
||||
* port to listen on. Is unspecified for the server */
|
||||
unsigned int listenport;
|
||||
|
||||
const struct ChanType *chantype;
|
||||
|
||||
};
|
||||
|
||||
void recv_msg_global_request_remotetcp();
|
||||
int listen_tcpfwd(struct TCPListener* tcpinfo);
|
||||
|
||||
#endif /* _REMOTETCPFWD_H */
|
@ -1,75 +0,0 @@
|
||||
#include "includes.h"
|
||||
#include "session.h"
|
||||
#include "dbutil.h"
|
||||
#include "channel.h"
|
||||
#include "tcp-connect.h"
|
||||
#include "runopts.h"
|
||||
|
||||
#ifndef DISABLE_TCP_CONNECT
|
||||
|
||||
/* Called upon creating a new direct tcp channel (ie we connect out to an
|
||||
* address */
|
||||
int newtcpdirect(struct Channel * channel) {
|
||||
|
||||
unsigned char* desthost = NULL;
|
||||
unsigned int destport;
|
||||
unsigned char* orighost = NULL;
|
||||
unsigned int origport;
|
||||
char portstring[NI_MAXSERV];
|
||||
int sock;
|
||||
int len;
|
||||
int ret = DROPBEAR_FAILURE;
|
||||
|
||||
if (opts.nolocaltcp) {
|
||||
TRACE(("leave newtcpdirect: local tcp forwarding disabled"));
|
||||
goto out;
|
||||
}
|
||||
|
||||
desthost = buf_getstring(ses.payload, &len);
|
||||
if (len > MAX_HOST_LEN) {
|
||||
TRACE(("leave newtcpdirect: desthost too long"));
|
||||
goto out;
|
||||
}
|
||||
|
||||
destport = buf_getint(ses.payload);
|
||||
|
||||
orighost = buf_getstring(ses.payload, &len);
|
||||
if (len > MAX_HOST_LEN) {
|
||||
TRACE(("leave newtcpdirect: orighost too long"));
|
||||
goto out;
|
||||
}
|
||||
|
||||
origport = buf_getint(ses.payload);
|
||||
|
||||
/* best be sure */
|
||||
if (origport > 65535 || destport > 65535) {
|
||||
TRACE(("leave newtcpdirect: port > 65535"));
|
||||
goto out;
|
||||
}
|
||||
|
||||
snprintf(portstring, sizeof(portstring), "%d", destport);
|
||||
sock = connect_remote(desthost, portstring, 1, NULL);
|
||||
if (sock < 0) {
|
||||
TRACE(("leave newtcpdirect: sock failed"));
|
||||
goto out;
|
||||
}
|
||||
|
||||
ses.maxfd = MAX(ses.maxfd, sock);
|
||||
|
||||
/* Note that infd is actually the "outgoing" direction on the
|
||||
* tcp connection, vice versa for outfd.
|
||||
* We don't set outfd, that will get set after the connection's
|
||||
* progress succeeds */
|
||||
channel->infd = sock;
|
||||
channel->initconn = 1;
|
||||
|
||||
ret = DROPBEAR_SUCCESS;
|
||||
|
||||
out:
|
||||
m_free(desthost);
|
||||
m_free(orighost);
|
||||
TRACE(("leave newtcpdirect: ret %d", ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* DISABLE_TCPFWD_DIRECT */
|
@ -21,15 +21,49 @@
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE. */
|
||||
#ifndef _TCPFWD_DIRECT_H_
|
||||
#define _TCPFWD_DIRECT_H_
|
||||
#ifndef DISABLE_TCFWD_DIRECT
|
||||
#ifndef _TCPFWD_H
|
||||
#define _TCPFWD_H
|
||||
|
||||
#include "includes.h"
|
||||
#include "channel.h"
|
||||
|
||||
struct TCPListener {
|
||||
|
||||
/* sendaddr/sendport are what we send in the channel init request. For a
|
||||
* forwarded-tcpip request, it's the addr/port we were binding to.
|
||||
* For a direct-tcpip request, it's the addr/port we want the other
|
||||
* end to connect to */
|
||||
|
||||
unsigned char *sendaddr;
|
||||
unsigned int sendport;
|
||||
|
||||
/* This is for direct-tcpip (ie the client listening), and specifies the
|
||||
* port to listen on. Is unspecified for the server */
|
||||
unsigned int listenport;
|
||||
|
||||
const struct ChanType *chantype;
|
||||
|
||||
};
|
||||
|
||||
/* A link in a list of forwards */
|
||||
struct TCPFwdList {
|
||||
|
||||
char* connectaddr;
|
||||
unsigned int connectport;
|
||||
unsigned int listenport;
|
||||
struct TCPFwdList * next;
|
||||
|
||||
};
|
||||
|
||||
/* Server */
|
||||
void recv_msg_global_request_remotetcp();
|
||||
extern const struct ChanType svr_chan_tcpdirect;
|
||||
int newtcpdirect(struct Channel * channel);
|
||||
|
||||
/* Client */
|
||||
void setup_localtcp();
|
||||
extern const struct ChanType cli_chan_tcpremote;
|
||||
|
||||
/* Common */
|
||||
int listen_tcpfwd(struct TCPListener* tcpinfo);
|
||||
|
||||
|
||||
#endif
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user