Skip to content

Commit

Permalink
Refuse to parse v2 onion addresses without deprecated_apis
Browse files Browse the repository at this point in the history
Tor v2 hidden services have been deprecated for a while:
https://blog.torproject.org/v2-deprecation-timeline .

This prevents user from being able to set them in the configuration
and to connect to them while still letting us be able to parse them
for gossip.

Signed-off-by: Antoine Poinsot <[email protected]>
  • Loading branch information
darosior committed May 20, 2021
1 parent de13855 commit aff0c6a
Show file tree
Hide file tree
Showing 12 changed files with 154 additions and 129 deletions.
7 changes: 7 additions & 0 deletions common/test/run-ip_port_parsing.c
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ void towire_u8_array(u8 **pptr UNNEEDED, const u8 *arr UNNEEDED, size_t num UNNE
int main(int argc, char *argv[])
{
struct wireaddr addr;
struct wireaddr_internal addr_int;
char *ip;
u16 port;

Expand Down Expand Up @@ -189,6 +190,12 @@ int main(int argc, char *argv[])
assert(parse_wireaddr("odpzvneidqdf5hdq.onion", &addr, 1, false, NULL));
assert(addr.port == 1);

// Don't accept legacy hidden services with deprecated APIs on
assert(!parse_wireaddr_internal("odpzvneidqdf5hdq.onion", &addr_int, 1,
false, false, false, /* allow_deprecated = */ false, NULL));
assert(parse_wireaddr_internal("odpzvneidqdf5hdq.onion", &addr_int, 1,
false, false, false, /* allow_deprecated = */ true, NULL));

assert(tal_count(wireaddr_from_hostname(tmpctx, "odpzvneidqdf5hdq.onion", 1, NULL, NULL, NULL)) > 0);
assert(wireaddr_from_hostname(tmpctx, "aaa.onion", 1, NULL, NULL, NULL) == NULL);

Expand Down
12 changes: 10 additions & 2 deletions common/wireaddr.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <ccan/str/hex/hex.h>
#include <ccan/tal/str/str.h>
#include <common/base32.h>
#include <common/configdir.h>
#include <common/type_to_string.h>
#include <common/utils.h>
#include <common/wireaddr.h>
Expand Down Expand Up @@ -446,7 +447,7 @@ bool parse_wireaddr(const char *arg, struct wireaddr *addr, u16 defport,

bool parse_wireaddr_internal(const char *arg, struct wireaddr_internal *addr,
u16 port, bool wildcard_ok, bool dns_ok,
bool unresolved_ok,
bool unresolved_ok, bool allow_deprecated,
const char **err_msg)
{
u16 splitport;
Expand Down Expand Up @@ -578,8 +579,15 @@ bool parse_wireaddr_internal(const char *arg, struct wireaddr_internal *addr,

addr->itype = ADDR_INTERNAL_WIREADDR;
if (parse_wireaddr(arg, &addr->u.wireaddr, port,
dns_ok ? NULL : &needed_dns, err_msg))
dns_ok ? NULL : &needed_dns, err_msg)) {
if (!allow_deprecated && addr->u.wireaddr.type == ADDR_TYPE_TOR_V2) {
if (err_msg)
*err_msg = "v2 Tor onion services are deprecated";
return false;
}

return true;
}

if (!needed_dns || !unresolved_ok)
return false;
Expand Down
3 changes: 2 additions & 1 deletion common/wireaddr.h
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,8 @@ struct wireaddr_internal {
};
bool parse_wireaddr_internal(const char *arg, struct wireaddr_internal *addr,
u16 port, bool wildcard_ok, bool dns_ok,
bool unresolved_ok, const char **err_msg);
bool unresolved_ok, bool allow_deprecated,
const char **err_msg);

void towire_wireaddr_internal(u8 **pptr,
const struct wireaddr_internal *addr);
Expand Down
2 changes: 1 addition & 1 deletion devtools/gossipwith.c
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ int main(int argc, char *argv[])
(int)(at - argv[1]), argv[1]);

if (!parse_wireaddr_internal(at+1, &addr, DEFAULT_PORT, NULL,
true, false, &err_msg))
true, false, true, &err_msg))
opt_usage_exit_fail("%s '%s'", err_msg, argv[1]);

