summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2004-08-04 02:35:06 +0000
committerNick Mathewson <nickm@torproject.org>2004-08-04 02:35:06 +0000
commit78f12ffccaa27af6ed936fb5bb7e81e7b783e658 (patch)
tree0d18eef4ea3265a359c7dc29ea03ac07d4fe445b
parentd0cfbcf87599ce258a24ee460a1cf33e26dc61e9 (diff)
downloadtor-78f12ffccaa27af6ed936fb5bb7e81e7b783e658.tar.gz
tor-78f12ffccaa27af6ed936fb5bb7e81e7b783e658.zip
Bugfix: "Okay, I just shut down like you told me. Now let me verify your signature." Also fix error message when running over-new version.
svn:r2135
-rw-r--r--src/or/routerlist.c1
-rw-r--r--src/or/routerparse.c60
2 files changed, 41 insertions, 20 deletions
diff --git a/src/or/routerlist.c b/src/or/routerlist.c
index b0ec3a8ba4..e67502aa7f 100644
--- a/src/or/routerlist.c
+++ b/src/or/routerlist.c
@@ -610,7 +610,6 @@ int router_load_routerlist_from_directory(const char *s,
crypto_pk_env_t *pkey)
{
routerlist_t *new_list = NULL;
- check_software_version_against_directory(s, options.IgnoreVersion);
if (router_parse_routerlist_from_directory(s, &new_list, pkey)) {
log_fn(LOG_WARN, "Couldn't parse directory.");
return -1;
diff --git a/src/or/routerparse.c b/src/or/routerparse.c
index 60dc8683e9..e4db112150 100644
--- a/src/or/routerparse.c
+++ b/src/or/routerparse.c
@@ -16,6 +16,8 @@
/****************************************************************************/
+extern or_options_t options; /* command-line and config-file options */
+
/** Enumeration of possible token types. The ones starting with K_
* correspond to directory 'keywords'. _UNRECOGNIZED is for an
* unrecognized keyword; _ERR is an error in the tokenizing process,
@@ -229,10 +231,13 @@ get_recommended_software_from_directory(const char *str)
* ignored.) */
/* static */ int is_obsolete_version(const char *myversion,
const char *versionlist) {
+ const char *vl;
char *version, *comma, *cp;
tor_version_t mine, other;
int found_newer = 0, r;
+ vl = versionlist;
+
log_fn(LOG_DEBUG,"checking '%s' in '%s'.", myversion, versionlist);
if (tor_version_parse(myversion, &mine)) {
@@ -241,9 +246,8 @@ get_recommended_software_from_directory(const char *str)
}
for(;;) {
- comma = strchr(versionlist, ',');
- version = tor_strndup(versionlist,
- comma?(comma-versionlist):strlen(versionlist));
+ comma = strchr(vl, ',');
+ version = tor_strndup(vl, comma?(comma-vl):strlen(vl));
cp = version;
while (isspace(*cp))
++cp;
@@ -263,7 +267,7 @@ get_recommended_software_from_directory(const char *str)
}
tor_free(version);
if (comma)
- versionlist = comma+1;
+ vl = comma+1;
else
break;
}
@@ -324,7 +328,7 @@ router_parse_routerlist_from_directory(const char *str,
smartlist_t *good_nickname_list = NULL;
time_t published_on;
int i, r;
- const char *end;
+ const char *end, *cp;
smartlist_t *tokens = NULL;
if (router_get_dir_hash(str, digest)) {
@@ -333,6 +337,37 @@ router_parse_routerlist_from_directory(const char *str,
}
log_fn(LOG_DEBUG,"Received directory hashes to %s",hex_str(digest,4));
+ /* Check signature first, before we try to tokenize. */
+ cp = str;
+ while (cp && (end = strstr(cp+1, "\ndirectory-signature")))
+ cp = end;
+ if (cp == str || !cp) {
+ log_fn(LOG_WARN, "No signature found on directory."); goto err;
+ }
+ ++cp;
+ tokens = smartlist_create();
+ if (tokenize_string(cp,strchr(cp,'\0'),tokens,1)) {
+ log_fn(LOG_WARN, "Error tokenizing directory signature"); goto err;
+ }
+ if (smartlist_len(tokens) != 1) {
+ log_fn(LOG_WARN, "Unexpected number of tokens in signature"); goto err;
+ }
+ if (smartlist_len(tokens) != 1 ||
+ (!(tok=smartlist_get(tokens,0))) || /* always succeeds */
+ (tok->tp != K_DIRECTORY_SIGNATURE)) {
+ log_fn(LOG_WARN,"Expected a single directory signature"); goto err;
+ }
+ if (check_directory_signature(digest, smartlist_get(tokens,0), pkey)<0) {
+ goto err;
+ }
+ SMARTLIST_FOREACH(tokens, directory_token_t *, tok, token_free(tok));
+ smartlist_free(tokens);
+ tokens = NULL;
+
+ /* Now that we know the signature is okay, check the version. */
+ check_software_version_against_directory(str, options.IgnoreVersion);
+
+ /* Now try to parse the first part of the directory. */
if ((end = strstr(str,"\nrouter "))) {
++end;
} else if ((end = strstr(str, "\ndirectory-signature"))) {
@@ -404,20 +439,7 @@ router_parse_routerlist_from_directory(const char *str,
SMARTLIST_FOREACH(tokens, directory_token_t *, tok, token_free(tok));
smartlist_free(tokens);
-
- tokens = smartlist_create();
- if (tokenize_string(str,str+strlen(str),tokens,1)<0) {
- log_fn(LOG_WARN, "Error tokenizing signature"); goto err;
- }
-
- if (smartlist_len(tokens) != 1 ||
- (!(tok=smartlist_get(tokens,0))) || /* always succeeds */
- (tok->tp != K_DIRECTORY_SIGNATURE)) {
- log_fn(LOG_WARN,"Expected a single directory signature"); goto err;
- }
- if (check_directory_signature(digest, smartlist_get(tokens,0), pkey)<0) {
- goto err;
- }
+ tokens = NULL;
/* Determine if my routerinfo is considered verified. */
{