mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-01-17 19:03:42 +01:00
Tor: don't do seed queries if we're supposed to always use proxy.
Risks leakage. We could do lookup via the proxy, but that's a TODO. There's only one occurance of getaddrinfo (and no gethostbyname), so we add a flag to the callers. Note: the use of --always-use-proxy suppresses *all* DNS lookups, even those from connect commands and the command line. FIXME: An implicit setting of use_proxy_always is done in gossipd if it determines that we are announcing nothing but Tor addresses, but that does *not* suppress 'connect'. This is fixed in a later patch. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
9d8e3cf3da
commit
5a0bc83b20
@ -85,35 +85,35 @@ int main(void)
|
||||
assert(!separate_address_and_port(tmpctx, "[::1]:http", &ip, &port));
|
||||
|
||||
// localhost hostnames for backward compat
|
||||
assert(parse_wireaddr("localhost", &addr, 200, NULL));
|
||||
assert(parse_wireaddr("localhost", &addr, 200, false, NULL));
|
||||
assert(addr.port == 200);
|
||||
|
||||
// string should win the port battle
|
||||
assert(parse_wireaddr("[::1]:9735", &addr, 500, NULL));
|
||||
assert(parse_wireaddr("[::1]:9735", &addr, 500, false, NULL));
|
||||
assert(addr.port == 9735);
|
||||
ip = fmt_wireaddr(tmpctx, &addr);
|
||||
assert(streq(ip, "[::1]:9735"));
|
||||
|
||||
// should use argument if we have no port in string
|
||||
assert(parse_wireaddr("2001:db8:85a3::8a2e:370:7334", &addr, 9777, NULL));
|
||||
assert(parse_wireaddr("2001:db8:85a3::8a2e:370:7334", &addr, 9777, false, NULL));
|
||||
assert(addr.port == 9777);
|
||||
|
||||
ip = fmt_wireaddr(tmpctx, &addr);
|
||||
assert(streq(ip, "[2001:db8:85a3::8a2e:370:7334]:9777"));
|
||||
|
||||
assert(parse_wireaddr("[::ffff:127.0.0.1]:49150", &addr, 1, NULL));
|
||||
assert(parse_wireaddr("[::ffff:127.0.0.1]:49150", &addr, 1, false, NULL));
|
||||
assert(addr.port == 49150);
|
||||
|
||||
assert(parse_wireaddr("4ruvswpqec5i2gogopxl4vm5bruzknbvbylov2awbo4rxiq4cimdldad.onion:49150", &addr, 1, NULL));
|
||||
assert(parse_wireaddr("4ruvswpqec5i2gogopxl4vm5bruzknbvbylov2awbo4rxiq4cimdldad.onion:49150", &addr, 1, false, NULL));
|
||||
assert(addr.port == 49150);
|
||||
|
||||
assert(parse_wireaddr("4ruvswpqec5i2gogopxl4vm5bruzknbvbylov2awbo4rxiq4cimdldad.onion", &addr, 1, NULL));
|
||||
assert(parse_wireaddr("4ruvswpqec5i2gogopxl4vm5bruzknbvbylov2awbo4rxiq4cimdldad.onion", &addr, 1, false, NULL));
|
||||
assert(addr.port == 1);
|
||||
|
||||
assert(parse_wireaddr("odpzvneidqdf5hdq.onion:49150", &addr, 1, NULL));
|
||||
assert(parse_wireaddr("odpzvneidqdf5hdq.onion:49150", &addr, 1, false, NULL));
|
||||
assert(addr.port == 49150);
|
||||
|
||||
assert(parse_wireaddr("odpzvneidqdf5hdq.onion", &addr, 1, NULL));
|
||||
assert(parse_wireaddr("odpzvneidqdf5hdq.onion", &addr, 1, false, NULL));
|
||||
assert(addr.port == 1);
|
||||
tal_free(tmpctx);
|
||||
return 0;
|
||||
|
@ -262,7 +262,7 @@ static bool separate_address_and_port(const tal_t *ctx, const char *arg,
|
||||
}
|
||||
|
||||
bool wireaddr_from_hostname(struct wireaddr *addr, const char *hostname,
|
||||
const u16 port, const char **err_msg)
|
||||
const u16 port, bool dns_ok, const char **err_msg)
|
||||
{
|
||||
struct sockaddr_in6 *sa6;
|
||||
struct sockaddr_in *sa4;
|
||||
@ -296,6 +296,8 @@ bool wireaddr_from_hostname(struct wireaddr *addr, const char *hostname,
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
hints.ai_protocol = 0;
|
||||
hints.ai_flags = AI_ADDRCONFIG;
|
||||
if (!dns_ok)
|
||||
hints.ai_flags = AI_NUMERICHOST;
|
||||
gai_err = getaddrinfo(hostname, tal_fmt(tmpctx, "%d", port),
|
||||
&hints, &addrinfo);
|
||||
if (gai_err != 0) {
|
||||
@ -320,7 +322,7 @@ bool wireaddr_from_hostname(struct wireaddr *addr, const char *hostname,
|
||||
}
|
||||
|
||||
bool parse_wireaddr(const char *arg, struct wireaddr *addr, u16 defport,
|
||||
const char **err_msg)
|
||||
bool dns_ok, const char **err_msg)
|
||||
{
|
||||
struct in6_addr v6;
|
||||
struct in_addr v4;
|
||||
@ -353,7 +355,7 @@ bool parse_wireaddr(const char *arg, struct wireaddr *addr, u16 defport,
|
||||
|
||||
/* Resolve with getaddrinfo */
|
||||
if (!res)
|
||||
res = wireaddr_from_hostname(addr, ip, port, err_msg);
|
||||
res = wireaddr_from_hostname(addr, ip, port, dns_ok, err_msg);
|
||||
|
||||
finish:
|
||||
if (!res && err_msg && !*err_msg)
|
||||
@ -362,7 +364,8 @@ finish:
|
||||
}
|
||||
|
||||
bool parse_wireaddr_internal(const char *arg, struct wireaddr_internal *addr,
|
||||
u16 port, bool wildcard_ok, const char **err_msg)
|
||||
u16 port, bool wildcard_ok, bool dns_ok,
|
||||
const char **err_msg)
|
||||
{
|
||||
u16 wildport;
|
||||
char *ip;
|
||||
@ -392,7 +395,7 @@ bool parse_wireaddr_internal(const char *arg, struct wireaddr_internal *addr,
|
||||
}
|
||||
|
||||
addr->itype = ADDR_INTERNAL_WIREADDR;
|
||||
return parse_wireaddr(arg, &addr->u.wireaddr, port, err_msg);
|
||||
return parse_wireaddr(arg, &addr->u.wireaddr, port, dns_ok, err_msg);
|
||||
}
|
||||
|
||||
void wireaddr_from_sockname(struct wireaddr_internal *addr,
|
||||
|
@ -67,13 +67,14 @@ enum addr_listen_announce fromwire_addr_listen_announce(const u8 **cursor,
|
||||
size_t *max);
|
||||
void towire_addr_listen_announce(u8 **pptr, enum addr_listen_announce ala);
|
||||
|
||||
bool parse_wireaddr(const char *arg, struct wireaddr *addr, u16 port, const char **err_msg);
|
||||
bool parse_wireaddr(const char *arg, struct wireaddr *addr, u16 port,
|
||||
bool dns_ok, const char **err_msg);
|
||||
|
||||
char *fmt_wireaddr(const tal_t *ctx, const struct wireaddr *a);
|
||||
char *fmt_wireaddr_without_port(const tal_t *ctx, const struct wireaddr *a);
|
||||
|
||||
bool wireaddr_from_hostname(struct wireaddr *addr, const char *hostname,
|
||||
const u16 port, const char **err_msg);
|
||||
const u16 port, bool dns_ok, const char **err_msg);
|
||||
|
||||
void wireaddr_from_ipv4(struct wireaddr *addr,
|
||||
const struct in_addr *ip4,
|
||||
@ -104,7 +105,9 @@ struct wireaddr_internal {
|
||||
char sockname[sizeof(((struct sockaddr_un *)0)->sun_path)];
|
||||
} u;
|
||||
};
|
||||
bool parse_wireaddr_internal(const char *arg, struct wireaddr_internal *addr, u16 port, bool wildcard_ok, const char **err_msg);
|
||||
bool parse_wireaddr_internal(const char *arg, struct wireaddr_internal *addr,
|
||||
u16 port, bool wildcard_ok, bool dns_ok,
|
||||
const char **err_msg);
|
||||
|
||||
void towire_wireaddr_internal(u8 **pptr,
|
||||
const struct wireaddr_internal *addr);
|
||||
|
@ -1930,7 +1930,8 @@ static struct io_plan *conn_tor_init(struct io_conn *conn,
|
||||
}
|
||||
|
||||
static struct addrhint *
|
||||
seed_resolve_addr(const tal_t *ctx, const struct pubkey *id, const u16 port)
|
||||
seed_resolve_addr(const tal_t *ctx, const struct pubkey *id, const u16 port,
|
||||
bool dns_ok)
|
||||
{
|
||||
struct addrhint *a;
|
||||
char bech32[100], *addr;
|
||||
@ -1946,7 +1947,8 @@ seed_resolve_addr(const tal_t *ctx, const struct pubkey *id, const u16 port)
|
||||
|
||||
a = tal(ctx, struct addrhint);
|
||||
a->addr.itype = ADDR_INTERNAL_WIREADDR;
|
||||
if (!wireaddr_from_hostname(&a->addr.u.wireaddr, addr, port, NULL)) {
|
||||
if (!wireaddr_from_hostname(&a->addr.u.wireaddr, addr, port, dns_ok,
|
||||
NULL)) {
|
||||
status_trace("Could not resolve %s", addr);
|
||||
return tal_free(a);
|
||||
} else {
|
||||
@ -2033,7 +2035,8 @@ static void try_reach_peer(struct daemon *daemon, const struct pubkey *id,
|
||||
id);
|
||||
|
||||
if (!a)
|
||||
a = seed_resolve_addr(tmpctx, id, 9735);
|
||||
a = seed_resolve_addr(tmpctx, id, 9735,
|
||||
!daemon->use_proxy_always);
|
||||
|
||||
if (!a) {
|
||||
status_debug("No address known for %s, giving up",
|
||||
|
@ -152,6 +152,7 @@ static void json_connect(struct command *cmd,
|
||||
port = DEFAULT_PORT;
|
||||
}
|
||||
if (!parse_wireaddr_internal(name, &addr, port, false,
|
||||
!cmd->ld->use_proxy_always,
|
||||
&err_msg)) {
|
||||
command_fail(cmd, "Host %s:%u not valid: %s",
|
||||
name, port, err_msg ? err_msg : "port is 0");
|
||||
|
@ -159,7 +159,7 @@ static char *opt_add_addr_withtype(const char *arg,
|
||||
ld->proposed_listen_announce[n] = ala;
|
||||
|
||||
if (!parse_wireaddr_internal(arg, &ld->proposed_wireaddr[n], ld->portnum,
|
||||
true, &err_msg)) {
|
||||
true, !ld->use_proxy_always, &err_msg)) {
|
||||
return tal_fmt(NULL, "Unable to parse address '%s': %s", arg, err_msg);
|
||||
}
|
||||
|
||||
@ -302,7 +302,8 @@ static char *opt_add_proxy_addr(const char *arg, struct lightningd *ld)
|
||||
/* We use a tal_arr here, so we can marshal it to gossipd */
|
||||
ld->proxyaddr = tal_arr(ld, struct wireaddr, 1);
|
||||
|
||||
if (!parse_wireaddr(arg, ld->proxyaddr, 9050, NULL)) {
|
||||
if (!parse_wireaddr(arg, ld->proxyaddr, 9050, !ld->use_proxy_always,
|
||||
NULL)) {
|
||||
return tal_fmt(NULL, "Unable to parse Tor proxy address '%s'",
|
||||
arg);
|
||||
}
|
||||
@ -313,7 +314,8 @@ static char *opt_add_tor_service_addr(const char *arg, struct lightningd *ld)
|
||||
{
|
||||
tal_free(ld->tor_serviceaddr);
|
||||
ld->tor_serviceaddr = tal(ld, struct wireaddr);
|
||||
if (!parse_wireaddr(arg, ld->tor_serviceaddr, 9051, NULL)) {
|
||||
if (!parse_wireaddr(arg, ld->tor_serviceaddr, 9051,
|
||||
!ld->use_proxy_always, NULL)) {
|
||||
return tal_fmt(NULL, "Unable to parse Tor service address '%s'",
|
||||
arg);
|
||||
}
|
||||
@ -432,7 +434,10 @@ static void config_register_opts(struct lightningd *ld)
|
||||
"Set a Tor hidden service password");
|
||||
opt_register_arg("--tor-auto-listen", opt_set_bool_arg, opt_show_bool,
|
||||
&ld->config.tor_enable_auto_hidden_service , "Generate and use a temp auto hidden-service and show the onion address");
|
||||
opt_register_arg("--always-use-proxy", opt_set_bool_arg, opt_show_bool,
|
||||
|
||||
/* Early, as it suppresses DNS lookups from cmdline too. */
|
||||
opt_register_early_arg("--always-use-proxy",
|
||||
opt_set_bool_arg, opt_show_bool,
|
||||
&ld->use_proxy_always, "Use the proxy always");
|
||||
}
|
||||
|
||||
|
@ -94,7 +94,7 @@ static void make_onion(struct lightningd *ld, struct rbuf *rbuf)
|
||||
tal_resize(&ld->proposed_listen_announce, n + 1);
|
||||
parse_wireaddr_internal(tal_fmt(tmpctx, "%s.onion", line),
|
||||
&ld->proposed_wireaddr[n],
|
||||
ld->portnum, false, NULL);
|
||||
ld->portnum, false, false, NULL);
|
||||
ld->proposed_listen_announce[n] = ADDR_ANNOUNCE;
|
||||
discard_remaining_response(ld, rbuf);
|
||||
return;
|
||||
|
@ -510,7 +510,7 @@ static struct peer *wallet_peer_load(struct wallet *w, const u64 dbid)
|
||||
addrstr = sqlite3_column_text(stmt, 2);
|
||||
if (addrstr) {
|
||||
addrp = &addr;
|
||||
if (!parse_wireaddr_internal((const char*)addrstr, addrp, DEFAULT_PORT, false, NULL)) {
|
||||
if (!parse_wireaddr_internal((const char*)addrstr, addrp, DEFAULT_PORT, false, false, NULL)) {
|
||||
db_stmt_done(stmt);
|
||||
return NULL;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user