ns_parse.c 59 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685
  1. /* Copyright (c) 2001 Matej Pfajfar.
  2. * Copyright (c) 2001-2004, Roger Dingledine.
  3. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
  4. * Copyright (c) 2007-2018, The Tor Project, Inc. */
  5. /* See LICENSE for licensing information */
  6. /**
  7. * \file routerparse.c
  8. * \brief Code to parse and validate consensus documents and votes.
  9. */
  10. #define NS_PARSE_PRIVATE
  11. #include "core/or/or.h"
  12. #include "app/config/config.h"
  13. #include "core/or/versions.h"
  14. #include "feature/client/entrynodes.h"
  15. #include "feature/dirauth/dirvote.h"
  16. #include "feature/dirparse/authcert_parse.h"
  17. #include "feature/dirparse/ns_parse.h"
  18. #include "feature/dirparse/parsecommon.h"
  19. #include "feature/dirparse/routerparse.h"
  20. #include "feature/dirparse/sigcommon.h"
  21. #include "feature/dirparse/unparseable.h"
  22. #include "feature/hs_common/shared_random_client.h"
  23. #include "feature/nodelist/authcert.h"
  24. #include "feature/nodelist/describe.h"
  25. #include "feature/nodelist/networkstatus.h"
  26. #include "feature/nodelist/nickname.h"
  27. #include "lib/crypt_ops/crypto_format.h"
  28. #include "lib/memarea/memarea.h"
  29. #include "feature/dirauth/vote_microdesc_hash_st.h"
  30. #include "feature/nodelist/authority_cert_st.h"
  31. #include "feature/nodelist/document_signature_st.h"
  32. #include "feature/nodelist/networkstatus_st.h"
  33. #include "feature/nodelist/networkstatus_voter_info_st.h"
  34. #include "feature/nodelist/vote_routerstatus_st.h"
  35. #undef log
  36. #include <math.h>
  37. /** List of tokens recognized in the body part of v3 networkstatus
  38. * documents. */
  39. static token_rule_t rtrstatus_token_table[] = {
  40. T01("p", K_P, CONCAT_ARGS, NO_OBJ ),
  41. T1( "r", K_R, GE(7), NO_OBJ ),
  42. T0N("a", K_A, GE(1), NO_OBJ ),
  43. T1( "s", K_S, ARGS, NO_OBJ ),
  44. T01("v", K_V, CONCAT_ARGS, NO_OBJ ),
  45. T01("w", K_W, ARGS, NO_OBJ ),
  46. T0N("m", K_M, CONCAT_ARGS, NO_OBJ ),
  47. T0N("id", K_ID, GE(2), NO_OBJ ),
  48. T01("pr", K_PROTO, CONCAT_ARGS, NO_OBJ ),
  49. T0N("opt", K_OPT, CONCAT_ARGS, OBJ_OK ),
  50. END_OF_TABLE
  51. };
  52. /** List of tokens recognized in V3 networkstatus votes. */
  53. static token_rule_t networkstatus_token_table[] = {
  54. T1_START("network-status-version", K_NETWORK_STATUS_VERSION,
  55. GE(1), NO_OBJ ),
  56. T1("vote-status", K_VOTE_STATUS, GE(1), NO_OBJ ),
  57. T1("published", K_PUBLISHED, CONCAT_ARGS, NO_OBJ ),
  58. T1("valid-after", K_VALID_AFTER, CONCAT_ARGS, NO_OBJ ),
  59. T1("fresh-until", K_FRESH_UNTIL, CONCAT_ARGS, NO_OBJ ),
  60. T1("valid-until", K_VALID_UNTIL, CONCAT_ARGS, NO_OBJ ),
  61. T1("voting-delay", K_VOTING_DELAY, GE(2), NO_OBJ ),
  62. T1("known-flags", K_KNOWN_FLAGS, ARGS, NO_OBJ ),
  63. T01("params", K_PARAMS, ARGS, NO_OBJ ),
  64. T( "fingerprint", K_FINGERPRINT, CONCAT_ARGS, NO_OBJ ),
  65. T01("signing-ed25519", K_SIGNING_CERT_ED, NO_ARGS , NEED_OBJ ),
  66. T01("shared-rand-participate",K_SR_FLAG, NO_ARGS, NO_OBJ ),
  67. T0N("shared-rand-commit", K_COMMIT, GE(3), NO_OBJ ),
  68. T01("shared-rand-previous-value", K_PREVIOUS_SRV,EQ(2), NO_OBJ ),
  69. T01("shared-rand-current-value", K_CURRENT_SRV, EQ(2), NO_OBJ ),
  70. T0N("package", K_PACKAGE, CONCAT_ARGS, NO_OBJ ),
  71. T01("recommended-client-protocols", K_RECOMMENDED_CLIENT_PROTOCOLS,
  72. CONCAT_ARGS, NO_OBJ ),
  73. T01("recommended-relay-protocols", K_RECOMMENDED_RELAY_PROTOCOLS,
  74. CONCAT_ARGS, NO_OBJ ),
  75. T01("required-client-protocols", K_REQUIRED_CLIENT_PROTOCOLS,
  76. CONCAT_ARGS, NO_OBJ ),
  77. T01("required-relay-protocols", K_REQUIRED_RELAY_PROTOCOLS,
  78. CONCAT_ARGS, NO_OBJ ),
  79. #include "feature/dirparse/authcert_members.i"
  80. T0N("opt", K_OPT, CONCAT_ARGS, OBJ_OK ),
  81. T1( "contact", K_CONTACT, CONCAT_ARGS, NO_OBJ ),
  82. T1( "dir-source", K_DIR_SOURCE, GE(6), NO_OBJ ),
  83. T01("legacy-dir-key", K_LEGACY_DIR_KEY, GE(1), NO_OBJ ),
  84. T1( "known-flags", K_KNOWN_FLAGS, CONCAT_ARGS, NO_OBJ ),
  85. T01("client-versions", K_CLIENT_VERSIONS, CONCAT_ARGS, NO_OBJ ),
  86. T01("server-versions", K_SERVER_VERSIONS, CONCAT_ARGS, NO_OBJ ),
  87. T1( "consensus-methods", K_CONSENSUS_METHODS, GE(1), NO_OBJ ),
  88. END_OF_TABLE
  89. };
  90. /** List of tokens recognized in V3 networkstatus consensuses. */
  91. static token_rule_t networkstatus_consensus_token_table[] = {
  92. T1_START("network-status-version", K_NETWORK_STATUS_VERSION,
  93. GE(1), NO_OBJ ),
  94. T1("vote-status", K_VOTE_STATUS, GE(1), NO_OBJ ),
  95. T1("valid-after", K_VALID_AFTER, CONCAT_ARGS, NO_OBJ ),
  96. T1("fresh-until", K_FRESH_UNTIL, CONCAT_ARGS, NO_OBJ ),
  97. T1("valid-until", K_VALID_UNTIL, CONCAT_ARGS, NO_OBJ ),
  98. T1("voting-delay", K_VOTING_DELAY, GE(2), NO_OBJ ),
  99. T0N("opt", K_OPT, CONCAT_ARGS, OBJ_OK ),
  100. T1N("dir-source", K_DIR_SOURCE, GE(6), NO_OBJ ),
  101. T1N("contact", K_CONTACT, CONCAT_ARGS, NO_OBJ ),
  102. T1N("vote-digest", K_VOTE_DIGEST, GE(1), NO_OBJ ),
  103. T1( "known-flags", K_KNOWN_FLAGS, CONCAT_ARGS, NO_OBJ ),
  104. T01("client-versions", K_CLIENT_VERSIONS, CONCAT_ARGS, NO_OBJ ),
  105. T01("server-versions", K_SERVER_VERSIONS, CONCAT_ARGS, NO_OBJ ),
  106. T01("consensus-method", K_CONSENSUS_METHOD, EQ(1), NO_OBJ),
  107. T01("params", K_PARAMS, ARGS, NO_OBJ ),
  108. T01("shared-rand-previous-value", K_PREVIOUS_SRV, EQ(2), NO_OBJ ),
  109. T01("shared-rand-current-value", K_CURRENT_SRV, EQ(2), NO_OBJ ),
  110. T01("recommended-client-protocols", K_RECOMMENDED_CLIENT_PROTOCOLS,
  111. CONCAT_ARGS, NO_OBJ ),
  112. T01("recommended-relay-protocols", K_RECOMMENDED_RELAY_PROTOCOLS,
  113. CONCAT_ARGS, NO_OBJ ),
  114. T01("required-client-protocols", K_REQUIRED_CLIENT_PROTOCOLS,
  115. CONCAT_ARGS, NO_OBJ ),
  116. T01("required-relay-protocols", K_REQUIRED_RELAY_PROTOCOLS,
  117. CONCAT_ARGS, NO_OBJ ),
  118. END_OF_TABLE
  119. };
  120. /** List of tokens recognized in the footer of v1 directory footers. */
  121. static token_rule_t networkstatus_vote_footer_token_table[] = {
  122. T01("directory-footer", K_DIRECTORY_FOOTER, NO_ARGS, NO_OBJ ),
  123. T01("bandwidth-weights", K_BW_WEIGHTS, ARGS, NO_OBJ ),
  124. T( "directory-signature", K_DIRECTORY_SIGNATURE, GE(2), NEED_OBJ ),
  125. END_OF_TABLE
  126. };
  127. /** Try to find the start and end of the signed portion of a networkstatus
  128. * document in <b>s</b>. On success, set <b>start_out</b> to the first
  129. * character of the document, and <b>end_out</b> to a position one after the
  130. * final character of the signed document, and return 0. On failure, return
  131. * -1. */
  132. int
  133. router_get_networkstatus_v3_signed_boundaries(const char *s,
  134. const char **start_out,
  135. const char **end_out)
  136. {
  137. return router_get_hash_impl_helper(s, strlen(s),
  138. "network-status-version",
  139. "\ndirectory-signature",
  140. ' ', LOG_INFO,
  141. start_out, end_out);
  142. }
  143. /** Set <b>digest_out</b> to the SHA3-256 digest of the signed portion of the
  144. * networkstatus vote in <b>s</b> -- or of the entirety of <b>s</b> if no
  145. * signed portion can be identified. Return 0 on success, -1 on failure. */
  146. int
  147. router_get_networkstatus_v3_sha3_as_signed(uint8_t *digest_out,
  148. const char *s)
  149. {
  150. const char *start, *end;
  151. if (router_get_networkstatus_v3_signed_boundaries(s, &start, &end) < 0) {
  152. start = s;
  153. end = s + strlen(s);
  154. }
  155. tor_assert(start);
  156. tor_assert(end);
  157. return crypto_digest256((char*)digest_out, start, end-start,
  158. DIGEST_SHA3_256);
  159. }
  160. /** Set <b>digests</b> to all the digests of the consensus document in
  161. * <b>s</b> */
  162. int
  163. router_get_networkstatus_v3_hashes(const char *s, common_digests_t *digests)
  164. {
  165. return router_get_hashes_impl(s,strlen(s),digests,
  166. "network-status-version",
  167. "\ndirectory-signature",
  168. ' ');
  169. }
  170. /** Helper: given a string <b>s</b>, return the start of the next router-status
  171. * object (starting with "r " at the start of a line). If none is found,
  172. * return the start of the directory footer, or the next directory signature.
  173. * If none is found, return the end of the string. */
  174. static inline const char *
  175. find_start_of_next_routerstatus(const char *s)
  176. {
  177. const char *eos, *footer, *sig;
  178. if ((eos = strstr(s, "\nr ")))
  179. ++eos;
  180. else
  181. eos = s + strlen(s);
  182. footer = tor_memstr(s, eos-s, "\ndirectory-footer");
  183. sig = tor_memstr(s, eos-s, "\ndirectory-signature");
  184. if (footer && sig)
  185. return MIN(footer, sig) + 1;
  186. else if (footer)
  187. return footer+1;
  188. else if (sig)
  189. return sig+1;
  190. else
  191. return eos;
  192. }
  193. /** Parse the GuardFraction string from a consensus or vote.
  194. *
  195. * If <b>vote</b> or <b>vote_rs</b> are set the document getting
  196. * parsed is a vote routerstatus. Otherwise it's a consensus. This is
  197. * the same semantic as in routerstatus_parse_entry_from_string(). */
  198. STATIC int
  199. routerstatus_parse_guardfraction(const char *guardfraction_str,
  200. networkstatus_t *vote,
  201. vote_routerstatus_t *vote_rs,
  202. routerstatus_t *rs)
  203. {
  204. int ok;
  205. const char *end_of_header = NULL;
  206. int is_consensus = !vote_rs;
  207. uint32_t guardfraction;
  208. tor_assert(bool_eq(vote, vote_rs));
  209. /* If this info comes from a consensus, but we should't apply
  210. guardfraction, just exit. */
  211. if (is_consensus && !should_apply_guardfraction(NULL)) {
  212. return 0;
  213. }
  214. end_of_header = strchr(guardfraction_str, '=');
  215. if (!end_of_header) {
  216. return -1;
  217. }
  218. guardfraction = (uint32_t)tor_parse_ulong(end_of_header+1,
  219. 10, 0, 100, &ok, NULL);
  220. if (!ok) {
  221. log_warn(LD_DIR, "Invalid GuardFraction %s", escaped(guardfraction_str));
  222. return -1;
  223. }
  224. log_debug(LD_GENERAL, "[*] Parsed %s guardfraction '%s' for '%s'.",
  225. is_consensus ? "consensus" : "vote",
  226. guardfraction_str, rs->nickname);
  227. if (!is_consensus) { /* We are parsing a vote */
  228. vote_rs->status.guardfraction_percentage = guardfraction;
  229. vote_rs->status.has_guardfraction = 1;
  230. } else {
  231. /* We are parsing a consensus. Only apply guardfraction to guards. */
  232. if (rs->is_possible_guard) {
  233. rs->guardfraction_percentage = guardfraction;
  234. rs->has_guardfraction = 1;
  235. } else {
  236. log_warn(LD_BUG, "Got GuardFraction for non-guard %s. "
  237. "This is not supposed to happen. Not applying. ", rs->nickname);
  238. }
  239. }
  240. return 0;
  241. }
  242. /** Given a string at *<b>s</b>, containing a routerstatus object, and an
  243. * empty smartlist at <b>tokens</b>, parse and return the first router status
  244. * object in the string, and advance *<b>s</b> to just after the end of the
  245. * router status. Return NULL and advance *<b>s</b> on error.
  246. *
  247. * If <b>vote</b> and <b>vote_rs</b> are provided, don't allocate a fresh
  248. * routerstatus but use <b>vote_rs</b> instead.
  249. *
  250. * If <b>consensus_method</b> is nonzero, this routerstatus is part of a
  251. * consensus, and we should parse it according to the method used to
  252. * make that consensus.
  253. *
  254. * Parse according to the syntax used by the consensus flavor <b>flav</b>.
  255. **/
  256. STATIC routerstatus_t *
  257. routerstatus_parse_entry_from_string(memarea_t *area,
  258. const char **s, smartlist_t *tokens,
  259. networkstatus_t *vote,
  260. vote_routerstatus_t *vote_rs,
  261. int consensus_method,
  262. consensus_flavor_t flav)
  263. {
  264. const char *eos, *s_dup = *s;
  265. routerstatus_t *rs = NULL;
  266. directory_token_t *tok;
  267. char timebuf[ISO_TIME_LEN+1];
  268. struct in_addr in;
  269. int offset = 0;
  270. tor_assert(tokens);
  271. tor_assert(bool_eq(vote, vote_rs));
  272. if (!consensus_method)
  273. flav = FLAV_NS;
  274. tor_assert(flav == FLAV_NS || flav == FLAV_MICRODESC);
  275. eos = find_start_of_next_routerstatus(*s);
  276. if (tokenize_string(area,*s, eos, tokens, rtrstatus_token_table,0)) {
  277. log_warn(LD_DIR, "Error tokenizing router status");
  278. goto err;
  279. }
  280. if (smartlist_len(tokens) < 1) {
  281. log_warn(LD_DIR, "Impossibly short router status");
  282. goto err;
  283. }
  284. tok = find_by_keyword(tokens, K_R);
  285. tor_assert(tok->n_args >= 7); /* guaranteed by GE(7) in K_R setup */
  286. if (flav == FLAV_NS) {
  287. if (tok->n_args < 8) {
  288. log_warn(LD_DIR, "Too few arguments to r");
  289. goto err;
  290. }
  291. } else if (flav == FLAV_MICRODESC) {
  292. offset = -1; /* There is no descriptor digest in an md consensus r line */
  293. }
  294. if (vote_rs) {
  295. rs = &vote_rs->status;
  296. } else {
  297. rs = tor_malloc_zero(sizeof(routerstatus_t));
  298. }
  299. if (!is_legal_nickname(tok->args[0])) {
  300. log_warn(LD_DIR,
  301. "Invalid nickname %s in router status; skipping.",
  302. escaped(tok->args[0]));
  303. goto err;
  304. }
  305. strlcpy(rs->nickname, tok->args[0], sizeof(rs->nickname));
  306. if (digest_from_base64(rs->identity_digest, tok->args[1])) {
  307. log_warn(LD_DIR, "Error decoding identity digest %s",
  308. escaped(tok->args[1]));
  309. goto err;
  310. }
  311. if (flav == FLAV_NS) {
  312. if (digest_from_base64(rs->descriptor_digest, tok->args[2])) {
  313. log_warn(LD_DIR, "Error decoding descriptor digest %s",
  314. escaped(tok->args[2]));
  315. goto err;
  316. }
  317. }
  318. if (tor_snprintf(timebuf, sizeof(timebuf), "%s %s",
  319. tok->args[3+offset], tok->args[4+offset]) < 0 ||
  320. parse_iso_time(timebuf, &rs->published_on)<0) {
  321. log_warn(LD_DIR, "Error parsing time '%s %s' [%d %d]",
  322. tok->args[3+offset], tok->args[4+offset],
  323. offset, (int)flav);
  324. goto err;
  325. }
  326. if (tor_inet_aton(tok->args[5+offset], &in) == 0) {
  327. log_warn(LD_DIR, "Error parsing router address in network-status %s",
  328. escaped(tok->args[5+offset]));
  329. goto err;
  330. }
  331. rs->addr = ntohl(in.s_addr);
  332. rs->or_port = (uint16_t) tor_parse_long(tok->args[6+offset],
  333. 10,0,65535,NULL,NULL);
  334. rs->dir_port = (uint16_t) tor_parse_long(tok->args[7+offset],
  335. 10,0,65535,NULL,NULL);
  336. {
  337. smartlist_t *a_lines = find_all_by_keyword(tokens, K_A);
  338. if (a_lines) {
  339. find_single_ipv6_orport(a_lines, &rs->ipv6_addr, &rs->ipv6_orport);
  340. smartlist_free(a_lines);
  341. }
  342. }
  343. tok = find_opt_by_keyword(tokens, K_S);
  344. if (tok && vote) {
  345. int i;
  346. vote_rs->flags = 0;
  347. for (i=0; i < tok->n_args; ++i) {
  348. int p = smartlist_string_pos(vote->known_flags, tok->args[i]);
  349. if (p >= 0) {
  350. vote_rs->flags |= (UINT64_C(1)<<p);
  351. } else {
  352. log_warn(LD_DIR, "Flags line had a flag %s not listed in known_flags.",
  353. escaped(tok->args[i]));
  354. goto err;
  355. }
  356. }
  357. } else if (tok) {
  358. /* This is a consensus, not a vote. */
  359. int i;
  360. for (i=0; i < tok->n_args; ++i) {
  361. if (!strcmp(tok->args[i], "Exit"))
  362. rs->is_exit = 1;
  363. else if (!strcmp(tok->args[i], "Stable"))
  364. rs->is_stable = 1;
  365. else if (!strcmp(tok->args[i], "Fast"))
  366. rs->is_fast = 1;
  367. else if (!strcmp(tok->args[i], "Running"))
  368. rs->is_flagged_running = 1;
  369. else if (!strcmp(tok->args[i], "Named"))
  370. rs->is_named = 1;
  371. else if (!strcmp(tok->args[i], "Valid"))
  372. rs->is_valid = 1;
  373. else if (!strcmp(tok->args[i], "Guard"))
  374. rs->is_possible_guard = 1;
  375. else if (!strcmp(tok->args[i], "BadExit"))
  376. rs->is_bad_exit = 1;
  377. else if (!strcmp(tok->args[i], "Authority"))
  378. rs->is_authority = 1;
  379. else if (!strcmp(tok->args[i], "Unnamed") &&
  380. consensus_method >= 2) {
  381. /* Unnamed is computed right by consensus method 2 and later. */
  382. rs->is_unnamed = 1;
  383. } else if (!strcmp(tok->args[i], "HSDir")) {
  384. rs->is_hs_dir = 1;
  385. } else if (!strcmp(tok->args[i], "V2Dir")) {
  386. rs->is_v2_dir = 1;
  387. }
  388. }
  389. /* These are implied true by having been included in a consensus made
  390. * with a given method */
  391. rs->is_flagged_running = 1; /* Starting with consensus method 4. */
  392. rs->is_valid = 1; /* Starting with consensus method 24. */
  393. }
  394. {
  395. const char *protocols = NULL, *version = NULL;
  396. if ((tok = find_opt_by_keyword(tokens, K_PROTO))) {
  397. tor_assert(tok->n_args == 1);
  398. protocols = tok->args[0];
  399. }
  400. if ((tok = find_opt_by_keyword(tokens, K_V))) {
  401. tor_assert(tok->n_args == 1);
  402. version = tok->args[0];
  403. if (vote_rs) {
  404. vote_rs->version = tor_strdup(tok->args[0]);
  405. }
  406. }
  407. summarize_protover_flags(&rs->pv, protocols, version);
  408. }
  409. /* handle weighting/bandwidth info */
  410. if ((tok = find_opt_by_keyword(tokens, K_W))) {
  411. int i;
  412. for (i=0; i < tok->n_args; ++i) {
  413. if (!strcmpstart(tok->args[i], "Bandwidth=")) {
  414. int ok;
  415. rs->bandwidth_kb =
  416. (uint32_t)tor_parse_ulong(strchr(tok->args[i], '=')+1,
  417. 10, 0, UINT32_MAX,
  418. &ok, NULL);
  419. if (!ok) {
  420. log_warn(LD_DIR, "Invalid Bandwidth %s", escaped(tok->args[i]));
  421. goto err;
  422. }
  423. rs->has_bandwidth = 1;
  424. } else if (!strcmpstart(tok->args[i], "Measured=") && vote_rs) {
  425. int ok;
  426. vote_rs->measured_bw_kb =
  427. (uint32_t)tor_parse_ulong(strchr(tok->args[i], '=')+1,
  428. 10, 0, UINT32_MAX, &ok, NULL);
  429. if (!ok) {
  430. log_warn(LD_DIR, "Invalid Measured Bandwidth %s",
  431. escaped(tok->args[i]));
  432. goto err;
  433. }
  434. vote_rs->has_measured_bw = 1;
  435. vote->has_measured_bws = 1;
  436. } else if (!strcmpstart(tok->args[i], "Unmeasured=1")) {
  437. rs->bw_is_unmeasured = 1;
  438. } else if (!strcmpstart(tok->args[i], "GuardFraction=")) {
  439. if (routerstatus_parse_guardfraction(tok->args[i],
  440. vote, vote_rs, rs) < 0) {
  441. goto err;
  442. }
  443. }
  444. }
  445. }
  446. /* parse exit policy summaries */
  447. if ((tok = find_opt_by_keyword(tokens, K_P))) {
  448. tor_assert(tok->n_args == 1);
  449. if (strcmpstart(tok->args[0], "accept ") &&
  450. strcmpstart(tok->args[0], "reject ")) {
  451. log_warn(LD_DIR, "Unknown exit policy summary type %s.",
  452. escaped(tok->args[0]));
  453. goto err;
  454. }
  455. /* XXX weasel: parse this into ports and represent them somehow smart,
  456. * maybe not here but somewhere on if we need it for the client.
  457. * we should still parse it here to check it's valid tho.
  458. */
  459. rs->exitsummary = tor_strdup(tok->args[0]);
  460. rs->has_exitsummary = 1;
  461. }
  462. if (vote_rs) {
  463. SMARTLIST_FOREACH_BEGIN(tokens, directory_token_t *, t) {
  464. if (t->tp == K_M && t->n_args) {
  465. vote_microdesc_hash_t *line =
  466. tor_malloc(sizeof(vote_microdesc_hash_t));
  467. line->next = vote_rs->microdesc;
  468. line->microdesc_hash_line = tor_strdup(t->args[0]);
  469. vote_rs->microdesc = line;
  470. }
  471. if (t->tp == K_ID) {
  472. tor_assert(t->n_args >= 2);
  473. if (!strcmp(t->args[0], "ed25519")) {
  474. vote_rs->has_ed25519_listing = 1;
  475. if (strcmp(t->args[1], "none") &&
  476. digest256_from_base64((char*)vote_rs->ed25519_id,
  477. t->args[1])<0) {
  478. log_warn(LD_DIR, "Bogus ed25519 key in networkstatus vote");
  479. goto err;
  480. }
  481. }
  482. }
  483. if (t->tp == K_PROTO) {
  484. tor_assert(t->n_args == 1);
  485. vote_rs->protocols = tor_strdup(t->args[0]);
  486. }
  487. } SMARTLIST_FOREACH_END(t);
  488. } else if (flav == FLAV_MICRODESC) {
  489. tok = find_opt_by_keyword(tokens, K_M);
  490. if (tok) {
  491. tor_assert(tok->n_args);
  492. if (digest256_from_base64(rs->descriptor_digest, tok->args[0])) {
  493. log_warn(LD_DIR, "Error decoding microdescriptor digest %s",
  494. escaped(tok->args[0]));
  495. goto err;
  496. }
  497. } else {
  498. log_info(LD_BUG, "Found an entry in networkstatus with no "
  499. "microdescriptor digest. (Router %s ($%s) at %s:%d.)",
  500. rs->nickname, hex_str(rs->identity_digest, DIGEST_LEN),
  501. fmt_addr32(rs->addr), rs->or_port);
  502. }
  503. }
  504. if (!strcasecmp(rs->nickname, UNNAMED_ROUTER_NICKNAME))
  505. rs->is_named = 0;
  506. goto done;
  507. err:
  508. dump_desc(s_dup, "routerstatus entry");
  509. if (rs && !vote_rs)
  510. routerstatus_free(rs);
  511. rs = NULL;
  512. done:
  513. SMARTLIST_FOREACH(tokens, directory_token_t *, t, token_clear(t));
  514. smartlist_clear(tokens);
  515. if (area) {
  516. DUMP_AREA(area, "routerstatus entry");
  517. memarea_clear(area);
  518. }
  519. *s = eos;
  520. return rs;
  521. }
  522. int
  523. compare_vote_routerstatus_entries(const void **_a, const void **_b)
  524. {
  525. const vote_routerstatus_t *a = *_a, *b = *_b;
  526. return fast_memcmp(a->status.identity_digest, b->status.identity_digest,
  527. DIGEST_LEN);
  528. }
  529. /** Verify the bandwidth weights of a network status document */
  530. int
  531. networkstatus_verify_bw_weights(networkstatus_t *ns, int consensus_method)
  532. {
  533. int64_t G=0, M=0, E=0, D=0, T=0;
  534. double Wgg, Wgm, Wgd, Wmg, Wmm, Wme, Wmd, Weg, Wem, Wee, Wed;
  535. double Gtotal=0, Mtotal=0, Etotal=0;
  536. const char *casename = NULL;
  537. int valid = 1;
  538. (void) consensus_method;
  539. const int64_t weight_scale = networkstatus_get_weight_scale_param(ns);
  540. tor_assert(weight_scale >= 1);
  541. Wgg = networkstatus_get_bw_weight(ns, "Wgg", -1);
  542. Wgm = networkstatus_get_bw_weight(ns, "Wgm", -1);
  543. Wgd = networkstatus_get_bw_weight(ns, "Wgd", -1);
  544. Wmg = networkstatus_get_bw_weight(ns, "Wmg", -1);
  545. Wmm = networkstatus_get_bw_weight(ns, "Wmm", -1);
  546. Wme = networkstatus_get_bw_weight(ns, "Wme", -1);
  547. Wmd = networkstatus_get_bw_weight(ns, "Wmd", -1);
  548. Weg = networkstatus_get_bw_weight(ns, "Weg", -1);
  549. Wem = networkstatus_get_bw_weight(ns, "Wem", -1);
  550. Wee = networkstatus_get_bw_weight(ns, "Wee", -1);
  551. Wed = networkstatus_get_bw_weight(ns, "Wed", -1);
  552. if (Wgg<0 || Wgm<0 || Wgd<0 || Wmg<0 || Wmm<0 || Wme<0 || Wmd<0 || Weg<0
  553. || Wem<0 || Wee<0 || Wed<0) {
  554. log_warn(LD_BUG, "No bandwidth weights produced in consensus!");
  555. return 0;
  556. }
  557. // First, sanity check basic summing properties that hold for all cases
  558. // We use > 1 as the check for these because they are computed as integers.
  559. // Sometimes there are rounding errors.
  560. if (fabs(Wmm - weight_scale) > 1) {
  561. log_warn(LD_BUG, "Wmm=%f != %"PRId64,
  562. Wmm, (weight_scale));
  563. valid = 0;
  564. }
  565. if (fabs(Wem - Wee) > 1) {
  566. log_warn(LD_BUG, "Wem=%f != Wee=%f", Wem, Wee);
  567. valid = 0;
  568. }
  569. if (fabs(Wgm - Wgg) > 1) {
  570. log_warn(LD_BUG, "Wgm=%f != Wgg=%f", Wgm, Wgg);
  571. valid = 0;
  572. }
  573. if (fabs(Weg - Wed) > 1) {
  574. log_warn(LD_BUG, "Wed=%f != Weg=%f", Wed, Weg);
  575. valid = 0;
  576. }
  577. if (fabs(Wgg + Wmg - weight_scale) > 0.001*weight_scale) {
  578. log_warn(LD_BUG, "Wgg=%f != %"PRId64" - Wmg=%f", Wgg,
  579. (weight_scale), Wmg);
  580. valid = 0;
  581. }
  582. if (fabs(Wee + Wme - weight_scale) > 0.001*weight_scale) {
  583. log_warn(LD_BUG, "Wee=%f != %"PRId64" - Wme=%f", Wee,
  584. (weight_scale), Wme);
  585. valid = 0;
  586. }
  587. if (fabs(Wgd + Wmd + Wed - weight_scale) > 0.001*weight_scale) {
  588. log_warn(LD_BUG, "Wgd=%f + Wmd=%f + Wed=%f != %"PRId64,
  589. Wgd, Wmd, Wed, (weight_scale));
  590. valid = 0;
  591. }
  592. Wgg /= weight_scale;
  593. Wgm /= weight_scale; (void) Wgm; // unused from here on.
  594. Wgd /= weight_scale;
  595. Wmg /= weight_scale;
  596. Wmm /= weight_scale;
  597. Wme /= weight_scale;
  598. Wmd /= weight_scale;
  599. Weg /= weight_scale; (void) Weg; // unused from here on.
  600. Wem /= weight_scale; (void) Wem; // unused from here on.
  601. Wee /= weight_scale;
  602. Wed /= weight_scale;
  603. // Then, gather G, M, E, D, T to determine case
  604. SMARTLIST_FOREACH_BEGIN(ns->routerstatus_list, routerstatus_t *, rs) {
  605. int is_exit = 0;
  606. /* Bug #2203: Don't count bad exits as exits for balancing */
  607. is_exit = rs->is_exit && !rs->is_bad_exit;
  608. if (rs->has_bandwidth) {
  609. T += rs->bandwidth_kb;
  610. if (is_exit && rs->is_possible_guard) {
  611. D += rs->bandwidth_kb;
  612. Gtotal += Wgd*rs->bandwidth_kb;
  613. Mtotal += Wmd*rs->bandwidth_kb;
  614. Etotal += Wed*rs->bandwidth_kb;
  615. } else if (is_exit) {
  616. E += rs->bandwidth_kb;
  617. Mtotal += Wme*rs->bandwidth_kb;
  618. Etotal += Wee*rs->bandwidth_kb;
  619. } else if (rs->is_possible_guard) {
  620. G += rs->bandwidth_kb;
  621. Gtotal += Wgg*rs->bandwidth_kb;
  622. Mtotal += Wmg*rs->bandwidth_kb;
  623. } else {
  624. M += rs->bandwidth_kb;
  625. Mtotal += Wmm*rs->bandwidth_kb;
  626. }
  627. } else {
  628. log_warn(LD_BUG, "Missing consensus bandwidth for router %s",
  629. routerstatus_describe(rs));
  630. }
  631. } SMARTLIST_FOREACH_END(rs);
  632. // Finally, check equality conditions depending upon case 1, 2 or 3
  633. // Full equality cases: 1, 3b
  634. // Partial equality cases: 2b (E=G), 3a (M=E)
  635. // Fully unknown: 2a
  636. if (3*E >= T && 3*G >= T) {
  637. // Case 1: Neither are scarce
  638. casename = "Case 1";
  639. if (fabs(Etotal-Mtotal) > 0.01*MAX(Etotal,Mtotal)) {
  640. log_warn(LD_DIR,
  641. "Bw Weight Failure for %s: Etotal %f != Mtotal %f. "
  642. "G=%"PRId64" M=%"PRId64" E=%"PRId64" D=%"PRId64
  643. " T=%"PRId64". "
  644. "Wgg=%f Wgd=%f Wmg=%f Wme=%f Wmd=%f Wee=%f Wed=%f",
  645. casename, Etotal, Mtotal,
  646. (G), (M), (E),
  647. (D), (T),
  648. Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
  649. valid = 0;
  650. }
  651. if (fabs(Etotal-Gtotal) > 0.01*MAX(Etotal,Gtotal)) {
  652. log_warn(LD_DIR,
  653. "Bw Weight Failure for %s: Etotal %f != Gtotal %f. "
  654. "G=%"PRId64" M=%"PRId64" E=%"PRId64" D=%"PRId64
  655. " T=%"PRId64". "
  656. "Wgg=%f Wgd=%f Wmg=%f Wme=%f Wmd=%f Wee=%f Wed=%f",
  657. casename, Etotal, Gtotal,
  658. (G), (M), (E),
  659. (D), (T),
  660. Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
  661. valid = 0;
  662. }
  663. if (fabs(Gtotal-Mtotal) > 0.01*MAX(Gtotal,Mtotal)) {
  664. log_warn(LD_DIR,
  665. "Bw Weight Failure for %s: Mtotal %f != Gtotal %f. "
  666. "G=%"PRId64" M=%"PRId64" E=%"PRId64" D=%"PRId64
  667. " T=%"PRId64". "
  668. "Wgg=%f Wgd=%f Wmg=%f Wme=%f Wmd=%f Wee=%f Wed=%f",
  669. casename, Mtotal, Gtotal,
  670. (G), (M), (E),
  671. (D), (T),
  672. Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
  673. valid = 0;
  674. }
  675. } else if (3*E < T && 3*G < T) {
  676. int64_t R = MIN(E, G);
  677. int64_t S = MAX(E, G);
  678. /*
  679. * Case 2: Both Guards and Exits are scarce
  680. * Balance D between E and G, depending upon
  681. * D capacity and scarcity. Devote no extra
  682. * bandwidth to middle nodes.
  683. */
  684. if (R+D < S) { // Subcase a
  685. double Rtotal, Stotal;
  686. if (E < G) {
  687. Rtotal = Etotal;
  688. Stotal = Gtotal;
  689. } else {
  690. Rtotal = Gtotal;
  691. Stotal = Etotal;
  692. }
  693. casename = "Case 2a";
  694. // Rtotal < Stotal
  695. if (Rtotal > Stotal) {
  696. log_warn(LD_DIR,
  697. "Bw Weight Failure for %s: Rtotal %f > Stotal %f. "
  698. "G=%"PRId64" M=%"PRId64" E=%"PRId64" D=%"PRId64
  699. " T=%"PRId64". "
  700. "Wgg=%f Wgd=%f Wmg=%f Wme=%f Wmd=%f Wee=%f Wed=%f",
  701. casename, Rtotal, Stotal,
  702. (G), (M), (E),
  703. (D), (T),
  704. Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
  705. valid = 0;
  706. }
  707. // Rtotal < T/3
  708. if (3*Rtotal > T) {
  709. log_warn(LD_DIR,
  710. "Bw Weight Failure for %s: 3*Rtotal %f > T "
  711. "%"PRId64". G=%"PRId64" M=%"PRId64" E=%"PRId64
  712. " D=%"PRId64" T=%"PRId64". "
  713. "Wgg=%f Wgd=%f Wmg=%f Wme=%f Wmd=%f Wee=%f Wed=%f",
  714. casename, Rtotal*3, (T),
  715. (G), (M), (E),
  716. (D), (T),
  717. Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
  718. valid = 0;
  719. }
  720. // Stotal < T/3
  721. if (3*Stotal > T) {
  722. log_warn(LD_DIR,
  723. "Bw Weight Failure for %s: 3*Stotal %f > T "
  724. "%"PRId64". G=%"PRId64" M=%"PRId64" E=%"PRId64
  725. " D=%"PRId64" T=%"PRId64". "
  726. "Wgg=%f Wgd=%f Wmg=%f Wme=%f Wmd=%f Wee=%f Wed=%f",
  727. casename, Stotal*3, (T),
  728. (G), (M), (E),
  729. (D), (T),
  730. Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
  731. valid = 0;
  732. }
  733. // Mtotal > T/3
  734. if (3*Mtotal < T) {
  735. log_warn(LD_DIR,
  736. "Bw Weight Failure for %s: 3*Mtotal %f < T "
  737. "%"PRId64". "
  738. "G=%"PRId64" M=%"PRId64" E=%"PRId64" D=%"PRId64
  739. " T=%"PRId64". "
  740. "Wgg=%f Wgd=%f Wmg=%f Wme=%f Wmd=%f Wee=%f Wed=%f",
  741. casename, Mtotal*3, (T),
  742. (G), (M), (E),
  743. (D), (T),
  744. Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
  745. valid = 0;
  746. }
  747. } else { // Subcase b: R+D > S
  748. casename = "Case 2b";
  749. /* Check the rare-M redirect case. */
  750. if (D != 0 && 3*M < T) {
  751. casename = "Case 2b (balanced)";
  752. if (fabs(Etotal-Mtotal) > 0.01*MAX(Etotal,Mtotal)) {
  753. log_warn(LD_DIR,
  754. "Bw Weight Failure for %s: Etotal %f != Mtotal %f. "
  755. "G=%"PRId64" M=%"PRId64" E=%"PRId64" D=%"PRId64
  756. " T=%"PRId64". "
  757. "Wgg=%f Wgd=%f Wmg=%f Wme=%f Wmd=%f Wee=%f Wed=%f",
  758. casename, Etotal, Mtotal,
  759. (G), (M), (E),
  760. (D), (T),
  761. Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
  762. valid = 0;
  763. }
  764. if (fabs(Etotal-Gtotal) > 0.01*MAX(Etotal,Gtotal)) {
  765. log_warn(LD_DIR,
  766. "Bw Weight Failure for %s: Etotal %f != Gtotal %f. "
  767. "G=%"PRId64" M=%"PRId64" E=%"PRId64" D=%"PRId64
  768. " T=%"PRId64". "
  769. "Wgg=%f Wgd=%f Wmg=%f Wme=%f Wmd=%f Wee=%f Wed=%f",
  770. casename, Etotal, Gtotal,
  771. (G), (M), (E),
  772. (D), (T),
  773. Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
  774. valid = 0;
  775. }
  776. if (fabs(Gtotal-Mtotal) > 0.01*MAX(Gtotal,Mtotal)) {
  777. log_warn(LD_DIR,
  778. "Bw Weight Failure for %s: Mtotal %f != Gtotal %f. "
  779. "G=%"PRId64" M=%"PRId64" E=%"PRId64" D=%"PRId64
  780. " T=%"PRId64". "
  781. "Wgg=%f Wgd=%f Wmg=%f Wme=%f Wmd=%f Wee=%f Wed=%f",
  782. casename, Mtotal, Gtotal,
  783. (G), (M), (E),
  784. (D), (T),
  785. Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
  786. valid = 0;
  787. }
  788. } else {
  789. if (fabs(Etotal-Gtotal) > 0.01*MAX(Etotal,Gtotal)) {
  790. log_warn(LD_DIR,
  791. "Bw Weight Failure for %s: Etotal %f != Gtotal %f. "
  792. "G=%"PRId64" M=%"PRId64" E=%"PRId64" D=%"PRId64
  793. " T=%"PRId64". "
  794. "Wgg=%f Wgd=%f Wmg=%f Wme=%f Wmd=%f Wee=%f Wed=%f",
  795. casename, Etotal, Gtotal,
  796. (G), (M), (E),
  797. (D), (T),
  798. Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
  799. valid = 0;
  800. }
  801. }
  802. }
  803. } else { // if (E < T/3 || G < T/3) {
  804. int64_t S = MIN(E, G);
  805. int64_t NS = MAX(E, G);
  806. if (3*(S+D) < T) { // Subcase a:
  807. double Stotal;
  808. double NStotal;
  809. if (G < E) {
  810. casename = "Case 3a (G scarce)";
  811. Stotal = Gtotal;
  812. NStotal = Etotal;
  813. } else { // if (G >= E) {
  814. casename = "Case 3a (E scarce)";
  815. NStotal = Gtotal;
  816. Stotal = Etotal;
  817. }
  818. // Stotal < T/3
  819. if (3*Stotal > T) {
  820. log_warn(LD_DIR,
  821. "Bw Weight Failure for %s: 3*Stotal %f > T "
  822. "%"PRId64". G=%"PRId64" M=%"PRId64" E=%"PRId64
  823. " D=%"PRId64" T=%"PRId64". "
  824. "Wgg=%f Wgd=%f Wmg=%f Wme=%f Wmd=%f Wee=%f Wed=%f",
  825. casename, Stotal*3, (T),
  826. (G), (M), (E),
  827. (D), (T),
  828. Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
  829. valid = 0;
  830. }
  831. if (NS >= M) {
  832. if (fabs(NStotal-Mtotal) > 0.01*MAX(NStotal,Mtotal)) {
  833. log_warn(LD_DIR,
  834. "Bw Weight Failure for %s: NStotal %f != Mtotal %f. "
  835. "G=%"PRId64" M=%"PRId64" E=%"PRId64" D=%"PRId64
  836. " T=%"PRId64". "
  837. "Wgg=%f Wgd=%f Wmg=%f Wme=%f Wmd=%f Wee=%f Wed=%f",
  838. casename, NStotal, Mtotal,
  839. (G), (M), (E),
  840. (D), (T),
  841. Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
  842. valid = 0;
  843. }
  844. } else {
  845. // if NS < M, NStotal > T/3 because only one of G or E is scarce
  846. if (3*NStotal < T) {
  847. log_warn(LD_DIR,
  848. "Bw Weight Failure for %s: 3*NStotal %f < T "
  849. "%"PRId64". G=%"PRId64" M=%"PRId64
  850. " E=%"PRId64" D=%"PRId64" T=%"PRId64". "
  851. "Wgg=%f Wgd=%f Wmg=%f Wme=%f Wmd=%f Wee=%f Wed=%f",
  852. casename, NStotal*3, (T),
  853. (G), (M), (E),
  854. (D), (T),
  855. Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
  856. valid = 0;
  857. }
  858. }
  859. } else { // Subcase b: S+D >= T/3
  860. casename = "Case 3b";
  861. if (fabs(Etotal-Mtotal) > 0.01*MAX(Etotal,Mtotal)) {
  862. log_warn(LD_DIR,
  863. "Bw Weight Failure for %s: Etotal %f != Mtotal %f. "
  864. "G=%"PRId64" M=%"PRId64" E=%"PRId64" D=%"PRId64
  865. " T=%"PRId64". "
  866. "Wgg=%f Wgd=%f Wmg=%f Wme=%f Wmd=%f Wee=%f Wed=%f",
  867. casename, Etotal, Mtotal,
  868. (G), (M), (E),
  869. (D), (T),
  870. Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
  871. valid = 0;
  872. }
  873. if (fabs(Etotal-Gtotal) > 0.01*MAX(Etotal,Gtotal)) {
  874. log_warn(LD_DIR,
  875. "Bw Weight Failure for %s: Etotal %f != Gtotal %f. "
  876. "G=%"PRId64" M=%"PRId64" E=%"PRId64" D=%"PRId64
  877. " T=%"PRId64". "
  878. "Wgg=%f Wgd=%f Wmg=%f Wme=%f Wmd=%f Wee=%f Wed=%f",
  879. casename, Etotal, Gtotal,
  880. (G), (M), (E),
  881. (D), (T),
  882. Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
  883. valid = 0;
  884. }
  885. if (fabs(Gtotal-Mtotal) > 0.01*MAX(Gtotal,Mtotal)) {
  886. log_warn(LD_DIR,
  887. "Bw Weight Failure for %s: Mtotal %f != Gtotal %f. "
  888. "G=%"PRId64" M=%"PRId64" E=%"PRId64" D=%"PRId64
  889. " T=%"PRId64". "
  890. "Wgg=%f Wgd=%f Wmg=%f Wme=%f Wmd=%f Wee=%f Wed=%f",
  891. casename, Mtotal, Gtotal,
  892. (G), (M), (E),
  893. (D), (T),
  894. Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
  895. valid = 0;
  896. }
  897. }
  898. }
  899. if (valid)
  900. log_notice(LD_DIR, "Bandwidth-weight %s is verified and valid.",
  901. casename);
  902. return valid;
  903. }
  904. /** Check if a shared random value of type <b>srv_type</b> is in
  905. * <b>tokens</b>. If there is, parse it and set it to <b>srv_out</b>. Return
  906. * -1 on failure, 0 on success. The resulting srv is allocated on the heap and
  907. * it's the responsibility of the caller to free it. */
  908. static int
  909. extract_one_srv(smartlist_t *tokens, directory_keyword srv_type,
  910. sr_srv_t **srv_out)
  911. {
  912. int ret = -1;
  913. directory_token_t *tok;
  914. sr_srv_t *srv = NULL;
  915. smartlist_t *chunks;
  916. tor_assert(tokens);
  917. chunks = smartlist_new();
  918. tok = find_opt_by_keyword(tokens, srv_type);
  919. if (!tok) {
  920. /* That's fine, no SRV is allowed. */
  921. ret = 0;
  922. goto end;
  923. }
  924. for (int i = 0; i < tok->n_args; i++) {
  925. smartlist_add(chunks, tok->args[i]);
  926. }
  927. srv = sr_parse_srv(chunks);
  928. if (srv == NULL) {
  929. log_warn(LD_DIR, "SR: Unparseable SRV %s", escaped(tok->object_body));
  930. goto end;
  931. }
  932. /* All is good. */
  933. *srv_out = srv;
  934. ret = 0;
  935. end:
  936. smartlist_free(chunks);
  937. return ret;
  938. }
  939. /** Extract any shared random values found in <b>tokens</b> and place them in
  940. * the networkstatus <b>ns</b>. */
  941. static void
  942. extract_shared_random_srvs(networkstatus_t *ns, smartlist_t *tokens)
  943. {
  944. const char *voter_identity;
  945. networkstatus_voter_info_t *voter;
  946. tor_assert(ns);
  947. tor_assert(tokens);
  948. /* Can be only one of them else code flow. */
  949. tor_assert(ns->type == NS_TYPE_VOTE || ns->type == NS_TYPE_CONSENSUS);
  950. if (ns->type == NS_TYPE_VOTE) {
  951. voter = smartlist_get(ns->voters, 0);
  952. tor_assert(voter);
  953. voter_identity = hex_str(voter->identity_digest,
  954. sizeof(voter->identity_digest));
  955. } else {
  956. /* Consensus has multiple voters so no specific voter. */
  957. voter_identity = "consensus";
  958. }
  959. /* We extract both, and on error everything is stopped because it means
  960. * the vote is malformed for the shared random value(s). */
  961. if (extract_one_srv(tokens, K_PREVIOUS_SRV, &ns->sr_info.previous_srv) < 0) {
  962. log_warn(LD_DIR, "SR: Unable to parse previous SRV from %s",
  963. voter_identity);
  964. /* Maybe we have a chance with the current SRV so let's try it anyway. */
  965. }
  966. if (extract_one_srv(tokens, K_CURRENT_SRV, &ns->sr_info.current_srv) < 0) {
  967. log_warn(LD_DIR, "SR: Unable to parse current SRV from %s",
  968. voter_identity);
  969. }
  970. }
  971. /** Parse a v3 networkstatus vote, opinion, or consensus (depending on
  972. * ns_type), from <b>s</b>, and return the result. Return NULL on failure. */
  973. networkstatus_t *
  974. networkstatus_parse_vote_from_string(const char *s, const char **eos_out,
  975. networkstatus_type_t ns_type)
  976. {
  977. smartlist_t *tokens = smartlist_new();
  978. smartlist_t *rs_tokens = NULL, *footer_tokens = NULL;
  979. networkstatus_voter_info_t *voter = NULL;
  980. networkstatus_t *ns = NULL;
  981. common_digests_t ns_digests;
  982. uint8_t sha3_as_signed[DIGEST256_LEN];
  983. const char *cert, *end_of_header, *end_of_footer, *s_dup = s;
  984. directory_token_t *tok;
  985. struct in_addr in;
  986. int i, inorder, n_signatures = 0;
  987. memarea_t *area = NULL, *rs_area = NULL;
  988. consensus_flavor_t flav = FLAV_NS;
  989. char *last_kwd=NULL;
  990. tor_assert(s);
  991. if (eos_out)
  992. *eos_out = NULL;
  993. if (router_get_networkstatus_v3_hashes(s, &ns_digests) ||
  994. router_get_networkstatus_v3_sha3_as_signed(sha3_as_signed, s)<0) {
  995. log_warn(LD_DIR, "Unable to compute digest of network-status");
  996. goto err;
  997. }
  998. area = memarea_new();
  999. end_of_header = find_start_of_next_routerstatus(s);
  1000. if (tokenize_string(area, s, end_of_header, tokens,
  1001. (ns_type == NS_TYPE_CONSENSUS) ?
  1002. networkstatus_consensus_token_table :
  1003. networkstatus_token_table, 0)) {
  1004. log_warn(LD_DIR, "Error tokenizing network-status header");
  1005. goto err;
  1006. }
  1007. ns = tor_malloc_zero(sizeof(networkstatus_t));
  1008. memcpy(&ns->digests, &ns_digests, sizeof(ns_digests));
  1009. memcpy(&ns->digest_sha3_as_signed, sha3_as_signed, sizeof(sha3_as_signed));
  1010. tok = find_by_keyword(tokens, K_NETWORK_STATUS_VERSION);
  1011. tor_assert(tok);
  1012. if (tok->n_args > 1) {
  1013. int flavor = networkstatus_parse_flavor_name(tok->args[1]);
  1014. if (flavor < 0) {
  1015. log_warn(LD_DIR, "Can't parse document with unknown flavor %s",
  1016. escaped(tok->args[1]));
  1017. goto err;
  1018. }
  1019. ns->flavor = flav = flavor;
  1020. }
  1021. if (flav != FLAV_NS && ns_type != NS_TYPE_CONSENSUS) {
  1022. log_warn(LD_DIR, "Flavor found on non-consensus networkstatus.");
  1023. goto err;
  1024. }
  1025. if (ns_type != NS_TYPE_CONSENSUS) {
  1026. const char *end_of_cert = NULL;
  1027. if (!(cert = strstr(s, "\ndir-key-certificate-version")))
  1028. goto err;
  1029. ++cert;
  1030. ns->cert = authority_cert_parse_from_string(cert, &end_of_cert);
  1031. if (!ns->cert || !end_of_cert || end_of_cert > end_of_header)
  1032. goto err;
  1033. }
  1034. tok = find_by_keyword(tokens, K_VOTE_STATUS);
  1035. tor_assert(tok->n_args);
  1036. if (!strcmp(tok->args[0], "vote")) {
  1037. ns->type = NS_TYPE_VOTE;
  1038. } else if (!strcmp(tok->args[0], "consensus")) {
  1039. ns->type = NS_TYPE_CONSENSUS;
  1040. } else if (!strcmp(tok->args[0], "opinion")) {
  1041. ns->type = NS_TYPE_OPINION;
  1042. } else {
  1043. log_warn(LD_DIR, "Unrecognized vote status %s in network-status",
  1044. escaped(tok->args[0]));
  1045. goto err;
  1046. }
  1047. if (ns_type != ns->type) {
  1048. log_warn(LD_DIR, "Got the wrong kind of v3 networkstatus.");
  1049. goto err;
  1050. }
  1051. if (ns->type == NS_TYPE_VOTE || ns->type == NS_TYPE_OPINION) {
  1052. tok = find_by_keyword(tokens, K_PUBLISHED);
  1053. if (parse_iso_time(tok->args[0], &ns->published))
  1054. goto err;
  1055. ns->supported_methods = smartlist_new();
  1056. tok = find_opt_by_keyword(tokens, K_CONSENSUS_METHODS);
  1057. if (tok) {
  1058. for (i=0; i < tok->n_args; ++i)
  1059. smartlist_add_strdup(ns->supported_methods, tok->args[i]);
  1060. } else {
  1061. smartlist_add_strdup(ns->supported_methods, "1");
  1062. }
  1063. } else {
  1064. tok = find_opt_by_keyword(tokens, K_CONSENSUS_METHOD);
  1065. if (tok) {
  1066. int num_ok;
  1067. ns->consensus_method = (int)tor_parse_long(tok->args[0], 10, 1, INT_MAX,
  1068. &num_ok, NULL);
  1069. if (!num_ok)
  1070. goto err;
  1071. } else {
  1072. ns->consensus_method = 1;
  1073. }
  1074. }
  1075. if ((tok = find_opt_by_keyword(tokens, K_RECOMMENDED_CLIENT_PROTOCOLS)))
  1076. ns->recommended_client_protocols = tor_strdup(tok->args[0]);
  1077. if ((tok = find_opt_by_keyword(tokens, K_RECOMMENDED_RELAY_PROTOCOLS)))
  1078. ns->recommended_relay_protocols = tor_strdup(tok->args[0]);
  1079. if ((tok = find_opt_by_keyword(tokens, K_REQUIRED_CLIENT_PROTOCOLS)))
  1080. ns->required_client_protocols = tor_strdup(tok->args[0]);
  1081. if ((tok = find_opt_by_keyword(tokens, K_REQUIRED_RELAY_PROTOCOLS)))
  1082. ns->required_relay_protocols = tor_strdup(tok->args[0]);
  1083. tok = find_by_keyword(tokens, K_VALID_AFTER);
  1084. if (parse_iso_time(tok->args[0], &ns->valid_after))
  1085. goto err;
  1086. tok = find_by_keyword(tokens, K_FRESH_UNTIL);
  1087. if (parse_iso_time(tok->args[0], &ns->fresh_until))
  1088. goto err;
  1089. tok = find_by_keyword(tokens, K_VALID_UNTIL);
  1090. if (parse_iso_time(tok->args[0], &ns->valid_until))
  1091. goto err;
  1092. tok = find_by_keyword(tokens, K_VOTING_DELAY);
  1093. tor_assert(tok->n_args >= 2);
  1094. {
  1095. int ok;
  1096. ns->vote_seconds =
  1097. (int) tor_parse_long(tok->args[0], 10, 0, INT_MAX, &ok, NULL);
  1098. if (!ok)
  1099. goto err;
  1100. ns->dist_seconds =
  1101. (int) tor_parse_long(tok->args[1], 10, 0, INT_MAX, &ok, NULL);
  1102. if (!ok)
  1103. goto err;
  1104. }
  1105. if (ns->valid_after +
  1106. (get_options()->TestingTorNetwork ?
  1107. MIN_VOTE_INTERVAL_TESTING : MIN_VOTE_INTERVAL) > ns->fresh_until) {
  1108. log_warn(LD_DIR, "Vote/consensus freshness interval is too short");
  1109. goto err;
  1110. }
  1111. if (ns->valid_after +
  1112. (get_options()->TestingTorNetwork ?
  1113. MIN_VOTE_INTERVAL_TESTING : MIN_VOTE_INTERVAL)*2 > ns->valid_until) {
  1114. log_warn(LD_DIR, "Vote/consensus liveness interval is too short");
  1115. goto err;
  1116. }
  1117. if (ns->vote_seconds < MIN_VOTE_SECONDS) {
  1118. log_warn(LD_DIR, "Vote seconds is too short");
  1119. goto err;
  1120. }
  1121. if (ns->dist_seconds < MIN_DIST_SECONDS) {
  1122. log_warn(LD_DIR, "Dist seconds is too short");
  1123. goto err;
  1124. }
  1125. if ((tok = find_opt_by_keyword(tokens, K_CLIENT_VERSIONS))) {
  1126. ns->client_versions = tor_strdup(tok->args[0]);
  1127. }
  1128. if ((tok = find_opt_by_keyword(tokens, K_SERVER_VERSIONS))) {
  1129. ns->server_versions = tor_strdup(tok->args[0]);
  1130. }
  1131. {
  1132. smartlist_t *package_lst = find_all_by_keyword(tokens, K_PACKAGE);
  1133. ns->package_lines = smartlist_new();
  1134. if (package_lst) {
  1135. SMARTLIST_FOREACH(package_lst, directory_token_t *, t,
  1136. smartlist_add_strdup(ns->package_lines, t->args[0]));
  1137. }
  1138. smartlist_free(package_lst);
  1139. }
  1140. tok = find_by_keyword(tokens, K_KNOWN_FLAGS);
  1141. ns->known_flags = smartlist_new();
  1142. inorder = 1;
  1143. for (i = 0; i < tok->n_args; ++i) {
  1144. smartlist_add_strdup(ns->known_flags, tok->args[i]);
  1145. if (i>0 && strcmp(tok->args[i-1], tok->args[i])>= 0) {
  1146. log_warn(LD_DIR, "%s >= %s", tok->args[i-1], tok->args[i]);
  1147. inorder = 0;
  1148. }
  1149. }
  1150. if (!inorder) {
  1151. log_warn(LD_DIR, "known-flags not in order");
  1152. goto err;
  1153. }
  1154. if (ns->type != NS_TYPE_CONSENSUS &&
  1155. smartlist_len(ns->known_flags) > MAX_KNOWN_FLAGS_IN_VOTE) {
  1156. /* If we allowed more than 64 flags in votes, then parsing them would make
  1157. * us invoke undefined behavior whenever we used 1<<flagnum to do a
  1158. * bit-shift. This is only for votes and opinions: consensus users don't
  1159. * care about flags they don't recognize, and so don't build a bitfield
  1160. * for them. */
  1161. log_warn(LD_DIR, "Too many known-flags in consensus vote or opinion");
  1162. goto err;
  1163. }
  1164. tok = find_opt_by_keyword(tokens, K_PARAMS);
  1165. if (tok) {
  1166. int any_dups = 0;
  1167. inorder = 1;
  1168. ns->net_params = smartlist_new();
  1169. for (i = 0; i < tok->n_args; ++i) {
  1170. int ok=0;
  1171. char *eq = strchr(tok->args[i], '=');
  1172. size_t eq_pos;
  1173. if (!eq) {
  1174. log_warn(LD_DIR, "Bad element '%s' in params", escaped(tok->args[i]));
  1175. goto err;
  1176. }
  1177. eq_pos = eq-tok->args[i];
  1178. tor_parse_long(eq+1, 10, INT32_MIN, INT32_MAX, &ok, NULL);
  1179. if (!ok) {
  1180. log_warn(LD_DIR, "Bad element '%s' in params", escaped(tok->args[i]));
  1181. goto err;
  1182. }
  1183. if (i > 0 && strcmp(tok->args[i-1], tok->args[i]) >= 0) {
  1184. log_warn(LD_DIR, "%s >= %s", tok->args[i-1], tok->args[i]);
  1185. inorder = 0;
  1186. }
  1187. if (last_kwd && eq_pos == strlen(last_kwd) &&
  1188. fast_memeq(last_kwd, tok->args[i], eq_pos)) {
  1189. log_warn(LD_DIR, "Duplicate value for %s parameter",
  1190. escaped(tok->args[i]));
  1191. any_dups = 1;
  1192. }
  1193. tor_free(last_kwd);
  1194. last_kwd = tor_strndup(tok->args[i], eq_pos);
  1195. smartlist_add_strdup(ns->net_params, tok->args[i]);
  1196. }
  1197. if (!inorder) {
  1198. log_warn(LD_DIR, "params not in order");
  1199. goto err;
  1200. }
  1201. if (any_dups) {
  1202. log_warn(LD_DIR, "Duplicate in parameters");
  1203. goto err;
  1204. }
  1205. }
  1206. ns->voters = smartlist_new();
  1207. SMARTLIST_FOREACH_BEGIN(tokens, directory_token_t *, _tok) {
  1208. tok = _tok;
  1209. if (tok->tp == K_DIR_SOURCE) {
  1210. tor_assert(tok->n_args >= 6);
  1211. if (voter)
  1212. smartlist_add(ns->voters, voter);
  1213. voter = tor_malloc_zero(sizeof(networkstatus_voter_info_t));
  1214. voter->sigs = smartlist_new();
  1215. if (ns->type != NS_TYPE_CONSENSUS)
  1216. memcpy(voter->vote_digest, ns_digests.d[DIGEST_SHA1], DIGEST_LEN);
  1217. voter->nickname = tor_strdup(tok->args[0]);
  1218. if (strlen(tok->args[1]) != HEX_DIGEST_LEN ||
  1219. base16_decode(voter->identity_digest, sizeof(voter->identity_digest),
  1220. tok->args[1], HEX_DIGEST_LEN)
  1221. != sizeof(voter->identity_digest)) {
  1222. log_warn(LD_DIR, "Error decoding identity digest %s in "
  1223. "network-status document.", escaped(tok->args[1]));
  1224. goto err;
  1225. }
  1226. if (ns->type != NS_TYPE_CONSENSUS &&
  1227. tor_memneq(ns->cert->cache_info.identity_digest,
  1228. voter->identity_digest, DIGEST_LEN)) {
  1229. log_warn(LD_DIR,"Mismatch between identities in certificate and vote");
  1230. goto err;
  1231. }
  1232. if (ns->type != NS_TYPE_CONSENSUS) {
  1233. if (authority_cert_is_blacklisted(ns->cert)) {
  1234. log_warn(LD_DIR, "Rejecting vote signature made with blacklisted "
  1235. "signing key %s",
  1236. hex_str(ns->cert->signing_key_digest, DIGEST_LEN));
  1237. goto err;
  1238. }
  1239. }
  1240. voter->address = tor_strdup(tok->args[2]);
  1241. if (!tor_inet_aton(tok->args[3], &in)) {
  1242. log_warn(LD_DIR, "Error decoding IP address %s in network-status.",
  1243. escaped(tok->args[3]));
  1244. goto err;
  1245. }
  1246. voter->addr = ntohl(in.s_addr);
  1247. int ok;
  1248. voter->dir_port = (uint16_t)
  1249. tor_parse_long(tok->args[4], 10, 0, 65535, &ok, NULL);
  1250. if (!ok)
  1251. goto err;
  1252. voter->or_port = (uint16_t)
  1253. tor_parse_long(tok->args[5], 10, 0, 65535, &ok, NULL);
  1254. if (!ok)
  1255. goto err;
  1256. } else if (tok->tp == K_CONTACT) {
  1257. if (!voter || voter->contact) {
  1258. log_warn(LD_DIR, "contact element is out of place.");
  1259. goto err;
  1260. }
  1261. voter->contact = tor_strdup(tok->args[0]);
  1262. } else if (tok->tp == K_VOTE_DIGEST) {
  1263. tor_assert(ns->type == NS_TYPE_CONSENSUS);
  1264. tor_assert(tok->n_args >= 1);
  1265. if (!voter || ! tor_digest_is_zero(voter->vote_digest)) {
  1266. log_warn(LD_DIR, "vote-digest element is out of place.");
  1267. goto err;
  1268. }
  1269. if (strlen(tok->args[0]) != HEX_DIGEST_LEN ||
  1270. base16_decode(voter->vote_digest, sizeof(voter->vote_digest),
  1271. tok->args[0], HEX_DIGEST_LEN)
  1272. != sizeof(voter->vote_digest)) {
  1273. log_warn(LD_DIR, "Error decoding vote digest %s in "
  1274. "network-status consensus.", escaped(tok->args[0]));
  1275. goto err;
  1276. }
  1277. }
  1278. } SMARTLIST_FOREACH_END(_tok);
  1279. if (voter) {
  1280. smartlist_add(ns->voters, voter);
  1281. voter = NULL;
  1282. }
  1283. if (smartlist_len(ns->voters) == 0) {
  1284. log_warn(LD_DIR, "Missing dir-source elements in a networkstatus.");
  1285. goto err;
  1286. } else if (ns->type != NS_TYPE_CONSENSUS && smartlist_len(ns->voters) != 1) {
  1287. log_warn(LD_DIR, "Too many dir-source elements in a vote networkstatus.");
  1288. goto err;
  1289. }
  1290. if (ns->type != NS_TYPE_CONSENSUS &&
  1291. (tok = find_opt_by_keyword(tokens, K_LEGACY_DIR_KEY))) {
  1292. int bad = 1;
  1293. if (strlen(tok->args[0]) == HEX_DIGEST_LEN) {
  1294. networkstatus_voter_info_t *voter_0 = smartlist_get(ns->voters, 0);
  1295. if (base16_decode(voter_0->legacy_id_digest, DIGEST_LEN,
  1296. tok->args[0], HEX_DIGEST_LEN) != DIGEST_LEN)
  1297. bad = 1;
  1298. else
  1299. bad = 0;
  1300. }
  1301. if (bad) {
  1302. log_warn(LD_DIR, "Invalid legacy key digest %s on vote.",
  1303. escaped(tok->args[0]));
  1304. }
  1305. }
  1306. /* If this is a vote document, check if information about the shared
  1307. randomness protocol is included, and extract it. */
  1308. if (ns->type == NS_TYPE_VOTE) {
  1309. dirvote_parse_sr_commits(ns, tokens);
  1310. }
  1311. /* For both a vote and consensus, extract the shared random values. */
  1312. if (ns->type == NS_TYPE_VOTE || ns->type == NS_TYPE_CONSENSUS) {
  1313. extract_shared_random_srvs(ns, tokens);
  1314. }
  1315. /* Parse routerstatus lines. */
  1316. rs_tokens = smartlist_new();
  1317. rs_area = memarea_new();
  1318. s = end_of_header;
  1319. ns->routerstatus_list = smartlist_new();
  1320. while (!strcmpstart(s, "r ")) {
  1321. if (ns->type != NS_TYPE_CONSENSUS) {
  1322. vote_routerstatus_t *rs = tor_malloc_zero(sizeof(vote_routerstatus_t));
  1323. if (routerstatus_parse_entry_from_string(rs_area, &s, rs_tokens, ns,
  1324. rs, 0, 0)) {
  1325. smartlist_add(ns->routerstatus_list, rs);
  1326. } else {
  1327. vote_routerstatus_free(rs);
  1328. }
  1329. } else {
  1330. routerstatus_t *rs;
  1331. if ((rs = routerstatus_parse_entry_from_string(rs_area, &s, rs_tokens,
  1332. NULL, NULL,
  1333. ns->consensus_method,
  1334. flav))) {
  1335. /* Use exponential-backoff scheduling when downloading microdescs */
  1336. smartlist_add(ns->routerstatus_list, rs);
  1337. }
  1338. }
  1339. }
  1340. for (i = 1; i < smartlist_len(ns->routerstatus_list); ++i) {
  1341. routerstatus_t *rs1, *rs2;
  1342. if (ns->type != NS_TYPE_CONSENSUS) {
  1343. vote_routerstatus_t *a = smartlist_get(ns->routerstatus_list, i-1);
  1344. vote_routerstatus_t *b = smartlist_get(ns->routerstatus_list, i);
  1345. rs1 = &a->status; rs2 = &b->status;
  1346. } else {
  1347. rs1 = smartlist_get(ns->routerstatus_list, i-1);
  1348. rs2 = smartlist_get(ns->routerstatus_list, i);
  1349. }
  1350. if (fast_memcmp(rs1->identity_digest, rs2->identity_digest, DIGEST_LEN)
  1351. >= 0) {
  1352. log_warn(LD_DIR, "Networkstatus entries not sorted by identity digest");
  1353. goto err;
  1354. }
  1355. }
  1356. if (ns_type != NS_TYPE_CONSENSUS) {
  1357. digest256map_t *ed_id_map = digest256map_new();
  1358. SMARTLIST_FOREACH_BEGIN(ns->routerstatus_list, vote_routerstatus_t *,
  1359. vrs) {
  1360. if (! vrs->has_ed25519_listing ||
  1361. tor_mem_is_zero((const char *)vrs->ed25519_id, DIGEST256_LEN))
  1362. continue;
  1363. if (digest256map_get(ed_id_map, vrs->ed25519_id) != NULL) {
  1364. log_warn(LD_DIR, "Vote networkstatus ed25519 identities were not "
  1365. "unique");
  1366. digest256map_free(ed_id_map, NULL);
  1367. goto err;
  1368. }
  1369. digest256map_set(ed_id_map, vrs->ed25519_id, (void*)1);
  1370. } SMARTLIST_FOREACH_END(vrs);
  1371. digest256map_free(ed_id_map, NULL);
  1372. }
  1373. /* Parse footer; check signature. */
  1374. footer_tokens = smartlist_new();
  1375. if ((end_of_footer = strstr(s, "\nnetwork-status-version ")))
  1376. ++end_of_footer;
  1377. else
  1378. end_of_footer = s + strlen(s);
  1379. if (tokenize_string(area,s, end_of_footer, footer_tokens,
  1380. networkstatus_vote_footer_token_table, 0)) {
  1381. log_warn(LD_DIR, "Error tokenizing network-status vote footer.");
  1382. goto err;
  1383. }
  1384. {
  1385. int found_sig = 0;
  1386. SMARTLIST_FOREACH_BEGIN(footer_tokens, directory_token_t *, _tok) {
  1387. tok = _tok;
  1388. if (tok->tp == K_DIRECTORY_SIGNATURE)
  1389. found_sig = 1;
  1390. else if (found_sig) {
  1391. log_warn(LD_DIR, "Extraneous token after first directory-signature");
  1392. goto err;
  1393. }
  1394. } SMARTLIST_FOREACH_END(_tok);
  1395. }
  1396. if ((tok = find_opt_by_keyword(footer_tokens, K_DIRECTORY_FOOTER))) {
  1397. if (tok != smartlist_get(footer_tokens, 0)) {
  1398. log_warn(LD_DIR, "Misplaced directory-footer token");
  1399. goto err;
  1400. }
  1401. }
  1402. tok = find_opt_by_keyword(footer_tokens, K_BW_WEIGHTS);
  1403. if (tok) {
  1404. ns->weight_params = smartlist_new();
  1405. for (i = 0; i < tok->n_args; ++i) {
  1406. int ok=0;
  1407. char *eq = strchr(tok->args[i], '=');
  1408. if (!eq) {
  1409. log_warn(LD_DIR, "Bad element '%s' in weight params",
  1410. escaped(tok->args[i]));
  1411. goto err;
  1412. }
  1413. tor_parse_long(eq+1, 10, INT32_MIN, INT32_MAX, &ok, NULL);
  1414. if (!ok) {
  1415. log_warn(LD_DIR, "Bad element '%s' in params", escaped(tok->args[i]));
  1416. goto err;
  1417. }
  1418. smartlist_add_strdup(ns->weight_params, tok->args[i]);
  1419. }
  1420. }
  1421. SMARTLIST_FOREACH_BEGIN(footer_tokens, directory_token_t *, _tok) {
  1422. char declared_identity[DIGEST_LEN];
  1423. networkstatus_voter_info_t *v;
  1424. document_signature_t *sig;
  1425. const char *id_hexdigest = NULL;
  1426. const char *sk_hexdigest = NULL;
  1427. digest_algorithm_t alg = DIGEST_SHA1;
  1428. tok = _tok;
  1429. if (tok->tp != K_DIRECTORY_SIGNATURE)
  1430. continue;
  1431. tor_assert(tok->n_args >= 2);
  1432. if (tok->n_args == 2) {
  1433. id_hexdigest = tok->args[0];
  1434. sk_hexdigest = tok->args[1];
  1435. } else {
  1436. const char *algname = tok->args[0];
  1437. int a;
  1438. id_hexdigest = tok->args[1];
  1439. sk_hexdigest = tok->args[2];
  1440. a = crypto_digest_algorithm_parse_name(algname);
  1441. if (a<0) {
  1442. log_warn(LD_DIR, "Unknown digest algorithm %s; skipping",
  1443. escaped(algname));
  1444. continue;
  1445. }
  1446. alg = a;
  1447. }
  1448. if (!tok->object_type ||
  1449. strcmp(tok->object_type, "SIGNATURE") ||
  1450. tok->object_size < 128 || tok->object_size > 512) {
  1451. log_warn(LD_DIR, "Bad object type or length on directory-signature");
  1452. goto err;
  1453. }
  1454. if (strlen(id_hexdigest) != HEX_DIGEST_LEN ||
  1455. base16_decode(declared_identity, sizeof(declared_identity),
  1456. id_hexdigest, HEX_DIGEST_LEN)
  1457. != sizeof(declared_identity)) {
  1458. log_warn(LD_DIR, "Error decoding declared identity %s in "
  1459. "network-status document.", escaped(id_hexdigest));
  1460. goto err;
  1461. }
  1462. if (!(v = networkstatus_get_voter_by_id(ns, declared_identity))) {
  1463. log_warn(LD_DIR, "ID on signature on network-status document does "
  1464. "not match any declared directory source.");
  1465. goto err;
  1466. }
  1467. sig = tor_malloc_zero(sizeof(document_signature_t));
  1468. memcpy(sig->identity_digest, v->identity_digest, DIGEST_LEN);
  1469. sig->alg = alg;
  1470. if (strlen(sk_hexdigest) != HEX_DIGEST_LEN ||
  1471. base16_decode(sig->signing_key_digest, sizeof(sig->signing_key_digest),
  1472. sk_hexdigest, HEX_DIGEST_LEN)
  1473. != sizeof(sig->signing_key_digest)) {
  1474. log_warn(LD_DIR, "Error decoding declared signing key digest %s in "
  1475. "network-status document.", escaped(sk_hexdigest));
  1476. tor_free(sig);
  1477. goto err;
  1478. }
  1479. if (ns->type != NS_TYPE_CONSENSUS) {
  1480. if (tor_memneq(declared_identity, ns->cert->cache_info.identity_digest,
  1481. DIGEST_LEN)) {
  1482. log_warn(LD_DIR, "Digest mismatch between declared and actual on "
  1483. "network-status vote.");
  1484. tor_free(sig);
  1485. goto err;
  1486. }
  1487. }
  1488. if (networkstatus_get_voter_sig_by_alg(v, sig->alg)) {
  1489. /* We already parsed a vote with this algorithm from this voter. Use the
  1490. first one. */
  1491. log_fn(LOG_PROTOCOL_WARN, LD_DIR, "We received a networkstatus "
  1492. "that contains two signatures from the same voter with the same "
  1493. "algorithm. Ignoring the second signature.");
  1494. tor_free(sig);
  1495. continue;
  1496. }
  1497. if (ns->type != NS_TYPE_CONSENSUS) {
  1498. if (check_signature_token(ns_digests.d[DIGEST_SHA1], DIGEST_LEN,
  1499. tok, ns->cert->signing_key, 0,
  1500. "network-status document")) {
  1501. tor_free(sig);
  1502. goto err;
  1503. }
  1504. sig->good_signature = 1;
  1505. } else {
  1506. if (tok->object_size >= INT_MAX || tok->object_size >= SIZE_T_CEILING) {
  1507. tor_free(sig);
  1508. goto err;
  1509. }
  1510. sig->signature = tor_memdup(tok->object_body, tok->object_size);
  1511. sig->signature_len = (int) tok->object_size;
  1512. }
  1513. smartlist_add(v->sigs, sig);
  1514. ++n_signatures;
  1515. } SMARTLIST_FOREACH_END(_tok);
  1516. if (! n_signatures) {
  1517. log_warn(LD_DIR, "No signatures on networkstatus document.");
  1518. goto err;
  1519. } else if (ns->type == NS_TYPE_VOTE && n_signatures != 1) {
  1520. log_warn(LD_DIR, "Received more than one signature on a "
  1521. "network-status vote.");
  1522. goto err;
  1523. }
  1524. if (eos_out)
  1525. *eos_out = end_of_footer;
  1526. goto done;
  1527. err:
  1528. dump_desc(s_dup, "v3 networkstatus");
  1529. networkstatus_vote_free(ns);
  1530. ns = NULL;
  1531. done:
  1532. if (tokens) {
  1533. SMARTLIST_FOREACH(tokens, directory_token_t *, t, token_clear(t));
  1534. smartlist_free(tokens);
  1535. }
  1536. if (voter) {
  1537. if (voter->sigs) {
  1538. SMARTLIST_FOREACH(voter->sigs, document_signature_t *, sig,
  1539. document_signature_free(sig));
  1540. smartlist_free(voter->sigs);
  1541. }
  1542. tor_free(voter->nickname);
  1543. tor_free(voter->address);
  1544. tor_free(voter->contact);
  1545. tor_free(voter);
  1546. }
  1547. if (rs_tokens) {
  1548. SMARTLIST_FOREACH(rs_tokens, directory_token_t *, t, token_clear(t));
  1549. smartlist_free(rs_tokens);
  1550. }
  1551. if (footer_tokens) {
  1552. SMARTLIST_FOREACH(footer_tokens, directory_token_t *, t, token_clear(t));
  1553. smartlist_free(footer_tokens);
  1554. }
  1555. if (area) {
  1556. DUMP_AREA(area, "v3 networkstatus");
  1557. memarea_drop_all(area);
  1558. }
  1559. if (rs_area)
  1560. memarea_drop_all(rs_area);
  1561. tor_free(last_kwd);
  1562. return ns;
  1563. }