diff options
author | Nick Mathewson <nickm@torproject.org> | 2015-01-30 07:36:55 -0500 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2015-01-30 07:36:55 -0500 |
commit | fac8d40886a03d442ed9f8c18df5ed017b1e6dd0 (patch) | |
tree | ebaa6185038792b896ce0f7fc147ef1a67f08599 /src/or/dirserv.c | |
parent | d1e52d9a2a26c1bf9f80b237e692c72517c30495 (diff) | |
parent | b4a8fd895802801198229574c55b3df975aa2244 (diff) | |
download | tor-fac8d40886a03d442ed9f8c18df5ed017b1e6dd0.tar.gz tor-fac8d40886a03d442ed9f8c18df5ed017b1e6dd0.zip |
Merge remote-tracking branch 'public/prop227_v2'
Conflicts:
src/test/test_dir.c
Diffstat (limited to 'src/or/dirserv.c')
-rw-r--r-- | src/or/dirserv.c | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/src/or/dirserv.c b/src/or/dirserv.c index b694f8af77..0be2a2071e 100644 --- a/src/or/dirserv.c +++ b/src/or/dirserv.c @@ -2511,6 +2511,15 @@ dirserv_generate_networkstatus_vote_obj(crypto_pk_t *private_key, v3_out->client_versions = client_versions; v3_out->server_versions = server_versions; + v3_out->package_lines = smartlist_new(); + { + config_line_t *cl; + for (cl = get_options()->RecommendedPackages; cl; cl = cl->next) { + if (validate_recommended_package_line(cl->value)) + smartlist_add(v3_out->package_lines, tor_strdup(cl->value)); + } + } + v3_out->known_flags = smartlist_new(); smartlist_split_string(v3_out->known_flags, "Authority Exit Fast Guard Stable V2Dir Valid", @@ -3256,6 +3265,83 @@ connection_dirserv_flushed_some(dir_connection_t *conn) } } +/** Return true iff <b>line</b> is a valid RecommendedPackages line. + */ +/* + The grammar is: + + "package" SP PACKAGENAME SP VERSION SP URL SP DIGESTS NL + + PACKAGENAME = NONSPACE + VERSION = NONSPACE + URL = NONSPACE + DIGESTS = DIGEST | DIGESTS SP DIGEST + DIGEST = DIGESTTYPE "=" DIGESTVAL + + NONSPACE = one or more non-space printing characters + + DIGESTVAL = DIGESTTYPE = one or more non-=, non-" " characters. + + SP = " " + NL = a newline + + */ +int +validate_recommended_package_line(const char *line) +{ + const char *cp = line; + +#define WORD() \ + do { \ + if (*cp == ' ') \ + return 0; \ + cp = strchr(cp, ' '); \ + if (!cp) \ + return 0; \ + } while (0) + + WORD(); /* skip packagename */ + ++cp; + WORD(); /* skip version */ + ++cp; + WORD(); /* Skip URL */ + ++cp; + + /* Skip digesttype=digestval + */ + int n_entries = 0; + while (1) { + const char *start_of_word = cp; + const char *end_of_word = strchr(cp, ' '); + if (! end_of_word) + end_of_word = cp + strlen(cp); + + if (start_of_word == end_of_word) + return 0; + + const char *eq = memchr(start_of_word, '=', end_of_word - start_of_word); + + if (!eq) + return 0; + if (eq == start_of_word) + return 0; + if (eq == end_of_word - 1) + return 0; + if (memchr(eq+1, '=', end_of_word - (eq+1))) + return 0; + + ++n_entries; + if (0 == *end_of_word) + break; + + cp = end_of_word + 1; + } + + if (n_entries == 0) + return 0; + + return 1; +} + /** Release all storage used by the directory server. */ void dirserv_free_all(void) |