mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-10 21:23:58 +01:00
Refactor common file code into util.c; add published to descriptors
svn:r487
This commit is contained in:
parent
9e5cafc395
commit
92acbe12bc
@ -472,6 +472,28 @@ int crypto_pk_read_public_key_from_string(crypto_pk_env_t *env, char *src, int l
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
crypto_pk_write_private_key_to_filename(crypto_pk_env_t *env,
|
||||||
|
const char *fname)
|
||||||
|
{
|
||||||
|
BIO *bio;
|
||||||
|
char *cp;
|
||||||
|
long len;
|
||||||
|
int r;
|
||||||
|
assert(env->type == CRYPTO_PK_RSA);
|
||||||
|
if (!(bio = BIO_new(BIO_s_mem())))
|
||||||
|
return -1;
|
||||||
|
if (PEM_write_bio_RSAPrivateKey(bio, (RSA*)env->key, NULL,NULL,0,0,NULL)) {
|
||||||
|
BIO_free(bio);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
len = BIO_get_mem_data(bio, &cp);
|
||||||
|
assert(len == strlen(cp));
|
||||||
|
r = write_str_to_file(fname, cp);
|
||||||
|
BIO_free(bio);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
int crypto_pk_write_private_key_to_file(crypto_pk_env_t *env, FILE *dest)
|
int crypto_pk_write_private_key_to_file(crypto_pk_env_t *env, FILE *dest)
|
||||||
{
|
{
|
||||||
assert(env && dest);
|
assert(env && dest);
|
||||||
|
@ -40,6 +40,7 @@ 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_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, 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_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);
|
int crypto_pk_write_public_key_to_file(crypto_pk_env_t *env, FILE *dest);
|
||||||
int crypto_pk_check_key(crypto_pk_env_t *env);
|
int crypto_pk_check_key(crypto_pk_env_t *env);
|
||||||
int crypto_pk_read_private_key_from_filename(crypto_pk_env_t *env, const char *keyfile);
|
int crypto_pk_read_private_key_from_filename(crypto_pk_env_t *env, const char *keyfile);
|
||||||
|
@ -13,6 +13,10 @@
|
|||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Memory
|
||||||
|
*/
|
||||||
|
|
||||||
void *tor_malloc(size_t size) {
|
void *tor_malloc(size_t size) {
|
||||||
void *result;
|
void *result;
|
||||||
|
|
||||||
@ -26,6 +30,10 @@ void *tor_malloc(size_t size) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Time
|
||||||
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
my_gettimeofday(struct timeval *timeval)
|
my_gettimeofday(struct timeval *timeval)
|
||||||
{
|
{
|
||||||
@ -88,6 +96,10 @@ void tv_addms(struct timeval *a, long ms) {
|
|||||||
a->tv_usec %= 1000000;
|
a->tv_usec %= 1000000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Low-level I/O.
|
||||||
|
*/
|
||||||
|
|
||||||
/* a wrapper for write(2) that makes sure to write all count bytes.
|
/* a wrapper for write(2) that makes sure to write all count bytes.
|
||||||
* Only use if fd is a blocking socket. */
|
* Only use if fd is a blocking socket. */
|
||||||
int write_all(int fd, const void *buf, size_t count) {
|
int write_all(int fd, const void *buf, size_t count) {
|
||||||
@ -129,6 +141,10 @@ void set_socket_nonblocking(int socket)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Process control
|
||||||
|
*/
|
||||||
|
|
||||||
int spawn_func(int (*func)(void *), void *data)
|
int spawn_func(int (*func)(void *), void *data)
|
||||||
{
|
{
|
||||||
#ifdef MS_WINDOWS
|
#ifdef MS_WINDOWS
|
||||||
@ -164,7 +180,9 @@ void spawn_exit()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Fake socket pair over TCP. Code adapted from perl 5.8.0's util.c */
|
/*
|
||||||
|
* Windows compatibility.
|
||||||
|
*/
|
||||||
int
|
int
|
||||||
tor_socketpair(int family, int type, int protocol, int fd[2])
|
tor_socketpair(int family, int type, int protocol, int fd[2])
|
||||||
{
|
{
|
||||||
@ -276,3 +294,100 @@ int correct_socket_errno(int s)
|
|||||||
return WSAEWOULDBLOCK;
|
return WSAEWOULDBLOCK;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Filesystem operations.
|
||||||
|
*/
|
||||||
|
file_status_t file_status(const char *fname)
|
||||||
|
{
|
||||||
|
struct stat st;
|
||||||
|
if (stat(fname, &st)) {
|
||||||
|
if (errno == ENOENT) {
|
||||||
|
return FN_NOENT;
|
||||||
|
}
|
||||||
|
return FN_ERROR;
|
||||||
|
}
|
||||||
|
if (st.st_mode & S_IFDIR)
|
||||||
|
return FN_DIR;
|
||||||
|
else if (st.st_mode & S_IFREG)
|
||||||
|
return FN_FILE;
|
||||||
|
else
|
||||||
|
return FN_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
int check_private_dir(const char *dirname, int create)
|
||||||
|
{
|
||||||
|
struct stat st;
|
||||||
|
if (stat(dirname, &st)) {
|
||||||
|
if (errno != ENOENT) {
|
||||||
|
log(LOG_ERR, "Directory %s cannot be read: %s", dirname,
|
||||||
|
strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (!create) {
|
||||||
|
log(LOG_ERR, "Directory %s does not exist.", dirname);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
log(LOG_INFO, "Creating directory %s", dirname);
|
||||||
|
if (mkdir(dirname, 0700)) {
|
||||||
|
log(LOG_ERR, "Error creating directory %s: %s", dirname,
|
||||||
|
strerror(errno));
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!(st.st_mode & S_IFDIR)) {
|
||||||
|
log(LOG_ERR, "%s is not a directory", dirname);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (st.st_uid != getuid()) {
|
||||||
|
log(LOG_ERR, "%s is not owned by this UID (%d)", dirname, getuid());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (st.st_mode & 0077) {
|
||||||
|
log(LOG_WARNING, "Fixing permissions on directory %s", dirname);
|
||||||
|
if (chmod(dirname, 0700)) {
|
||||||
|
log(LOG_ERR, "Could not chmod directory %s: %s", dirname,
|
||||||
|
strerror(errno));
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
write_str_to_file(const char *fname, const char *str)
|
||||||
|
{
|
||||||
|
char tempname[1024];
|
||||||
|
int fd;
|
||||||
|
FILE *file;
|
||||||
|
if (strlen(fname) > 1000) {
|
||||||
|
log(LOG_ERR, "Filename %s is too long.", fname);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
strcpy(tempname,fname);
|
||||||
|
strcat(tempname,".tmp");
|
||||||
|
if ((fd = open(tempname, O_WRONLY|O_CREAT|O_TRUNC, 0600)) < 0) {
|
||||||
|
log(LOG_ERR, "Couldn't open %s for writing: %s", tempname,
|
||||||
|
strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (!(file = fdopen(fd, "w"))) {
|
||||||
|
log(LOG_ERR, "Couldn't fdopen %s for writing: %s", tempname,
|
||||||
|
strerror(errno));
|
||||||
|
close(fd); return -1;
|
||||||
|
}
|
||||||
|
if (fputs(str,file)) {
|
||||||
|
log(LOG_ERR, "Error writing to %s: %s", tempname, strerror(errno));
|
||||||
|
fclose(file); return -1;
|
||||||
|
}
|
||||||
|
fclose(file);
|
||||||
|
if (rename(tempname, fname)) {
|
||||||
|
log(LOG_ERR, "Error replacing %s: %s", fname, strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@ -56,6 +56,18 @@ int read_all(int fd, void *buf, size_t count);
|
|||||||
|
|
||||||
void set_socket_nonblocking(int socket);
|
void set_socket_nonblocking(int socket);
|
||||||
|
|
||||||
|
typedef enum { FN_ERROR, FN_NOENT, FN_FILE, FN_DIR} file_status_t;
|
||||||
|
|
||||||
|
/* Return FN_ERROR if filename can't be read, FN_NOENT if it doesn't
|
||||||
|
* exist, FN_FILE if it is a regular file, or FN_DIR if it's a
|
||||||
|
* directory. */
|
||||||
|
file_status_t file_status(const char *filename);
|
||||||
|
/* Check whether dirname exists and is private. If yes returns
|
||||||
|
* 0. Else returns -1.
|
||||||
|
*/
|
||||||
|
int check_private_dir(const char *dirname, int create);
|
||||||
|
int write_str_to_file(const char *fname, const char *str);
|
||||||
|
|
||||||
/* Minimalist interface to run a void function in the background. On
|
/* Minimalist interface to run a void function in the background. On
|
||||||
unix calls fork, on win32 calls beginthread. Returns -1 on failure.
|
unix calls fork, on win32 calls beginthread. Returns -1 on failure.
|
||||||
func should not return, but rather should call spawn_exit.
|
func should not return, but rather should call spawn_exit.
|
||||||
|
@ -433,25 +433,6 @@ static int prepare_for_poll(void) {
|
|||||||
return (1000 - (now.tv_usec / 1000)); /* how many milliseconds til the next second? */
|
return (1000 - (now.tv_usec / 1000)); /* how many milliseconds til the next second? */
|
||||||
}
|
}
|
||||||
|
|
||||||
#define FN_ERROR -1
|
|
||||||
#define FN_NOENT 0
|
|
||||||
#define FN_FILE 1
|
|
||||||
#define FN_DIR 2
|
|
||||||
static int fn_exists(const char *fname)
|
|
||||||
{
|
|
||||||
struct stat st;
|
|
||||||
if (stat(fname, &st)) {
|
|
||||||
if (errno == ENOENT) {
|
|
||||||
return FN_NOENT;
|
|
||||||
}
|
|
||||||
return FN_ERROR;
|
|
||||||
}
|
|
||||||
if (st.st_mode & S_IFDIR)
|
|
||||||
return FN_DIR;
|
|
||||||
else
|
|
||||||
return FN_FILE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static crypto_pk_env_t *init_key_from_file(const char *fname)
|
static crypto_pk_env_t *init_key_from_file(const char *fname)
|
||||||
{
|
{
|
||||||
crypto_pk_env_t *prkey = NULL;
|
crypto_pk_env_t *prkey = NULL;
|
||||||
@ -463,7 +444,7 @@ static crypto_pk_env_t *init_key_from_file(const char *fname)
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(fn_exists(fname)) {
|
switch(file_status(fname)) {
|
||||||
case FN_DIR:
|
case FN_DIR:
|
||||||
case FN_ERROR:
|
case FN_ERROR:
|
||||||
log(LOG_ERR, "Can't read key from %s", fname);
|
log(LOG_ERR, "Can't read key from %s", fname);
|
||||||
@ -479,22 +460,10 @@ static crypto_pk_env_t *init_key_from_file(const char *fname)
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
log(LOG_INFO, "Generated key seems valid");
|
log(LOG_INFO, "Generated key seems valid");
|
||||||
fd = open(fname, O_WRONLY|O_CREAT|O_TRUNC, 0400);
|
if (crypto_pk_write_private_key_to_filename(prkey, fname)) {
|
||||||
if (fd == -1) {
|
log(LOG_ERR, "Couldn't write generated key to %s.", fname);
|
||||||
log(LOG_ERR, "Can't open %s for writing", fname);
|
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
file = fdopen(fd, "w");
|
|
||||||
if (!file) {
|
|
||||||
log(LOG_ERR, "Can't fdopen %s for writing", fname);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
if (crypto_pk_write_private_key_to_file(prkey, file) < 0) {
|
|
||||||
log(LOG_ERR, "Can't write private key to %s", fname);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
fclose(file);
|
|
||||||
/* XXX fingerprint */
|
|
||||||
return prkey;
|
return prkey;
|
||||||
case FN_FILE:
|
case FN_FILE:
|
||||||
if (crypto_pk_read_private_key_from_filename(prkey, fname)) {
|
if (crypto_pk_read_private_key_from_filename(prkey, fname)) {
|
||||||
@ -519,10 +488,9 @@ static crypto_pk_env_t *init_key_from_file(const char *fname)
|
|||||||
static int init_keys(void)
|
static int init_keys(void)
|
||||||
{
|
{
|
||||||
char keydir[512];
|
char keydir[512];
|
||||||
char fingerprint[FINGERPRINT_LEN+1];
|
char fingerprint[FINGERPRINT_LEN+MAX_NICKNAME_LEN+3];
|
||||||
char *cp;
|
char *cp;
|
||||||
crypto_pk_env_t *prkey;
|
crypto_pk_env_t *prkey;
|
||||||
FILE *file;
|
|
||||||
|
|
||||||
/* OP's don't need keys. Just initialize the TLS context.*/
|
/* OP's don't need keys. Just initialize the TLS context.*/
|
||||||
if (!options.OnionRouter && !options.DirPort) {
|
if (!options.OnionRouter && !options.DirPort) {
|
||||||
@ -538,35 +506,13 @@ static int init_keys(void)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
strcpy(keydir, options.DataDirectory);
|
strcpy(keydir, options.DataDirectory);
|
||||||
switch (fn_exists(keydir)) {
|
if (check_private_dir(keydir, 1)) {
|
||||||
case FN_NOENT:
|
|
||||||
log_fn(LOG_ERR, "DataDirectory does not exist");
|
|
||||||
return -1;
|
|
||||||
case FN_ERROR:
|
|
||||||
log_fn(LOG_ERR, "DataDirectory can't be read");
|
|
||||||
return -1;
|
|
||||||
case FN_FILE:
|
|
||||||
log_fn(LOG_ERR, "DataDirectory is not a directory.");
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
strcat(keydir, "/keys");
|
strcat(keydir, "/keys");
|
||||||
switch (fn_exists(keydir)) {
|
if (check_private_dir(keydir, 1)) {
|
||||||
case FN_NOENT:
|
|
||||||
if (mkdir(keydir, 0700)) {
|
|
||||||
log_fn(LOG_ERR, "Error making key directory.");
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
case FN_ERROR:
|
|
||||||
log_fn(LOG_ERR, "Error reading key directory.");
|
|
||||||
return -1;
|
|
||||||
case FN_FILE:
|
|
||||||
log_fn(LOG_ERR, "Key directory is not a directory.");
|
|
||||||
return -1;
|
|
||||||
case FN_DIR:
|
|
||||||
chmod(keydir, 0700);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
cp = keydir + strlen(keydir); /* End of string. */
|
cp = keydir + strlen(keydir); /* End of string. */
|
||||||
assert(!*cp);
|
assert(!*cp);
|
||||||
|
|
||||||
@ -600,28 +546,23 @@ static int init_keys(void)
|
|||||||
}
|
}
|
||||||
strcpy(keydir, options.DataDirectory);
|
strcpy(keydir, options.DataDirectory);
|
||||||
strcat(keydir, "/router.desc");
|
strcat(keydir, "/router.desc");
|
||||||
file = fopen(keydir, "w");
|
if (write_str_to_file(keydir, router_get_my_descriptor())) {
|
||||||
if (!file) {
|
|
||||||
log_fn(LOG_ERR, "Error opening %s for writing", keydir);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
fputs(router_get_my_descriptor(), file);
|
|
||||||
fclose(file);
|
|
||||||
/* 5. Dump fingerprint to 'fingerprint' */
|
/* 5. Dump fingerprint to 'fingerprint' */
|
||||||
strcpy(keydir, options.DataDirectory);
|
strcpy(keydir, options.DataDirectory);
|
||||||
strcat(keydir, "/fingerprint");
|
strcat(keydir, "/fingerprint");
|
||||||
file = fopen(keydir, "w");
|
assert(strlen(options.Nickname) <= MAX_NICKNAME_LEN);
|
||||||
if (!file) {
|
strcpy(fingerprint, options.Nickname);
|
||||||
log_fn(LOG_ERR, "Error opening %s for writing", keydir);
|
strcat(fingerprint, " ");
|
||||||
return -1;
|
if (crypto_pk_get_fingerprint(get_identity_key(),
|
||||||
}
|
fingerprint+strlen(fingerprint))<0) {
|
||||||
if (crypto_pk_get_fingerprint(get_identity_key(), fingerprint)<0) {
|
|
||||||
log_fn(LOG_ERR, "Error computing fingerprint");
|
log_fn(LOG_ERR, "Error computing fingerprint");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
fprintf(file, "%s %s\n", options.Nickname, fingerprint);
|
strcat(fingerprint, "\n");
|
||||||
fclose(file);
|
if (write_str_to_file(keydir, fingerprint))
|
||||||
|
return -1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -774,6 +715,7 @@ int dump_router_to_string(char *s, int maxlen, routerinfo_t *router,
|
|||||||
char *identity_pkey;
|
char *identity_pkey;
|
||||||
char digest[20];
|
char digest[20];
|
||||||
char signature[128];
|
char signature[128];
|
||||||
|
char published[32];
|
||||||
int onion_pkeylen, link_pkeylen, identity_pkeylen;
|
int onion_pkeylen, link_pkeylen, identity_pkeylen;
|
||||||
int written;
|
int written;
|
||||||
int result=0;
|
int result=0;
|
||||||
@ -796,9 +738,12 @@ int dump_router_to_string(char *s, int maxlen, routerinfo_t *router,
|
|||||||
log_fn(LOG_WARNING,"write link_pkey to string failed!");
|
log_fn(LOG_WARNING,"write link_pkey to string failed!");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
strftime(published, 32, "%Y-%m-%d %H:%M:%S", gmtime(&router->published_on));
|
||||||
|
|
||||||
result = snprintf(s, maxlen,
|
result = snprintf(s, maxlen,
|
||||||
"router %s %d %d %d %d\nonion-key\n%s"
|
"router %s %d %d %d %d\n"
|
||||||
|
"published %s\n"
|
||||||
|
"onion-key\n%s"
|
||||||
"link-key\n%s"
|
"link-key\n%s"
|
||||||
"signing-key\n%s",
|
"signing-key\n%s",
|
||||||
router->address,
|
router->address,
|
||||||
@ -806,6 +751,7 @@ int dump_router_to_string(char *s, int maxlen, routerinfo_t *router,
|
|||||||
router->ap_port,
|
router->ap_port,
|
||||||
router->dir_port,
|
router->dir_port,
|
||||||
router->bandwidth,
|
router->bandwidth,
|
||||||
|
published,
|
||||||
onion_pkey, link_pkey, identity_pkey);
|
onion_pkey, link_pkey, identity_pkey);
|
||||||
|
|
||||||
free(onion_pkey);
|
free(onion_pkey);
|
||||||
@ -1005,6 +951,7 @@ static int init_descriptor(void) {
|
|||||||
ri->or_port = options.ORPort;
|
ri->or_port = options.ORPort;
|
||||||
ri->ap_port = options.APPort;
|
ri->ap_port = options.APPort;
|
||||||
ri->dir_port = options.DirPort;
|
ri->dir_port = options.DirPort;
|
||||||
|
ri->published_on = time(NULL);
|
||||||
ri->onion_pkey = crypto_pk_dup_key(get_onion_key());
|
ri->onion_pkey = crypto_pk_dup_key(get_onion_key());
|
||||||
ri->link_pkey = crypto_pk_dup_key(get_link_key());
|
ri->link_pkey = crypto_pk_dup_key(get_link_key());
|
||||||
ri->identity_pkey = crypto_pk_dup_key(get_identity_key());
|
ri->identity_pkey = crypto_pk_dup_key(get_identity_key());
|
||||||
|
@ -101,6 +101,7 @@
|
|||||||
|
|
||||||
#define MAX_BUF_SIZE (640*1024)
|
#define MAX_BUF_SIZE (640*1024)
|
||||||
#define DEFAULT_BANDWIDTH_OP (1024 * 1000)
|
#define DEFAULT_BANDWIDTH_OP (1024 * 1000)
|
||||||
|
#define MAX_NICKNAME_LEN 32
|
||||||
|
|
||||||
#define ACI_TYPE_LOWER 0
|
#define ACI_TYPE_LOWER 0
|
||||||
#define ACI_TYPE_HIGHER 1
|
#define ACI_TYPE_HIGHER 1
|
||||||
@ -327,6 +328,8 @@ typedef struct {
|
|||||||
uint16_t ap_port;
|
uint16_t ap_port;
|
||||||
uint16_t dir_port;
|
uint16_t dir_port;
|
||||||
|
|
||||||
|
time_t published_on;
|
||||||
|
|
||||||
crypto_pk_env_t *onion_pkey; /* public RSA key for onions */
|
crypto_pk_env_t *onion_pkey; /* public RSA key for onions */
|
||||||
crypto_pk_env_t *link_pkey; /* public RSA key for TLS */
|
crypto_pk_env_t *link_pkey; /* public RSA key for TLS */
|
||||||
crypto_pk_env_t *identity_pkey; /* public RSA key for signing */
|
crypto_pk_env_t *identity_pkey; /* public RSA key for signing */
|
||||||
|
@ -318,6 +318,7 @@ typedef enum {
|
|||||||
K_ONION_KEY,
|
K_ONION_KEY,
|
||||||
K_LINK_KEY,
|
K_LINK_KEY,
|
||||||
K_ROUTER_SIGNATURE,
|
K_ROUTER_SIGNATURE,
|
||||||
|
K_PUBLISHED,
|
||||||
_SIGNATURE,
|
_SIGNATURE,
|
||||||
_PUBLIC_KEY,
|
_PUBLIC_KEY,
|
||||||
_ERR,
|
_ERR,
|
||||||
@ -337,6 +338,7 @@ static struct token_table_ent token_table[] = {
|
|||||||
{ "onion-key", K_ONION_KEY },
|
{ "onion-key", K_ONION_KEY },
|
||||||
{ "link-key", K_LINK_KEY },
|
{ "link-key", K_LINK_KEY },
|
||||||
{ "router-signature", K_ROUTER_SIGNATURE },
|
{ "router-signature", K_ROUTER_SIGNATURE },
|
||||||
|
{ "published", K_PUBLISHED },
|
||||||
{ NULL, -1 }
|
{ NULL, -1 }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -492,6 +494,7 @@ router_dump_token(directory_token_t *tok) {
|
|||||||
case K_ONION_KEY: printf("Onion-key"); break;
|
case K_ONION_KEY: printf("Onion-key"); break;
|
||||||
case K_LINK_KEY: printf("Link-key"); break;
|
case K_LINK_KEY: printf("Link-key"); break;
|
||||||
case K_ROUTER_SIGNATURE: printf("Router-signature"); break;
|
case K_ROUTER_SIGNATURE: printf("Router-signature"); break;
|
||||||
|
case K_PUBLISHED: printf("Published"); break;
|
||||||
default:
|
default:
|
||||||
printf("?????? %d\n", tok->tp); return;
|
printf("?????? %d\n", tok->tp); return;
|
||||||
}
|
}
|
||||||
@ -513,7 +516,6 @@ router_get_next_token(char **s, directory_token_t *tok) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* return the first char of s that is not whitespace and not a comment */
|
/* return the first char of s that is not whitespace and not a comment */
|
||||||
static char *eat_whitespace(char *s) {
|
static char *eat_whitespace(char *s) {
|
||||||
assert(s);
|
assert(s);
|
||||||
@ -817,6 +819,7 @@ routerinfo_t *router_get_entry_from_string(char**s) {
|
|||||||
char digest[128];
|
char digest[128];
|
||||||
directory_token_t _tok;
|
directory_token_t _tok;
|
||||||
directory_token_t *tok = &_tok;
|
directory_token_t *tok = &_tok;
|
||||||
|
struct tm published;
|
||||||
|
|
||||||
#define NEXT_TOKEN() \
|
#define NEXT_TOKEN() \
|
||||||
do { if (router_get_next_token(s, tok)) { \
|
do { if (router_get_next_token(s, tok)) { \
|
||||||
@ -875,6 +878,19 @@ routerinfo_t *router_get_entry_from_string(char**s) {
|
|||||||
log_fn(LOG_DEBUG,"or_port %d, ap_port %d, dir_port %d, bandwidth %d.",
|
log_fn(LOG_DEBUG,"or_port %d, ap_port %d, dir_port %d, bandwidth %d.",
|
||||||
router->or_port, router->ap_port, router->dir_port, router->bandwidth);
|
router->or_port, router->ap_port, router->dir_port, router->bandwidth);
|
||||||
|
|
||||||
|
NEXT_TOKEN();
|
||||||
|
if (tok->tp != K_PUBLISHED) {
|
||||||
|
log_fn(LOG_WARNING, "Missing published time"); goto err;
|
||||||
|
}
|
||||||
|
if (tok->val.cmd.n_args != 2) {
|
||||||
|
log_fn(LOG_WARNING, "Wrong number of arguments to published"); goto err;
|
||||||
|
}
|
||||||
|
tok->val.cmd.args[1][-1] = ' '; /* Re-insert space. */
|
||||||
|
if (!strptime(tok->val.cmd.args[0], "%Y-%m-%d %H:%M:%S", &published)) {
|
||||||
|
log_fn(LOG_WARNING, "Published time was unparseable"); goto err;
|
||||||
|
}
|
||||||
|
router->published_on = timegm(&published);
|
||||||
|
|
||||||
NEXT_TOKEN();
|
NEXT_TOKEN();
|
||||||
if (tok->tp != K_ONION_KEY) {
|
if (tok->tp != K_ONION_KEY) {
|
||||||
log_fn(LOG_WARNING, "Missing onion-key"); goto err;
|
log_fn(LOG_WARNING, "Missing onion-key"); goto err;
|
||||||
|
@ -519,6 +519,7 @@ test_dir_format()
|
|||||||
|
|
||||||
r1.address = "testaddr1.foo.bar";
|
r1.address = "testaddr1.foo.bar";
|
||||||
r1.addr = 0xc0a80001u; /* 192.168.0.1 */
|
r1.addr = 0xc0a80001u; /* 192.168.0.1 */
|
||||||
|
r1.published_on = 0;
|
||||||
r1.or_port = 9000;
|
r1.or_port = 9000;
|
||||||
r1.ap_port = 9002;
|
r1.ap_port = 9002;
|
||||||
r1.dir_port = 9003;
|
r1.dir_port = 9003;
|
||||||
@ -539,6 +540,7 @@ test_dir_format()
|
|||||||
ex2.next = NULL;
|
ex2.next = NULL;
|
||||||
r2.address = "tor.tor.tor";
|
r2.address = "tor.tor.tor";
|
||||||
r2.addr = 0x0a030201u; /* 10.3.2.1 */
|
r2.addr = 0x0a030201u; /* 10.3.2.1 */
|
||||||
|
r2.published_on = 5;
|
||||||
r2.or_port = 9005;
|
r2.or_port = 9005;
|
||||||
r2.ap_port = 0;
|
r2.ap_port = 0;
|
||||||
r2.dir_port = 0;
|
r2.dir_port = 0;
|
||||||
@ -555,7 +557,9 @@ test_dir_format()
|
|||||||
test_assert(!crypto_pk_write_public_key_to_string(pk3 , &pk3_str,
|
test_assert(!crypto_pk_write_public_key_to_string(pk3 , &pk3_str,
|
||||||
&pk3_str_len));
|
&pk3_str_len));
|
||||||
|
|
||||||
strcpy(buf2, "router testaddr1.foo.bar 9000 9002 9003 1000\nonion-key\n");
|
strcpy(buf2, "router testaddr1.foo.bar 9000 9002 9003 1000\n"
|
||||||
|
"published 1970-01-01 00:00:00\n"
|
||||||
|
"onion-key\n");
|
||||||
strcat(buf2, pk1_str);
|
strcat(buf2, pk1_str);
|
||||||
strcat(buf2, "link-key\n");
|
strcat(buf2, "link-key\n");
|
||||||
strcat(buf2, pk3_str);
|
strcat(buf2, pk3_str);
|
||||||
|
Loading…
Reference in New Issue
Block a user