mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-13 06:33:44 +01:00
Merge remote-tracking branch 'tor-gitlab/mr/94'
This commit is contained in:
commit
d1fda62d11
3
changes/bug27194
Normal file
3
changes/bug27194
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
o Minor bugfixes (protover):
|
||||||
|
- Consistently reject extra commas, instead of only rejecting leading commas.
|
||||||
|
Fixes bug 27194; bugfix on 0.2.9.4-alpha.
|
@ -250,7 +250,8 @@ parse_single_entry(const char *s, const char *end_of_entry)
|
|||||||
}
|
}
|
||||||
|
|
||||||
s = comma;
|
s = comma;
|
||||||
while (*s == ',' && s < end_of_entry)
|
// Skip the comma separator between ranges. Don't ignore a trailing comma.
|
||||||
|
if (s < (end_of_entry - 1))
|
||||||
++s;
|
++s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
#include "core/or/or.h"
|
#include "core/or/or.h"
|
||||||
#include "app/config/config.h"
|
#include "app/config/config.h"
|
||||||
|
#include "core/or/protover.h"
|
||||||
#include "core/or/versions.h"
|
#include "core/or/versions.h"
|
||||||
#include "feature/client/entrynodes.h"
|
#include "feature/client/entrynodes.h"
|
||||||
#include "feature/dirauth/dirvote.h"
|
#include "feature/dirauth/dirvote.h"
|
||||||
@ -466,6 +467,10 @@ routerstatus_parse_entry_from_string(memarea_t *area,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If the protover line is malformed, reject this routerstatus.
|
||||||
|
if (protocols && protover_contains_long_protocol_names(protocols)) {
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
summarize_protover_flags(&rs->pv, protocols, version);
|
summarize_protover_flags(&rs->pv, protocols, version);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1063,6 +1068,19 @@ extract_shared_random_srvs(networkstatus_t *ns, smartlist_t *tokens)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Allocate a copy of a protover line, if present. If present but malformed,
|
||||||
|
* set *error to true. */
|
||||||
|
static char *
|
||||||
|
dup_protocols_string(smartlist_t *tokens, bool *error, directory_keyword kw)
|
||||||
|
{
|
||||||
|
directory_token_t *tok = find_opt_by_keyword(tokens, kw);
|
||||||
|
if (!tok)
|
||||||
|
return NULL;
|
||||||
|
if (protover_contains_long_protocol_names(tok->args[0]))
|
||||||
|
*error = true;
|
||||||
|
return tor_strdup(tok->args[0]);
|
||||||
|
}
|
||||||
|
|
||||||
/** Parse a v3 networkstatus vote, opinion, or consensus (depending on
|
/** Parse a v3 networkstatus vote, opinion, or consensus (depending on
|
||||||
* ns_type), from <b>s</b>, and return the result. Return NULL on failure. */
|
* ns_type), from <b>s</b>, and return the result. Return NULL on failure. */
|
||||||
networkstatus_t *
|
networkstatus_t *
|
||||||
@ -1184,14 +1202,18 @@ networkstatus_parse_vote_from_string(const char *s,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((tok = find_opt_by_keyword(tokens, K_RECOMMENDED_CLIENT_PROTOCOLS)))
|
// Reject the vote if any of the protocols lines are malformed.
|
||||||
ns->recommended_client_protocols = tor_strdup(tok->args[0]);
|
bool unparseable = false;
|
||||||
if ((tok = find_opt_by_keyword(tokens, K_RECOMMENDED_RELAY_PROTOCOLS)))
|
ns->recommended_client_protocols = dup_protocols_string(tokens, &unparseable,
|
||||||
ns->recommended_relay_protocols = tor_strdup(tok->args[0]);
|
K_RECOMMENDED_CLIENT_PROTOCOLS);
|
||||||
if ((tok = find_opt_by_keyword(tokens, K_REQUIRED_CLIENT_PROTOCOLS)))
|
ns->recommended_relay_protocols = dup_protocols_string(tokens, &unparseable,
|
||||||
ns->required_client_protocols = tor_strdup(tok->args[0]);
|
K_RECOMMENDED_RELAY_PROTOCOLS);
|
||||||
if ((tok = find_opt_by_keyword(tokens, K_REQUIRED_RELAY_PROTOCOLS)))
|
ns->required_client_protocols = dup_protocols_string(tokens, &unparseable,
|
||||||
ns->required_relay_protocols = tor_strdup(tok->args[0]);
|
K_REQUIRED_CLIENT_PROTOCOLS);
|
||||||
|
ns->required_relay_protocols = dup_protocols_string(tokens, &unparseable,
|
||||||
|
K_REQUIRED_RELAY_PROTOCOLS);
|
||||||
|
if (unparseable)
|
||||||
|
goto err;
|
||||||
|
|
||||||
tok = find_by_keyword(tokens, K_VALID_AFTER);
|
tok = find_by_keyword(tokens, K_VALID_AFTER);
|
||||||
if (parse_iso_time(tok->args[0], &ns->valid_after))
|
if (parse_iso_time(tok->args[0], &ns->valid_after))
|
||||||
@ -1453,6 +1475,7 @@ networkstatus_parse_vote_from_string(const char *s,
|
|||||||
smartlist_add(ns->routerstatus_list, rs);
|
smartlist_add(ns->routerstatus_list, rs);
|
||||||
} else {
|
} else {
|
||||||
vote_routerstatus_free(rs);
|
vote_routerstatus_free(rs);
|
||||||
|
goto err; // Malformed routerstatus, reject this vote.
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
routerstatus_t *rs;
|
routerstatus_t *rs;
|
||||||
@ -1463,6 +1486,8 @@ networkstatus_parse_vote_from_string(const char *s,
|
|||||||
flav))) {
|
flav))) {
|
||||||
/* Use exponential-backoff scheduling when downloading microdescs */
|
/* Use exponential-backoff scheduling when downloading microdescs */
|
||||||
smartlist_add(ns->routerstatus_list, rs);
|
smartlist_add(ns->routerstatus_list, rs);
|
||||||
|
} else {
|
||||||
|
goto err; // Malformed routerstatus, reject this vote.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -253,6 +253,11 @@ impl FromStr for ProtoEntry {
|
|||||||
/// Otherwise, the `Err` value of this `Result` is a `ProtoverError`.
|
/// Otherwise, the `Err` value of this `Result` is a `ProtoverError`.
|
||||||
fn from_str(protocol_entry: &str) -> Result<ProtoEntry, ProtoverError> {
|
fn from_str(protocol_entry: &str) -> Result<ProtoEntry, ProtoverError> {
|
||||||
let mut proto_entry: ProtoEntry = ProtoEntry::default();
|
let mut proto_entry: ProtoEntry = ProtoEntry::default();
|
||||||
|
|
||||||
|
if protocol_entry.is_empty() {
|
||||||
|
return Ok(proto_entry);
|
||||||
|
}
|
||||||
|
|
||||||
let entries = protocol_entry.split(' ');
|
let entries = protocol_entry.split(' ');
|
||||||
|
|
||||||
for entry in entries {
|
for entry in entries {
|
||||||
@ -501,6 +506,10 @@ impl UnvalidatedProtoEntry {
|
|||||||
) -> Result<Vec<(&'a str, &'a str)>, ProtoverError> {
|
) -> Result<Vec<(&'a str, &'a str)>, ProtoverError> {
|
||||||
let mut protovers: Vec<(&str, &str)> = Vec::new();
|
let mut protovers: Vec<(&str, &str)> = Vec::new();
|
||||||
|
|
||||||
|
if protocol_string.is_empty() {
|
||||||
|
return Ok(protovers);
|
||||||
|
}
|
||||||
|
|
||||||
for subproto in protocol_string.split(' ') {
|
for subproto in protocol_string.split(' ') {
|
||||||
let mut parts = subproto.splitn(2, '=');
|
let mut parts = subproto.splitn(2, '=');
|
||||||
|
|
||||||
@ -859,7 +868,8 @@ mod test {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_protoentry_from_str_empty() {
|
fn test_protoentry_from_str_empty() {
|
||||||
assert_protoentry_is_unparseable!("");
|
assert_protoentry_is_parseable!("");
|
||||||
|
assert!(UnvalidatedProtoEntry::from_str("").is_ok());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -882,11 +892,6 @@ mod test {
|
|||||||
assert_protoentry_is_unparseable!("Desc=1-4294967295");
|
assert_protoentry_is_unparseable!("Desc=1-4294967295");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_protoentry_from_str_() {
|
|
||||||
assert_protoentry_is_unparseable!("");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_protoentry_all_supported_single_protocol_single_version() {
|
fn test_protoentry_all_supported_single_protocol_single_version() {
|
||||||
let protocol: UnvalidatedProtoEntry = "Cons=1".parse().unwrap();
|
let protocol: UnvalidatedProtoEntry = "Cons=1".parse().unwrap();
|
||||||
|
@ -69,18 +69,6 @@ fn protocol_all_supported_with_one_value() {
|
|||||||
assert_eq!(true, unsupported.is_none());
|
assert_eq!(true, unsupported.is_none());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
#[should_panic]
|
|
||||||
fn parse_protocol_unvalidated_with_empty() {
|
|
||||||
let _: UnvalidatedProtoEntry = "".parse().unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
#[should_panic]
|
|
||||||
fn parse_protocol_validated_with_empty() {
|
|
||||||
let _: UnvalidatedProtoEntry = "".parse().unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn protocol_all_supported_with_three_values() {
|
fn protocol_all_supported_with_three_values() {
|
||||||
let protocols: UnvalidatedProtoEntry = "LinkAuth=1 Microdesc=1-2 Relay=2".parse().unwrap();
|
let protocols: UnvalidatedProtoEntry = "LinkAuth=1 Microdesc=1-2 Relay=2".parse().unwrap();
|
||||||
@ -156,7 +144,6 @@ fn parse_protocol_with_unexpected_characters() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[should_panic]
|
|
||||||
fn protover_compute_vote_returns_empty_for_empty_string() {
|
fn protover_compute_vote_returns_empty_for_empty_string() {
|
||||||
let protocols: &[UnvalidatedProtoEntry] = &["".parse().unwrap()];
|
let protocols: &[UnvalidatedProtoEntry] = &["".parse().unwrap()];
|
||||||
let listed = ProtoverVote::compute(protocols, &1);
|
let listed = ProtoverVote::compute(protocols, &1);
|
||||||
|
@ -612,6 +612,10 @@ test_protover_vote_roundtrip(void *args)
|
|||||||
{ "N-1=1,2", "N-1=1-2" },
|
{ "N-1=1,2", "N-1=1-2" },
|
||||||
{ "-1=4294967295", NULL },
|
{ "-1=4294967295", NULL },
|
||||||
{ "-1=3", "-1=3" },
|
{ "-1=3", "-1=3" },
|
||||||
|
{ "Foo=,", NULL },
|
||||||
|
{ "Foo=,1", NULL },
|
||||||
|
{ "Foo=1,,3", NULL },
|
||||||
|
{ "Foo=1,3,", NULL },
|
||||||
/* junk. */
|
/* junk. */
|
||||||
{ "!!3@*", NULL },
|
{ "!!3@*", NULL },
|
||||||
/* Missing equals sign */
|
/* Missing equals sign */
|
||||||
|
Loading…
Reference in New Issue
Block a user