Fix for a DoS attack:
A remote user could telnet to the tinc daemon and type only this line: 61 6 00000000/00000000:28f This would deny any packets to be sent to other tinc networks (except for to the hosts that run tincd's themselves). Solution is to skip hosts in lookup_conn() that have not been activated yet. Fixed potential conn_list table corruption: If a new connection is accepted but a connection with the same subnet would already exist in the connection list, the OLD connection is terminated.
This commit is contained in:
		
							parent
							
								
									4d71de15e8
								
							
						
					
					
						commit
						e4ff969a98
					
				
					 3 changed files with 17 additions and 9 deletions
				
			
		|  | @ -821,8 +821,8 @@ cp | |||
| 
 | ||||
|   if(cl->status.outgoing) | ||||
|     { | ||||
|       alarm(5); | ||||
|       signal(SIGALRM, sigalrm_handler); | ||||
|       alarm(5); | ||||
|       syslog(LOG_NOTICE, "Try to re-establish outgoing connection in 5 seconds."); | ||||
|     } | ||||
|    | ||||
|  |  | |||
|  | @ -37,7 +37,8 @@ | |||
| 
 | ||||
| /*
 | ||||
|   look for a connection associated with the given vpn ip, | ||||
|   return its connection structure | ||||
|   return its connection structure. | ||||
|   Skips connections that are not activated! | ||||
| */ | ||||
| conn_list_t *lookup_conn(ip_t ip) | ||||
| { | ||||
|  | @ -45,10 +46,10 @@ conn_list_t *lookup_conn(ip_t ip) | |||
| cp | ||||
|   /* Exact match suggested by James B. MacLean */ | ||||
|   for(p = conn_list; p != NULL; p = p->next) | ||||
|     if(ip  == p->vpn_ip) | ||||
|     if((ip  == p->vpn_ip) && p->active) | ||||
|       return p; | ||||
|   for(p = conn_list; p != NULL; p = p->next) | ||||
|     if((ip & p->vpn_mask) == (p->vpn_ip & p->vpn_mask)) | ||||
|     if(((ip & p->vpn_mask) == (p->vpn_ip & p->vpn_mask)) && p->active) | ||||
|       return p; | ||||
| cp | ||||
|   return NULL; | ||||
|  |  | |||
|  | @ -188,7 +188,7 @@ void send_key_changed_all(void) | |||
|   conn_list_t *p; | ||||
| cp | ||||
|   for(p = conn_list; p != NULL; p = p->next) | ||||
|     if(p->status.meta && p->protocol_version > PROT_3) | ||||
|     if(p->status.meta && p->active) | ||||
|       send_key_changed(p, myself); | ||||
| cp | ||||
| } | ||||
|  | @ -332,7 +332,7 @@ int notify_others(conn_list_t *new, conn_list_t *source, | |||
|   conn_list_t *p; | ||||
| cp | ||||
|   for(p = conn_list; p != NULL; p = p->next) | ||||
|     if(p != new && p != source && p->status.meta) | ||||
|     if(p != new && p != source && p->status.meta && p->active) | ||||
|       function(p, new); | ||||
| cp | ||||
|   return 0; | ||||
|  | @ -347,7 +347,7 @@ int notify_one(conn_list_t *new) | |||
|   conn_list_t *p; | ||||
| cp | ||||
|   for(p = conn_list; p != NULL; p = p->next) | ||||
|     if(p != new && p->protocol_version > PROT_3) | ||||
|     if(p != new && p->active) | ||||
|       send_add_host(new, p); | ||||
| cp | ||||
|   return 0; | ||||
|  | @ -392,8 +392,6 @@ cp | |||
| 	return -1; | ||||
|       send_passphrase(cl); | ||||
|     } | ||||
| 
 | ||||
|   cl->status.active = 0; | ||||
| cp | ||||
|   return 0; | ||||
| } | ||||
|  | @ -424,6 +422,7 @@ cp | |||
| int public_key_h(conn_list_t *cl) | ||||
| { | ||||
|   char *g_n; | ||||
|   conn_list_t *old; | ||||
| cp | ||||
|   if(sscanf(cl->buffer, "%*d %as", &g_n) != 1) | ||||
|     { | ||||
|  | @ -449,6 +448,14 @@ cp | |||
|   else | ||||
|     send_ack(cl); | ||||
| 
 | ||||
|   /* Okay, before we active the connection, we check if there is another entry
 | ||||
|      in the connection list with the same vpn_ip. If so, it presumably is an | ||||
|      old connection that has timed out but we don't know it yet. Because our | ||||
|      conn_list entry is not active, lookup_conn will skip ourself. */ | ||||
| 
 | ||||
|   if(old=lookup_conn(cl->vpn_ip))  | ||||
|     terminate_connection(old); | ||||
| 
 | ||||
|   cl->status.active = 1; | ||||
|   notify_others(cl, NULL, send_add_host); | ||||
|   notify_one(cl); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue