mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-10 21:23:58 +01:00
Check recommended-software string *early*, before actually parsing the directory.
svn:r1930
This commit is contained in:
parent
74f611581e
commit
94782444f8
2
doc/TODO
2
doc/TODO
@ -23,7 +23,7 @@ For 0.0.7:
|
||||
D try to break apart the main clump of functions better.
|
||||
o rend_services_introduce should check if it's failed a lot
|
||||
recently, and not try for a while if so
|
||||
- check tor version as soon as you get the recommended-versions
|
||||
o check tor version as soon as you get the recommended-versions
|
||||
string, regardless of whether parsing the directory succeeded.
|
||||
- make all ORs serve the directory too.
|
||||
|
||||
|
@ -1334,6 +1334,9 @@ int router_parse_routerlist_from_directory(const char *s,
|
||||
routerinfo_t *router_parse_entry_from_string(const char *s, const char *end);
|
||||
int router_add_exit_policy_from_string(routerinfo_t *router, const char *s);
|
||||
struct exit_policy_t *router_parse_exit_policy_from_string(const char *s);
|
||||
int check_software_version_against_directory(const char *directory,
|
||||
int ignoreversion);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -445,34 +445,13 @@ int router_load_routerlist_from_string(const char *s, int trusted)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Return 1 if myversion is in versionlist. Else return 0.
|
||||
* (versionlist is a comma-separated list of versions.) */
|
||||
int is_recommended_version(const char *myversion,
|
||||
const char *versionlist) {
|
||||
int len_myversion = strlen(myversion);
|
||||
char *comma;
|
||||
const char *end = versionlist + strlen(versionlist);
|
||||
|
||||
log_fn(LOG_DEBUG,"checking '%s' in '%s'.", myversion, versionlist);
|
||||
|
||||
for(;;) {
|
||||
comma = strchr(versionlist, ',');
|
||||
if( ((comma ? comma : end) - versionlist == len_myversion) &&
|
||||
!strncmp(versionlist, myversion, len_myversion))
|
||||
/* only do strncmp if the length matches */
|
||||
return 1; /* success, it's there */
|
||||
if(!comma)
|
||||
return 0; /* nope */
|
||||
versionlist = comma+1;
|
||||
}
|
||||
}
|
||||
|
||||
/** Add to the current routerlist each router stored in the
|
||||
* signed directory <b>s</b>. If pkey is provided, make sure that <b>s</b> is
|
||||
* signed with pkey. */
|
||||
int router_load_routerlist_from_directory(const char *s, crypto_pk_env_t *pkey)
|
||||
{
|
||||
routerlist_t *new_list = NULL;
|
||||
check_software_version_against_directory(s, options.IgnoreVersion);
|
||||
if (router_parse_routerlist_from_directory(s, &new_list, pkey)) {
|
||||
log_fn(LOG_WARN, "Couldn't parse directory.");
|
||||
return -1;
|
||||
@ -493,19 +472,6 @@ int router_load_routerlist_from_directory(const char *s, crypto_pk_env_t *pkey)
|
||||
log_fn(LOG_WARN, "Error resolving routerlist");
|
||||
return -1;
|
||||
}
|
||||
if (!is_recommended_version(VERSION, routerlist->software_versions)) {
|
||||
log(options.IgnoreVersion ? LOG_WARN : LOG_ERR,
|
||||
"You are running Tor version %s, which will not work with this network.\n"
|
||||
"Please use %s%s.",
|
||||
VERSION, strchr(routerlist->software_versions,',') ? "one of " : "",
|
||||
routerlist->software_versions);
|
||||
if(options.IgnoreVersion) {
|
||||
log(LOG_WARN, "IgnoreVersion is set. If it breaks, we told you so.");
|
||||
} else {
|
||||
fflush(0);
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -176,6 +176,89 @@ static int parse_time(const char *cp, time_t *t)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the first instance of "recommended-software ...\n" at the start of
|
||||
* a line; return a newly allocated string containing the "..." portion.
|
||||
* Return NULL if no such instance was found.
|
||||
*/
|
||||
static char *
|
||||
get_recommended_software_from_directory(const char *str)
|
||||
{
|
||||
#define REC "recommended-software "
|
||||
const char *cp = str, *eol;
|
||||
int len = strlen(REC);
|
||||
cp = str;
|
||||
if (strncmp(str, REC, len)==0) {
|
||||
cp += len;
|
||||
} else {
|
||||
cp = strstr(str, "\n"REC);
|
||||
if (!cp)
|
||||
return NULL;
|
||||
cp += len+1;
|
||||
}
|
||||
eol = strchr(cp, '\n');
|
||||
if (!eol)
|
||||
return NULL;
|
||||
return tor_strndup(cp, eol-cp);
|
||||
#undef REC
|
||||
}
|
||||
|
||||
/** Return 1 if myversion is in versionlist. Else return 0.
|
||||
* (versionlist is a comma-separated list of versions.) */
|
||||
/* static */ int is_recommended_version(const char *myversion,
|
||||
const char *versionlist) {
|
||||
int len_myversion = strlen(myversion);
|
||||
char *comma;
|
||||
const char *end = versionlist + strlen(versionlist);
|
||||
|
||||
log_fn(LOG_DEBUG,"checking '%s' in '%s'.", myversion, versionlist);
|
||||
|
||||
for(;;) {
|
||||
comma = strchr(versionlist, ',');
|
||||
if( ((comma ? comma : end) - versionlist == len_myversion) &&
|
||||
!strncmp(versionlist, myversion, len_myversion))
|
||||
/* only do strncmp if the length matches */
|
||||
return 1; /* success, it's there */
|
||||
if(!comma)
|
||||
return 0; /* nope */
|
||||
versionlist = comma+1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Return 0 if myversion is supported; else log a message and return
|
||||
* -1 (or exit if ignoreversions is false) */
|
||||
int check_software_version_against_directory(const char *directory,
|
||||
int ignoreversion)
|
||||
{
|
||||
char *v;
|
||||
v = get_recommended_software_from_directory(directory);
|
||||
if (!v) {
|
||||
log_fn(LOG_WARN, "No recommended-versions string found in directory");
|
||||
return -1;
|
||||
}
|
||||
/* Look for versions of the form "0.1.0" and of the form "Tor 0.1.0".
|
||||
* Eventually, we should deprecate the first form.
|
||||
*/
|
||||
if (is_recommended_version(VERSION, v) ||
|
||||
is_recommended_version("Tor "VERSION, v)) {
|
||||
tor_free(v);
|
||||
return 0;
|
||||
}
|
||||
log(ignoreversion ? LOG_WARN : LOG_ERR,
|
||||
"You are running Tor version %s, which will not work with this network.\n"
|
||||
"Please use %s%s.",
|
||||
VERSION, strchr(v,',') ? "one of " : "", v);
|
||||
tor_free(v);
|
||||
|
||||
if(ignoreversion) {
|
||||
log(LOG_WARN, "IgnoreVersion is set. If it breaks, we told you so.");
|
||||
return -1;
|
||||
} else {
|
||||
fflush(0);
|
||||
exit(0);
|
||||
return -1; /* never reached */
|
||||
}
|
||||
}
|
||||
|
||||
/** Parse a directory from <b>s</b> and, when done, store the
|
||||
* resulting routerlist in *<b>dest</b>, freeing the old value if necessary.
|
||||
|
@ -635,8 +635,8 @@ test_onion_handshake() {
|
||||
crypto_free_pk_env(pk);
|
||||
}
|
||||
|
||||
/* from routers.c */
|
||||
int is_recommended_version(char *myversion, char *start);
|
||||
/* from routerparse.c */
|
||||
int is_recommended_version(const char *myversion, const char *start);
|
||||
|
||||
void
|
||||
test_dir_format()
|
||||
|
Loading…
Reference in New Issue
Block a user