[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[or-cvs] put most of the remaining exit policy stuff in



Update of /home/or/cvsroot/src/or
In directory moria.mit.edu:/home/arma/work/onion/cvs/src/or

Modified Files:
	connection_exit.c main.c onion.c or.h routers.c 
Log Message:
put most of the remaining exit policy stuff in
route selection still doesn't pay attention to exit policies though


Index: connection_exit.c
===================================================================
RCS file: /home/or/cvsroot/src/or/connection_exit.c,v
retrieving revision 1.29
retrieving revision 1.30
diff -u -d -r1.29 -r1.30
--- connection_exit.c	7 Apr 2003 02:12:02 -0000	1.29
+++ connection_exit.c	8 Apr 2003 06:44:38 -0000	1.30
@@ -339,6 +339,11 @@
   int s; /* for the new socket */
   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() */
   s=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
   if (s < 0) {

Index: main.c
===================================================================
RCS file: /home/or/cvsroot/src/or/main.c,v
retrieving revision 1.46
retrieving revision 1.47
diff -u -d -r1.46 -r1.47
--- main.c	7 Apr 2003 02:12:02 -0000	1.46
+++ main.c	8 Apr 2003 06:44:38 -0000	1.47
@@ -547,12 +547,15 @@
   char *pkey;
   int pkeylen;
   int written;
+  int result=0;
+  struct exit_policy_t *tmpe;
 
   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!");
     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->or_port,
     router->op_port,
@@ -563,7 +566,35 @@
 
   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) {
@@ -595,13 +626,12 @@
 
     written = dump_router_to_string(s, maxlen, router);
 
-    if(written < 0 || written > maxlen) { 
-      /* apparently different glibcs do different things on error.. so check both */
+    if(written < 0) { 
       log(LOG_ERR,"dump_directory_to_string(): tried to exceed string length.");
       s[maxlen-1] = 0; /* make sure it's null terminated */
       return;
     }
-  
+
     maxlen -= written;
     s += written;
   }

Index: onion.c
===================================================================
RCS file: /home/or/cvsroot/src/or/onion.c,v
retrieving revision 1.31
retrieving revision 1.32
diff -u -d -r1.31 -r1.32
--- onion.c	7 Apr 2003 02:12:02 -0000	1.31
+++ onion.c	8 Apr 2003 06:44:38 -0000	1.32
@@ -8,6 +8,7 @@
 
 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 count_acceptable_routers(routerinfo_t **rarray, int rarray_len);
 static int find_tracked_onion(unsigned char *onion, uint32_t onionlen);
 
 int decide_aci_type(uint32_t local_addr, uint16_t local_port,
@@ -335,7 +336,7 @@
 unsigned int *new_route(double cw, routerinfo_t **rarray, int rarray_len, int *routelen)
 {
   int i, j;
-  int num_acceptable_routers = 0;
+  int num_acceptable_routers;
   unsigned int *route = NULL;
   unsigned int oldchoice, choice;
   
@@ -348,26 +349,8 @@
   }
   log(LOG_DEBUG,"new_route(): Chosen route length %d.",*routelen);
 
-  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_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 */
-  }
-      
+  num_acceptable_routers = count_acceptable_routers(rarray, rarray_len);
+
   if(num_acceptable_routers < *routelen) {
     log(LOG_DEBUG,"new_route(): Cutting routelen from %d to %d.",*routelen, num_acceptable_routers);
     *routelen = num_acceptable_routers;
@@ -412,6 +395,34 @@
    
   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 *
 create_onion_cipher(int cipher_type, char *key, char *iv, int encrypt_mode)

Index: or.h
===================================================================
RCS file: /home/or/cvsroot/src/or/or.h,v
retrieving revision 1.58
retrieving revision 1.59
diff -u -d -r1.58 -r1.59
--- or.h	7 Apr 2003 04:38:19 -0000	1.58
+++ or.h	8 Apr 2003 06:44:38 -0000	1.59
@@ -779,6 +779,8 @@
 int router_get_list_from_file(char *routerfile);
 int router_get_list_from_string(char *s);
 
+int router_compare_to_exit_policy(connection_t *conn);
+
 #endif
 
 /*

Index: routers.c
===================================================================
RCS file: /home/or/cvsroot/src/or/routers.c,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -d -r1.20 -r1.21
--- routers.c	7 Apr 2003 04:38:19 -0000	1.20
+++ routers.c	8 Apr 2003 06:44:38 -0000	1.21
@@ -563,15 +563,18 @@
   memset(newe,0,sizeof(struct exit_policy_t));
 
   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;
-  } else if(!strncasecmp(string,"accept ",strlen("accept "))) {
+  } else if(!strcasecmp(string,"accept")) {
     newe->policy_type = EXIT_POLICY_ACCEPT;
   } else {
     goto policy_read_failed;
   }
 
-  string = eat_whitespace(string + strlen("reject "));
+  string = eat_whitespace(n+1);
   if(!*string) {
     goto policy_read_failed;
   }
@@ -612,6 +615,38 @@
     free(newe->port);
   free(newe);
   return;
+
+}
+
+/* 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. */
 
 }