summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--Makefile.in10
-rw-r--r--channel.h3
-rw-r--r--chansession.h5
-rw-r--r--common-channel.c25
-rw-r--r--listener.c123
-rw-r--r--listener.h37
-rw-r--r--options.h2
-rw-r--r--session.h6
-rw-r--r--svr-chansession.c6
-rw-r--r--svr-session.c2
-rw-r--r--tcpfwd-direct.c (renamed from localtcpfwd.c)7
-rw-r--r--tcpfwd-direct.h (renamed from localtcpfwd.h)6
-rw-r--r--tcpfwd-remote.c (renamed from remotetcpfwd.c)55
-rw-r--r--tcpfwd-remote.h (renamed from remotetcpfwd.h)0
-rw-r--r--tcpfwd.c124
-rw-r--r--tcpfwd.h37
-rw-r--r--x11fwd.c72
-rw-r--r--x11fwd.h2
18 files changed, 277 insertions, 245 deletions
diff --git a/Makefile.in b/Makefile.in
index 10d3cc1..cc3127a 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -4,9 +4,9 @@ LTM=libtommath/libtommath.a
COMMONOBJS=dbutil.o common-session.o common-packet.o common-algo.o buffer.o \
common-kex.o dss.o bignum.o \
signkey.o rsa.o random.o common-channel.o \
- common-chansession.o queue.o termcodes.o runopts.o \
- loginrec.o atomicio.o x11fwd.o agentfwd.o localtcpfwd.o compat.o \
- remotetcpfwd.o tcpfwd.o
+ common-chansession.o queue.o termcodes.o \
+ loginrec.o atomicio.o x11fwd.o tcpfwd-direct.o compat.o \
+ tcpfwd-remote.o listener.o
SVROBJS=svr-kex.o svr-packet.o svr-algo.o svr-auth.o sshpty.o \
svr-authpasswd.o svr-authpubkey.o svr-session.o svr-service.o \
@@ -28,8 +28,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 debug.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 localtcpfwd.h compat.h \
- remotetcpfwd.h tcpfwd.h
+ loginrec.h atomicio.h x11fwd.h agentfwd.h tcpfwd-direct.h compat.h \
+ tcpfwd-remote.h listener.h
ALLOBJS=$(OBJS) $(DROPBEARKEYOBJS) $(DROPBEAROBJS)
diff --git a/channel.h b/channel.h
index e033164..b77a660 100644
--- a/channel.h
+++ b/channel.h
@@ -114,8 +114,7 @@ void recv_msg_channel_close();
void recv_msg_channel_eof();
#ifdef USE_LISTENERS
-int send_msg_channel_open_init(int fd, struct ChanType *type,
- const char * typestring);
+int send_msg_channel_open_init(int fd, const struct ChanType *type);
void recv_msg_channel_open_confirmation();
void recv_msg_channel_open_failure();
#endif
diff --git a/chansession.h b/chansession.h
index 85dc9c1..7879791 100644
--- a/chansession.h
+++ b/chansession.h
@@ -27,6 +27,7 @@
#include "loginrec.h"
#include "channel.h"
+#include "listener.h"
struct ChanSess {
@@ -47,7 +48,7 @@ struct ChanSess {
unsigned char exitcore;
#ifndef DISABLE_X11FWD
- int x11fd; /* set to -1 to indicate forwarding not established */
+ struct Listener * x11listener;
int x11port;
char * x11authprot;
char * x11authcookie;
@@ -56,7 +57,7 @@ struct ChanSess {
#endif
#ifndef DISABLE_AGENTFWD
- int agentfd;
+ struct Listener * agentlistener;
char * agentfile;
char * agentdir;
#endif
diff --git a/common-channel.c b/common-channel.c
index 4643fc2..63ed275 100644
--- a/common-channel.c
+++ b/common-channel.c
@@ -32,9 +32,9 @@
#include "dbutil.h"
#include "channel.h"
#include "ssh.h"
-#include "localtcpfwd.h"
-#include "remotetcpfwd.h"
-#include "tcpfwd.h"
+#include "tcpfwd-direct.h"
+#include "tcpfwd-remote.h"
+#include "listener.h"
static void send_msg_channel_open_failure(unsigned int remotechan, int reason,
const unsigned char *text, const unsigned char *lang);
@@ -70,8 +70,8 @@ void chaninitialise(const struct ChanType *chantypes[]) {
ses.chantypes = chantypes;
-#ifdef USING_TCP_LISTENERS
- tcp_fwd_initialise();
+#ifdef USING_LISTENERS
+ listeners_initialise();
#endif
}
@@ -219,9 +219,9 @@ void channelio(fd_set *readfd, fd_set *writefd) {
} /* foreach channel */
- /* Not channel specific */
-#ifdef USING_TCP_LISTENERS
- handle_tcp_fwd(readfd);
+ /* Listeners such as TCP, X11, agent-auth */
+#ifdef USING_LISTENERS
+ handle_listeners(readfd);
#endif
}
@@ -429,8 +429,8 @@ void setchannelfds(fd_set *readfd, fd_set *writefd) {
} /* foreach channel */
-#ifdef USING_TCP_LISTENERS
- set_tcp_fwd_fds(readfd);
+#ifdef USING_LISTENERS
+ set_listener_fds(readfd);
#endif
}
@@ -895,8 +895,7 @@ static void send_msg_channel_open_confirmation(struct Channel* channel,
* options, with the calling function calling encrypt_packet() after
* completion. It is mandatory for the caller to encrypt_packet() if
* DROPBEAR_SUCCESS is returned */
-int send_msg_channel_open_init(int fd, struct ChanType *type,
- const char * typestring) {
+int send_msg_channel_open_init(int fd, const struct ChanType *type) {
struct Channel* chan;
@@ -920,7 +919,7 @@ int send_msg_channel_open_init(int fd, struct ChanType *type,
CHECKCLEARTOWRITE();
buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_OPEN);
- buf_putstring(ses.writepayload, typestring, strlen(typestring));
+ buf_putstring(ses.writepayload, type->name, strlen(type->name));
buf_putint(ses.writepayload, chan->index);
buf_putint(ses.writepayload, RECV_MAXWINDOW);
buf_putint(ses.writepayload, RECV_MAXPACKET);
diff --git a/listener.c b/listener.c
new file mode 100644
index 0000000..df66629
--- /dev/null
+++ b/listener.c
@@ -0,0 +1,123 @@
+#include "includes.h"
+#include "listener.h"
+#include "session.h"
+#include "dbutil.h"
+
+void listener_initialise() {
+
+ /* just one slot to start with */
+ ses.listeners = (struct Listener**)m_malloc(sizeof(struct Listener*));
+ ses.listensize = 1;
+ ses.listeners[0] = NULL;
+
+}
+
+void set_listener_fds(fd_set * readfds) {
+
+ unsigned int i;
+ struct Listener *listener;
+
+ /* check each in turn */
+ for (i = 0; i < ses.listensize; i++) {
+ listener = ses.listeners[i];
+ if (listener != NULL) {
+ FD_SET(listener->sock, readfds);
+ }
+ }
+}
+
+
+void handle_listeners(fd_set * readfds) {
+
+ unsigned int i;
+ struct Listener *listener;
+
+ /* check each in turn */
+ for (i = 0; i < ses.listensize; i++) {
+ listener = ses.listeners[i];
+ if (listener != NULL) {
+ if (FD_ISSET(listener->sock, readfds)) {
+ listener->accepter(listener);
+ }
+ }
+ }
+}
+
+
+/* accepter(int fd, void* typedata) is a function to accept connections,
+ * cleanup(void* typedata) happens when cleaning up */
+struct Listener* new_listener(int sock, int type, void* typedata,
+ void (*accepter)(struct Listener*),
+ void (*cleanup)(struct Listener*)) {
+
+ unsigned int i, j;
+ struct Listener *newlisten = NULL;
+ /* try get a new structure to hold it */
+ for (i = 0; i < ses.listensize; i++) {
+ if (ses.listeners[i] == NULL) {
+ break;
+ }
+ }
+
+ /* or create a new one */
+ if (i == ses.listensize) {
+ if (ses.listensize > MAX_LISTENERS) {
+ TRACE(("leave newlistener: too many already"));
+ close(sock);
+ return NULL;
+ }
+
+ ses.listeners = (struct Listener**)m_realloc(ses.listeners,
+ (ses.listensize+LISTENER_EXTEND_SIZE)
+ *sizeof(struct Listener*));
+
+ ses.listensize += LISTENER_EXTEND_SIZE;
+
+ for (j = i; j < ses.listensize; j++) {
+ ses.listeners[j] = NULL;
+ }
+ }
+
+ ses.maxfd = MAX(ses.maxfd, sock);
+
+ newlisten = (struct Listener*)m_malloc(sizeof(struct Listener));
+ newlisten->index = i;
+ newlisten->type = type;
+ newlisten->typedata = typedata;
+ newlisten->sock = sock;
+ newlisten->accepter = accepter;
+ newlisten->cleanup = cleanup;
+
+ ses.listeners[i] = newlisten;
+ return newlisten;
+}
+
+/* Return the first listener which matches the type-specific comparison
+ * function. Particularly needed for global requests, like tcp */
+struct Listener * get_listener(int type, void* typedata,
+ int (*match)(void*, void*)) {
+
+ unsigned int i;
+ struct Listener* listener;
+
+ for (i = 0, listener = ses.listeners[i]; i < ses.listensize; i++) {
+ if (listener->type == type
+ && match(typedata, listener->typedata)) {
+ return listener;
+ }
+ }
+
+ return NULL;
+}
+
+void remove_listener(struct Listener* listener) {
+
+ if (listener->cleanup) {
+ listener->cleanup(listener);
+ }
+
+ close(listener->sock);
+ ses.listeners[listener->index] = NULL;
+ m_free(listener);
+
+}
diff --git a/listener.h b/listener.h
new file mode 100644
index 0000000..ab77351
--- /dev/null
+++ b/listener.h
@@ -0,0 +1,37 @@
+#ifndef _LISTENER_H
+#define _LISTENER_H
+
+#define MAX_LISTENERS 20
+#define LISTENER_EXTEND_SIZE 1
+
+struct Listener {
+
+ int sock;
+
+ int index; /* index in the array of listeners */
+
+ void (*accepter)(struct Listener*);
+ void (*cleanup)(struct Listener*);
+
+ int type; /* CHANNEL_ID_X11, CHANNEL_ID_AGENT,
+ CHANNEL_ID_TCPDIRECT (for clients),
+ CHANNEL_ID_TCPFORWARDED (for servers) */
+
+ void *typedata;
+
+};
+
+void listener_initialise();
+void handle_listeners(fd_set * readfds);
+void set_listener_fds(fd_set * readfds);
+
+struct Listener* new_listener(int sock, int type, void* typedata,
+ void (*accepter)(struct Listener*),
+ void (*cleanup)(struct Listener*));
+
+struct Listener * get_listener(int type, void* typedata,
+ int (*match)(void*, void*));
+
+void remove_listener(struct Listener* listener);
+
+#endif /* _LISTENER_H */
diff --git a/options.h b/options.h
index d1f1794..703fec0 100644
--- a/options.h
+++ b/options.h
@@ -296,7 +296,7 @@
#endif
#ifndef ENABLE_LOCALTCPFWD
-#define DISABLE_LOCALTCPFWD
+#define DISABLE_TCPDIRECT
#endif
#ifndef ENABLE_REMOTETCPFWD
diff --git a/session.h b/session.h
index e372232..0cb2eaa 100644
--- a/session.h
+++ b/session.h
@@ -33,7 +33,7 @@
#include "channel.h"
#include "queue.h"
#include "runopts.h"
-#include "remotetcpfwd.h"
+#include "listener.h"
extern int sessinitdone; /* Is set to 0 somewhere */
extern int exitflag;
@@ -139,8 +139,8 @@ struct sshsession {
/* TCP forwarding - where manage listeners */
#ifndef DISABLE_REMOTETCPFWD
- struct TCPListener ** tcplisteners;
- unsigned int tcplistensize;
+ struct Listener ** listeners;
+ unsigned int listensize;
#endif
};
diff --git a/svr-chansession.c b/svr-chansession.c
index f5b4308..4dd4228 100644
--- a/svr-chansession.c
+++ b/svr-chansession.c
@@ -201,13 +201,13 @@ static int newchansess(struct Channel *channel) {
channel->typedata = chansess;
#ifndef DISABLE_X11FWD
- chansess->x11fd = -1;
+ chansess->x11listener = NULL;
chansess->x11authprot = NULL;
chansess->x11authcookie = NULL;
#endif
#ifndef DISABLE_AGENTFWD
- chansess->agentfd = -1;
+ chansess->agentlistener = NULL;
chansess->agentfile = NULL;
chansess->agentdir = NULL;
#endif
@@ -881,7 +881,7 @@ static void execchild(struct ChanSess *chansess) {
/* only reached on error */
dropbear_exit("child failed");
}
-
+
const struct ChanType svrchansess = {
0, /* sepfds */
"session", /* name */
diff --git a/svr-session.c b/svr-session.c
index 8e8eaea..2a97f94 100644
--- a/svr-session.c
+++ b/svr-session.c
@@ -35,7 +35,7 @@
#include "channel.h"
#include "chansession.h"
#include "atomicio.h"
-#include "localtcpfwd.h"
+#include "tcpfwd-direct.h"
static void svr_remoteclosed();
diff --git a/localtcpfwd.c b/tcpfwd-direct.c
index bf89fa0..81cd415 100644
--- a/localtcpfwd.c
+++ b/tcpfwd-direct.c
@@ -2,9 +2,9 @@
#include "session.h"
#include "dbutil.h"
#include "channel.h"
-#include "localtcpfwd.h"
+#include "tcpfwd-direct.h"
-#ifndef DISABLE_LOCALTCPFWD
+#ifndef DISABLE_TCPFWD_DIRECT
static int newtcpdirect(struct Channel * channel);
static int newtcp(const char * host, int port);
@@ -18,7 +18,6 @@ const struct ChanType chan_tcpdirect = {
};
-
/* Called upon creating a new direct tcp channel (ie we connect out to an
* address */
static int newtcpdirect(struct Channel * channel) {
@@ -152,4 +151,4 @@ static int newtcp(const char * host, int port) {
setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (void*)&val, sizeof(val));
return sock;
}
-#endif /* DISABLE_LOCALTCPFWD */
+#endif /* DISABLE_TCPFWD_DIRECT */
diff --git a/localtcpfwd.h b/tcpfwd-direct.h
index 65efa6e..20cd278 100644
--- a/localtcpfwd.h
+++ b/tcpfwd-direct.h
@@ -21,9 +21,9 @@
* 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 _LOCALTCPFWD_H_
-#define _LOCALTCPFWD_H_
-#ifndef DISABLE_LOCALTCPFWD
+#ifndef _TCPFWD_DIRECT_H_
+#define _TCPFWD_DIRECT_H_
+#ifndef DISABLE_TCFWD_DIRECT
#include "includes.h"
#include "channel.h"
diff --git a/remotetcpfwd.c b/tcpfwd-remote.c
index 40a3a82..9996dbd 100644
--- a/remotetcpfwd.c
+++ b/tcpfwd-remote.c
@@ -1,11 +1,11 @@
#include "includes.h"
#include "ssh.h"
-#include "remotetcpfwd.h"
+#include "tcpfwd-remote.h"
#include "dbutil.h"
#include "session.h"
#include "buffer.h"
#include "packet.h"
-#include "tcpfwd.h"
+#include "listener.h"
#ifndef DISABLE_REMOTETCPFWD
@@ -20,8 +20,8 @@ static void send_msg_request_success();
static void send_msg_request_failure();
static int cancelremotetcp();
static int remotetcpreq();
-static int newlistener(unsigned char* bindaddr, unsigned int port);
-static void acceptremote(struct TCPListener *listener);
+static int listen_tcpfwd(unsigned char* bindaddr, unsigned int port);
+static void acceptremote(struct Listener *listener);
/* At the moment this is completely used for tcp code (with the name reflecting
* that). If new request types are added, this should be replaced with code
@@ -70,7 +70,17 @@ out:
TRACE(("leave recv_msg_global_request"));
}
-static void acceptremote(struct TCPListener *listener) {
+static const struct ChanType chan_tcpremote = {
+ 0, /* sepfds */
+ "forwarded-tcpip",
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+
+static void acceptremote(struct Listener *listener) {
int fd;
struct sockaddr addr;
@@ -90,19 +100,22 @@ static void acceptremote(struct TCPListener *listener) {
return;
}
- /* XXX XXX XXX - type here needs fixing */
- if (send_msg_channel_open_init(fd, CHANNEL_ID_TCPFORWARDED,
- "forwarded-tcpip") == DROPBEAR_SUCCESS) {
+ if (send_msg_channel_open_init(fd, &chan_tcpremote) == DROPBEAR_SUCCESS) {
+
buf_putstring(ses.writepayload, tcpinfo->addr,
strlen(tcpinfo->addr));
buf_putint(ses.writepayload, tcpinfo->port);
buf_putstring(ses.writepayload, ipstring, strlen(ipstring));
buf_putint(ses.writepayload, atol(portstring));
encrypt_packet();
+
+ } else {
+ /* XXX debug? */
+ close(fd);
}
}
-static void cleanupremote(struct TCPListener *listener) {
+static void cleanupremote(struct Listener *listener) {
struct RemoteTCP *tcpinfo = (struct RemoteTCP*)(listener->typedata);
@@ -141,7 +154,7 @@ static int cancelremotetcp() {
unsigned char * bindaddr = NULL;
unsigned int addrlen;
unsigned int port;
- struct TCPListener * listener = NULL;
+ struct Listener * listener = NULL;
struct RemoteTCP tcpinfo;
TRACE(("enter cancelremotetcp"));
@@ -203,7 +216,7 @@ static int remotetcpreq() {
}
*/
- ret = newlistener(bindaddr, port);
+ ret = listen_tcpfwd(bindaddr, port);
out:
if (ret == DROPBEAR_FAILURE) {
@@ -215,16 +228,16 @@ out:
return ret;
}
-static int newlistener(unsigned char* bindaddr, unsigned int port) {
+static int listen_tcpfwd(unsigned char* bindaddr, unsigned int port) {
struct RemoteTCP * tcpinfo = NULL;
char portstring[6]; /* "65535\0" */
struct addrinfo *res = NULL, *ai = NULL;
struct addrinfo hints;
int sock = -1;
- int ret = DROPBEAR_FAILURE;
+ struct Listener *listener = NULL;
- TRACE(("enter newlistener"));
+ 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", port);
@@ -234,7 +247,7 @@ static int newlistener(unsigned char* bindaddr, unsigned int port) {
hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST;
if (getaddrinfo(bindaddr, portstring, &hints, &res) < 0) {
- TRACE(("leave newlistener: getaddrinfo failed: %s",
+ TRACE(("leave listen_tcpfwd: getaddrinfo failed: %s",
strerror(errno)));
goto done;
}
@@ -283,10 +296,10 @@ fail:
tcpinfo->addr = bindaddr;
tcpinfo->port = port;
- ret = new_fwd(sock, CHANNEL_ID_TCPFORWARDED, tcpinfo,
+ listener = new_listener(sock, CHANNEL_ID_TCPFORWARDED, tcpinfo,
acceptremote, cleanupremote);
- if (ret == DROPBEAR_FAILURE) {
+ if (listener == NULL) {
m_free(tcpinfo);
}
@@ -295,8 +308,12 @@ done:
freeaddrinfo(res);
}
- TRACE(("leave newlistener"));
- return ret;
+ TRACE(("leave listen_tcpfwd"));
+ if (listener == NULL) {
+ return DROPBEAR_FAILURE;
+ } else {
+ return DROPBEAR_SUCCESS;
+ }
}
#endif /* DISABLE_REMOTETCPFWD */
diff --git a/remotetcpfwd.h b/tcpfwd-remote.h
index 64dbed3..64dbed3 100644
--- a/remotetcpfwd.h
+++ b/tcpfwd-remote.h
diff --git a/tcpfwd.c b/tcpfwd.c
deleted file mode 100644
index d95970a..0000000
--- a/tcpfwd.c
+++ /dev/null
@@ -1,124 +0,0 @@
-#include "includes.h"
-#include "tcpfwd.h"
-#include "session.h"
-#include "dbutil.h"
-
-void tcp_fwd_initialise() {
-
- /* just one slot to start with */
- ses.tcplisteners =
- (struct TCPListener**)m_malloc(sizeof(struct TCPListener*));
- ses.tcplistensize = 1;
- ses.tcplisteners[0] = NULL;
-
-}
-
-void set_tcp_fwd_fds(fd_set * readfds) {
-
- unsigned int i;
- struct TCPListener *listener;
-
- /* check each in turn */
- for (i = 0; i < ses.tcplistensize; i++) {
- listener = ses.tcplisteners[i];
- if (listener != NULL) {
- FD_SET(listener->sock, readfds);
- }
- }
-}
-
-
-void handle_tcp_fwd(fd_set * readfds) {
-
- unsigned int i;
- struct TCPListener *listener;
-
- /* check each in turn */
- for (i = 0; i < ses.tcplistensize; i++) {
- listener = ses.tcplisteners[i];
- if (listener != NULL) {
- if (FD_ISSET(listener->sock, readfds)) {
- listener->accepter(listener);
- }
- }
- }
-}
-
-
-/* accepter(int fd, void* typedata) is a function to accept connections,
- * cleanup(void* typedata) happens when cleaning up */
-int new_fwd(int sock, int type, void* typedata,
- void (*accepter)(struct TCPListener*),
- void (*cleanup)(struct TCPListener*)) {
-
- unsigned int i, j;
- struct TCPListener *newtcp = NULL;
- /* try get a new structure to hold it */
- for (i = 0; i < ses.tcplistensize; i++) {
- if (ses.tcplisteners[i] == NULL) {
- break;
- }
- }
-
- /* or create a new one */
- if (i == ses.tcplistensize) {
- if (ses.tcplistensize > MAX_TCPLISTENERS) {
- TRACE(("leave newlistener: too many already"));
- close(sock);
- return DROPBEAR_FAILURE;
- }
-
- ses.tcplisteners = (struct TCPListener**)m_realloc(ses.tcplisteners,
- (ses.tcplistensize+TCP_EXTEND_SIZE)
- *sizeof(struct TCPListener*));
-
- ses.tcplistensize += TCP_EXTEND_SIZE;
-
- for (j = i; j < ses.tcplistensize; j++) {
- ses.tcplisteners[j] = NULL;
- }
- }
-
- ses.maxfd = MAX(ses.maxfd, sock);
-
- newtcp = (struct TCPListener*)m_malloc(sizeof(struct TCPListener));
- newtcp->index = i;
- newtcp->type = type;
- newtcp->typedata = typedata;
- newtcp->sock = sock;
- newtcp->accepter = accepter;
- newtcp->cleanup = cleanup;
-
- ses.tcplisteners[i] = newtcp;
- return DROPBEAR_SUCCESS;
-}
-
-/* Return the first listener which matches the type-specific comparison
- * function */
-struct TCPListener * get_listener(int type, void* typedata,
- int (*match)(void*, void*)) {
-
- unsigned int i;
- struct TCPListener* listener;
-
- for (i = 0, listener = ses.tcplisteners[i]; i < ses.tcplistensize; i++) {
- if (listener->type == type
- && match(typedata, listener->typedata)) {
- return listener;
- }
- }
-
- return NULL;
-}
-
-void remove_listener(struct TCPListener* listener) {
-
- if (listener->cleanup) {
- listener->cleanup(listener);
- }
-
- close(listener->sock);
- ses.tcplisteners[listener->index] = NULL;
- m_free(listener);
-
-}
diff --git a/tcpfwd.h b/tcpfwd.h
deleted file mode 100644
index 85d7373..0000000
--- a/tcpfwd.h
+++ /dev/null
@@ -1,37 +0,0 @@
-#ifndef _TCPFWD_H
-#define _TCPFWD_H
-
-#define MAX_TCPLISTENERS 20
-#define TCP_EXTEND_SIZE 1
-
-struct TCPListener {
-
- int sock;
-
- int index; /* index in the array of listeners */
-
- void (*accepter)(struct TCPListener*);
- void (*cleanup)(struct TCPListener*);
-
- int type; /* CHANNEL_ID_X11, CHANNEL_ID_AGENT,
- CHANNEL_ID_TCPDIRECT (for clients),
- CHANNEL_ID_TCPFORWARDED (for servers) */
-
- void *typedata;
-
-};
-
-void tcp_fwd_initialise();
-void handle_tcp_fwd(fd_set * readfds);
-void set_tcp_fwd_fds(fd_set * readfds);
-
-int new_fwd(int sock, int type, void* typedata,
- void (*accepter)(struct TCPListener*),
- void (*cleanup)(struct TCPListener*));
-
-struct TCPListener * get_listener(int type, void* typedata,
- int (*match)(void*, void*));
-
-void remove_listener(struct TCPListener* listener);
-
-#endif /* _TCPFWD_H */
diff --git a/x11fwd.c b/x11fwd.c
index 229b0df..e1b6961 100644
--- a/x11fwd.c
+++ b/x11fwd.c
@@ -37,6 +37,8 @@
#define X11BASEPORT 6000
#define X11BINDBASE 6010
+static void x11accept(struct Listener* listener);
+static void x11cleanup(struct Listener *listener);
static int bindport(int fd);
static int send_msg_channel_open_x11(int fd, struct sockaddr_in* addr);
@@ -44,8 +46,10 @@ static int send_msg_channel_open_x11(int fd, struct sockaddr_in* addr);
/* returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */
int x11req(struct ChanSess * chansess) {
+ int fd;
+
/* we already have an x11 connection */
- if (chansess->x11fd != -1) {
+ if (chansess->x11listener != NULL) {
return DROPBEAR_FAILURE;
}
@@ -55,62 +59,71 @@ int x11req(struct ChanSess * chansess) {
chansess->x11screennum = buf_getint(ses.payload);
/* create listening socket */
- chansess->x11fd = socket(PF_INET, SOCK_STREAM, 0);
- if (chansess->x11fd < 0) {
+ fd = socket(PF_INET, SOCK_STREAM, 0);
+ if (fd < 0) {
goto fail;
}
/* allocate port and bind */
- chansess->x11port = bindport(chansess->x11fd);
+ chansess->x11port = bindport(fd);
if (chansess->x11port < 0) {
goto fail;
}
/* listen */
- if (listen(chansess->x11fd, 20) < 0) {
+ if (listen(fd, 20) < 0) {
goto fail;
}
/* set non-blocking */
- if (fcntl(chansess->x11fd, F_SETFL, O_NONBLOCK) < 0) {
+ if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) {
goto fail;
}
- /* channel.c's channel fd code will handle the socket now */
-
- /* set the maxfd so that select() loop will notice it */
- ses.maxfd = MAX(ses.maxfd, chansess->x11fd);
+ /* listener code will handle the socket now.
+ * No cleanup handler needed, since listener_remove only happens
+ * from our cleanup anyway */
+ chansess->x11listener = new_listener( fd, 0, chansess, x11accept, NULL);
+ if (chansess->x11listener == NULL) {
+ goto fail;
+ }
return DROPBEAR_SUCCESS;
fail:
/* cleanup */
- x11cleanup(chansess);
+ m_free(chansess->x11authprot);
+ m_free(chansess->x11authcookie);
+ close(fd);
return DROPBEAR_FAILURE;
}
/* accepts a new X11 socket */
/* returns DROPBEAR_FAILURE or DROPBEAR_SUCCESS */
-int x11accept(struct ChanSess * chansess) {
+static void x11accept(struct Listener* listener) {
int fd;
struct sockaddr_in addr;
int len;
+ int ret;
len = sizeof(addr);
- fd = accept(chansess->x11fd, (struct sockaddr*)&addr, &len);
+ fd = accept(listener->sock, (struct sockaddr*)&addr, &len);
if (fd < 0) {
- return DROPBEAR_FAILURE;
+ return;
}
/* if single-connection we close it up */
- if (chansess->x11singleconn) {
- x11cleanup(chansess);
+ if (((struct ChanSess *)(listener->typedata))->x11singleconn) {
+ x11cleanup(listener);
}
- return send_msg_channel_open_x11(fd, &addr);
+ ret = send_msg_channel_open_x11(fd, &addr);
+ if (ret == DROPBEAR_FAILURE) {
+ close(fd);
+ }
}
/* This is called after switching to the user, and sets up the xauth
@@ -121,7 +134,7 @@ void x11setauth(struct ChanSess *chansess) {
FILE * authprog;
int val;
- if (chansess->x11fd == -1) {
+ if (chansess->x11listener == NULL) {
return;
}
@@ -154,24 +167,31 @@ void x11setauth(struct ChanSess *chansess) {
}
}
-void x11cleanup(struct ChanSess * chansess) {
+static void x11cleanup(struct Listener *listener) {
- if (chansess->x11fd == -1) {
- return;
- }
+ struct ChanSess *chansess = (struct ChanSess*)listener->typedata;
m_free(chansess->x11authprot);
m_free(chansess->x11authcookie);
- close(chansess->x11fd);
- chansess->x11fd = -1;
+ remove_listener(listener);
+ chansess->x11listener = NULL;
}
+static const struct ChanType chan_x11 = {
+ 0, /* sepfds */
+ "x11",
+ NULL, /* inithandler */
+ NULL, /* checkclose */
+ NULL, /* reqhandler */
+ NULL /* closehandler */
+};
+
+
static int send_msg_channel_open_x11(int fd, struct sockaddr_in* addr) {
char* ipstring;
- if (send_msg_channel_open_init(fd, CHANNEL_ID_X11, "x11")
- == DROPBEAR_SUCCESS) {
+ if (send_msg_channel_open_init(fd, &chan_x11) == DROPBEAR_SUCCESS) {
ipstring = inet_ntoa(addr->sin_addr);
buf_putstring(ses.writepayload, ipstring, strlen(ipstring));
buf_putint(ses.writepayload, addr->sin_port);
diff --git a/x11fwd.h b/x11fwd.h
index 889033f..6cf4b96 100644
--- a/x11fwd.h
+++ b/x11fwd.h
@@ -30,8 +30,6 @@
#include "channel.h"
int x11req(struct ChanSess * chansess);
-int x11accept(struct ChanSess * chansess);
-void x11cleanup(struct ChanSess * chansess);
void x11setauth(struct ChanSess *chansess);
#endif /* DROPBEAR_X11FWD */