mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-24 04:13:28 +01:00
Allow multiple exit policy lines; mostly add support for AP policies
svn:r1905
This commit is contained in:
parent
80be19d9da
commit
80365b9897
4
doc/TODO
4
doc/TODO
@ -16,9 +16,9 @@ For 0.0.7:
|
|||||||
o the keep-trying-to-build-intropoints-always bug.
|
o the keep-trying-to-build-intropoints-always bug.
|
||||||
- *bindaddress
|
- *bindaddress
|
||||||
o include the port
|
o include the port
|
||||||
- allow multiple of them
|
o allow multiple of them
|
||||||
- have an allow/deny series for them
|
- have an allow/deny series for them
|
||||||
- break exitpolicy into multiple config lines
|
o break exitpolicy into multiple config lines
|
||||||
- have the OP forget routers it hasn't heard about in 24 hours
|
- have the OP forget routers it hasn't heard about in 24 hours
|
||||||
- rename/rearrange functions for what file they're in
|
- rename/rearrange functions for what file they're in
|
||||||
- try to break apart the main clump of functions better.
|
- try to break apart the main clump of functions better.
|
||||||
|
@ -195,7 +195,7 @@ static int config_assign(or_options_t *options, struct config_line_t *list) {
|
|||||||
config_compare(list, "DebugLogFile", CONFIG_TYPE_STRING, &options->DebugLogFile) ||
|
config_compare(list, "DebugLogFile", CONFIG_TYPE_STRING, &options->DebugLogFile) ||
|
||||||
config_compare(list, "DataDirectory", CONFIG_TYPE_STRING, &options->DataDirectory) ||
|
config_compare(list, "DataDirectory", CONFIG_TYPE_STRING, &options->DataDirectory) ||
|
||||||
config_compare(list, "DirPort", CONFIG_TYPE_INT, &options->DirPort) ||
|
config_compare(list, "DirPort", CONFIG_TYPE_INT, &options->DirPort) ||
|
||||||
config_compare(list, "DirBindAddress", CONFIG_TYPE_STRING, &options->DirBindAddress) ||
|
config_compare(list, "DirBindAddress", CONFIG_TYPE_LINELIST, &options->DirBindAddress) ||
|
||||||
config_compare(list, "DirFetchPostPeriod",CONFIG_TYPE_INT, &options->DirFetchPostPeriod) ||
|
config_compare(list, "DirFetchPostPeriod",CONFIG_TYPE_INT, &options->DirFetchPostPeriod) ||
|
||||||
|
|
||||||
config_compare(list, "ExitNodes", CONFIG_TYPE_STRING, &options->ExitNodes) ||
|
config_compare(list, "ExitNodes", CONFIG_TYPE_STRING, &options->ExitNodes) ||
|
||||||
@ -221,7 +221,7 @@ static int config_assign(or_options_t *options, struct config_line_t *list) {
|
|||||||
config_compare(list, "NumCpus", CONFIG_TYPE_INT, &options->NumCpus) ||
|
config_compare(list, "NumCpus", CONFIG_TYPE_INT, &options->NumCpus) ||
|
||||||
|
|
||||||
config_compare(list, "ORPort", CONFIG_TYPE_INT, &options->ORPort) ||
|
config_compare(list, "ORPort", CONFIG_TYPE_INT, &options->ORPort) ||
|
||||||
config_compare(list, "ORBindAddress", CONFIG_TYPE_STRING, &options->ORBindAddress) ||
|
config_compare(list, "ORBindAddress", CONFIG_TYPE_LINELIST, &options->ORBindAddress) ||
|
||||||
|
|
||||||
config_compare(list, "PidFile", CONFIG_TYPE_STRING, &options->PidFile) ||
|
config_compare(list, "PidFile", CONFIG_TYPE_STRING, &options->PidFile) ||
|
||||||
config_compare(list, "PathlenCoinWeight",CONFIG_TYPE_DOUBLE, &options->PathlenCoinWeight) ||
|
config_compare(list, "PathlenCoinWeight",CONFIG_TYPE_DOUBLE, &options->PathlenCoinWeight) ||
|
||||||
@ -233,7 +233,8 @@ static int config_assign(or_options_t *options, struct config_line_t *list) {
|
|||||||
config_compare(list, "RendExcludeNodes",CONFIG_TYPE_STRING, &options->RendExcludeNodes) ||
|
config_compare(list, "RendExcludeNodes",CONFIG_TYPE_STRING, &options->RendExcludeNodes) ||
|
||||||
|
|
||||||
config_compare(list, "SocksPort", CONFIG_TYPE_INT, &options->SocksPort) ||
|
config_compare(list, "SocksPort", CONFIG_TYPE_INT, &options->SocksPort) ||
|
||||||
config_compare(list, "SocksBindAddress",CONFIG_TYPE_STRING,&options->SocksBindAddress) ||
|
config_compare(list, "SocksBindAddress",CONFIG_TYPE_LINELIST,&options->SocksBindAddress) ||
|
||||||
|
config_compare(list, "SocksPolicy", CONFIG_TYPE_LINELIST,&options->SocksPolicy) ||
|
||||||
|
|
||||||
config_compare(list, "TrafficShaping", CONFIG_TYPE_BOOL, &options->TrafficShaping) ||
|
config_compare(list, "TrafficShaping", CONFIG_TYPE_BOOL, &options->TrafficShaping) ||
|
||||||
|
|
||||||
@ -477,14 +478,15 @@ static void free_options(or_options_t *options) {
|
|||||||
tor_free(options->ExcludeNodes);
|
tor_free(options->ExcludeNodes);
|
||||||
tor_free(options->RendNodes);
|
tor_free(options->RendNodes);
|
||||||
tor_free(options->RendExcludeNodes);
|
tor_free(options->RendExcludeNodes);
|
||||||
tor_free(options->ExitPolicy);
|
|
||||||
tor_free(options->SocksBindAddress);
|
|
||||||
tor_free(options->ORBindAddress);
|
|
||||||
tor_free(options->DirBindAddress);
|
|
||||||
tor_free(options->RecommendedVersions);
|
tor_free(options->RecommendedVersions);
|
||||||
tor_free(options->User);
|
tor_free(options->User);
|
||||||
tor_free(options->Group);
|
tor_free(options->Group);
|
||||||
config_free_lines(options->RendConfigLines);
|
config_free_lines(options->RendConfigLines);
|
||||||
|
config_free_lines(options->SocksBindAddress);
|
||||||
|
config_free_lines(options->ORBindAddress);
|
||||||
|
config_free_lines(options->DirBindAddress);
|
||||||
|
config_free_lines(options->ExitPolicy);
|
||||||
|
config_free_lines(options->SocksPolicy);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Set <b>options</b> to hold reasonable defaults for most options. */
|
/** Set <b>options</b> to hold reasonable defaults for most options. */
|
||||||
@ -497,10 +499,11 @@ static void init_options(or_options_t *options) {
|
|||||||
options->ExcludeNodes = tor_strdup("");
|
options->ExcludeNodes = tor_strdup("");
|
||||||
options->RendNodes = tor_strdup("");
|
options->RendNodes = tor_strdup("");
|
||||||
options->RendExcludeNodes = tor_strdup("");
|
options->RendExcludeNodes = tor_strdup("");
|
||||||
options->ExitPolicy = tor_strdup("");
|
options->ExitPolicy = NULL;
|
||||||
options->SocksBindAddress = tor_strdup("127.0.0.1");
|
options->SocksPolicy = NULL;
|
||||||
options->ORBindAddress = tor_strdup("0.0.0.0");
|
options->SocksBindAddress = NULL;
|
||||||
options->DirBindAddress = tor_strdup("0.0.0.0");
|
options->ORBindAddress = NULL;
|
||||||
|
options->DirBindAddress = NULL;
|
||||||
options->RecommendedVersions = NULL;
|
options->RecommendedVersions = NULL;
|
||||||
options->PidFile = NULL; // tor_strdup("tor.pid");
|
options->PidFile = NULL; // tor_strdup("tor.pid");
|
||||||
options->DataDirectory = NULL;
|
options->DataDirectory = NULL;
|
||||||
@ -808,6 +811,57 @@ void config_init_logs(or_options_t *options)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
config_parse_exit_policy(struct config_line_t *cfg,
|
||||||
|
struct exit_policy_t **dest)
|
||||||
|
{
|
||||||
|
struct exit_policy_t **nextp;
|
||||||
|
char *e, *s;
|
||||||
|
int last=0;
|
||||||
|
char line[1024];
|
||||||
|
|
||||||
|
if (!cfg)
|
||||||
|
return;
|
||||||
|
nextp = dest;
|
||||||
|
while (*nextp)
|
||||||
|
nextp = &((*nextp)->next);
|
||||||
|
|
||||||
|
for (; cfg; cfg = cfg->next) {
|
||||||
|
s = cfg->value;
|
||||||
|
for (;;) {
|
||||||
|
e = strchr(s,',');
|
||||||
|
if(!e) {
|
||||||
|
last = 1;
|
||||||
|
strncpy(line,s,1023);
|
||||||
|
} else {
|
||||||
|
memcpy(line,s, ((e-s)<1023)?(e-s):1023);
|
||||||
|
line[e-s] = 0;
|
||||||
|
}
|
||||||
|
line[1023]=0;
|
||||||
|
log_fn(LOG_DEBUG,"Adding new entry '%s'",line);
|
||||||
|
*nextp = router_parse_exit_policy_from_string(line);
|
||||||
|
if(*nextp) {
|
||||||
|
nextp = &((*nextp)->next);
|
||||||
|
} else {
|
||||||
|
log_fn(LOG_WARN,"Malformed exit policy %s; skipping.", line);
|
||||||
|
}
|
||||||
|
if (last)
|
||||||
|
break;
|
||||||
|
s = e+1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void exit_policy_free(struct exit_policy_t *p) {
|
||||||
|
struct exit_policy_t *e;
|
||||||
|
while (p) {
|
||||||
|
e = p;
|
||||||
|
p = p->next;
|
||||||
|
tor_free(e->string);
|
||||||
|
tor_free(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Local Variables:
|
Local Variables:
|
||||||
mode:c
|
mode:c
|
||||||
|
@ -74,6 +74,8 @@ char *conn_state_to_string[][_CONN_TYPE_MAX+1] = {
|
|||||||
|
|
||||||
/********* END VARIABLES ************/
|
/********* END VARIABLES ************/
|
||||||
|
|
||||||
|
static int connection_create_listener(const char *bindaddress,
|
||||||
|
uint16_t bindport, int type);
|
||||||
static int connection_init_accepted_conn(connection_t *conn);
|
static int connection_init_accepted_conn(connection_t *conn);
|
||||||
static int connection_handle_listener_read(connection_t *conn, int new_type);
|
static int connection_handle_listener_read(connection_t *conn, int new_type);
|
||||||
static int connection_receiver_bucket_should_increase(connection_t *conn);
|
static int connection_receiver_bucket_should_increase(connection_t *conn);
|
||||||
@ -307,7 +309,7 @@ void connection_expire_held_open(void)
|
|||||||
* If <b>bindaddress</b> includes a port, we bind on that port; otherwise, we
|
* If <b>bindaddress</b> includes a port, we bind on that port; otherwise, we
|
||||||
* use bindport.
|
* use bindport.
|
||||||
*/
|
*/
|
||||||
int connection_create_listener(char *bindaddress, uint16_t bindport, int type) {
|
static int connection_create_listener(const char *bindaddress, uint16_t bindport, int type) {
|
||||||
struct sockaddr_in bindaddr; /* where to bind */
|
struct sockaddr_in bindaddr; /* where to bind */
|
||||||
connection_t *conn;
|
connection_t *conn;
|
||||||
char *hostname, *cp;
|
char *hostname, *cp;
|
||||||
@ -488,54 +490,64 @@ int connection_connect(connection_t *conn, char *address, uint32_t addr, uint16_
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** If there exists a listener of type <b>type</b> in the connection
|
/** If there exist any listeners of type <b>type</b> in the connection
|
||||||
* array, mark it for close.
|
* array, mark them for close.
|
||||||
*/
|
*/
|
||||||
static void listener_close_if_present(int type) {
|
static void listener_close_if_present(int type) {
|
||||||
connection_t *conn;
|
connection_t *conn;
|
||||||
|
connection_t **carray;
|
||||||
|
int i,n;
|
||||||
tor_assert(type == CONN_TYPE_OR_LISTENER ||
|
tor_assert(type == CONN_TYPE_OR_LISTENER ||
|
||||||
type == CONN_TYPE_AP_LISTENER ||
|
type == CONN_TYPE_AP_LISTENER ||
|
||||||
type == CONN_TYPE_DIR_LISTENER);
|
type == CONN_TYPE_DIR_LISTENER);
|
||||||
conn = connection_get_by_type(type);
|
get_connection_array(&carray,&n);
|
||||||
if (conn) {
|
for(i=0;i<n;i++) {
|
||||||
connection_close_immediate(conn);
|
conn = carray[i];
|
||||||
connection_mark_for_close(conn);
|
if (conn->type == type && !conn->marked_for_close) {
|
||||||
|
connection_close_immediate(conn);
|
||||||
|
connection_mark_for_close(conn);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int retry_listeners(int type, struct config_line_t *cfg,
|
||||||
|
int port_option, const char *default_addr)
|
||||||
|
{
|
||||||
|
listener_close_if_present(type);
|
||||||
|
if (port_option) {
|
||||||
|
if (!cfg) {
|
||||||
|
if (connection_create_listener(default_addr, (uint16_t) port_option,
|
||||||
|
type)<0)
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
for ( ; cfg; cfg = cfg->next) {
|
||||||
|
if (connection_create_listener(cfg->value, (uint16_t) port_option,
|
||||||
|
type)<0)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/** Start all connections that should be up but aren't.
|
/** Start all connections that should be up but aren't.
|
||||||
* - Connect to all ORs if you're an OR.
|
* - Connect to all ORs if you're an OR.
|
||||||
* - Relaunch listeners for each port you have open.
|
* - Relaunch listeners for each port you have open.
|
||||||
*/
|
*/
|
||||||
int retry_all_connections(void) {
|
int retry_all_connections(void) {
|
||||||
|
|
||||||
if(options.ORPort) {
|
if(options.ORPort) {
|
||||||
router_retry_connections();
|
router_retry_connections();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(options.ORPort) {
|
if (retry_listeners(CONN_TYPE_OR_LISTENER, options.ORBindAddress,
|
||||||
listener_close_if_present(CONN_TYPE_OR_LISTENER);
|
options.ORPort, "0.0.0.0")<0)
|
||||||
if(connection_create_listener(options.ORBindAddress,
|
return -1;
|
||||||
(uint16_t) options.ORPort,
|
if (retry_listeners(CONN_TYPE_DIR_LISTENER, options.DirBindAddress,
|
||||||
CONN_TYPE_OR_LISTENER) < 0)
|
options.DirPort, "0.0.0.0")<0)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
if (retry_listeners(CONN_TYPE_AP_LISTENER, options.SocksBindAddress,
|
||||||
|
options.SocksPort, "127.0.0.1")<0)
|
||||||
if(options.DirPort) {
|
return -1;
|
||||||
listener_close_if_present(CONN_TYPE_DIR_LISTENER);
|
|
||||||
if(connection_create_listener(options.DirBindAddress,
|
|
||||||
(uint16_t) options.DirPort,
|
|
||||||
CONN_TYPE_DIR_LISTENER) < 0)
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(options.SocksPort) {
|
|
||||||
listener_close_if_present(CONN_TYPE_AP_LISTENER);
|
|
||||||
if(connection_create_listener(options.SocksBindAddress,
|
|
||||||
(uint16_t) options.SocksPort,
|
|
||||||
CONN_TYPE_AP_LISTENER) < 0)
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,11 @@
|
|||||||
extern or_options_t options; /* command-line and config-file options */
|
extern or_options_t options; /* command-line and config-file options */
|
||||||
extern char *conn_state_to_string[][_CONN_TYPE_MAX+1]; /* from connection.c */
|
extern char *conn_state_to_string[][_CONN_TYPE_MAX+1]; /* from connection.c */
|
||||||
|
|
||||||
|
static struct exit_policy_t *socks_policy = NULL;
|
||||||
|
|
||||||
static int connection_ap_handshake_process_socks(connection_t *conn);
|
static int connection_ap_handshake_process_socks(connection_t *conn);
|
||||||
|
static void parse_socks_policy(void);
|
||||||
|
static int socks_policy_permits_address(uint32_t addr);
|
||||||
|
|
||||||
/** Handle new bytes on conn->inbuf, or notification of eof.
|
/** Handle new bytes on conn->inbuf, or notification of eof.
|
||||||
*
|
*
|
||||||
@ -781,6 +785,38 @@ int connection_ap_can_use_exit(connection_t *conn, routerinfo_t *exit)
|
|||||||
conn->socks_request->port, exit->exit_policy);
|
conn->socks_request->port, exit->exit_policy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void parse_socks_policy(void)
|
||||||
|
{
|
||||||
|
struct exit_policy_t *n;
|
||||||
|
if (socks_policy) {
|
||||||
|
exit_policy_free(socks_policy);
|
||||||
|
socks_policy = NULL;
|
||||||
|
}
|
||||||
|
config_parse_exit_policy(options.SocksPolicy, &socks_policy);
|
||||||
|
/* ports aren't used. */
|
||||||
|
for (n=socks_policy; n; n = n->next) {
|
||||||
|
n->prt_min = 1;
|
||||||
|
n->prt_max = 65535;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int socks_policy_permits_address(uint32_t addr)
|
||||||
|
{
|
||||||
|
int a;
|
||||||
|
if (options.SocksPolicy && !socks_policy)
|
||||||
|
parse_socks_policy();
|
||||||
|
|
||||||
|
a = router_compare_addr_to_exit_policy(addr, 1, socks_policy);
|
||||||
|
if (a==-1)
|
||||||
|
return 0;
|
||||||
|
else if (a==0)
|
||||||
|
return 1;
|
||||||
|
else if (a==1) {
|
||||||
|
log_fn(LOG_WARN, "Got unexpected 'maybe' answer from socks policy");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* ***** Client DNS code ***** */
|
/* ***** Client DNS code ***** */
|
||||||
|
|
||||||
/* XXX Perhaps this should get merged with the dns.c code somehow. */
|
/* XXX Perhaps this should get merged with the dns.c code somehow. */
|
||||||
|
21
src/or/or.h
21
src/or/or.h
@ -777,13 +777,14 @@ typedef struct {
|
|||||||
char *RendExcludeNodes; /**< Comma-separated list of nicknames not to use
|
char *RendExcludeNodes; /**< Comma-separated list of nicknames not to use
|
||||||
* as introduction points. */
|
* as introduction points. */
|
||||||
|
|
||||||
char *ExitPolicy; /**< Comma-separated list of exit policy components. */
|
struct config_line_t *ExitPolicy; /**< Lists of exit policy components. */
|
||||||
char *SocksBindAddress; /**< Address to bind for listening for SOCKS
|
struct config_line_t *SocksPolicy; /**< Lists of socks policy components */
|
||||||
* connections. */
|
struct config_line_t *SocksBindAddress;
|
||||||
char *ORBindAddress; /**< Address to bind for listening for OR
|
/**< Addresses to bind for listening for SOCKS connections. */
|
||||||
* connections. */
|
struct config_line_t *ORBindAddress;
|
||||||
char *DirBindAddress; /**< Address to bind for listening for directory
|
/**< Addresses to bind for listening for OR connections. */
|
||||||
* connections. */
|
struct config_line_t *DirBindAddress;
|
||||||
|
/**< Addresses to bind for listening for directory connections. */
|
||||||
char *RecommendedVersions; /**< Directory server only: which versions of
|
char *RecommendedVersions; /**< Directory server only: which versions of
|
||||||
* Tor should we tell users to run? */
|
* Tor should we tell users to run? */
|
||||||
char *User; /**< Name of user to run Tor as. */
|
char *User; /**< Name of user to run Tor as. */
|
||||||
@ -953,6 +954,9 @@ struct config_line_t {
|
|||||||
int config_assign_default_dirservers(void);
|
int config_assign_default_dirservers(void);
|
||||||
int getconfig(int argc, char **argv, or_options_t *options);
|
int getconfig(int argc, char **argv, or_options_t *options);
|
||||||
void config_init_logs(or_options_t *options);
|
void config_init_logs(or_options_t *options);
|
||||||
|
void config_parse_exit_policy(struct config_line_t *cfg,
|
||||||
|
struct exit_policy_t **dest);
|
||||||
|
void exit_policy_free(struct exit_policy_t *p);
|
||||||
|
|
||||||
/********************************* connection.c ***************************/
|
/********************************* connection.c ***************************/
|
||||||
|
|
||||||
@ -982,8 +986,6 @@ int _connection_mark_for_close(connection_t *conn);
|
|||||||
|
|
||||||
void connection_expire_held_open(void);
|
void connection_expire_held_open(void);
|
||||||
|
|
||||||
int connection_create_listener(char *bindaddress, uint16_t bindport, int type);
|
|
||||||
|
|
||||||
int connection_connect(connection_t *conn, char *address, uint32_t addr, uint16_t port);
|
int connection_connect(connection_t *conn, char *address, uint32_t addr, uint16_t port);
|
||||||
int retry_all_connections(void);
|
int retry_all_connections(void);
|
||||||
|
|
||||||
@ -1318,6 +1320,7 @@ int router_parse_routerlist_from_directory(const char *s,
|
|||||||
crypto_pk_env_t *pkey);
|
crypto_pk_env_t *pkey);
|
||||||
routerinfo_t *router_parse_entry_from_string(const char *s, const char *end);
|
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);
|
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);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -324,41 +324,6 @@ void router_upload_dir_desc_to_dirservers(void) {
|
|||||||
directory_post_to_dirservers(DIR_PURPOSE_UPLOAD_DIR, s, strlen(s));
|
directory_post_to_dirservers(DIR_PURPOSE_UPLOAD_DIR, s, strlen(s));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Append the comma-separated sequence of exit policies in <b>s</b> to the
|
|
||||||
* exit policy in <b>router</b>. */
|
|
||||||
static void router_add_exit_policy_from_config_helper(const char *s, routerinfo_t *router) {
|
|
||||||
char *e;
|
|
||||||
int last=0;
|
|
||||||
char line[1024];
|
|
||||||
|
|
||||||
if(!s) {
|
|
||||||
log_fn(LOG_INFO,"No exit policy configured. Ok.");
|
|
||||||
return; /* nothing to see here */
|
|
||||||
}
|
|
||||||
if(!*s) {
|
|
||||||
log_fn(LOG_INFO,"Exit policy is empty. Ok.");
|
|
||||||
return; /* nothing to see here */
|
|
||||||
}
|
|
||||||
|
|
||||||
for(;;) {
|
|
||||||
e = strchr(s,',');
|
|
||||||
if(!e) {
|
|
||||||
last = 1;
|
|
||||||
strncpy(line,s,1023);
|
|
||||||
} else {
|
|
||||||
memcpy(line,s, ((e-s)<1023)?(e-s):1023);
|
|
||||||
line[e-s] = 0;
|
|
||||||
}
|
|
||||||
line[1023]=0;
|
|
||||||
log_fn(LOG_DEBUG,"Adding new entry '%s'",line);
|
|
||||||
if(router_add_exit_policy_from_string(router,line) < 0)
|
|
||||||
log_fn(LOG_WARN,"Malformed exit policy %s; skipping.", line);
|
|
||||||
if(last)
|
|
||||||
return;
|
|
||||||
s = e+1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#define DEFAULT_EXIT_POLICY "reject 0.0.0.0/8,reject 169.254.0.0/16,reject 127.0.0.0/8,reject 192.168.0.0/16,reject 10.0.0.0/8,reject 172.16.0.0/12,accept *:20-22,accept *:53,accept *:79-81,accept *:110,accept *:143,accept *:443,accept *:873,accept *:993,accept *:995,accept *:1024-65535,reject *:*"
|
#define DEFAULT_EXIT_POLICY "reject 0.0.0.0/8,reject 169.254.0.0/16,reject 127.0.0.0/8,reject 192.168.0.0/16,reject 10.0.0.0/8,reject 172.16.0.0/12,accept *:20-22,accept *:53,accept *:79-81,accept *:110,accept *:143,accept *:443,accept *:873,accept *:993,accept *:995,accept *:1024-65535,reject *:*"
|
||||||
|
|
||||||
/** Set the exit policy on <b>router</b> to match the exit policy in the
|
/** Set the exit policy on <b>router</b> to match the exit policy in the
|
||||||
@ -366,14 +331,22 @@ static void router_add_exit_policy_from_config_helper(const char *s, routerinfo_
|
|||||||
* rule, then append the default exit policy as well.
|
* rule, then append the default exit policy as well.
|
||||||
*/
|
*/
|
||||||
static void router_add_exit_policy_from_config(routerinfo_t *router) {
|
static void router_add_exit_policy_from_config(routerinfo_t *router) {
|
||||||
router_add_exit_policy_from_config_helper(options.ExitPolicy, router);
|
struct exit_policy_t *ep;
|
||||||
/* XXXX This is wrong; you can spell *:* many ways. -NM
|
struct config_line_t default_policy;
|
||||||
* So? If they spell it sneakily, then their exit policy is bulkier. -RD */
|
config_parse_exit_policy(options.ExitPolicy, &router->exit_policy);
|
||||||
if(strstr(options.ExitPolicy," *:*") == NULL) {
|
|
||||||
/* if exitpolicy includes a *:* line, then we're done. Else, append
|
for (ep = router->exit_policy; ep; ep = ep->next) {
|
||||||
* the default exitpolicy. */
|
if (ep->msk == 0 && ep->prt_min <= 1 && ep->prt_max >= 65535) {
|
||||||
router_add_exit_policy_from_config_helper(DEFAULT_EXIT_POLICY, router);
|
/* if exitpolicy includes a *:* line, then we're done. */
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Else, append the default exitpolicy. */
|
||||||
|
default_policy.key = NULL;
|
||||||
|
default_policy.value = DEFAULT_EXIT_POLICY;
|
||||||
|
default_policy.next = NULL;
|
||||||
|
config_parse_exit_policy(&default_policy, &router->exit_policy);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** OR only: Return false if my exit policy says to allow connection to
|
/** OR only: Return false if my exit policy says to allow connection to
|
||||||
|
@ -232,8 +232,6 @@ void router_get_routerlist(routerlist_t **prouterlist) {
|
|||||||
/** Free all storage held by <b>router</b>. */
|
/** Free all storage held by <b>router</b>. */
|
||||||
void routerinfo_free(routerinfo_t *router)
|
void routerinfo_free(routerinfo_t *router)
|
||||||
{
|
{
|
||||||
struct exit_policy_t *e;
|
|
||||||
|
|
||||||
if (!router)
|
if (!router)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -244,12 +242,7 @@ void routerinfo_free(routerinfo_t *router)
|
|||||||
crypto_free_pk_env(router->onion_pkey);
|
crypto_free_pk_env(router->onion_pkey);
|
||||||
if (router->identity_pkey)
|
if (router->identity_pkey)
|
||||||
crypto_free_pk_env(router->identity_pkey);
|
crypto_free_pk_env(router->identity_pkey);
|
||||||
while (router->exit_policy) {
|
exit_policy_free(router->exit_policy);
|
||||||
e = router->exit_policy;
|
|
||||||
router->exit_policy = e->next;
|
|
||||||
tor_free(e->string);
|
|
||||||
free(e);
|
|
||||||
}
|
|
||||||
free(router);
|
free(router);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,6 +115,7 @@ static struct {
|
|||||||
|
|
||||||
/* static function prototypes */
|
/* static function prototypes */
|
||||||
static int router_add_exit_policy(routerinfo_t *router,directory_token_t *tok);
|
static int router_add_exit_policy(routerinfo_t *router,directory_token_t *tok);
|
||||||
|
static struct exit_policy_t *router_parse_exit_policy(directory_token_t *tok);
|
||||||
static int router_get_hash_impl(const char *s, char *digest,
|
static int router_get_hash_impl(const char *s, char *digest,
|
||||||
const char *start_str, const char *end_str);
|
const char *start_str, const char *end_str);
|
||||||
static void token_free(directory_token_t *tok);
|
static void token_free(directory_token_t *tok);
|
||||||
@ -590,15 +591,15 @@ routerinfo_t *router_parse_entry_from_string(const char *s,
|
|||||||
return router;
|
return router;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Parse the exit policy in the string <b>s</b> and add it to <b>router</b>.
|
/** Parse the exit policy in the string <b>s</b> and return it.
|
||||||
*/
|
*/
|
||||||
int
|
struct exit_policy_t *
|
||||||
router_add_exit_policy_from_string(routerinfo_t *router, const char *s)
|
router_parse_exit_policy_from_string(const char *s)
|
||||||
{
|
{
|
||||||
directory_token_t *tok = NULL;
|
directory_token_t *tok = NULL;
|
||||||
const char *cp;
|
const char *cp;
|
||||||
char *tmp;
|
char *tmp;
|
||||||
int r;
|
struct exit_policy_t *r;
|
||||||
int len, idx;
|
int len, idx;
|
||||||
|
|
||||||
/* *s might not end with \n, so we need to extend it with one. */
|
/* *s might not end with \n, so we need to extend it with one. */
|
||||||
@ -620,22 +621,49 @@ router_add_exit_policy_from_string(routerinfo_t *router, const char *s)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Now that we've gotten an exit policy, add it to the router. */
|
/* Now that we've gotten an exit policy, add it to the router. */
|
||||||
r = router_add_exit_policy(router, tok);
|
r = router_parse_exit_policy(tok);
|
||||||
goto done;
|
goto done;
|
||||||
err:
|
err:
|
||||||
r = -1;
|
r = NULL;
|
||||||
done:
|
done:
|
||||||
free(tmp);
|
free(tmp);
|
||||||
token_free(tok);
|
token_free(tok);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int router_add_exit_policy_from_string(routerinfo_t *router, const char *s)
|
||||||
|
{
|
||||||
|
struct exit_policy_t *newe, *tmpe;
|
||||||
|
newe = router_parse_exit_policy_from_string(s);
|
||||||
|
if (!newe)
|
||||||
|
return -1;
|
||||||
|
for (tmpe = router->exit_policy; tmpe; tmpe=tmpe->next)
|
||||||
|
;
|
||||||
|
tmpe->next = newe;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int router_add_exit_policy(routerinfo_t *router,directory_token_t *tok)
|
||||||
|
{
|
||||||
|
struct exit_policy_t *newe, **tmpe;
|
||||||
|
newe = router_parse_exit_policy(tok);
|
||||||
|
if (!newe)
|
||||||
|
return -1;
|
||||||
|
for (tmpe = &router->exit_policy; *tmpe; tmpe=&((*tmpe)->next))
|
||||||
|
;
|
||||||
|
*tmpe = newe;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/** Given a K_ACCEPT or K_REJECT token and a router, create a new exit_policy_t
|
/** Given a K_ACCEPT or K_REJECT token and a router, create a new exit_policy_t
|
||||||
* corresponding to the token, and add it to <b>router</b> */
|
* corresponding to the token, and add it to <b>router</b> */
|
||||||
static int
|
static struct exit_policy_t *
|
||||||
router_add_exit_policy(routerinfo_t *router, directory_token_t *tok) {
|
router_parse_exit_policy(directory_token_t *tok) {
|
||||||
|
|
||||||
struct exit_policy_t *tmpe, *newe;
|
struct exit_policy_t*newe;
|
||||||
struct in_addr in;
|
struct in_addr in;
|
||||||
char *arg, *address, *mask, *port, *endptr;
|
char *arg, *address, *mask, *port, *endptr;
|
||||||
int bits;
|
int bits;
|
||||||
@ -643,7 +671,7 @@ router_add_exit_policy(routerinfo_t *router, directory_token_t *tok) {
|
|||||||
tor_assert(tok->tp == K_REJECT || tok->tp == K_ACCEPT);
|
tor_assert(tok->tp == K_REJECT || tok->tp == K_ACCEPT);
|
||||||
|
|
||||||
if (tok->n_args != 1)
|
if (tok->n_args != 1)
|
||||||
return -1;
|
return NULL;
|
||||||
arg = tok->args[0];
|
arg = tok->args[0];
|
||||||
|
|
||||||
newe = tor_malloc_zero(sizeof(struct exit_policy_t));
|
newe = tor_malloc_zero(sizeof(struct exit_policy_t));
|
||||||
@ -728,24 +756,15 @@ router_add_exit_policy(routerinfo_t *router, directory_token_t *tok) {
|
|||||||
address, inet_ntoa(in), newe->prt_min, newe->prt_max);
|
address, inet_ntoa(in), newe->prt_min, newe->prt_max);
|
||||||
tor_free(address);
|
tor_free(address);
|
||||||
|
|
||||||
/* now link newe onto the end of exit_policy */
|
newe->next = NULL;
|
||||||
|
return newe;
|
||||||
if(!router->exit_policy) {
|
|
||||||
router->exit_policy = newe;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(tmpe=router->exit_policy; tmpe->next; tmpe=tmpe->next) ;
|
|
||||||
tmpe->next = newe;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
policy_read_failed:
|
policy_read_failed:
|
||||||
tor_assert(newe->string);
|
tor_assert(newe->string);
|
||||||
log_fn(LOG_WARN,"Couldn't parse line '%s'. Dropping", newe->string);
|
log_fn(LOG_WARN,"Couldn't parse line '%s'. Dropping", newe->string);
|
||||||
tor_free(newe->string);
|
tor_free(newe->string);
|
||||||
free(newe);
|
free(newe);
|
||||||
return -1;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
Reference in New Issue
Block a user