mirror of
				https://github.com/clearml/dropbear
				synced 2025-06-26 18:17:32 +00:00 
			
		
		
		
	Mostly done with the listener changeover
--HG-- extra : convert_revision : 1a4dca8836a2a04a21fb675c718a549a8d445d25
This commit is contained in:
		
							parent
							
								
									444dbb5364
								
							
						
					
					
						commit
						9f369bc42f
					
				| @ -30,9 +30,8 @@ | ||||
| #include "channel.h" | ||||
| 
 | ||||
| int agentreq(struct ChanSess * chansess); | ||||
| int agentaccept(struct ChanSess * chansess); | ||||
| void agentcleanup(struct ChanSess * chansess); | ||||
| void agentsetauth(struct ChanSess *chansess); | ||||
| void agentcleanup(struct ChanSess * chansess); | ||||
| void agentset(struct ChanSess *chansess); | ||||
| 
 | ||||
| #ifdef __hpux | ||||
|  | ||||
							
								
								
									
										12
									
								
								dbutil.c
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								dbutil.c
									
									
									
									
									
								
							| @ -158,7 +158,7 @@ char* getaddrhostname(struct sockaddr * addr) { | ||||
| 		retstring = host->h_name; | ||||
| 	} | ||||
| 
 | ||||
| 	return strdup(retstring); | ||||
| 	return m_strdup(retstring); | ||||
| } | ||||
| #ifdef DEBUG_TRACE | ||||
| void printhex(unsigned char* buf, int len) { | ||||
| @ -263,6 +263,16 @@ void * m_malloc(size_t size) { | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| void * m_strdup(const char * str) { | ||||
| 	char* ret; | ||||
| 
 | ||||
| 	ret = strdup(str); | ||||
| 	if (ret == NULL) { | ||||
| 		dropbear_exit("m_strdup failed"); | ||||
| 	} | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| void __m_free(void* ptr) { | ||||
| 	if (ptr != NULL) { | ||||
| 		free(ptr); | ||||
|  | ||||
							
								
								
									
										1
									
								
								dbutil.h
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								dbutil.h
									
									
									
									
									
								
							| @ -51,6 +51,7 @@ int buf_readfile(buffer* buf, const char* filename); | ||||
| 
 | ||||
| int m_close(int fd); | ||||
| void * m_malloc(size_t size); | ||||
| void * m_strdup(const char * str); | ||||
| void * m_realloc(void* ptr, size_t size); | ||||
| #define m_free(X) __m_free(X); (X) = NULL; | ||||
| void __m_free(void* ptr); | ||||
|  | ||||
							
								
								
									
										122
									
								
								svr-agentfwd.c
									
									
									
									
									
								
							
							
						
						
									
										122
									
								
								svr-agentfwd.c
									
									
									
									
									
								
							| @ -38,45 +38,52 @@ | ||||
| #include "packet.h" | ||||
| #include "buffer.h" | ||||
| #include "random.h" | ||||
| #include "listener.h" | ||||
| 
 | ||||
| #define AGENTDIRPREFIX "/tmp/dropbear-" | ||||
| 
 | ||||
| static int send_msg_channel_open_agent(int fd); | ||||
| static int bindagent(struct ChanSess * chansess); | ||||
| static int bindagent(int fd, struct ChanSess * chansess); | ||||
| static void agentaccept(struct Listener * listener); | ||||
| 
 | ||||
| /* Handles client requests to start agent forwarding, sets up listening socket.
 | ||||
|  * Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */ | ||||
| int agentreq(struct ChanSess * chansess) { | ||||
| 
 | ||||
| 	if (chansess->agentfd != -1) { | ||||
| 	int fd; | ||||
| 
 | ||||
| 	if (chansess->agentlistener != NULL) { | ||||
| 		return DROPBEAR_FAILURE; | ||||
| 	} | ||||
| 
 | ||||
| 	/* create listening socket */ | ||||
| 	chansess->agentfd = socket(PF_UNIX, SOCK_STREAM, 0); | ||||
| 	if (chansess->agentfd < 0) { | ||||
| 	fd = socket(PF_UNIX, SOCK_STREAM, 0); | ||||
| 	if (fd < 0) { | ||||
| 		goto fail; | ||||
| 	} | ||||
| 
 | ||||
| 	/* create the unix socket dir and file */ | ||||
| 	if (bindagent(chansess) == DROPBEAR_FAILURE) { | ||||
| 	if (bindagent(fd, chansess) == DROPBEAR_FAILURE) { | ||||
| 		return DROPBEAR_FAILURE; | ||||
| 	} | ||||
| 
 | ||||
| 	/* listen */ | ||||
| 	if (listen(chansess->agentfd, 20) < 0) { | ||||
| 	if (listen(fd, 20) < 0) { | ||||
| 		goto fail; | ||||
| 	} | ||||
| 
 | ||||
| 	/* set non-blocking */ | ||||
| 	if (fcntl(chansess->agentfd, 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 */ | ||||
| 	/* pass if off to listener */ | ||||
| 	chansess->agentlistener = new_listener( fd, 0, chansess,  | ||||
| 								agentaccept, NULL); | ||||
| 
 | ||||
| 	/* set the maxfd so that select() loop will notice it */ | ||||
| 	ses.maxfd = MAX(ses.maxfd, chansess->agentfd); | ||||
| 	if (chansess->agentlistener == NULL) { | ||||
| 		goto fail; | ||||
| 	} | ||||
| 
 | ||||
| 	return DROPBEAR_SUCCESS; | ||||
| 
 | ||||
| @ -90,16 +97,18 @@ fail: | ||||
| /* accepts a connection on the forwarded socket and opens a new channel for it
 | ||||
|  * back to the client */ | ||||
| /* returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */ | ||||
| int agentaccept(struct ChanSess * chansess) { | ||||
| static void agentaccept(struct Listener * listener) { | ||||
| 
 | ||||
| 	int fd; | ||||
| 
 | ||||
| 	fd = accept(chansess->agentfd, NULL, NULL); | ||||
| 	fd = accept(listener->sock, NULL, NULL); | ||||
| 	if (fd < 0) { | ||||
| 		return DROPBEAR_FAILURE; | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	return send_msg_channel_open_agent(fd); | ||||
| 	if (send_msg_channel_open_agent(listener->sock) != DROPBEAR_SUCCESS) { | ||||
| 		close(fd); | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| @ -110,7 +119,7 @@ void agentset(struct ChanSess * chansess) { | ||||
| 	char *path = NULL; | ||||
| 	int len; | ||||
| 
 | ||||
| 	if (chansess->agentfd == -1) { | ||||
| 	if (chansess->agentlistener == NULL) { | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| @ -131,46 +140,57 @@ void agentcleanup(struct ChanSess * chansess) { | ||||
| 	gid_t gid; | ||||
| 	int len; | ||||
| 
 | ||||
| 	if (chansess->agentfd == -1) { | ||||
| 		return; | ||||
| 	if (chansess->agentlistener != NULL) { | ||||
| 		remove_listener(chansess->agentlistener); | ||||
| 		chansess->agentlistener = NULL; | ||||
| 	} | ||||
| 
 | ||||
| 	close(chansess->agentfd); | ||||
| 	if (chansess->agentfile && chansess->agentdir) { | ||||
| 
 | ||||
| 	/* Remove the dir as the user. That way they can't cause problems except
 | ||||
| 	 * for themselves */ | ||||
| 	uid = getuid(); | ||||
| 	gid = getgid(); | ||||
| 	if ((setegid(svr_ses.authstate.pw->pw_gid)) < 0 || | ||||
| 		(seteuid(svr_ses.authstate.pw->pw_uid)) < 0) { | ||||
| 		dropbear_exit("failed to set euid"); | ||||
| 		/* Remove the dir as the user. That way they can't cause problems except
 | ||||
| 		 * for themselves */ | ||||
| 		uid = getuid(); | ||||
| 		gid = getgid(); | ||||
| 		if ((setegid(svr_ses.authstate.pw->pw_gid)) < 0 || | ||||
| 			(seteuid(svr_ses.authstate.pw->pw_uid)) < 0) { | ||||
| 			dropbear_exit("failed to set euid"); | ||||
| 		} | ||||
| 
 | ||||
| 		/* 2 for "/" and "\0" */ | ||||
| 		len = strlen(chansess->agentdir) + strlen(chansess->agentfile) + 2; | ||||
| 
 | ||||
| 		path = m_malloc(len); | ||||
| 		snprintf(path, len, "%s/%s", chansess->agentdir, chansess->agentfile); | ||||
| 		unlink(path); | ||||
| 		m_free(path); | ||||
| 
 | ||||
| 		rmdir(chansess->agentdir); | ||||
| 
 | ||||
| 		if ((seteuid(uid)) < 0 || | ||||
| 			(setegid(gid)) < 0) { | ||||
| 			dropbear_exit("failed to revert euid"); | ||||
| 		} | ||||
| 
 | ||||
| 		m_free(chansess->agentfile); | ||||
| 		m_free(chansess->agentdir); | ||||
| 	} | ||||
| 
 | ||||
| 	/* 2 for "/" and "\0" */ | ||||
| 	len = strlen(chansess->agentdir) + strlen(chansess->agentfile) + 2; | ||||
| 
 | ||||
| 	path = m_malloc(len); | ||||
| 	snprintf(path, len, "%s/%s", chansess->agentdir, chansess->agentfile); | ||||
| 	unlink(path); | ||||
| 	m_free(path); | ||||
| 
 | ||||
| 	rmdir(chansess->agentdir); | ||||
| 
 | ||||
| 	if ((seteuid(uid)) < 0 || | ||||
| 		(setegid(gid)) < 0) { | ||||
| 		dropbear_exit("failed to revert euid"); | ||||
| 	} | ||||
| 
 | ||||
| 	m_free(chansess->agentfile); | ||||
| 	m_free(chansess->agentdir); | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| static const struct ChanType chan_agent = { | ||||
| 	0, /* sepfds */ | ||||
| 	"auth-agent@openssh.com", | ||||
| 	NULL, | ||||
| 	NULL, | ||||
| 	NULL, | ||||
| 	NULL | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| /* helper for accepting an agent request */ | ||||
| static int send_msg_channel_open_agent(int fd) { | ||||
| 
 | ||||
| 	if (send_msg_channel_open_init(fd, CHANNEL_ID_AGENT, | ||||
| 				"auth-agent@openssh.com") == DROPBEAR_SUCCESS) { | ||||
| 	if (send_msg_channel_open_init(fd, &chan_agent) == DROPBEAR_SUCCESS) { | ||||
| 		encrypt_packet(); | ||||
| 		return DROPBEAR_SUCCESS; | ||||
| 	} else { | ||||
| @ -180,7 +200,7 @@ static int send_msg_channel_open_agent(int fd) { | ||||
| 
 | ||||
| /* helper for creating the agent socket-file
 | ||||
|    returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */ | ||||
| static int bindagent(struct ChanSess * chansess) { | ||||
| static int bindagent(int fd, struct ChanSess * chansess) { | ||||
| 
 | ||||
| 	struct sockaddr_un addr; | ||||
| 	unsigned int prefix; | ||||
| @ -225,13 +245,13 @@ bindsocket: | ||||
| 	 * between subsequent user processes reusing socket fds (odds are now | ||||
| 	 * 1/(2^64) */ | ||||
| 	genrandom((unsigned char*)&prefix, sizeof(prefix)); | ||||
| 	snprintf(sockfile, sizeof(sockfile), "auth-%.8x-%d", prefix, | ||||
| 			chansess->agentfd); | ||||
| 	snprintf(sockfile, sizeof(sockfile), "auth-%.8x-%d", prefix, fd); | ||||
| 			 | ||||
| 	snprintf(addr.sun_path, sizeof(addr.sun_path), "%s/%s", path, sockfile); | ||||
| 
 | ||||
| 	if (bind(chansess->agentfd, (struct sockaddr*)&addr, sizeof(addr)) == 0) { | ||||
| 		chansess->agentdir = strdup(path); | ||||
| 		chansess->agentfile = strdup(sockfile); | ||||
| 	if (bind(fd, (struct sockaddr*)&addr, sizeof(addr)) == 0) { | ||||
| 		chansess->agentdir = m_strdup(path); | ||||
| 		chansess->agentfile = m_strdup(sockfile); | ||||
| 		ret = DROPBEAR_SUCCESS; | ||||
| 	} | ||||
| 
 | ||||
|  | ||||
| @ -151,7 +151,7 @@ void recv_msg_userauth_request() { | ||||
| 		if (methodlen == AUTH_METHOD_PASSWORD_LEN && | ||||
| 				strncmp(methodname, AUTH_METHOD_PASSWORD, | ||||
| 					AUTH_METHOD_PASSWORD_LEN) == 0) { | ||||
| 			passwordauth(username, userlen); | ||||
| 			passwordauth(); | ||||
| 			goto out; | ||||
| 		} | ||||
| 	} | ||||
| @ -162,7 +162,7 @@ void recv_msg_userauth_request() { | ||||
| 	if (methodlen == AUTH_METHOD_PUBKEY_LEN && | ||||
| 			strncmp(methodname, AUTH_METHOD_PUBKEY, | ||||
| 				AUTH_METHOD_PUBKEY_LEN) == 0) { | ||||
| 		pubkeyauth(username, userlen); | ||||
| 		pubkeyauth(); | ||||
| 		goto out; | ||||
| 	} | ||||
| #endif | ||||
| @ -200,7 +200,7 @@ static int checkusername(unsigned char *username, unsigned int userlen) { | ||||
| 			} | ||||
| 			authclear(); | ||||
| 			svr_ses.authstate.pw = getpwnam((char*)username); | ||||
| 			svr_ses.authstate.username = strdup(username); | ||||
| 			svr_ses.authstate.username = m_strdup(username); | ||||
| 			m_free(svr_ses.authstate.printableuser); | ||||
| 	} | ||||
| 
 | ||||
| @ -214,7 +214,7 @@ static int checkusername(unsigned char *username, unsigned int userlen) { | ||||
| 	} | ||||
| 
 | ||||
| 	/* We can set it once we know its a real user */ | ||||
| 	svr_ses.authstate.printableuser = strdup(svr_ses.authstate.pw->pw_name); | ||||
| 	svr_ses.authstate.printableuser = m_strdup(svr_ses.authstate.pw->pw_name); | ||||
| 
 | ||||
| 	/* check for non-root if desired */ | ||||
| 	if (ses.opts->norootlogin && svr_ses.authstate.pw->pw_uid == 0) { | ||||
|  | ||||
| @ -419,7 +419,7 @@ static int sessionpty(struct ChanSess * chansess) { | ||||
| 		return DROPBEAR_FAILURE; | ||||
| 	} | ||||
| 	 | ||||
| 	chansess->tty = (char*)strdup(namebuf); | ||||
| 	chansess->tty = (char*)m_strdup(namebuf); | ||||
| 	if (!chansess->tty) { | ||||
| 		dropbear_exit("out of memory"); /* TODO disconnect */ | ||||
| 	} | ||||
| @ -541,7 +541,7 @@ static int sessioncommand(struct Channel *channel, struct ChanSess *chansess, | ||||
| #ifdef SFTPSERVER_PATH | ||||
| 			if ((cmdlen == 4) && strncmp(chansess->cmd, "sftp", 4) == 0) { | ||||
| 				m_free(chansess->cmd); | ||||
| 				chansess->cmd = strdup(SFTPSERVER_PATH); | ||||
| 				chansess->cmd = m_strdup(SFTPSERVER_PATH); | ||||
| 			} else  | ||||
| #endif | ||||
| 			{ | ||||
|  | ||||
| @ -9,7 +9,7 @@ static int newtcpdirect(struct Channel * channel); | ||||
| static int newtcp(const char * host, int port); | ||||
| 
 | ||||
| const struct ChanType chan_tcpdirect = { | ||||
| 	0, /* sepfds */ | ||||
| 	1, /* sepfds */ | ||||
| 	"direct-tcpip", | ||||
| 	newtcpdirect, /* init */ | ||||
| 	NULL, /* checkclose */ | ||||
|  | ||||
| @ -71,7 +71,7 @@ out: | ||||
| } | ||||
| 
 | ||||
| static const struct ChanType chan_tcpremote = { | ||||
| 	0, /* sepfds */ | ||||
| 	1, /* sepfds */ | ||||
| 	"forwarded-tcpip", | ||||
| 	NULL, | ||||
| 	NULL, | ||||
|  | ||||
							
								
								
									
										3
									
								
								x11fwd.c
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								x11fwd.c
									
									
									
									
									
								
							| @ -38,7 +38,6 @@ | ||||
| #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); | ||||
| 
 | ||||
| @ -167,7 +166,7 @@ void x11setauth(struct ChanSess *chansess) { | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| static void x11cleanup(struct Listener *listener) { | ||||
| void x11cleanup(struct Listener *listener) { | ||||
| 
 | ||||
| 	struct ChanSess *chansess = (struct ChanSess*)listener->typedata; | ||||
| 
 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user