diff --git a/src/or/directory.c b/src/or/directory.c index 6f3014557c..da82a5a92c 100644 --- a/src/or/directory.c +++ b/src/or/directory.c @@ -1973,7 +1973,8 @@ directory_handle_command_post(dir_connection_t *conn, const char *headers, case -2: case -1: case 1: - log_notice(LD_DIRSERV,"Rejected router descriptor from %s.", + log_notice(LD_DIRSERV, + "Rejected router descriptor or extra-info from %s.", conn->_base.address); /* malformed descriptor, or something wrong */ write_http_status_line(conn, 400, msg); diff --git a/src/or/dirserv.c b/src/or/dirserv.c index 8f3a922e5a..03bf5b1924 100644 --- a/src/or/dirserv.c +++ b/src/or/dirserv.c @@ -630,8 +630,7 @@ dirserv_add_extrainfo(extrainfo_t *ei, const char **msg) extrainfo_free(ei); return -1; } - if (routerinfo_incompatible_with_extrainfo(ri, ei)) { - *msg = "Router descriptor incompatible with extra-info descriptor"; + if (routerinfo_incompatible_with_extrainfo(ri, ei, msg)) { extrainfo_free(ei); return -1; } diff --git a/src/or/or.h b/src/or/or.h index caad528a04..8f0cb4859e 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -3185,7 +3185,8 @@ void networkstatus_list_update_recent(time_t now); void router_reset_descriptor_download_failures(void); void router_reset_status_download_failures(void); int router_differences_are_cosmetic(routerinfo_t *r1, routerinfo_t *r2); -int routerinfo_incompatible_with_extrainfo(routerinfo_t *ri, extrainfo_t *ei); +int routerinfo_incompatible_with_extrainfo(routerinfo_t *ri, extrainfo_t *ei, + const char **msg); const char *esc_router_info(routerinfo_t *router); char *networkstatus_getinfo_helper_single(routerstatus_t *rs); diff --git a/src/or/router.c b/src/or/router.c index 50ab1b416c..0e36f98d5f 100644 --- a/src/or/router.c +++ b/src/or/router.c @@ -1063,7 +1063,7 @@ router_rebuild_descriptor(int force) ri->cache_info.signed_descriptor_body, ri->cache_info.signed_descriptor_len); - tor_assert(! routerinfo_incompatible_with_extrainfo(ri, ei)); + tor_assert(! routerinfo_incompatible_with_extrainfo(ri, ei, NULL)); if (desc_routerinfo) routerinfo_free(desc_routerinfo); diff --git a/src/or/routerlist.c b/src/or/routerlist.c index bda3a3b50a..ee7b7023a9 100644 --- a/src/or/routerlist.c +++ b/src/or/routerlist.c @@ -1802,7 +1802,7 @@ extrainfo_insert(routerlist_t *rl, extrainfo_t *ei) /* This router is unknown; we can't even verify the signature. Give up.*/ goto done; } - if (routerinfo_incompatible_with_extrainfo(ri, ei)) { + if (routerinfo_incompatible_with_extrainfo(ri, ei, NULL)) { if (ei->bad_sig) /* If the signature didn't check, it's just wrong. */ goto done; sd = digestmap_get(rl->desc_by_eid_map, @@ -4029,7 +4029,8 @@ routerstatus_list_update_from_networkstatus(time_t now) if ((rs_old = router_get_combined_status_by_digest(lowest))) { if (!memcmp(rs_out->status.descriptor_digest, most_recent->descriptor_digest, DIGEST_LEN)) { - rs_out->dl_status.n_download_failures = rs_old->dl_status.n_download_failures; + rs_out->dl_status.n_download_failures = + rs_old->dl_status.n_download_failures; rs_out->dl_status.next_attempt_at = rs_old->dl_status.next_attempt_at; } rs_out->name_lookup_warned = rs_old->name_lookup_warned; @@ -4848,7 +4849,8 @@ router_differences_are_cosmetic(routerinfo_t *r1, routerinfo_t *r2) /** DOCDOC */ int -routerinfo_incompatible_with_extrainfo(routerinfo_t *ri, extrainfo_t *ei) +routerinfo_incompatible_with_extrainfo(routerinfo_t *ri, extrainfo_t *ei, + const char **msg) { tor_assert(ri); tor_assert(ei); @@ -4860,8 +4862,10 @@ routerinfo_incompatible_with_extrainfo(routerinfo_t *ri, extrainfo_t *ei) * by the same rotuer. */ if (strcmp(ri->nickname, ei->nickname) || memcmp(ri->cache_info.identity_digest, ei->cache_info.identity_digest, - DIGEST_LEN)) + DIGEST_LEN)) { + if (msg) *msg = "Extrainfo nickname or identity did not match routerinfo"; return 1; /* different servers */ + } if (ei->pending_sig) { char signed_digest[128]; @@ -4871,20 +4875,26 @@ routerinfo_incompatible_with_extrainfo(routerinfo_t *ri, extrainfo_t *ei) DIGEST_LEN)) { ei->bad_sig = 1; tor_free(ei->pending_sig); + if (msg) *msg = "Extrainfo signature bad, or signed with wrong key"; return 1; /* Bad signature, or no match. */ } tor_free(ei->pending_sig); } - if (memcmp(ei->cache_info.signed_descriptor_digest, - ri->cache_info.extra_info_digest, DIGEST_LEN)) - return 1; /* Digest doesn't match declared value. */ - - if (ei->cache_info.published_on < ei->cache_info.published_on) + if (ei->cache_info.published_on < ei->cache_info.published_on) { + if (msg) *msg = "Extrainfo published time did not match routerdesc"; return 1; - else if (ei->cache_info.published_on > ei->cache_info.published_on) + } else if (ei->cache_info.published_on > ei->cache_info.published_on) { + if (msg) *msg = "Extrainfo published time did not match routerdesc"; return -1; + } + + if (memcmp(ei->cache_info.signed_descriptor_digest, + ri->cache_info.extra_info_digest, DIGEST_LEN)) { + if (msg) *msg = "Extrainfo digest did not match value from routerdesc"; + return 1; /* Digest doesn't match declared value. */ + } return 0; } diff --git a/src/or/test.c b/src/or/test.c index 5c4d349c82..ca6ffa0db7 100644 --- a/src/or/test.c +++ b/src/or/test.c @@ -1106,7 +1106,6 @@ test_smartlist(void) test_assert(smartlist_string_isin(sl, "arma")); test_assert(smartlist_string_isin(sl, "the")); - /* Test bsearch. */ smartlist_sort(sl, _compare_strs); test_streq("nickm", smartlist_bsearch(sl, "zNicKM", @@ -1114,8 +1113,6 @@ test_smartlist(void) test_streq("and", smartlist_bsearch(sl, " AND", _compare_without_first_ch)); test_eq_ptr(NULL, smartlist_bsearch(sl, " ANz", _compare_without_first_ch)); - - /* Test reverse() and pop_last() */ smartlist_reverse(sl); cp = smartlist_join_strings(sl, ",", 0, NULL);