Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
ZerXes
Tor
Commits
ac552573
Commit
ac552573
authored
Dec 08, 2003
by
Nick Mathewson
🐻
Browse files
Make router/directory parsing nondestructive and more const-friendly
svn:r890
parent
8bd7c94b
Changes
9
Hide whitespace changes
Inline
Side-by-side
src/common/crypto.c
View file @
ac552573
...
...
@@ -441,7 +441,7 @@ int crypto_pk_write_public_key_to_string(crypto_pk_env_t *env, char **dest, int
return
0
;
}
int
crypto_pk_read_public_key_from_string
(
crypto_pk_env_t
*
env
,
char
*
src
,
int
len
)
{
int
crypto_pk_read_public_key_from_string
(
crypto_pk_env_t
*
env
,
const
char
*
src
,
int
len
)
{
BIO
*
b
;
assert
(
env
&&
src
);
...
...
@@ -820,7 +820,7 @@ crypto_cipher_advance(crypto_cipher_env_t *env, long delta)
/* SHA-1 */
int
crypto_SHA_digest
(
unsigned
char
*
m
,
int
len
,
unsigned
char
*
digest
)
int
crypto_SHA_digest
(
const
unsigned
char
*
m
,
int
len
,
unsigned
char
*
digest
)
{
assert
(
m
&&
digest
);
return
(
SHA1
(
m
,
len
,
digest
)
==
NULL
);
...
...
@@ -1034,7 +1034,7 @@ char *crypto_perror()
}
int
base64_encode
(
char
*
dest
,
int
destlen
,
char
*
src
,
int
srclen
)
base64_encode
(
char
*
dest
,
int
destlen
,
const
char
*
src
,
int
srclen
)
{
EVP_ENCODE_CTX
ctx
;
int
len
,
ret
;
...
...
@@ -1046,13 +1046,13 @@ base64_encode(char *dest, int destlen, char *src, int srclen)
return
-
1
;
EVP_EncodeInit
(
&
ctx
);
EVP_EncodeUpdate
(
&
ctx
,
dest
,
&
len
,
src
,
srclen
);
EVP_EncodeUpdate
(
&
ctx
,
dest
,
&
len
,
(
char
*
)
src
,
srclen
);
EVP_EncodeFinal
(
&
ctx
,
dest
+
len
,
&
ret
);
ret
+=
len
;
return
ret
;
}
int
base64_decode
(
char
*
dest
,
int
destlen
,
char
*
src
,
int
srclen
)
base64_decode
(
char
*
dest
,
int
destlen
,
const
char
*
src
,
int
srclen
)
{
EVP_ENCODE_CTX
ctx
;
int
len
,
ret
;
...
...
@@ -1063,7 +1063,7 @@ base64_decode(char *dest, int destlen, char *src, int srclen)
return
-
1
;
EVP_DecodeInit
(
&
ctx
);
EVP_DecodeUpdate
(
&
ctx
,
dest
,
&
len
,
src
,
srclen
);
EVP_DecodeUpdate
(
&
ctx
,
dest
,
&
len
,
(
char
*
)
src
,
srclen
);
EVP_DecodeFinal
(
&
ctx
,
dest
,
&
ret
);
ret
+=
len
;
return
ret
;
...
...
src/common/crypto.h
View file @
ac552573
...
...
@@ -38,7 +38,7 @@ int crypto_pk_generate_key(crypto_pk_env_t *env);
int
crypto_pk_read_private_key_from_file
(
crypto_pk_env_t
*
env
,
FILE
*
src
);
int
crypto_pk_read_public_key_from_file
(
crypto_pk_env_t
*
env
,
FILE
*
src
);
int
crypto_pk_write_public_key_to_string
(
crypto_pk_env_t
*
env
,
char
**
dest
,
int
*
len
);
int
crypto_pk_read_public_key_from_string
(
crypto_pk_env_t
*
env
,
char
*
src
,
int
len
);
int
crypto_pk_read_public_key_from_string
(
crypto_pk_env_t
*
env
,
const
char
*
src
,
int
len
);
int
crypto_pk_write_private_key_to_file
(
crypto_pk_env_t
*
env
,
FILE
*
dest
);
int
crypto_pk_write_private_key_to_filename
(
crypto_pk_env_t
*
env
,
const
char
*
fname
);
int
crypto_pk_write_public_key_to_file
(
crypto_pk_env_t
*
env
,
FILE
*
dest
);
...
...
@@ -58,8 +58,8 @@ int crypto_pk_public_checksig(crypto_pk_env_t *env, unsigned char *from, int fro
int
crypto_pk_get_fingerprint
(
crypto_pk_env_t
*
pk
,
char
*
fp_out
);
int
crypto_pk_check_fingerprint_syntax
(
const
char
*
s
);
int
base64_encode
(
char
*
dest
,
int
destlen
,
char
*
src
,
int
srclen
);
int
base64_decode
(
char
*
dest
,
int
destlen
,
char
*
src
,
int
srclen
);
int
base64_encode
(
char
*
dest
,
int
destlen
,
const
char
*
src
,
int
srclen
);
int
base64_decode
(
char
*
dest
,
int
destlen
,
const
char
*
src
,
int
srclen
);
/* Key negotiation */
typedef
struct
crypto_dh_env_st
{
...
...
@@ -95,7 +95,7 @@ int crypto_cipher_advance(crypto_cipher_env_t *env, long delta);
crypto_cipher_env_t
*
crypto_create_init_cipher
(
int
cipher_type
,
char
*
key
,
char
*
iv
,
int
encrypt_mode
);
/* SHA-1 */
int
crypto_SHA_digest
(
unsigned
char
*
m
,
int
len
,
unsigned
char
*
digest
);
int
crypto_SHA_digest
(
const
unsigned
char
*
m
,
int
len
,
unsigned
char
*
digest
);
/* random numbers */
int
crypto_seed_rng
();
...
...
src/common/util.c
View file @
ac552573
...
...
@@ -54,12 +54,21 @@ char *tor_strdup(const char *s) {
return
dup
;
}
char
*
tor_strndup
(
const
char
*
s
,
size_t
n
)
{
char
*
dup
;
assert
(
s
);
dup
=
tor_malloc
(
n
+
1
);
strncpy
(
dup
,
s
,
n
);
dup
[
n
]
=
0
;
return
dup
;
}
/*
* String manipulation
*/
/* return the first char of s that is not whitespace and not a comment */
char
*
eat_whitespace
(
char
*
s
)
{
const
char
*
eat_whitespace
(
const
char
*
s
)
{
assert
(
s
);
while
(
isspace
(
*
s
)
||
*
s
==
'#'
)
{
...
...
@@ -75,14 +84,14 @@ char *eat_whitespace(char *s) {
return
s
;
}
char
*
eat_whitespace_no_nl
(
char
*
s
)
{
const
char
*
eat_whitespace_no_nl
(
const
char
*
s
)
{
while
(
*
s
==
' '
||
*
s
==
'\t'
)
++
s
;
return
s
;
}
/* return the first char of s that is whitespace or '#' or '\0 */
char
*
find_whitespace
(
char
*
s
)
{
const
char
*
find_whitespace
(
const
char
*
s
)
{
assert
(
s
);
while
(
*
s
&&
!
isspace
(
*
s
)
&&
*
s
!=
'#'
)
...
...
src/common/util.h
View file @
ac552573
...
...
@@ -36,11 +36,12 @@ void *tor_malloc(size_t size);
void
*
tor_malloc_zero
(
size_t
size
);
void
*
tor_realloc
(
void
*
ptr
,
size_t
size
);
char
*
tor_strdup
(
const
char
*
s
);
char
*
tor_strndup
(
const
char
*
s
,
size_t
n
);
#define tor_free(p) do {if(p) {free(p); (p)=NULL;}} while(0)
char
*
eat_whitespace
(
char
*
s
);
char
*
eat_whitespace_no_nl
(
char
*
s
);
char
*
find_whitespace
(
char
*
s
);
const
char
*
eat_whitespace
(
const
char
*
s
);
const
char
*
eat_whitespace_no_nl
(
const
char
*
s
);
const
char
*
find_whitespace
(
const
char
*
s
);
void
tor_gettimeofday
(
struct
timeval
*
timeval
);
long
tv_udiff
(
struct
timeval
*
start
,
struct
timeval
*
end
);
...
...
src/or/dirserv.c
View file @
ac552573
...
...
@@ -202,7 +202,8 @@ dirserv_add_descriptor(const char **desc)
routerinfo_t
*
ri
=
NULL
;
int
i
,
r
;
char
*
start
,
*
end
;
char
*
desc_tmp
=
NULL
,
*
cp
;
char
*
desc_tmp
=
NULL
;
const
char
*
cp
;
size_t
desc_len
;
start
=
strstr
(
*
desc
,
"router "
);
...
...
@@ -218,9 +219,7 @@ dirserv_add_descriptor(const char **desc)
end
=
start
+
strlen
(
start
);
}
desc_len
=
end
-
start
;
cp
=
desc_tmp
=
tor_malloc
(
desc_len
+
1
);
strncpy
(
desc_tmp
,
start
,
desc_len
);
desc_tmp
[
desc_len
]
=
'\0'
;
cp
=
desc_tmp
=
tor_strndup
(
start
,
desc_len
);
/* Check: is the descriptor syntactically valid? */
ri
=
router_get_entry_from_string
(
&
cp
);
...
...
src/or/or.h
View file @
ac552573
...
...
@@ -749,11 +749,11 @@ void router_get_routerlist(routerlist_t **prouterlist);
void
routerinfo_free
(
routerinfo_t
*
router
);
void
router_mark_as_down
(
char
*
nickname
);
int
router_set_routerlist_from_file
(
char
*
routerfile
);
int
router_get_dir_hash
(
char
*
s
,
char
*
digest
);
int
router_get_router_hash
(
char
*
s
,
char
*
digest
);
int
router_set_routerlist_from_directory
(
char
*
s
,
crypto_pk_env_t
*
pkey
);
routerinfo_t
*
router_get_entry_from_string
(
char
**
s
);
int
router_add_exit_policy_from_string
(
routerinfo_t
*
router
,
char
*
s
);
int
router_get_dir_hash
(
const
char
*
s
,
char
*
digest
);
int
router_get_router_hash
(
const
char
*
s
,
char
*
digest
);
int
router_set_routerlist_from_directory
(
const
char
*
s
,
crypto_pk_env_t
*
pkey
);
routerinfo_t
*
router_get_entry_from_string
(
const
char
**
s
);
int
router_add_exit_policy_from_string
(
routerinfo_t
*
router
,
const
char
*
s
);
int
router_supports_exit_address
(
uint32_t
addr
,
uint16_t
port
,
routerinfo_t
*
router
);
int
router_compare_addr_to_exit_policy
(
uint32_t
addr
,
uint16_t
port
,
...
...
src/or/router.c
View file @
ac552573
...
...
@@ -378,7 +378,8 @@ int router_dump_router_to_string(char *s, int maxlen, routerinfo_t *router,
int
result
=
0
;
struct
exit_policy_t
*
tmpe
;
#ifdef DEBUG_ROUTER_DUMP_ROUTER_TO_STRING
char
*
s_tmp
,
*
s_dup
;
char
*
s_tmp
,
*
s_dup
;
const
char
*
cp
;
routerinfo_t
*
ri_tmp
;
#endif
...
...
@@ -494,8 +495,8 @@ int router_dump_router_to_string(char *s, int maxlen, routerinfo_t *router,
s
[
written
+
1
]
=
0
;
#ifdef DEBUG_ROUTER_DUMP_ROUTER_TO_STRING
s_tmp
=
s_dup
=
tor_strdup
(
s
);
ri_tmp
=
router_get_entry_from_string
(
&
s_tm
p
);
cp
=
s_tmp
=
s_dup
=
tor_strdup
(
s
);
ri_tmp
=
router_get_entry_from_string
(
&
c
p
);
if
(
!
ri_tmp
)
{
log_fn
(
LOG_ERR
,
"We just generated a router descriptor we can't parse: <<%s>>"
,
s
);
...
...
src/or/routerlist.c
View file @
ac552573
...
...
@@ -21,17 +21,17 @@ extern or_options_t options; /* command-line and config-file options */
/****************************************************************************/
struct
directory_token
;
typedef
struct
directory_token
directory_token_t
;
struct
directory_token
_t
;
typedef
struct
directory_token
_t
directory_token_t
;
/* static function prototypes */
static
int
router_set_routerlist_from_string
(
char
*
s
);
static
int
router_set_routerlist_from_string
(
const
char
*
s
);
static
int
router_get_list_from_string_impl
(
char
**
s
,
routerlist_t
**
dest
,
router_get_list_from_string_impl
(
const
char
**
s
,
routerlist_t
**
dest
,
int
n_good_nicknames
,
const
char
**
good_nickname_lst
);
static
int
router_get_routerlist_from_directory_impl
(
char
*
s
,
routerlist_t
**
dest
,
router_get_routerlist_from_directory_impl
(
const
char
*
s
,
routerlist_t
**
dest
,
crypto_pk_env_t
*
pkey
);
static
int
router_add_exit_policy
(
routerinfo_t
*
router
,
directory_token_t
*
tok
);
...
...
@@ -245,30 +245,38 @@ typedef enum {
_SIGNATURE
,
_PUBLIC_KEY
,
_ERR
,
_EOF
_EOF
,
_NIL
}
directory_keyword
;
struct
token_table_ent
{
char
*
t
;
int
v
;
};
typedef
enum
{
NO_ARGS
,
ARGS
,
CONCAT_ARGS
,
}
arg_syntax
;
struct
token_table_ent
{
char
*
t
;
int
v
;
arg_syntax
s
;
};
static
struct
token_table_ent
token_table
[]
=
{
{
"accept"
,
K_ACCEPT
},
{
"directory-signature"
,
K_DIRECTORY_SIGNATURE
},
{
"reject"
,
K_REJECT
},
{
"router"
,
K_ROUTER
},
{
"recommended-software"
,
K_RECOMMENDED_SOFTWARE
},
{
"signed-directory"
,
K_SIGNED_DIRECTORY
},
{
"signing-key"
,
K_SIGNING_KEY
},
{
"onion-key"
,
K_ONION_KEY
},
{
"link-key"
,
K_LINK_KEY
},
{
"router-signature"
,
K_ROUTER_SIGNATURE
},
{
"published"
,
K_PUBLISHED
},
{
"running-routers"
,
K_RUNNING_ROUTERS
},
{
"platform"
,
K_PLATFORM
},
{
"accept"
,
K_ACCEPT
,
ARGS
},
{
"directory-signature"
,
K_DIRECTORY_SIGNATURE
,
NO_ARGS
},
{
"reject"
,
K_REJECT
,
ARGS
},
{
"router"
,
K_ROUTER
,
ARGS
},
{
"recommended-software"
,
K_RECOMMENDED_SOFTWARE
,
ARGS
},
{
"signed-directory"
,
K_SIGNED_DIRECTORY
,
NO_ARGS
},
{
"signing-key"
,
K_SIGNING_KEY
,
NO_ARGS
},
{
"onion-key"
,
K_ONION_KEY
,
NO_ARGS
},
{
"link-key"
,
K_LINK_KEY
,
NO_ARGS
},
{
"router-signature"
,
K_ROUTER_SIGNATURE
,
NO_ARGS
},
{
"published"
,
K_PUBLISHED
,
CONCAT_ARGS
},
{
"running-routers"
,
K_RUNNING_ROUTERS
,
ARGS
},
{
"platform"
,
K_PLATFORM
,
ARGS
},
{
NULL
,
-
1
}
};
#define MAX_ARGS 1024
struct
directory_token
{
struct
directory_token
_t
{
directory_keyword
tp
;
union
{
struct
{
...
...
@@ -287,6 +295,7 @@ struct directory_token {
static
void
router_release_token
(
directory_token_t
*
tok
)
{
int
i
;
switch
(
tok
->
tp
)
{
case
_SIGNATURE
:
...
...
@@ -295,14 +304,21 @@ router_release_token(directory_token_t *tok)
case
_PUBLIC_KEY
:
crypto_free_pk_env
(
tok
->
val
.
public_key
);
break
;
default:
case
_ERR
:
case
_EOF
:
case
_NIL
:
break
;
default:
for
(
i
=
0
;
i
<
tok
->
val
.
cmd
.
n_args
;
++
i
)
{
tor_free
(
tok
->
val
.
cmd
.
args
[
i
]);
}
}
tok
->
tp
=
_NIL
;
}
static
int
_router_get_next_token
(
char
**
s
,
directory_token_t
*
tok
)
{
char
*
next
;
_router_get_next_token
(
const
char
**
s
,
directory_token_t
*
tok
)
{
const
char
*
next
;
crypto_pk_env_t
*
pkey
=
NULL
;
char
*
signature
=
NULL
;
int
i
,
done
;
...
...
@@ -310,6 +326,8 @@ _router_get_next_token(char **s, directory_token_t *tok) {
tok
->
tp
=
_ERR
;
tok
->
val
.
error
=
""
;
router_release_token
(
tok
);
*
s
=
eat_whitespace
(
*
s
);
if
(
!**
s
)
{
tok
->
tp
=
_EOF
;
...
...
@@ -368,21 +386,42 @@ _router_get_next_token(char **s, directory_token_t *tok) {
for
(
i
=
0
;
token_table
[
i
].
t
;
++
i
)
{
if
(
!
strncmp
(
token_table
[
i
].
t
,
*
s
,
next
-*
s
))
{
tok
->
tp
=
token_table
[
i
].
v
;
i
=
0
;
done
=
(
*
next
==
'\n'
);
*
s
=
eat_whitespace_no_nl
(
next
);
while
(
**
s
!=
'\n'
&&
i
<=
MAX_ARGS
&&
!
done
)
{
next
=
find_whitespace
(
*
s
);
if
(
*
next
==
'\n'
)
done
=
1
;
*
next
=
0
;
tok
->
val
.
cmd
.
args
[
i
++
]
=
*
s
;
if
(
token_table
[
i
].
s
==
ARGS
)
{
i
=
0
;
done
=
(
*
next
==
'\n'
);
*
s
=
eat_whitespace_no_nl
(
next
);
while
(
**
s
!=
'\n'
&&
i
<
MAX_ARGS
&&
!
done
)
{
next
=
find_whitespace
(
*
s
);
if
(
*
next
==
'\n'
)
done
=
1
;
tok
->
val
.
cmd
.
args
[
i
++
]
=
tor_strndup
(
*
s
,
next
-*
s
);
*
s
=
eat_whitespace_no_nl
(
next
+
1
);
}
tok
->
val
.
cmd
.
n_args
=
i
;
if
(
i
>=
MAX_ARGS
)
{
/* XXX free args[0..i] */
tok
->
tp
=
_ERR
;
tok
->
val
.
error
=
"Too many arguments"
;
return
-
1
;
}
}
else
if
(
token_table
[
i
].
s
==
CONCAT_ARGS
)
{
*
s
=
eat_whitespace_no_nl
(
next
);
next
=
strchr
(
*
s
,
'\n'
);
if
(
!
next
)
{
tok
->
tp
=
_ERR
;
tok
->
val
.
error
=
"Unexpected EOF"
;
return
-
1
;
}
tok
->
val
.
cmd
.
args
[
0
]
=
tor_strndup
(
*
s
,
next
-*
s
);
tok
->
val
.
cmd
.
n_args
=
1
;
*
s
=
eat_whitespace_no_nl
(
next
+
1
);
};
tok
->
val
.
cmd
.
n_args
=
i
;
if
(
i
>
MAX_ARGS
)
{
tok
->
tp
=
_ERR
;
tok
->
val
.
error
=
"Too many arguments"
;
return
-
1
;
}
else
{
*
s
=
eat_whitespace_no_nl
(
next
);
if
(
**
s
!=
'\n'
)
{
tok
->
tp
=
_ERR
;
tok
->
val
.
error
=
"Unexpected arguments"
;
return
-
1
;
}
tok
->
val
.
cmd
.
n_args
=
0
;
*
s
=
eat_whitespace_no_nl
(
*
s
+
1
);
}
return
0
;
}
...
...
@@ -444,7 +483,7 @@ router_get_next_token(char **s, directory_token_t *tok) {
/* read routerinfo elements from s, and throw out the ones that
* don't parse and resolve. */
static
int
router_set_routerlist_from_string
(
char
*
s
)
static
int
router_set_routerlist_from_string
(
const
char
*
s
)
{
if
(
router_get_list_from_string_impl
(
&
s
,
&
routerlist
,
-
1
,
NULL
))
{
log
(
LOG_WARN
,
"Error parsing router file"
);
...
...
@@ -457,7 +496,8 @@ static int router_set_routerlist_from_string(char *s)
return
0
;
}
static
int
router_get_hash_impl
(
char
*
s
,
char
*
digest
,
const
char
*
start_str
,
static
int
router_get_hash_impl
(
const
char
*
s
,
char
*
digest
,
const
char
*
start_str
,
const
char
*
end_str
)
{
char
*
start
,
*
end
;
...
...
@@ -486,22 +526,22 @@ static int router_get_hash_impl(char *s, char *digest, const char *start_str,
return
0
;
}
int
router_get_dir_hash
(
char
*
s
,
char
*
digest
)
int
router_get_dir_hash
(
const
char
*
s
,
char
*
digest
)
{
return
router_get_hash_impl
(
s
,
digest
,
"signed-directory"
,
"directory-signature"
);
}
int
router_get_router_hash
(
char
*
s
,
char
*
digest
)
int
router_get_router_hash
(
const
char
*
s
,
char
*
digest
)
{
return
router_get_hash_impl
(
s
,
digest
,
"router "
,
"router-signature"
);
}
/* return 0 if myversion is in start. Else return -1. */
int
compare_recommended_versions
(
char
*
myversion
,
char
*
start
)
{
int
compare_recommended_versions
(
const
char
*
myversion
,
const
char
*
start
)
{
int
len_myversion
=
strlen
(
myversion
);
char
*
comma
;
char
*
end
=
start
+
strlen
(
start
);
const
char
*
end
=
start
+
strlen
(
start
);
log_fn
(
LOG_DEBUG
,
"checking '%s' in '%s'."
,
myversion
,
start
);
...
...
@@ -517,7 +557,7 @@ int compare_recommended_versions(char *myversion, char *start) {
}
}
int
router_set_routerlist_from_directory
(
char
*
s
,
crypto_pk_env_t
*
pkey
)
int
router_set_routerlist_from_directory
(
const
char
*
s
,
crypto_pk_env_t
*
pkey
)
{
if
(
router_get_routerlist_from_directory_impl
(
s
,
&
routerlist
,
pkey
))
{
log_fn
(
LOG_WARN
,
"Couldn't parse directory."
);
...
...
@@ -544,18 +584,19 @@ int router_set_routerlist_from_directory(char *s, crypto_pk_env_t *pkey)
}
static
int
router_get_routerlist_from_directory_impl
(
char
*
s
,
routerlist_t
**
dest
,
router_get_routerlist_from_directory_impl
(
const
char
*
s
,
routerlist_t
**
dest
,
crypto_pk_env_t
*
pkey
)
{
directory_token_t
tok
;
char
digest
[
20
];
char
signed_digest
[
128
];
routerlist_t
*
new_dir
=
NULL
;
char
*
versions
;
char
*
versions
=
NULL
;
struct
tm
published
;
time_t
published_on
;
const
char
*
good_nickname_lst
[
1024
];
int
n_good_nicknames
;
char
*
good_nickname_lst
[
1024
];
int
n_good_nicknames
=
0
;
int
i
;
#define NEXT_TOK() \
do { \
...
...
@@ -570,6 +611,10 @@ router_get_routerlist_from_directory_impl(char *s, routerlist_t **dest,
log_fn(LOG_WARN, "Error reading directory: expected %s", name);\
return -1; \
} } while(0)
#define N_ARGS tok.val.cmd.n_args
#define ARGS tok.val.cmd.args
tok
.
tp
=
_NIL
;
if
(
router_get_dir_hash
(
s
,
digest
))
{
log_fn
(
LOG_WARN
,
"Unable to compute digest of directory"
);
...
...
@@ -584,35 +629,34 @@ router_get_routerlist_from_directory_impl(char *s, routerlist_t **dest,
NEXT_TOK
();
TOK_IS
(
K_PUBLISHED
,
"published"
);
if
(
tok
.
val
.
cmd
.
n_args
!=
2
)
{
log_fn
(
LOG_WARN
,
"Invalid published line"
);
goto
err
;
}
tok
.
val
.
cmd
.
args
[
1
][
-
1
]
=
' '
;
if
(
!
strptime
(
tok
.
val
.
cmd
.
args
[
0
],
"%Y-%m-%d %H:%M:%S"
,
&
published
))
{
assert
(
N_ARGS
==
1
);
if
(
!
strptime
(
ARGS
[
0
],
"%Y-%m-%d %H:%M:%S"
,
&
published
))
{
log_fn
(
LOG_WARN
,
"Published time was unparseable"
);
goto
err
;
}
published_on
=
tor_timegm
(
&
published
);
NEXT_TOK
();
TOK_IS
(
K_RECOMMENDED_SOFTWARE
,
"recommended-software"
);
if
(
tok
.
val
.
cmd
.
n_args
!=
1
)
{
if
(
N_ARGS
!=
1
)
{
log_fn
(
LOG_WARN
,
"Invalid recommended-software line"
);
goto
err
;
}
versions
=
tor_strdup
(
tok
.
val
.
cmd
.
args
[
0
]);
versions
=
ARGS
[
0
];
tok
.
val
.
cmd
.
n_args
=
0
;
/* Don't let the versions string get freed. */
NEXT_TOK
();
TOK_IS
(
K_RUNNING_ROUTERS
,
"running-routers"
);
n_good_nicknames
=
tok
.
val
.
cmd
.
n_args
;
memcpy
(
good_nickname_lst
,
tok
.
val
.
cmd
.
args
,
n_good_nicknames
*
sizeof
(
char
*
));
n_good_nicknames
=
N_ARGS
;
memcpy
(
good_nickname_lst
,
ARGS
,
n_good_nicknames
*
sizeof
(
char
*
));
N_ARGS
=
0
;
/* Don't free the strings in good_nickname_lst. */
if
(
router_get_list_from_string_impl
(
&
s
,
&
new_dir
,
n_good_nicknames
,
good_nickname_lst
))
{
n_good_nicknames
,
(
const
char
**
)
good_nickname_lst
))
{
log_fn
(
LOG_WARN
,
"Error reading routers from directory"
);
goto
err
;
}
new_dir
->
software_versions
=
versions
;
new_dir
->
software_versions
=
versions
;
versions
=
NULL
;
new_dir
->
published_on
=
published_on
;
NEXT_TOK
();
...
...
@@ -623,7 +667,6 @@ router_get_routerlist_from_directory_impl(char *s, routerlist_t **dest,
if
(
crypto_pk_public_checksig
(
pkey
,
tok
.
val
.
signature
,
128
,
signed_digest
)
!=
20
)
{
log_fn
(
LOG_WARN
,
"Error reading directory: invalid signature."
);
free
(
tok
.
val
.
signature
);
goto
err
;
}
log
(
LOG_DEBUG
,
"Signed directory hash starts %02x:%02x:%02x:%02x"
,
...
...
@@ -631,11 +674,9 @@ router_get_routerlist_from_directory_impl(char *s, routerlist_t **dest,
((
int
)
signed_digest
[
2
])
&
0xff
,((
int
)
signed_digest
[
3
])
&
0xff
);
if
(
memcmp
(
digest
,
signed_digest
,
20
))
{
log_fn
(
LOG_WARN
,
"Error reading directory: signature does not match."
);
free
(
tok
.
val
.
signature
);
goto
err
;
}
}
free
(
tok
.
val
.
signature
);
NEXT_TOK
();
TOK_IS
(
_EOF
,
"end of directory"
);
...
...
@@ -647,15 +688,25 @@ router_get_routerlist_from_directory_impl(char *s, routerlist_t **dest,
return
0
;
err:
router_release_token
(
&
tok
);
if
(
new_dir
)
routerlist_free
(
new_dir
);
if
(
versions
)
tor_free
(
versions
);
if
(
n_good_nicknames
)
{
for
(
i
=
0
;
i
<
n_good_nicknames
;
++
i
)
{
tor_free
(
good_nickname_lst
[
i
]);
}
}
return
-
1
;
#undef NEXT_TOK
#undef TOK_IS
#undef ARGS
#undef N_ARGS
}
static
int
router_get_list_from_string_impl
(
char
**
s
,
routerlist_t
**
dest
,
router_get_list_from_string_impl
(
const
char
**
s
,
routerlist_t
**
dest
,
int
n_good_nicknames
,
const
char
**
good_nickname_lst
)
{
...
...
@@ -759,7 +810,7 @@ router_resolve_routerlist(routerlist_t *rl)
* updates s so it points to after the router it just read.
* mallocs a new router and returns it if all goes well, else returns NULL.
*/
routerinfo_t
*
router_get_entry_from_string
(
char
**
s
)
{
routerinfo_t
*
router_get_entry_from_string
(
const
char
**
s
)
{
routerinfo_t
*
router
=
NULL
;
char
signed_digest
[
128
];
char
digest
[
128
];
...
...
@@ -775,6 +826,9 @@ routerinfo_t *router_get_entry_from_string(char**s) {
} } while(0)
#define ARGS tok->val.cmd.args
#define N_ARGS tok->val.cmd.n_args
_tok
.
tp
=
_NIL
;
if
(
router_get_router_hash
(
*
s
,
digest
)
<
0
)
{
log_fn
(
LOG_WARN
,
"Couldn't compute router hash."
);
...
...
@@ -784,15 +838,14 @@ routerinfo_t *router_get_entry_from_string(char**s) {
NEXT_TOKEN
();
if
(
tok
->
tp
!=
K_ROUTER
)
{
router_release_token
(
tok
);
log_fn
(
LOG_WARN
,
"Entry does not start with
\"
router
\"
"
);
return
NULL
;
goto
err
;
}
router
=
tor_malloc_zero
(
sizeof
(
routerinfo_t
));
router
->
onion_pkey
=
router
->
identity_pkey
=
router
->
link_pkey
=
NULL
;
if
(
tok
->
val
.
cmd
.
n_args
!=
6
)
{
if
(
N_ARGS
!=
6
)
{
log_fn
(
LOG_WARN
,
"Wrong # of arguments to
\"
router
\"
"
);
goto
err
;
}
...
...
@@ -843,10 +896,7 @@ routerinfo_t *router_get_entry_from_string(char**s) {
if
(
tok
->
tp
!=
K_PUBLISHED
)
{
log_fn
(
LOG_WARN
,
"Missing published time"
);
goto
err
;
}
if
(
tok
->
val
.
cmd
.
n_args
!=
2
)
{
log_fn
(
LOG_WARN
,
"Wrong number of arguments to published"
);
goto
err
;
}
ARGS
[
1
][
-
1
]
=
' '
;
/* Re-insert space. */
assert
(
N_ARGS
==
1
);
if
(
!
strptime
(
ARGS
[
0
],
"%Y-%m-%d %H:%M:%S"
,
&
published
))
{
log_fn
(
LOG_WARN
,
"Published time was unparseable"
);
goto
err
;
}
...
...
@@ -912,24 +962,28 @@ routerinfo_t *router_get_entry_from_string(char**s) {
router_release_token
(
tok
);
/* free the signature */
return
router
;
err:
err:
router_release_token
(
tok
);
routerinfo_free
(
router
);
return
NULL
;
#undef ARGS
#undef N_ARGS
#undef NEXT_TOKEN
}
int
router_add_exit_policy_from_string
(
routerinfo_t
*
router
,
char
*
s
)
router_add_exit_policy_from_string
(
routerinfo_t
*
router
,
const
char
*
s
)
{