aboutsummaryrefslogtreecommitdiff
path: root/src/or/dirserv.c
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2015-01-30 07:36:55 -0500
committerNick Mathewson <nickm@torproject.org>2015-01-30 07:36:55 -0500
commitfac8d40886a03d442ed9f8c18df5ed017b1e6dd0 (patch)
treeebaa6185038792b896ce0f7fc147ef1a67f08599 /src/or/dirserv.c
parentd1e52d9a2a26c1bf9f80b237e692c72517c30495 (diff)
parentb4a8fd895802801198229574c55b3df975aa2244 (diff)
downloadtor-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.c86
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)