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
92acbe12
Commit
92acbe12
authored
Sep 26, 2003
by
Nick Mathewson
👁
Browse files
Refactor common file code into util.c; add published to descriptors
svn:r487
parent
9e5cafc3
Changes
8
Hide whitespace changes
Inline
Side-by-side
src/common/crypto.c
View file @
92acbe12
...
...
@@ -472,6 +472,28 @@ int crypto_pk_read_public_key_from_string(crypto_pk_env_t *env, char *src, int l
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
)
{
assert
(
env
&&
dest
);
...
...
src/common/crypto.h
View file @
92acbe12
...
...
@@ -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_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_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_check_key
(
crypto_pk_env_t
*
env
);
int
crypto_pk_read_private_key_from_filename
(
crypto_pk_env_t
*
env
,
const
char
*
keyfile
);
...
...
src/common/util.c
View file @
92acbe12
...
...
@@ -13,6 +13,10 @@
#include
"util.h"
#include
"log.h"
/*
* Memory
*/
void
*
tor_malloc
(
size_t
size
)
{
void
*
result
;
...
...
@@ -26,6 +30,10 @@ void *tor_malloc(size_t size) {
return
result
;
}
/*
* Time
*/
void
my_gettimeofday
(
struct
timeval
*
timeval
)
{
...
...
@@ -88,6 +96,10 @@ void tv_addms(struct timeval *a, long ms) {
a
->
tv_usec
%=
1000000
;
}
/*
* Low-level I/O.
*/
/* a wrapper for write(2) that makes sure to write all count bytes.
* Only use if fd is a blocking socket. */
int
write_all
(
int
fd
,
const
void
*
buf
,
size_t
count
)
{
...
...
@@ -129,6 +141,10 @@ void set_socket_nonblocking(int socket)
#endif
}
/*
* Process control
*/
int
spawn_func
(
int
(
*
func
)(
void
*
),
void
*
data
)
{
#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
tor_socketpair
(
int
family
,
int
type
,
int
protocol
,
int
fd
[
2
])
{
...
...
@@ -276,3 +294,100 @@ int correct_socket_errno(int s)
return
WSAEWOULDBLOCK
;
}
#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
;
}
src/common/util.h
View file @
92acbe12
...
...
@@ -56,6 +56,18 @@ int read_all(int fd, void *buf, size_t count);
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
unix calls fork, on win32 calls beginthread. Returns -1 on failure.
func should not return, but rather should call spawn_exit.
...
...
src/or/main.c
View file @
92acbe12
...
...
@@ -433,25 +433,6 @@ static int prepare_for_poll(void) {
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
)
{
crypto_pk_env_t
*
prkey
=
NULL
;
...
...
@@ -463,7 +444,7 @@ static crypto_pk_env_t *init_key_from_file(const char *fname)
goto
error
;
}
switch
(
f
n_exist
s
(
fname
))
{
switch
(
f
ile_statu
s
(
fname
))
{
case
FN_DIR
:
case
FN_ERROR
:
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
;
}
log
(
LOG_INFO
,
"Generated key seems valid"
);
fd
=
open
(
fname
,
O_WRONLY
|
O_CREAT
|
O_TRUNC
,
0400
);
if
(
fd
==
-
1
)
{
log
(
LOG_ERR
,
"Can't open %s for writing"
,
fname
);
goto
error
;
}
file
=
fdopen
(
fd
,
"w"
);
if
(
!
file
)
{
log
(
LOG_ERR
,
"Can't fdopen %s for writing"
,
fname
);
if
(
crypto_pk_write_private_key_to_filename
(
prkey
,
fname
))
{
log
(
LOG_ERR
,
"Couldn't write generated key to %s."
,
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
;
case
FN_FILE
:
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
)
{
char
keydir
[
512
];
char
fingerprint
[
FINGERPRINT_LEN
+
1
];
char
fingerprint
[
FINGERPRINT_LEN
+
MAX_NICKNAME_LEN
+
3
];
char
*
cp
;
crypto_pk_env_t
*
prkey
;
FILE
*
file
;
/* OP's don't need keys. Just initialize the TLS context.*/
if
(
!
options
.
OnionRouter
&&
!
options
.
DirPort
)
{
...
...
@@ -538,34 +506,12 @@ static int init_keys(void)
return
-
1
;
}
strcpy
(
keydir
,
options
.
DataDirectory
);
switch
(
fn_exists
(
keydir
))
{
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."
);
if
(
check_private_dir
(
keydir
,
1
))
{
return
-
1
;
}
strcat
(
keydir
,
"/keys"
);
switch
(
fn_exists
(
keydir
))
{
case
FN_NOENT
:
if
(
mkdir
(
keydir
,
0700
))
{
log_fn
(
LOG_ERR
,
"Error making key directory."
);
return
-
1
;
}
break
;
case
FN_ERROR
:
log_fn
(
LOG_ERR
,
"Error reading key directory."
);
if
(
check_private_dir
(
keydir
,
1
))
{
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. */
assert
(
!*
cp
);
...
...
@@ -600,28 +546,23 @@ static int init_keys(void)
}
strcpy
(
keydir
,
options
.
DataDirectory
);
strcat
(
keydir
,
"/router.desc"
);
file
=
fopen
(
keydir
,
"w"
);
if
(
!
file
)
{
log_fn
(
LOG_ERR
,
"Error opening %s for writing"
,
keydir
);
if
(
write_str_to_file
(
keydir
,
router_get_my_descriptor
()))
{
return
-
1
;
}
fputs
(
router_get_my_descriptor
(),
file
);
fclose
(
file
);
/* 5. Dump fingerprint to 'fingerprint' */
strcpy
(
keydir
,
options
.
DataDirectory
);
strcat
(
keydir
,
"/fingerprint"
);
file
=
fopen
(
keydir
,
"w"
);
if
(
!
file
)
{
log_fn
(
LOG_ERR
,
"Error opening %s for writing"
,
keydir
);
return
-
1
;
}
if
(
crypto_pk_get_fingerprint
(
get_identity_key
(),
fingerprint
)
<
0
)
{
assert
(
strlen
(
options
.
Nickname
)
<=
MAX_NICKNAME_LEN
);
strcpy
(
fingerprint
,
options
.
Nickname
);
strcat
(
fingerprint
,
" "
);
if
(
crypto_pk_get_fingerprint
(
get_identity_key
(),
fingerprint
+
strlen
(
fingerprint
))
<
0
)
{
log_fn
(
LOG_ERR
,
"Error computing fingerprint"
);
return
-
1
;
}
fprintf
(
file
,
"%s %s
\n
"
,
options
.
Nickname
,
fingerprint
);
fclose
(
file
);
strcat
(
fingerprint
,
"
\n
"
);
if
(
write_str_to_file
(
keydir
,
fingerprint
))
return
-
1
;
return
0
;
}
...
...
@@ -774,6 +715,7 @@ int dump_router_to_string(char *s, int maxlen, routerinfo_t *router,
char
*
identity_pkey
;
char
digest
[
20
];
char
signature
[
128
];
char
published
[
32
];
int
onion_pkeylen
,
link_pkeylen
,
identity_pkeylen
;
int
written
;
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!"
);
return
-
1
;
}
strftime
(
published
,
32
,
"%Y-%m-%d %H:%M:%S"
,
gmtime
(
&
router
->
published_on
));
result
=
snprintf
(
s
,
maxlen
,
"router %s %d %d %d %d
\n
onion-key
\n
%s"
"router %s %d %d %d %d
\n
"
"published %s
\n
"
"onion-key
\n
%s"
"link-key
\n
%s"
"signing-key
\n
%s"
,
router
->
address
,
...
...
@@ -806,6 +751,7 @@ int dump_router_to_string(char *s, int maxlen, routerinfo_t *router,
router
->
ap_port
,
router
->
dir_port
,
router
->
bandwidth
,
published
,
onion_pkey
,
link_pkey
,
identity_pkey
);
free
(
onion_pkey
);
...
...
@@ -1005,6 +951,7 @@ static int init_descriptor(void) {
ri
->
or_port
=
options
.
ORPort
;
ri
->
ap_port
=
options
.
APPort
;
ri
->
dir_port
=
options
.
DirPort
;
ri
->
published_on
=
time
(
NULL
);
ri
->
onion_pkey
=
crypto_pk_dup_key
(
get_onion_key
());
ri
->
link_pkey
=
crypto_pk_dup_key
(
get_link_key
());
ri
->
identity_pkey
=
crypto_pk_dup_key
(
get_identity_key
());
...
...
src/or/or.h
View file @
92acbe12
...
...
@@ -101,6 +101,7 @@
#define MAX_BUF_SIZE (640*1024)
#define DEFAULT_BANDWIDTH_OP (1024 * 1000)
#define MAX_NICKNAME_LEN 32
#define ACI_TYPE_LOWER 0
#define ACI_TYPE_HIGHER 1
...
...
@@ -326,6 +327,8 @@ typedef struct {
uint16_t
or_port
;
uint16_t
ap_port
;
uint16_t
dir_port
;
time_t
published_on
;
crypto_pk_env_t
*
onion_pkey
;
/* public RSA key for onions */
crypto_pk_env_t
*
link_pkey
;
/* public RSA key for TLS */
...
...
src/or/routers.c
View file @
92acbe12
...
...
@@ -318,6 +318,7 @@ typedef enum {
K_ONION_KEY
,
K_LINK_KEY
,
K_ROUTER_SIGNATURE
,
K_PUBLISHED
,
_SIGNATURE
,
_PUBLIC_KEY
,
_ERR
,
...
...
@@ -337,6 +338,7 @@ static struct token_table_ent token_table[] = {
{
"onion-key"
,
K_ONION_KEY
},
{
"link-key"
,
K_LINK_KEY
},
{
"router-signature"
,
K_ROUTER_SIGNATURE
},
{
"published"
,
K_PUBLISHED
},
{
NULL
,
-
1
}
};
...
...
@@ -492,6 +494,7 @@ router_dump_token(directory_token_t *tok) {
case
K_ONION_KEY
:
printf
(
"Onion-key"
);
break
;
case
K_LINK_KEY
:
printf
(
"Link-key"
);
break
;
case
K_ROUTER_SIGNATURE
:
printf
(
"Router-signature"
);
break
;
case
K_PUBLISHED
:
printf
(
"Published"
);
break
;
default:
printf
(
"?????? %d
\n
"
,
tok
->
tp
);
return
;
}
...
...
@@ -513,7 +516,6 @@ router_get_next_token(char **s, directory_token_t *tok) {
#endif
/* return the first char of s that is not whitespace and not a comment */
static
char
*
eat_whitespace
(
char
*
s
)
{
assert
(
s
);
...
...
@@ -817,6 +819,7 @@ routerinfo_t *router_get_entry_from_string(char**s) {
char
digest
[
128
];
directory_token_t
_tok
;
directory_token_t
*
tok
=
&
_tok
;
struct
tm
published
;
#define NEXT_TOKEN() \
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."
,
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
();
if
(
tok
->
tp
!=
K_ONION_KEY
)
{
log_fn
(
LOG_WARNING
,
"Missing onion-key"
);
goto
err
;
...
...
src/or/test.c
View file @
92acbe12
...
...
@@ -519,6 +519,7 @@ test_dir_format()
r1
.
address
=
"testaddr1.foo.bar"
;
r1
.
addr
=
0xc0a80001u
;
/* 192.168.0.1 */
r1
.
published_on
=
0
;
r1
.
or_port
=
9000
;
r1
.
ap_port
=
9002
;
r1
.
dir_port
=
9003
;
...
...
@@ -539,6 +540,7 @@ test_dir_format()
ex2
.
next
=
NULL
;
r2
.
address
=
"tor.tor.tor"
;
r2
.
addr
=
0x0a030201u
;
/* 10.3.2.1 */
r2
.
published_on
=
5
;
r2
.
or_port
=
9005
;
r2
.
ap_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
,
&
pk3_str_len
));
strcpy
(
buf2
,
"router testaddr1.foo.bar 9000 9002 9003 1000
\n
onion-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
,
"link-key
\n
"
);
strcat
(
buf2
,
pk3_str
);
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment