mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-27 22:03:31 +01:00
put most of the remaining exit policy stuff in
route selection still doesn't pay attention to exit policies though svn:r227
This commit is contained in:
parent
79b77b421d
commit
cdf6ea201f
@ -339,6 +339,11 @@ int connection_exit_connect(connection_t *conn) {
|
|||||||
int s; /* for the new socket */
|
int s; /* for the new socket */
|
||||||
struct sockaddr_in dest_addr;
|
struct sockaddr_in dest_addr;
|
||||||
|
|
||||||
|
if(router_compare_to_exit_policy(conn) < 0) {
|
||||||
|
log(LOG_INFO,"connection_exit_connect(): %s:%d failed exit policy. Closing.", conn->address, conn->port);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/* all the necessary info is here. Start the connect() */
|
/* all the necessary info is here. Start the connect() */
|
||||||
s=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
|
s=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
|
||||||
if (s < 0) {
|
if (s < 0) {
|
||||||
|
@ -547,12 +547,15 @@ int dump_router_to_string(char *s, int maxlen, routerinfo_t *router) {
|
|||||||
char *pkey;
|
char *pkey;
|
||||||
int pkeylen;
|
int pkeylen;
|
||||||
int written;
|
int written;
|
||||||
|
int result=0;
|
||||||
|
struct exit_policy_t *tmpe;
|
||||||
|
|
||||||
if(crypto_pk_write_public_key_to_string(router->pkey,&pkey,&pkeylen)<0) {
|
if(crypto_pk_write_public_key_to_string(router->pkey,&pkey,&pkeylen)<0) {
|
||||||
log(LOG_ERR,"dump_router_to_string(): write pkey to string failed!");
|
log(LOG_ERR,"dump_router_to_string(): write pkey to string failed!");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
written = snprintf(s, maxlen, "%s %d %d %d %d %d\n%s\n",
|
|
||||||
|
result = snprintf(s, maxlen, "%s %d %d %d %d %d\n%s",
|
||||||
router->address,
|
router->address,
|
||||||
router->or_port,
|
router->or_port,
|
||||||
router->op_port,
|
router->op_port,
|
||||||
@ -563,7 +566,35 @@ int dump_router_to_string(char *s, int maxlen, routerinfo_t *router) {
|
|||||||
|
|
||||||
free(pkey);
|
free(pkey);
|
||||||
|
|
||||||
return written;
|
if(result < 0 || result > maxlen) {
|
||||||
|
/* apparently different glibcs do different things on snprintf error.. so check both */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
written = result;
|
||||||
|
|
||||||
|
for(tmpe=router->exit_policy; tmpe; tmpe=tmpe->next) {
|
||||||
|
result = snprintf(s+written, maxlen-written, "%s %s:%s\n",
|
||||||
|
tmpe->policy_type == EXIT_POLICY_ACCEPT ? "accept" : "reject",
|
||||||
|
tmpe->address, tmpe->port);
|
||||||
|
if(result < 0 || result+written > maxlen) {
|
||||||
|
/* apparently different glibcs do different things on snprintf error.. so check both */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
written += result;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(written > maxlen-2) {
|
||||||
|
return -1; /* not enough space for \n\0 */
|
||||||
|
}
|
||||||
|
/* XXX count fenceposts here. They're probably wrong. In general,
|
||||||
|
* we need a better way to handle overruns in building the directory
|
||||||
|
* string, and a better way to handle directory string size in general. */
|
||||||
|
|
||||||
|
/* include a last '\n' */
|
||||||
|
s[written] = '\n';
|
||||||
|
s[written+1] = 0;
|
||||||
|
return written+1;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void dump_directory_to_string(char *s, int maxlen) {
|
void dump_directory_to_string(char *s, int maxlen) {
|
||||||
@ -595,13 +626,12 @@ void dump_directory_to_string(char *s, int maxlen) {
|
|||||||
|
|
||||||
written = dump_router_to_string(s, maxlen, router);
|
written = dump_router_to_string(s, maxlen, router);
|
||||||
|
|
||||||
if(written < 0 || written > maxlen) {
|
if(written < 0) {
|
||||||
/* apparently different glibcs do different things on error.. so check both */
|
|
||||||
log(LOG_ERR,"dump_directory_to_string(): tried to exceed string length.");
|
log(LOG_ERR,"dump_directory_to_string(): tried to exceed string length.");
|
||||||
s[maxlen-1] = 0; /* make sure it's null terminated */
|
s[maxlen-1] = 0; /* make sure it's null terminated */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
maxlen -= written;
|
maxlen -= written;
|
||||||
s += written;
|
s += written;
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ extern or_options_t options; /* command-line and config-file options */
|
|||||||
|
|
||||||
static int onion_process(circuit_t *circ);
|
static int onion_process(circuit_t *circ);
|
||||||
static int onion_deliver_to_conn(aci_t aci, unsigned char *onion, uint32_t onionlen, connection_t *conn);
|
static int onion_deliver_to_conn(aci_t aci, unsigned char *onion, uint32_t onionlen, connection_t *conn);
|
||||||
|
static int count_acceptable_routers(routerinfo_t **rarray, int rarray_len);
|
||||||
static int find_tracked_onion(unsigned char *onion, uint32_t onionlen);
|
static int find_tracked_onion(unsigned char *onion, uint32_t onionlen);
|
||||||
|
|
||||||
int decide_aci_type(uint32_t local_addr, uint16_t local_port,
|
int decide_aci_type(uint32_t local_addr, uint16_t local_port,
|
||||||
@ -335,7 +336,7 @@ int chooselen(double cw)
|
|||||||
unsigned int *new_route(double cw, routerinfo_t **rarray, int rarray_len, int *routelen)
|
unsigned int *new_route(double cw, routerinfo_t **rarray, int rarray_len, int *routelen)
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
int num_acceptable_routers = 0;
|
int num_acceptable_routers;
|
||||||
unsigned int *route = NULL;
|
unsigned int *route = NULL;
|
||||||
unsigned int oldchoice, choice;
|
unsigned int oldchoice, choice;
|
||||||
|
|
||||||
@ -348,26 +349,8 @@ unsigned int *new_route(double cw, routerinfo_t **rarray, int rarray_len, int *r
|
|||||||
}
|
}
|
||||||
log(LOG_DEBUG,"new_route(): Chosen route length %d.",*routelen);
|
log(LOG_DEBUG,"new_route(): Chosen route length %d.",*routelen);
|
||||||
|
|
||||||
for(i=0;i<rarray_len;i++) {
|
num_acceptable_routers = count_acceptable_routers(rarray, rarray_len);
|
||||||
log(LOG_DEBUG,"Contemplating whether router %d is a new option...",i);
|
|
||||||
if(options.ORPort &&
|
|
||||||
!connection_exact_get_by_addr_port(rarray[i]->addr, rarray[i]->or_port)) {
|
|
||||||
log(LOG_DEBUG,"Nope, %d is not connected.",i);
|
|
||||||
goto next_i_loop;
|
|
||||||
}
|
|
||||||
for(j=0;j<i;j++) {
|
|
||||||
if(!crypto_pk_cmp_keys(rarray[i]->pkey, rarray[j]->pkey)) {
|
|
||||||
/* these guys are twins. so we've already counted him. */
|
|
||||||
log(LOG_DEBUG,"Nope, %d is a twin of %d.",i,j);
|
|
||||||
goto next_i_loop;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
num_acceptable_routers++;
|
|
||||||
log(LOG_DEBUG,"I like %d. num_acceptable_routers now %d.",i, num_acceptable_routers);
|
|
||||||
next_i_loop:
|
|
||||||
; /* our compiler may need an explicit statement after the label */
|
|
||||||
}
|
|
||||||
|
|
||||||
if(num_acceptable_routers < *routelen) {
|
if(num_acceptable_routers < *routelen) {
|
||||||
log(LOG_DEBUG,"new_route(): Cutting routelen from %d to %d.",*routelen, num_acceptable_routers);
|
log(LOG_DEBUG,"new_route(): Cutting routelen from %d to %d.",*routelen, num_acceptable_routers);
|
||||||
*routelen = num_acceptable_routers;
|
*routelen = num_acceptable_routers;
|
||||||
@ -413,6 +396,34 @@ unsigned int *new_route(double cw, routerinfo_t **rarray, int rarray_len, int *r
|
|||||||
return route;
|
return route;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int count_acceptable_routers(routerinfo_t **rarray, int rarray_len) {
|
||||||
|
int i, j;
|
||||||
|
int num=0;
|
||||||
|
|
||||||
|
for(i=0;i<rarray_len;i++) {
|
||||||
|
log(LOG_DEBUG,"Contemplating whether router %d is a new option...",i);
|
||||||
|
if(options.ORPort &&
|
||||||
|
!connection_exact_get_by_addr_port(rarray[i]->addr, rarray[i]->or_port)) {
|
||||||
|
log(LOG_DEBUG,"Nope, %d is not connected.",i);
|
||||||
|
goto next_i_loop;
|
||||||
|
}
|
||||||
|
for(j=0;j<i;j++) {
|
||||||
|
if(!crypto_pk_cmp_keys(rarray[i]->pkey, rarray[j]->pkey)) {
|
||||||
|
/* these guys are twins. so we've already counted him. */
|
||||||
|
log(LOG_DEBUG,"Nope, %d is a twin of %d.",i,j);
|
||||||
|
goto next_i_loop;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
num++;
|
||||||
|
log(LOG_DEBUG,"I like %d. num_acceptable_routers now %d.",i, num);
|
||||||
|
next_i_loop:
|
||||||
|
; /* our compiler may need an explicit statement after the label */
|
||||||
|
}
|
||||||
|
|
||||||
|
return num;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
crypto_cipher_env_t *
|
crypto_cipher_env_t *
|
||||||
create_onion_cipher(int cipher_type, char *key, char *iv, int encrypt_mode)
|
create_onion_cipher(int cipher_type, char *key, char *iv, int encrypt_mode)
|
||||||
{
|
{
|
||||||
|
@ -779,6 +779,8 @@ void router_forget_router(uint32_t addr, uint16_t port);
|
|||||||
int router_get_list_from_file(char *routerfile);
|
int router_get_list_from_file(char *routerfile);
|
||||||
int router_get_list_from_string(char *s);
|
int router_get_list_from_string(char *s);
|
||||||
|
|
||||||
|
int router_compare_to_exit_policy(connection_t *conn);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -563,15 +563,18 @@ static void router_add_exit_policy(routerinfo_t *router, char *string) {
|
|||||||
memset(newe,0,sizeof(struct exit_policy_t));
|
memset(newe,0,sizeof(struct exit_policy_t));
|
||||||
|
|
||||||
newe->string = strdup(string);
|
newe->string = strdup(string);
|
||||||
if(!strncasecmp(string,"reject ",strlen("reject "))) {
|
n = find_whitespace(string);
|
||||||
|
*n = 0;
|
||||||
|
|
||||||
|
if(!strcasecmp(string,"reject")) {
|
||||||
newe->policy_type = EXIT_POLICY_REJECT;
|
newe->policy_type = EXIT_POLICY_REJECT;
|
||||||
} else if(!strncasecmp(string,"accept ",strlen("accept "))) {
|
} else if(!strcasecmp(string,"accept")) {
|
||||||
newe->policy_type = EXIT_POLICY_ACCEPT;
|
newe->policy_type = EXIT_POLICY_ACCEPT;
|
||||||
} else {
|
} else {
|
||||||
goto policy_read_failed;
|
goto policy_read_failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
string = eat_whitespace(string + strlen("reject "));
|
string = eat_whitespace(n+1);
|
||||||
if(!*string) {
|
if(!*string) {
|
||||||
goto policy_read_failed;
|
goto policy_read_failed;
|
||||||
}
|
}
|
||||||
@ -615,6 +618,38 @@ policy_read_failed:
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Return 0 if my exit policy says to allow connection to conn.
|
||||||
|
* Else return -1.
|
||||||
|
*/
|
||||||
|
int router_compare_to_exit_policy(connection_t *conn) {
|
||||||
|
struct exit_policy_t *tmpe;
|
||||||
|
|
||||||
|
if(!my_routerinfo) {
|
||||||
|
log(LOG_WARNING, "router_compare_to_exit_policy(): my_routerinfo undefined! Rejected.");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(tmpe=my_routerinfo->exit_policy; tmpe; tmpe=tmpe->next) {
|
||||||
|
assert(tmpe->address);
|
||||||
|
assert(tmpe->port);
|
||||||
|
|
||||||
|
/* Totally ignore the address field of the exit policy, for now. */
|
||||||
|
|
||||||
|
if(!strcmp(tmpe->port,"*") || atoi(tmpe->port) == conn->port) {
|
||||||
|
log(LOG_INFO,"router_compare_to_exit_policy(): Port '%s' matches '%d'. %s.",
|
||||||
|
tmpe->port, conn->port,
|
||||||
|
tmpe->policy_type == EXIT_POLICY_ACCEPT ? "Accepting" : "Rejecting");
|
||||||
|
if(tmpe->policy_type == EXIT_POLICY_ACCEPT)
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0; /* accept all by default. */
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Local Variables:
|
Local Variables:
|
||||||
mode:c
|
mode:c
|
||||||
|
Loading…
Reference in New Issue
Block a user