switch (addr.itype) {
Expand Down
3 changes: 2 additions & 1 deletion lightningd/connect_control.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include <ccan/fdpass/fdpass.h>
#include <ccan/list/list.h>
#include <ccan/tal/str/str.h>
#include <common/configdir.h>
#include <common/errcode.h>
#include <common/features.h>
#include <common/json_command.h>
Expand Down Expand Up @@ -166,7 +167,7 @@ static struct command_result *json_connect(struct command *cmd,
if (!parse_wireaddr_internal(name, addr, *port, false,
!cmd->ld->use_proxy_always
&& !cmd->ld->pure_tor_setup,
true,
true, deprecated_apis,
&err_msg)) {
return command_fail(cmd, LIGHTNINGD,
"Host %s:%u not valid: %s",
Expand Down
15 changes: 9 additions & 6 deletions lightningd/options.c
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ static char *opt_add_addr_withtype(const char *arg,
if (!parse_wireaddr_internal(arg, &wi,
ld->portnum,
wildcard_ok, !ld->use_proxy_always, false,
&err_msg)) {
deprecated_apis, &err_msg)) {
return tal_fmt(NULL, "Unable to parse address '%s': %s", arg, err_msg);
}
tal_arr_expand(&ld->proposed_wireaddr, wi);
Expand Down Expand Up @@ -202,7 +202,8 @@ static char *opt_add_addr(const char *arg, struct lightningd *ld)
struct wireaddr_internal addr;

/* handle in case you used the addr option with an .onion */
if (parse_wireaddr_internal(arg, &addr, 0, true, false, true, NULL)) {
if (parse_wireaddr_internal(arg, &addr, 0, true, false, true,
deprecated_apis, NULL)) {
if (addr.itype == ADDR_INTERNAL_WIREADDR && (
addr.u.wireaddr.type == ADDR_TYPE_TOR_V2 ||
addr.u.wireaddr.type == ADDR_TYPE_TOR_V3)) {
Expand Down Expand Up @@ -249,7 +250,8 @@ static char *opt_add_bind_addr(const char *arg, struct lightningd *ld)
struct wireaddr_internal addr;

/* handle in case you used the bind option with an .onion */
if (parse_wireaddr_internal(arg, &addr, 0, true, false, true, NULL)) {
if (parse_wireaddr_internal(arg, &addr, 0, true, false, true,
deprecated_apis, NULL)) {
if (addr.itype == ADDR_INTERNAL_WIREADDR && (
addr.u.wireaddr.type == ADDR_TYPE_TOR_V2 ||
addr.u.wireaddr.type == ADDR_TYPE_TOR_V3)) {
Expand Down Expand Up @@ -949,7 +951,7 @@ static void register_opts(struct lightningd *ld)
"Set an IP address (v4 or v6) to listen on, but not announce");
opt_register_arg("--announce-addr", opt_add_announce_addr, NULL,
ld,
"Set an IP address (v4 or v6) or .onion v2/v3 to announce, but not listen on");
"Set an IP address (v4 or v6) or .onion v3 to announce, but not listen on");

opt_register_noarg("--offline", opt_set_offline, ld,
"Start in offline-mode (do not automatically reconnect and do not accept incoming connections)");
Expand All @@ -966,8 +968,9 @@ static void register_opts(struct lightningd *ld)
opt_register_noarg("--disable-dns", opt_set_invbool, &ld->config.use_dns,
"Disable DNS lookups of peers");

opt_register_noarg("--enable-autotor-v2-mode", opt_set_invbool, &ld->config.use_v3_autotor,
"Try to get a v2 onion address from the Tor service call, default is v3");
if (deprecated_apis)
opt_register_noarg("--enable-autotor-v2-mode", opt_set_invbool, &ld->config.use_v3_autotor,
"Try to get a v2 onion address from the Tor service call, default is v3");

opt_register_noarg("--encrypted-hsm", opt_set_hsm_password, ld,
"Set the password to encrypt hsm_secret with. If no password is passed through command line, "
Expand Down
24 changes: 14 additions & 10 deletions tests/test_gossip.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ def test_announce_address(node_factory, bitcoind):
# We do not allow announcement of duplicates.
opts = {'announce-addr':
['4acth47i6kxnvkewtm6q7ib2s3ufpo5sqbsnzjpbi7utijcltosqemad.onion',
'silkroad6ownowfk.onion',
# 'silkroad6ownowfk.onion',
'1.2.3.4:1234',
'::'],
'log-level': 'io',
Expand All @@ -127,11 +127,11 @@ def test_announce_address(node_factory, bitcoind):

# We should see it send node announce with all addresses (257 = 0x0101)
# local ephemeral port is masked out.
l1.daemon.wait_for_log(r"\[OUT\] 0101.*54"
l1.daemon.wait_for_log(r"\[OUT\] 0101.*47"
"010102030404d2"
"017f000001...."
"02000000000000000000000000000000002607"
"039216a8b803f3acd758aa2607"
# "039216a8b803f3acd758aa2607"
"04e00533f3e8f2aedaa8969b3d0fa03a96e857bbb28064dca5e147e934244b9ba50230032607")


Expand Down Expand Up @@ -218,7 +218,6 @@ def test_connect_by_gossip(node_factory, bitcoind):
opts=[{'announce-addr':
['127.0.0.1:2',
'[::]:2',
'3fyb44wdhnd2ghhl.onion',
'vww6ybal4bd7szmgncyruucpgfkqahzddi37ktceo3ah7ngmcopnpyyd.onion'],
'dev-allow-localhost': None},
{},
Expand Down Expand Up @@ -904,12 +903,17 @@ def test_query_short_channel_id(node_factory, bitcoind, chainparams):


def test_gossip_addresses(node_factory, bitcoind):
l1 = node_factory.get_node(options={'announce-addr': [
'[::]:3',
'127.0.0.1:2',
'vww6ybal4bd7szmgncyruucpgfkqahzddi37ktceo3ah7ngmcopnpyyd.onion',
'3fyb44wdhnd2ghhl.onion:1234'
]})
l1 = node_factory.get_node(
options={
'announce-addr': [
'[::]:3',
'127.0.0.1:2',
'vww6ybal4bd7szmgncyruucpgfkqahzddi37ktceo3ah7ngmcopnpyyd.onion',
'3fyb44wdhnd2ghhl.onion:1234'
],
'allow-deprecated-apis': True,
}
)
l2 = node_factory.get_node()
l1.rpc.connect(l2.info['id'], 'localhost', l2.port)

Expand Down
2 changes: 1 addition & 1 deletion wallet/db_postgres_sqlgen.c

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion wallet/db_sqlite3_sqlgen.c

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit aff0c6a

Please sign in to comment.