diff options
author | Nick Mathewson <nickm@torproject.org> | 2004-12-24 02:17:32 +0000 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2004-12-24 02:17:32 +0000 |
commit | e8585dfe9785c9fd6e74707aa84637c3be0cd1d2 (patch) | |
tree | 8f0b0083acbeb658a845c295227fc2f2585fcfb8 | |
parent | 7117366810c11845339ec21253d4d509b5aeb1e5 (diff) | |
download | tor-e8585dfe9785c9fd6e74707aa84637c3be0cd1d2.tar.gz tor-e8585dfe9785c9fd6e74707aa84637c3be0cd1d2.zip |
Remove length restriction when generating directories.
svn:r3218
-rw-r--r-- | src/or/dirserv.c | 61 | ||||
-rw-r--r-- | src/or/or.h | 2 | ||||
-rw-r--r-- | src/or/test.c | 6 |
3 files changed, 44 insertions, 25 deletions
diff --git a/src/or/dirserv.c b/src/or/dirserv.c index 9c35816a1a..8795f3181e 100644 --- a/src/or/dirserv.c +++ b/src/or/dirserv.c @@ -569,16 +569,16 @@ dirserv_remove_old_servers(int age) } } -/** Dump all routers currently in the directory into the string - * <b>s</b>, using at most <b>maxlen</b> characters, and signing the +/** Generate a new directory and write it into a newly allocated string. + * Point *<b>dir_out</b> to the allocated string. Sign the * directory with <b>private_key</b>. Return 0 on success, -1 on * failure. */ int -dirserv_dump_directory_to_string(char *s, size_t maxlen, +dirserv_dump_directory_to_string(char **dir_out, crypto_pk_env_t *private_key) { - char *eos, *cp; + char *cp; char *running_routers, *router_status; char *identity_pkey; /* Identity key, DER64-encoded. */ char *recommended_versions; @@ -586,8 +586,12 @@ dirserv_dump_directory_to_string(char *s, size_t maxlen, char signature[128]; char published[33]; time_t published_on; + char *buf = NULL; + size_t buf_len; int i; - eos = s+maxlen; + + tor_assert(dir_out); + *dir_out = NULL; if (!descriptor_list) descriptor_list = smartlist_create(); @@ -630,7 +634,18 @@ dirserv_dump_directory_to_string(char *s, size_t maxlen, dirserv_remove_old_servers(ROUTER_MAX_AGE); published_on = time(NULL); format_iso_time(published, published_on); - tor_snprintf(s, maxlen, + + buf_len = 2048+strlen(recommended_versions)+strlen(running_routers)+ + strlen(router_status); + SMARTLIST_FOREACH(descriptor_list, descriptor_entry_t *, d, + buf_len += strlen(d->descriptor)); + buf = tor_malloc(buf_len); + /* We'll be comparing against buf_len throughout the rest of the + function, though strictly speaking we shouldn't be able to exceed + it. This is C, after all, so we may as well check for buffer + overruns.*/ + + tor_snprintf(buf, buf_len, "signed-directory\n" "published %s\n" "recommended-software %s\n" @@ -643,49 +658,54 @@ dirserv_dump_directory_to_string(char *s, size_t maxlen, tor_free(running_routers); tor_free(router_status); tor_free(identity_pkey); - i = strlen(s); - cp = s+i; + i = strlen(buf); + cp = buf+i; SMARTLIST_FOREACH(descriptor_list, descriptor_entry_t *, d, - if (strlcat(s, d->descriptor, maxlen) >= maxlen) + if (strlcat(buf, d->descriptor, buf_len) >= buf_len) goto truncated); /* These multiple strlcat calls are inefficient, but dwarfed by the RSA signature. */ - if (strlcat(s, "directory-signature ", maxlen) >= maxlen) + if (strlcat(buf, "directory-signature ", buf_len) >= buf_len) goto truncated; - if (strlcat(s, get_options()->Nickname, maxlen) >= maxlen) + if (strlcat(buf, get_options()->Nickname, buf_len) >= buf_len) goto truncated; - if (strlcat(s, "\n", maxlen) >= maxlen) + if (strlcat(buf, "\n", buf_len) >= buf_len) goto truncated; - if (router_get_dir_hash(s,digest)) { + if (router_get_dir_hash(buf,digest)) { log_fn(LOG_WARN,"couldn't compute digest"); + tor_free(buf); return -1; } if (crypto_pk_private_sign(private_key, signature, digest, 20) < 0) { log_fn(LOG_WARN,"couldn't sign digest"); + tor_free(buf); return -1; } log(LOG_DEBUG,"generated directory digest begins with %s",hex_str(digest,4)); - if (strlcat(cp, "-----BEGIN SIGNATURE-----\n", maxlen) >= maxlen) + if (strlcat(cp, "-----BEGIN SIGNATURE-----\n", buf_len) >= buf_len) goto truncated; - i = strlen(s); - cp = s+i; - if (base64_encode(cp, maxlen-i, signature, 128) < 0) { + i = strlen(buf); + cp = buf+i; + if (base64_encode(cp, buf_len-i, signature, 128) < 0) { log_fn(LOG_WARN,"couldn't base64-encode signature"); + tor_free(buf); return -1; } - if (strlcat(s, "-----END SIGNATURE-----\n", maxlen) >= maxlen) + if (strlcat(buf, "-----END SIGNATURE-----\n", buf_len) >= buf_len) goto truncated; + *dir_out = buf; return 0; truncated: log_fn(LOG_WARN,"tried to exceed string length."); + tor_free(buf); return -1; } @@ -774,10 +794,9 @@ size_t dirserv_get_directory(const char **directory, int compress) */ static int dirserv_regenerate_directory(void) { - char *new_directory; + char *new_directory=NULL; - new_directory = tor_malloc(MAX_DIR_SIZE); - if (dirserv_dump_directory_to_string(new_directory, MAX_DIR_SIZE, + if (dirserv_dump_directory_to_string(&new_directory, get_identity_key())) { log(LOG_WARN, "Error creating directory."); tor_free(new_directory); diff --git a/src/or/or.h b/src/or/or.h index 59bf131ce4..bc4d4f093d 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -1331,7 +1331,7 @@ int dirserv_add_descriptor(const char **desc); int dirserv_load_from_directory_string(const char *dir); void dirserv_free_descriptors(void); void dirserv_remove_old_servers(int age); -int dirserv_dump_directory_to_string(char *s, size_t maxlen, +int dirserv_dump_directory_to_string(char **dir_out, crypto_pk_env_t *private_key); void directory_set_dirty(void); size_t dirserv_get_directory(const char **cp, int compress); diff --git a/src/or/test.c b/src/or/test.c index 817e571e92..2260f204b7 100644 --- a/src/or/test.c +++ b/src/or/test.c @@ -1164,11 +1164,11 @@ test_dir_format(void) cp = buf; test_eq(dirserv_add_descriptor((const char**)&cp), 1); get_options()->Nickname = tor_strdup("DirServer"); - test_assert(!dirserv_dump_directory_to_string(buf,8192,pk3)); - cp = buf; - test_assert(!router_parse_routerlist_from_directory(buf, &dir1, pk3, 1)); + test_assert(!dirserv_dump_directory_to_string(&cp,pk3)); + test_assert(!router_parse_routerlist_from_directory(cp, &dir1, pk3, 1)); test_eq(2, smartlist_len(dir1->routers)); dirserv_free_fingerprint_list(); + tor_free(cp); tor_free(pk1_str); tor_free(pk2_str); |