[or-cvs] Tested backends for directory signing and checking. Direct...
Nick Mathewson
nickm at seul.org
Wed May 7 18:30:50 UTC 2003
Update of /home/or/cvsroot/src/or
In directory moria.mit.edu:/tmp/cvs-serv22193/src/or
Modified Files:
main.c or.h routers.c test.c
Log Message:
Tested backends for directory signing and checking. Directory parser completely refactored. Need documentation and integration. Explanitory mail forthcoming.
Index: main.c
===================================================================
RCS file: /home/or/cvsroot/src/or/main.c,v
retrieving revision 1.55
retrieving revision 1.56
diff -u -d -r1.55 -r1.56
--- main.c 7 May 2003 03:32:18 -0000 1.55
+++ main.c 7 May 2003 18:30:46 -0000 1.56
@@ -678,16 +678,17 @@
dump_directory_to_string_impl(s+i, maxlen-i, dir);
i = strlen(s);
+ strncat(s, "directory-signature\n", maxlen-i);
+ i = strlen(s);
cp = s + i;
if (crypto_SHA_digest(s, i, digest))
return -1;
- if (crypto_pk_private_sign(private_key, digest, 20, signature))
+ if (crypto_pk_private_sign(private_key, digest, 20, signature) < 0)
return -1;
-
strncpy(cp,
- "directory-signature\n-----BEGIN SIGNATURE-----\n", maxlen-i);
+ "-----BEGIN SIGNATURE-----\n", maxlen-i);
i = strlen(s);
cp = s+i;
Index: or.h
===================================================================
RCS file: /home/or/cvsroot/src/or/or.h,v
retrieving revision 1.77
retrieving revision 1.78
diff -u -d -r1.77 -r1.78
--- or.h 7 May 2003 02:28:42 -0000 1.77
+++ or.h 7 May 2003 18:30:46 -0000 1.78
@@ -739,6 +739,8 @@
void dumpstats(void);
void dump_directory_to_string(char *s, int maxlen);
void dump_directory_to_string_impl(char *s, int maxlen, directory_t *directory);
+int dump_signed_directory_to_string_impl(char *s, int maxlen, directory_t *dir, crypto_pk_env_t *private_key);
+
int main(int argc, char *argv[]);
@@ -790,10 +792,13 @@
int router_is_me(uint32_t addr, uint16_t port);
void router_forget_router(uint32_t addr, uint16_t port);
int router_get_list_from_file(char *routerfile);
+int router_resolve(routerinfo_t *router);
int router_get_list_from_string(char *s);
int router_get_list_from_string_impl(char *s, directory_t **dest);
+int router_get_dir_from_string(char *s, crypto_pk_env_t *pkey);
+int router_get_dir_from_string_impl(char *s, directory_t **dest,
+ crypto_pk_env_t *pkey);
routerinfo_t *router_get_entry_from_string(char **s);
-
int router_compare_to_exit_policy(connection_t *conn);
void routerlist_free(routerinfo_t *list);
Index: routers.c
===================================================================
RCS file: /home/or/cvsroot/src/or/routers.c,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -d -r1.24 -r1.25
--- routers.c 7 May 2003 02:13:23 -0000 1.24
+++ routers.c 7 May 2003 18:30:46 -0000 1.25
@@ -2,7 +2,10 @@
/* See LICENSE for licensing information */
/* $Id$ */
+#define OR_PUBLICKEY_BEGIN_TAG "-----BEGIN RSA PUBLIC KEY-----\n"
#define OR_PUBLICKEY_END_TAG "-----END RSA PUBLIC KEY-----\n"
+#define OR_SIGNATURE_BEGIN_TAG "-----BEGIN SIGNATURE-----\n"
+#define OR_SIGNATURE_END_TAG "-----END SIGNATURE-----\n"
#include "or.h"
@@ -16,14 +19,22 @@
/****************************************************************************/
+struct directory_token;
+typedef struct directory_token directory_token_t;
+
/* static function prototypes */
void routerlist_free(routerinfo_t *list);
static routerinfo_t **make_rarray(routerinfo_t* list, int *len);
static char *eat_whitespace(char *s);
+static char *eat_whitespace_no_nl(char *s);
static char *find_whitespace(char *s);
-static int router_resolve(routerinfo_t *router);
-static void router_add_exit_policy(routerinfo_t *router, char *string);
static void router_free_exit_policy(routerinfo_t *router);
+static routerinfo_t *router_get_entry_from_string_tok(char**s,
+ directory_token_t *tok);
+static int router_get_list_from_string_tok(char **s, directory_t **dest,
+ directory_token_t *tok);
+static int router_add_exit_policy(routerinfo_t *router,
+ directory_token_t *tok);
/****************************************************************************/
@@ -288,12 +299,323 @@
return 0;
}
+
+typedef enum {
+ K_ACCEPT,
+ K_CLIENT_SOFTWARE,
+ K_DIRECTORY_SIGNATURE,
+ K_REJECT,
+ K_ROUTER,
+ K_SERVER_SOFTWARE,
+ K_SIGNED_DIRECTORY,
+ K_SIGNING_KEY,
+ _SIGNATURE,
+ _PUBLIC_KEY,
+ _ERR,
+ _EOF
+} directory_keyword;
+
+struct token_table_ent { char *t; int v; };
+
+static struct token_table_ent token_table[] = {
+ { "accept", K_ACCEPT },
+ { "client-software", K_CLIENT_SOFTWARE },
+ { "directory-signature", K_DIRECTORY_SIGNATURE },
+ { "reject", K_REJECT },
+ { "router", K_ROUTER },
+ { "server-software", K_SERVER_SOFTWARE },
+ { "signed-directory", K_SIGNED_DIRECTORY },
+ { "signing-key", K_SIGNING_KEY },
+ { NULL, -1 }
+};
+
+#define MAX_ARGS 8
+struct directory_token {
+ directory_keyword tp;
+ union {
+ struct {
+ char *args[MAX_ARGS+1];
+ int n_args;
+ } cmd;
+ char *signature;
+ char *error;
+ crypto_pk_env_t *public_key;
+ } val;
+};
+
+static int
+_router_get_next_token(char **s, directory_token_t *tok) {
+ char *next;
+ crypto_pk_env_t *pkey = NULL;
+ char *signature = NULL;
+ int i, done;
+
+ tok->tp = _ERR;
+ tok->val.error = "";
+
+ *s = eat_whitespace(*s);
+ if (!**s) {
+ tok->tp = _EOF;
+ return 0;
+ } else if (**s == '-') {
+ next = strchr(*s, '\n');
+ if (! next) { tok->val.error = "No newline at EOF"; return -1; }
+ ++next;
+ if (! strncmp(*s, OR_PUBLICKEY_BEGIN_TAG, next-*s)) {
+ next = strstr(*s, OR_PUBLICKEY_END_TAG);
+ if (!next) { tok->val.error = "No public key end tag found"; return -1; }
+ next = strchr(next, '\n'); /* Part of OR_PUBLICKEY_END_TAG; can't fail.*/
+ ++next;
+ if (!(pkey = crypto_new_pk_env(CRYPTO_PK_RSA)))
+ return -1;
+ if (crypto_pk_read_public_key_from_string(pkey, *s, next-*s)) {
+ crypto_free_pk_env(pkey);
+ tok->val.error = "Couldn't parse public key.";
+ return -1;
+ }
+ tok->tp = _PUBLIC_KEY;
+ tok->val.public_key = pkey;
+ *s = next;
+ return 0;
+ } else if (! strncmp(*s, OR_SIGNATURE_BEGIN_TAG, next-*s)) {
+ /* Advance past newline; can't fail. */
+ *s = strchr(*s, '\n');
+ ++*s;
+ /* Find end of base64'd data */
+ next = strstr(*s, OR_SIGNATURE_END_TAG);
+ if (!next) { tok->val.error = "No signature end tag found"; return -1; }
+
+ signature = malloc(256);
+ i = base64_decode(signature, 256, *s, next-*s);
+ if (i<0) {
+ free(signature);
+ tok->val.error = "Error decoding signature."; return -1;
+ } else if (i != 128) {
+ free(signature);
+ tok->val.error = "Bad length on decoded signature."; return -1;
+ }
+ tok->tp = _SIGNATURE;
+ tok->val.signature = signature;
+
+ next = strchr(next, '\n'); /* Part of OR_SIGNATURE_END_TAG; can't fail.*/
+ *s = next+1;
+ return 0;
+ } else {
+ tok->val.error = "Unrecognized begin line"; return -1;
+ }
+ } else {
+ next = find_whitespace(*s);
+ if (!next) {
+ tok->val.error = "Unexpected EOF"; return -1;
+ }
+ for (i = 0 ; token_table[i].t ; ++i) {
+ if (!strncmp(token_table[i].t, *s, next-*s)) {
+ tok->tp = token_table[i].v;
+ i = 0;
+ done = (*next == '\n');
+ *s = eat_whitespace_no_nl(next);
+ while (**s != '\n' && i <= MAX_ARGS && !done) {
+ next = find_whitespace(*s);
+ if (*next == '\n')
+ done = 1;
+ *next = 0;
+ tok->val.cmd.args[i++] = *s;
+ *s = eat_whitespace_no_nl(next+1);
+ };
+ tok->val.cmd.n_args = i;
+ if (i > MAX_ARGS) {
+ tok->tp = _ERR;
+ tok->val.error = "Too many arguments"; return -1;
+ }
+ return 0;
+ }
+ }
+ tok->val.error = "Unrecognized command"; return -1;
+ }
+}
+
+static void
+router_dump_token(directory_token_t *tok) {
+ int i;
+ switch(tok->tp)
+ {
+ case _SIGNATURE:
+ puts("(signature)");
+ return;
+ case _PUBLIC_KEY:
+ puts("(public key)");
+ return;
+ case _ERR:
+ printf("(Error: %s\n)", tok->val.error);
+ return;
+ case _EOF:
+ puts("EOF");
+ return;
+ case K_ACCEPT: printf("Accept"); break;
+ case K_CLIENT_SOFTWARE: printf("Client-Software"); break;
+ case K_DIRECTORY_SIGNATURE: printf("Directory-Signature"); break;
+ case K_REJECT: printf("Reject"); break;
+ case K_ROUTER: printf("Router"); break;
+ case K_SERVER_SOFTWARE: printf("Server-Software"); break;
+ case K_SIGNED_DIRECTORY: printf("Signed-Directory"); break;
+ case K_SIGNING_KEY: printf("Signing-Key"); break;
+ default:
+ printf("?????? %d\n", tok->tp); return;
+ }
+ for (i = 0; i < tok->val.cmd.n_args; ++i) {
+ printf(" \"%s\"", tok->val.cmd.args[i]);
+ }
+ printf("\n");
+ return;
+}
+
+#ifdef DEBUG_ROUTER_TOKENS
+static int
+router_get_next_token(char **s, directory_token_t *tok) {
+ int i;
+ i = _router_get_next_token(s, tok);
+ router_dump_token(tok);
+ return i;
+}
+#else
+#define router_get_next_token _router_get_next_token
+#endif
+
+
+
+/* return the first char of s that is not whitespace and not a comment */
+static char *eat_whitespace(char *s) {
+ assert(s);
+
+ while(isspace(*s) || *s == '#') {
+ while(isspace(*s))
+ s++;
+ if(*s == '#') { /* read to a \n or \0 */
+ while(*s && *s != '\n')
+ s++;
+ if(!*s)
+ return s;
+ }
+ }
+ return s;
+}
+
+static char *eat_whitespace_no_nl(char *s) {
+ while(*s == ' ' || *s == '\t')
+ ++s;
+ return s;
+}
+
+/* return the first char of s that is whitespace or '#' or '\0 */
+static char *find_whitespace(char *s) {
+ assert(s);
+
+ while(*s && !isspace(*s) && *s != '#')
+ s++;
+
+ return s;
+}
+
int router_get_list_from_string(char *s)
{
return router_get_list_from_string_impl(s, &directory);
}
-int router_get_list_from_string_impl(char *s, directory_t **dest)
+int router_get_list_from_string_impl(char *s, directory_t **dest) {
+ directory_token_t tok;
+ if (router_get_next_token(&s, &tok)) {
+ return NULL;
+ }
+ return router_get_list_from_string_tok(&s, dest, &tok);
+}
+
+static int router_get_dir_hash(char *s, char *digest)
+{
+ char *start, *end;
+ start = strstr(s, "signed-directory");
+ if (!start) return -1;
+ end = strstr(start, "directory-signature");
+ if (!end) return -1;
+ end = strchr(end, '\n');
+ if (!end) return -1;
+ ++end;
+
+ if (crypto_SHA_digest(start, end-start, digest))
+ return -1;
+
+ return 0;
+}
+
+int router_get_dir_from_string(char *s, crypto_pk_env_t *pkey)
+{
+ return router_get_dir_from_string_impl(s, &directory, pkey);
+}
+
+int router_get_dir_from_string_impl(char *s, directory_t **dest,
+ crypto_pk_env_t *pkey)
+{
+ directory_token_t tok;
+ char digest[20];
+ char signed_digest[128];
+
+#define NEXT_TOK() \
+ do { \
+ if (router_get_next_token(&s, &tok)) { \
+ log(LOG_ERR, "Error reading directory: %s", tok.val.error); \
+ return -1; \
+ } } while (0)
+#define TOK_IS(type,name) \
+ do { \
+ if (tok.tp != type) { \
+ log(LOG_ERR, "Error reading directory: expected %s", name); \
+ return -1; \
+ } } while(0)
+
+ if (router_get_dir_hash(s, digest))
+ return -1;
+
+ NEXT_TOK();
+ TOK_IS(K_SIGNED_DIRECTORY, "signed-directory");
+
+ NEXT_TOK();
+ TOK_IS(K_CLIENT_SOFTWARE, "client-software");
+
+ NEXT_TOK();
+ TOK_IS(K_SERVER_SOFTWARE, "server-software");
+
+ NEXT_TOK();
+ if (router_get_list_from_string_tok(&s, dest, &tok))
+ return -1;
+
+ TOK_IS(K_DIRECTORY_SIGNATURE, "directory-signature");
+ NEXT_TOK();
+ TOK_IS(_SIGNATURE, "signature");
+ if (pkey) {
+ if (crypto_pk_public_checksig(pkey, tok.val.signature, 128, signed_digest)
+ != 20) {
+ log(LOG_ERR, "Error reading directory: invalid signature.");
+ free(tok.val.signature);
+ return -1;
+ }
+ if (memcmp(digest, signed_digest, 20)) {
+ log(LOG_ERR, "Error reading directory: signature does not match.");
+ free(tok.val.signature);
+ return -1;
+ }
+ }
+ free(tok.val.signature);
+
+ NEXT_TOK();
+ TOK_IS(_EOF, "end of directory");
+
+ return 0;
+#undef NEXT_TOK
+#undef TOK_IS
+}
+
+
+static int router_get_list_from_string_tok(char **s, directory_t **dest,
+ directory_token_t *tok)
{
routerinfo_t *routerlist=NULL;
routerinfo_t *router;
@@ -302,17 +624,8 @@
assert(s);
- while(*s) { /* while not at the end of the string */
- router = router_get_entry_from_string(&s);
- if(router == NULL) {
- routerlist_free(routerlist);
- return -1;
- }
- if (router_resolve(router)) {
- routerlist_free(router);
- routerlist_free(routerlist);
- return -1;
- }
+ while (tok->tp == K_ROUTER) {
+ router = router_get_entry_from_string_tok(s, tok);
switch(router_is_me(router->addr, router->or_port)) {
case 0: /* it's not me */
router->next = routerlist;
@@ -329,7 +642,6 @@
routerlist_free(routerlist);
return -1;
}
- s = eat_whitespace(s);
}
new_router_array = make_rarray(routerlist, &new_rarray_len);
@@ -343,34 +655,6 @@
}
return -1;
}
-
-/* return the first char of s that is not whitespace and not a comment */
-static char *eat_whitespace(char *s) {
- assert(s);
-
- while(isspace(*s) || *s == '#') {
- while(isspace(*s))
- s++;
- if(*s == '#') { /* read to a \n or \0 */
- while(*s && *s != '\n')
- s++;
- if(!*s)
- return s;
- }
- }
- return s;
-}
-
-/* return the first char of s that is whitespace or '#' or '\0 */
-static char *find_whitespace(char *s) {
- assert(s);
-
- while(*s && !isspace(*s) && *s != '#')
- s++;
-
- return s;
-}
-
static int
router_resolve(routerinfo_t *router)
{
@@ -388,157 +672,102 @@
return 0;
}
+
+routerinfo_t *router_get_entry_from_string(char **s) {
+ directory_token_t tok;
+ routerinfo_t *router;
+ if (router_get_next_token(s, &tok)) return NULL;
+ router = router_get_entry_from_string_tok(s, &tok);
+ if (tok.tp != _EOF)
+ return NULL;
+ return router;
+}
+
/* reads a single router entry from s.
* updates s so it points to after the router it just read.
* mallocs a new router, returns it if all goes well, else returns NULL.
*/
-routerinfo_t *router_get_entry_from_string(char **s) {
- routerinfo_t *router;
- char *next;
+static routerinfo_t *router_get_entry_from_string_tok(char**s, directory_token_t *tok) {
+ routerinfo_t *router = NULL;
- /* Make sure that this string really starts with a router entry. */
- *s = eat_whitespace(*s);
- if (strncasecmp(*s, "router ", 7)) {
+#define NEXT_TOKEN() \
+ do { if (router_get_next_token(s, tok)) goto err; \
+ } while(0)
+
+#define ARGS tok->val.cmd.args
+
+ if (tok->tp != K_ROUTER) {
log(LOG_ERR,"router_get_entry_from_string(): Entry does not start with \"router\"");
return NULL;
}
-
- router = malloc(sizeof(routerinfo_t));
- if (!router) {
+ if (!(router = malloc(sizeof(routerinfo_t)))) {
log(LOG_ERR,"router_get_entry_from_string(): Could not allocate memory.");
return NULL;
}
memset(router,0,sizeof(routerinfo_t)); /* zero it out first */
router->next = NULL;
-/* Bug: if find_whitespace returns a '#', we'll squish it. */
-#define NEXT_TOKEN(s, next) \
- *s = eat_whitespace(*s); \
- next = find_whitespace(*s); \
- if(!*next) { \
- goto router_read_failed; \
- } \
- *next = 0;
-
- /* Skip the "router" */
- NEXT_TOKEN(s, next);
- *s = next+1;
-
- /* read router->address */
- NEXT_TOKEN(s, next);
- router->address = strdup(*s);
- *s = next+1;
+ if (tok->val.cmd.n_args != 6) {
+ log(LOG_ERR,"router_get_entry_from_string(): Wrong # of arguments to \"router\"");
+ goto err;
+ }
- /* Don't resolve address till later. */
+ /* read router.address */
+ if (!(router->address = strdup(ARGS[0])))
+ goto err;
router->addr = 0;
- /* read router->or_port */
- NEXT_TOKEN(s, next);
- router->or_port = atoi(*s);
+ /* Read router->or_port */
+ router->or_port = atoi(ARGS[1]);
if(!router->or_port) {
- log(LOG_ERR,"router_get_entry_from_string(): or_port '%s' unreadable or 0. Failing.",*s);
- goto router_read_failed;
+ log(LOG_ERR,"router_get_entry_from_string(): or_port unreadable or 0. Failing.");
+ goto err;
}
- *s = next+1;
- /* read router->op_port */
- NEXT_TOKEN(s, next);
- router->op_port = atoi(*s);
- *s = next+1;
+ /* Router->op_port */
+ router->op_port = atoi(ARGS[2]);
- /* read router->ap_port */
- NEXT_TOKEN(s, next);
- router->ap_port = atoi(*s);
- *s = next+1;
+ /* Router->ap_port */
+ router->ap_port = atoi(ARGS[3]);
- /* read router->dir_port */
- NEXT_TOKEN(s, next);
- router->dir_port = atoi(*s);
- *s = next+1;
+ /* Router->dir_port */
+ router->dir_port = atoi(ARGS[4]);
- /* read router->bandwidth */
- NEXT_TOKEN(s, next);
- router->bandwidth = atoi(*s);
- if(!router->bandwidth) {
- log(LOG_ERR,"router_get_entry_from_string(): bandwidth '%s' unreadable or 0. Failing.",*s);
- goto router_read_failed;
+ /* Router->bandwidth */
+ router->bandwidth = atoi(ARGS[5]);
+ if (!router->bandwidth) {
+ log(LOG_ERR,"router_get_entry_from_string(): bandwidth unreadable or 0. Failing.");
}
- *s = next+1;
-
+
log(LOG_DEBUG,"or_port %d, op_port %d, ap_port %d, dir_port %d, bandwidth %d.",
router->or_port, router->op_port, router->ap_port, router->dir_port, router->bandwidth);
- *s = eat_whitespace(*s);
- next = strstr(*s,OR_PUBLICKEY_END_TAG);
- router->pkey = crypto_new_pk_env(CRYPTO_PK_RSA);
- if(!next || !router->pkey) {
- log(LOG_ERR,"router_get_entry_from_string(): Couldn't find pk in string");
- goto router_read_failed;
- }
-
- /* now advance *s so it's at the end of this public key */
- next = strchr(next, '\n');
- assert(next); /* can't fail, we just checked it was here */
- *next = 0;
-// log(LOG_DEBUG,"Key about to be read is: '%s'",*s);
- if((crypto_pk_read_public_key_from_string(router->pkey, *s, strlen(*s))<0)) {
- log(LOG_ERR,"router_get_entry_from_string(): Couldn't read pk from string");
- goto router_read_failed;
- }
- log(LOG_DEBUG,"router_get_entry_from_string(): Public key size = %u.", crypto_pk_keysize(router->pkey));
-
- if (crypto_pk_keysize(router->pkey) != 128) { /* keys MUST be 1024 bits in size */
- log(LOG_ERR,"Key for router %s:%u is not 1024 bits. All keys must be exactly 1024 bits long.",
- router->address,router->or_port);
- goto router_read_failed;
- }
-
- *s = next+1;
- *s = eat_whitespace(*s);
- if (!strncasecmp(*s, "signing-key", 11)) {
- /* We have a signing key */
- *s = strchr(*s, '\n');
- *s = eat_whitespace(*s);
- next = strstr(*s,OR_PUBLICKEY_END_TAG);
- router->signing_pkey = crypto_new_pk_env(CRYPTO_PK_RSA);
- if (!next || !router->signing_pkey) {
- log(LOG_ERR,"router_get_entry_from_string(): Couldn't find signing_pk in string");
- goto router_read_failed;
- }
- next = strchr(next, '\n');
- assert(next);
- *next = 0;
- if ((crypto_pk_read_public_key_from_string(router->signing_pkey, *s,
- strlen(*s)))<0) {
- log(LOG_ERR,"router_get_entry_from_string(): Couldn't read signing pk from string");
- goto router_read_failed;
- }
-
- log(LOG_DEBUG,"router_get_entry_from_string(): Signing key size = %u.", crypto_pk_keysize(router->signing_pkey));
+ NEXT_TOKEN();
+ if (tok->tp != _PUBLIC_KEY) {
+ log(LOG_ERR,"router_get_entry_from_string(): Missing public key");
+ goto err;
+ } /* Check key length */
+ router->pkey = tok->val.public_key;
- if (crypto_pk_keysize(router->signing_pkey) != 128) { /* keys MUST be 1024 bits in size */
- log(LOG_ERR,"Signing key for router %s:%u is 1024 bits. All keys must be exactly 1024 bits long.",
- router->address,router->or_port);
- goto router_read_failed;
+ NEXT_TOKEN();
+ if (tok->tp == K_SIGNING_KEY) {
+ NEXT_TOKEN();
+ if (tok->tp != _PUBLIC_KEY) {
+ log(LOG_ERR,"router_get_entry_from_string(): Missing signing key");
+ goto err;
}
- *s = next+1;
- }
-
- // test_write_pkey(router->pkey);
+ router->signing_pkey = tok->val.public_key;
+ NEXT_TOKEN();
+ }
- while(**s && **s != '\n') {
- /* pull in a line of exit policy */
- next = strchr(*s, '\n');
- if(!next)
- goto router_read_failed;
- *next = 0;
- router_add_exit_policy(router, *s);
- *s = next+1;
+ while (tok->tp == K_ACCEPT || tok->tp == K_REJECT) {
+ router_add_exit_policy(router, tok);
+ NEXT_TOKEN();
}
-
+
return router;
-router_read_failed:
+ err:
if(router->address)
free(router->address);
if(router->pkey)
@@ -546,6 +775,8 @@
router_free_exit_policy(router);
free(router);
return NULL;
+#undef ARGS
+#undef NEXT_TOKEN
}
static void router_free_exit_policy(routerinfo_t *router) {
@@ -576,43 +807,35 @@
}
#endif
-static void router_add_exit_policy(routerinfo_t *router, char *string) {
+static int router_add_exit_policy(routerinfo_t *router,
+ directory_token_t *tok) {
struct exit_policy_t *tmpe, *newe;
- char *n;
+ char *arg, *colon;
- string = eat_whitespace(string);
- if(!*string) /* it was all whitespace or comment */
- return;
+ if (tok->val.cmd.n_args != 1)
+ return -1;
+ arg = tok->val.cmd.args[0];
newe = malloc(sizeof(struct exit_policy_t));
memset(newe,0,sizeof(struct exit_policy_t));
-
- newe->string = strdup(string);
- n = find_whitespace(string);
- *n = 0;
-
- if(!strcasecmp(string,"reject")) {
+
+ newe->string = malloc(8+strlen(arg));
+ if (tok->tp == K_REJECT) {
+ strcpy(newe->string, "reject ");
newe->policy_type = EXIT_POLICY_REJECT;
- } else if(!strcasecmp(string,"accept")) {
- newe->policy_type = EXIT_POLICY_ACCEPT;
} else {
- goto policy_read_failed;
- }
-
- string = eat_whitespace(n+1);
- if(!*string) {
- goto policy_read_failed;
+ assert(tok->tp == K_ACCEPT);
+ strcpy(newe->string, "accept ");
+ newe->policy_type = EXIT_POLICY_ACCEPT;
}
-
- n = strchr(string,':');
- if(!n)
+ strcat(newe->string, arg);
+
+ colon = strchr(arg,':');
+ if(!colon)
goto policy_read_failed;
- *n = 0;
- newe->address = strdup(string);
- string = n+1;
- n = find_whitespace(string);
- *n = 0;
- newe->port = strdup(string);
+ *colon = 0;
+ newe->address = strdup(arg);
+ newe->port = strdup(colon+1);
log(LOG_DEBUG,"router_add_exit_policy(): type %d, address '%s', port '%s'.",
newe->policy_type, newe->address, newe->port);
@@ -621,13 +844,13 @@
if(!router->exit_policy) {
router->exit_policy = newe;
- return;
+ return 0;
}
for(tmpe=router->exit_policy; tmpe->next; tmpe=tmpe->next) ;
tmpe->next = newe;
- return;
+ return 0;
policy_read_failed:
assert(newe->string);
@@ -639,8 +862,7 @@
if(newe->port)
free(newe->port);
free(newe);
- return;
-
+ return -1;
}
/* Return 0 if my exit policy says to allow connection to conn.
Index: test.c
===================================================================
RCS file: /home/or/cvsroot/src/or/test.c,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -d -r1.15 -r1.16
--- test.c 7 May 2003 02:28:42 -0000 1.15
+++ test.c 7 May 2003 18:30:46 -0000 1.16
@@ -405,7 +405,7 @@
memcpy(data2+1, "XYZZY", 5); /* This has fails ~ once-in-2^40 */
test_eq(-1, crypto_pk_private_decrypt(pk1, data2, 128, data3,
RSA_PKCS1_OAEP_PADDING));
-
+
/* File operations: save and load private key */
f = fopen("/tmp/tor_test/pkey1", "wb");
test_assert(! crypto_pk_write_private_key_to_file(pk1, f));
@@ -419,11 +419,28 @@
"/tmp/tor_test/pkey1"));
test_eq(15, crypto_pk_private_decrypt(pk2, data1, 128, data3,
RSA_PKCS1_OAEP_PADDING));
-
+ /* Now try signing. */
+ strcpy(data1, "Ossifrage");
+ test_eq(128, crypto_pk_private_sign(pk1, data1, 10, data2));
+ test_eq(10, crypto_pk_public_checksig(pk1, data2, 128, data3));
+ test_streq(data3, "Ossifrage");
+ /*XXXX test failed signing*/
+
crypto_free_pk_env(pk1);
crypto_free_pk_env(pk2);
+ /* Base64 tests */
+ strcpy(data1, "Test string that contains 35 chars.");
+ strcat(data1, " 2nd string that contains 35 chars.");
+
+ i = base64_encode(data2, 1024, data1, 71);
+ j = base64_decode(data3, 1024, data2, i);
+ test_streq(data3, data1);
+ test_eq(j, 71);
+ test_assert(data2[i] == '\0');
+
+
free(data1);
free(data2);
free(data3);
@@ -512,9 +529,8 @@
routerinfo_t r1, r2;
crypto_pk_env_t *pk1 = NULL, *pk2 = NULL;
routerinfo_t *rp1, *rp2;
- struct exit_policy_t ex1, ex2, ex3;
-
- int i;
+ struct exit_policy_t ex1, ex2;
+ directory_t *dir1 = NULL, *dir2 = NULL;
test_assert( (pk1 = crypto_new_pk_env(CRYPTO_PK_RSA)) );
test_assert( (pk2 = crypto_new_pk_env(CRYPTO_PK_RSA)) );
@@ -609,8 +625,15 @@
test_assert(rp2->exit_policy->next->next == NULL);
/* Okay, now for the directories. */
+ dir1 = (directory_t*) malloc(sizeof(directory_t));
+ dir1->n_routers = 2;
+ dir1->routers = (routerinfo_t**) malloc(sizeof(routerinfo_t*)*2);
+ dir1->routers[0] = &r1;
+ dir1->routers[1] = &r2;
+ test_assert(! dump_signed_directory_to_string_impl(buf, 2048, dir1, pk1));
+ /* puts(buf); */
-
+ test_assert(! router_get_dir_from_string_impl(buf, &dir2, pk1));
if (pk1_str) free(pk1_str);
if (pk2_str) free(pk2_str);
@@ -618,6 +641,8 @@
if (pk2) crypto_free_pk_env(pk2);
if (rp1) routerlist_free(rp1);
if (rp2) routerlist_free(rp2);
+ if (dir1) free(dir1); /* And more !*/
+ if (dir1) free(dir2); /* And more !*/
}
int
More information about the tor-commits
mailing list