mirror of
				https://github.com/clearml/dropbear
				synced 2025-06-26 18:17:32 +00:00 
			
		
		
		
	- tcpfwd bindaddr support against trunk. needs merging.
--HG-- extra : convert_revision : 658fd03abd21e0da7c4c89b9fff9dc693c72daae
This commit is contained in:
		
							parent
							
								
									8174a2f27b
								
							
						
					
					
						commit
						3b07844548
					
				@ -628,13 +628,15 @@ static void fill_own_user() {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef ENABLE_CLI_ANYTCPFWD
 | 
					#ifdef ENABLE_CLI_ANYTCPFWD
 | 
				
			||||||
/* Turn a "listenport:remoteaddr:remoteport" string into into a forwarding
 | 
					/* Turn a "[listenaddr:]listenport:remoteaddr:remoteport" string into into a forwarding
 | 
				
			||||||
 * set, and add it to the forwarding list */
 | 
					 * set, and add it to the forwarding list */
 | 
				
			||||||
static void addforward(const char* origstr, m_list *fwdlist) {
 | 
					static void addforward(const char* origstr, m_list *fwdlist) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						char *part1 = NULL, *part2 = NULL, *part3 = NULL, *part4 = NULL;
 | 
				
			||||||
 | 
						char * listenaddr = NULL;
 | 
				
			||||||
	char * listenport = NULL;
 | 
						char * listenport = NULL;
 | 
				
			||||||
	char * connectport = NULL;
 | 
					 | 
				
			||||||
	char * connectaddr = NULL;
 | 
						char * connectaddr = NULL;
 | 
				
			||||||
 | 
						char * connectport = NULL;
 | 
				
			||||||
	struct TCPFwdEntry* newfwd = NULL;
 | 
						struct TCPFwdEntry* newfwd = NULL;
 | 
				
			||||||
	char * str = NULL;
 | 
						char * str = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -644,23 +646,43 @@ static void addforward(const char* origstr, m_list *fwdlist) {
 | 
				
			|||||||
	   is never free()d. */ 
 | 
						   is never free()d. */ 
 | 
				
			||||||
	str = m_strdup(origstr);
 | 
						str = m_strdup(origstr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	listenport = str;
 | 
						part1 = str;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	connectaddr = strchr(str, ':');
 | 
						part2 = strchr(str, ':');
 | 
				
			||||||
	if (connectaddr == NULL) {
 | 
						if (part2 == NULL) {
 | 
				
			||||||
		TRACE(("connectaddr == NULL"))
 | 
							TRACE(("part2 == NULL"))
 | 
				
			||||||
		goto fail;
 | 
							goto fail;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	*connectaddr = '\0';
 | 
						*part2 = '\0';
 | 
				
			||||||
	connectaddr++;
 | 
						part2++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	connectport = strchr(connectaddr, ':');
 | 
						part3 = strchr(part2, ':');
 | 
				
			||||||
	if (connectport == NULL) {
 | 
						if (part3 == NULL) {
 | 
				
			||||||
		TRACE(("connectport == NULL"))
 | 
							TRACE(("part3 == NULL"))
 | 
				
			||||||
		goto fail;
 | 
							goto fail;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	*connectport = '\0';
 | 
						*part3 = '\0';
 | 
				
			||||||
	connectport++;
 | 
						part3++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						part4 = strchr(part3, ':');
 | 
				
			||||||
 | 
						if (part4) {
 | 
				
			||||||
 | 
							*part4 = '\0';
 | 
				
			||||||
 | 
							part4++;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (part4) {
 | 
				
			||||||
 | 
							listenaddr = part1;
 | 
				
			||||||
 | 
							listenport = part2;
 | 
				
			||||||
 | 
							connectaddr = part3;
 | 
				
			||||||
 | 
							connectport = part4;
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							listenaddr = NULL;
 | 
				
			||||||
 | 
							listenport = part1;
 | 
				
			||||||
 | 
							connectaddr = part2;
 | 
				
			||||||
 | 
							connectport = part3;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	newfwd = m_malloc(sizeof(struct TCPFwdEntry));
 | 
						newfwd = m_malloc(sizeof(struct TCPFwdEntry));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -676,6 +698,7 @@ static void addforward(const char* origstr, m_list *fwdlist) {
 | 
				
			|||||||
		goto fail;
 | 
							goto fail;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						newfwd->listenaddr = listenaddr;
 | 
				
			||||||
	newfwd->connectaddr = connectaddr;
 | 
						newfwd->connectaddr = connectaddr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (newfwd->listenport > 65535) {
 | 
						if (newfwd->listenport > 65535) {
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										58
									
								
								cli-tcpfwd.c
									
									
									
									
									
								
							
							
						
						
									
										58
									
								
								cli-tcpfwd.c
									
									
									
									
									
								
							@ -45,7 +45,9 @@ const struct ChanType cli_chan_tcpremote = {
 | 
				
			|||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef ENABLE_CLI_LOCALTCPFWD
 | 
					#ifdef ENABLE_CLI_LOCALTCPFWD
 | 
				
			||||||
static int cli_localtcp(unsigned int listenport, const char* remoteaddr,
 | 
					static int cli_localtcp(const char* listenaddr, 
 | 
				
			||||||
 | 
							unsigned int listenport, 
 | 
				
			||||||
 | 
							const char* remoteaddr,
 | 
				
			||||||
		unsigned int remoteport);
 | 
							unsigned int remoteport);
 | 
				
			||||||
static const struct ChanType cli_chan_tcplocal = {
 | 
					static const struct ChanType cli_chan_tcplocal = {
 | 
				
			||||||
	1, /* sepfds */
 | 
						1, /* sepfds */
 | 
				
			||||||
@ -66,11 +68,14 @@ void setup_localtcp() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	for (iter = cli_opts.localfwds->first; iter; iter = iter->next) {
 | 
						for (iter = cli_opts.localfwds->first; iter; iter = iter->next) {
 | 
				
			||||||
		struct TCPFwdEntry * fwd = (struct TCPFwdEntry*)iter->item;
 | 
							struct TCPFwdEntry * fwd = (struct TCPFwdEntry*)iter->item;
 | 
				
			||||||
		ret = cli_localtcp(fwd->listenport,
 | 
							ret = cli_localtcp(
 | 
				
			||||||
 | 
									fwd->listenaddr,
 | 
				
			||||||
 | 
									fwd->listenport,
 | 
				
			||||||
				fwd->connectaddr,
 | 
									fwd->connectaddr,
 | 
				
			||||||
				fwd->connectport);
 | 
									fwd->connectport);
 | 
				
			||||||
		if (ret == DROPBEAR_FAILURE) {
 | 
							if (ret == DROPBEAR_FAILURE) {
 | 
				
			||||||
			dropbear_log(LOG_WARNING, "Failed local port forward %d:%s:%d",
 | 
								dropbear_log(LOG_WARNING, "Failed local port forward %s:%d:%s:%d",
 | 
				
			||||||
 | 
										fwd->listenaddr,
 | 
				
			||||||
					fwd->listenport,
 | 
										fwd->listenport,
 | 
				
			||||||
					fwd->connectaddr,
 | 
										fwd->connectaddr,
 | 
				
			||||||
					fwd->connectport);
 | 
										fwd->connectport);
 | 
				
			||||||
@ -80,7 +85,9 @@ void setup_localtcp() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int cli_localtcp(unsigned int listenport, const char* remoteaddr,
 | 
					static int cli_localtcp(const char* listenaddr, 
 | 
				
			||||||
 | 
							unsigned int listenport, 
 | 
				
			||||||
 | 
							const char* remoteaddr,
 | 
				
			||||||
		unsigned int remoteport) {
 | 
							unsigned int remoteport) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct TCPListener* tcpinfo = NULL;
 | 
						struct TCPListener* tcpinfo = NULL;
 | 
				
			||||||
@ -94,11 +101,18 @@ static int cli_localtcp(unsigned int listenport, const char* remoteaddr,
 | 
				
			|||||||
	tcpinfo->sendaddr = m_strdup(remoteaddr);
 | 
						tcpinfo->sendaddr = m_strdup(remoteaddr);
 | 
				
			||||||
	tcpinfo->sendport = remoteport;
 | 
						tcpinfo->sendport = remoteport;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (listenaddr)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							tcpinfo->listenaddr = m_strdup(listenaddr);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
		if (opts.listen_fwd_all) {
 | 
							if (opts.listen_fwd_all) {
 | 
				
			||||||
			tcpinfo->listenaddr = m_strdup("");
 | 
								tcpinfo->listenaddr = m_strdup("");
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			tcpinfo->listenaddr = m_strdup("localhost");
 | 
								tcpinfo->listenaddr = m_strdup("localhost");
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	tcpinfo->listenport = listenport;
 | 
						tcpinfo->listenport = listenport;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	tcpinfo->chantype = &cli_chan_tcplocal;
 | 
						tcpinfo->chantype = &cli_chan_tcplocal;
 | 
				
			||||||
@ -115,7 +129,7 @@ static int cli_localtcp(unsigned int listenport, const char* remoteaddr,
 | 
				
			|||||||
#endif /* ENABLE_CLI_LOCALTCPFWD */
 | 
					#endif /* ENABLE_CLI_LOCALTCPFWD */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef  ENABLE_CLI_REMOTETCPFWD
 | 
					#ifdef  ENABLE_CLI_REMOTETCPFWD
 | 
				
			||||||
static void send_msg_global_request_remotetcp(int port) {
 | 
					static void send_msg_global_request_remotetcp(const char *addr, int port) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	char* listenspec = NULL;
 | 
						char* listenspec = NULL;
 | 
				
			||||||
	TRACE(("enter send_msg_global_request_remotetcp"))
 | 
						TRACE(("enter send_msg_global_request_remotetcp"))
 | 
				
			||||||
@ -124,13 +138,7 @@ static void send_msg_global_request_remotetcp(int port) {
 | 
				
			|||||||
	buf_putbyte(ses.writepayload, SSH_MSG_GLOBAL_REQUEST);
 | 
						buf_putbyte(ses.writepayload, SSH_MSG_GLOBAL_REQUEST);
 | 
				
			||||||
	buf_putstring(ses.writepayload, "tcpip-forward", 13);
 | 
						buf_putstring(ses.writepayload, "tcpip-forward", 13);
 | 
				
			||||||
	buf_putbyte(ses.writepayload, 1); /* want_reply */
 | 
						buf_putbyte(ses.writepayload, 1); /* want_reply */
 | 
				
			||||||
	if (opts.listen_fwd_all) {
 | 
						buf_putstring(ses.writepayload, addr, strlen(addr));
 | 
				
			||||||
		listenspec = "";
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		listenspec = "localhost";
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	/* TODO: IPv6? */;
 | 
					 | 
				
			||||||
	buf_putstring(ses.writepayload, listenspec, strlen(listenspec));
 | 
					 | 
				
			||||||
	buf_putint(ses.writepayload, port);
 | 
						buf_putint(ses.writepayload, port);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	encrypt_packet();
 | 
						encrypt_packet();
 | 
				
			||||||
@ -173,7 +181,17 @@ void setup_remotetcp() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	for (iter = cli_opts.remotefwds->first; iter; iter = iter->next) {
 | 
						for (iter = cli_opts.remotefwds->first; iter; iter = iter->next) {
 | 
				
			||||||
		struct TCPFwdEntry *fwd = (struct TCPFwdEntry*)iter->item;
 | 
							struct TCPFwdEntry *fwd = (struct TCPFwdEntry*)iter->item;
 | 
				
			||||||
		send_msg_global_request_remotetcp(fwd->listenport);
 | 
							if (!fwd->listenaddr)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								// we store the addresses so that we can compare them
 | 
				
			||||||
 | 
								// when the server sends them back
 | 
				
			||||||
 | 
								if (opts.listen_fwd_all) {
 | 
				
			||||||
 | 
									fwd->listenaddr = m_strdup("");
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									fwd->listenaddr = m_strdup("localhost");
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							send_msg_global_request_remotetcp(fwd->listenaddr, fwd->listenport);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	TRACE(("leave setup_remotetcp"))
 | 
						TRACE(("leave setup_remotetcp"))
 | 
				
			||||||
@ -181,6 +199,7 @@ void setup_remotetcp() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
static int newtcpforwarded(struct Channel * channel) {
 | 
					static int newtcpforwarded(struct Channel * channel) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    char *origaddr = NULL;
 | 
				
			||||||
	unsigned int origport;
 | 
						unsigned int origport;
 | 
				
			||||||
	m_list_elem * iter = NULL;
 | 
						m_list_elem * iter = NULL;
 | 
				
			||||||
	struct TCPFwdEntry *fwd;
 | 
						struct TCPFwdEntry *fwd;
 | 
				
			||||||
@ -188,23 +207,23 @@ static int newtcpforwarded(struct Channel * channel) {
 | 
				
			|||||||
	int sock;
 | 
						int sock;
 | 
				
			||||||
	int err = SSH_OPEN_ADMINISTRATIVELY_PROHIBITED;
 | 
						int err = SSH_OPEN_ADMINISTRATIVELY_PROHIBITED;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* We don't care what address they connected to */
 | 
						origaddr = buf_getstring(ses.payload, NULL);
 | 
				
			||||||
	buf_eatstring(ses.payload);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	origport = buf_getint(ses.payload);
 | 
						origport = buf_getint(ses.payload);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Find which port corresponds */
 | 
						/* Find which port corresponds */
 | 
				
			||||||
	for (iter = cli_opts.remotefwds->first; iter; iter = iter->next) {
 | 
						for (iter = cli_opts.remotefwds->first; iter; iter = iter->next) {
 | 
				
			||||||
		fwd = (struct TCPFwdEntry*)iter->item;
 | 
							fwd = (struct TCPFwdEntry*)iter->item;
 | 
				
			||||||
		if (origport == fwd->listenport) {
 | 
							if (origport == fwd->listenport
 | 
				
			||||||
 | 
									&& (strcmp(origaddr, fwd->listenaddr) == 0)) {
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (iter == NULL) {
 | 
						if (iter == NULL) {
 | 
				
			||||||
		/* We didn't request forwarding on that port */
 | 
							/* We didn't request forwarding on that port */
 | 
				
			||||||
		dropbear_log(LOG_INFO, "Server send unrequested port, from port %d", 
 | 
					        cleantext(origaddr);
 | 
				
			||||||
										origport);
 | 
							dropbear_log(LOG_INFO, "Server sent unrequested forward from \"%s:%d\"", 
 | 
				
			||||||
 | 
					                origaddr, origport);
 | 
				
			||||||
		goto out;
 | 
							goto out;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
@ -226,6 +245,7 @@ static int newtcpforwarded(struct Channel * channel) {
 | 
				
			|||||||
	err = SSH_OPEN_IN_PROGRESS;
 | 
						err = SSH_OPEN_IN_PROGRESS;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
out:
 | 
					out:
 | 
				
			||||||
 | 
						m_free(origaddr);
 | 
				
			||||||
	TRACE(("leave newtcpdirect: err %d", err))
 | 
						TRACE(("leave newtcpdirect: err %d", err))
 | 
				
			||||||
	return err;
 | 
						return err;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										1
									
								
								tcpfwd.h
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								tcpfwd.h
									
									
									
									
									
								
							@ -48,6 +48,7 @@ struct TCPListener {
 | 
				
			|||||||
struct TCPFwdEntry {
 | 
					struct TCPFwdEntry {
 | 
				
			||||||
	const unsigned char* connectaddr;
 | 
						const unsigned char* connectaddr;
 | 
				
			||||||
	unsigned int connectport;
 | 
						unsigned int connectport;
 | 
				
			||||||
 | 
						const unsigned char* listenaddr;
 | 
				
			||||||
	unsigned int listenport;
 | 
						unsigned int listenport;
 | 
				
			||||||
	unsigned int have_reply; /* is set to 1 after a reply has been received
 | 
						unsigned int have_reply; /* is set to 1 after a reply has been received
 | 
				
			||||||
								when setting up the forwarding */
 | 
													when setting up the forwarding */
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user