Browse Source

Init commit to be able to create a tor static service on the fly.

We  want to have a static Tor service created from a blob bound to
our node on cmdline

Changelog-added: persistent Tor address support
Changelog-added: allow the Tor inbound service port differ from 9735

Signed-off-by: Saibato <saibato.naga@pm.me>

Add base64 encode/decode to common

We need this to encode the blob for the tor service

Signed-off-by: Saibato <saibato.naga@pm.me>
travis-debug
Saibato 5 years ago
committed by Christian Decker
parent
commit
f6006f43a9
  1. 1
      common/Makefile
  2. 37
      common/base64.c
  3. 10
      common/base64.h
  4. 118
      common/wireaddr.c
  5. 12
      common/wireaddr.h
  6. 1
      connectd/Makefile
  7. 81
      connectd/connectd.c
  8. 138
      connectd/tor_autoservice.c
  9. 13
      connectd/tor_autoservice.h
  10. 1
      devtools/gossipwith.c
  11. 1
      lightningd/Makefile
  12. 8
      lightningd/json.c
  13. 2
      lightningd/lightningd.h
  14. 6
      lightningd/options.c

1
common/Makefile

@ -2,6 +2,7 @@ COMMON_SRC_NOGEN := \
common/addr.c \
common/amount.c \
common/base32.c \
common/base64.c \
common/bech32.c \
common/bech32_util.c \
common/bigsize.c \

37
common/base64.c

@ -0,0 +1,37 @@
#include <common/base64.h>
#include <sodium.h>
#include <sodium/utils.h>
/* Decode/encode from/to base64, base64 helper functions.
* We import base64 from libsodium to generate tor V3 ED25519-V3 onions from blobs
*/
char *b64_encode(const tal_t *ctx, const u8 *data, size_t len)
{
char *str = tal_arr(ctx, char, sodium_base64_encoded_len(len, sodium_base64_VARIANT_ORIGINAL) + 1);
str = sodium_bin2base64(str, tal_count(str), data,
len, sodium_base64_VARIANT_ORIGINAL);
return str;
}
u8 *b64_decode(const tal_t *ctx, const char *str, size_t len)
{
size_t bin_len = len + 1;
u8 *ret = tal_arr(ctx, u8, bin_len);
if (!sodium_base642bin(ret,
tal_count(ret),
(const char * const)str,
len,
NULL,
&bin_len,
NULL,
sodium_base64_VARIANT_ORIGINAL))
return tal_free(ret);
ret[bin_len] = 0;
tal_resize(&ret, bin_len + 1);
return ret;
}

10
common/base64.h

@ -0,0 +1,10 @@
#ifndef LIGHTNING_COMMON_BASE64_H
#define LIGHTNING_COMMON_BASE64_H
#include "config.h"
#include <ccan/short_types/short_types.h>
#include <ccan/tal/tal.h>
char *b64_encode(const tal_t *ctx, const u8 *data, size_t len);
u8 *b64_decode(const tal_t *ctx, const char *str, size_t len);
#endif /* LIGHTNING_COMMON_BASE64_H */

118
common/wireaddr.c

@ -1,6 +1,7 @@
#include <arpa/inet.h>
#include <assert.h>
#include <ccan/build_assert/build_assert.h>
#include <ccan/err/err.h>
#include <ccan/io/io.h>
#include <ccan/mem/mem.h>
#include <ccan/str/hex/hex.h>
@ -13,6 +14,7 @@
#include <fcntl.h>
#include <netdb.h>
#include <netinet/in.h>
#include <sodium/randombytes.h>
#include <sys/types.h>
#include <unistd.h>
#include <wire/wire.h>
@ -80,7 +82,14 @@ void towire_wireaddr_internal(u8 **pptr, const struct wireaddr_internal *addr)
sizeof(addr->u.sockname));
return;
case ADDR_INTERNAL_AUTOTOR:
towire_wireaddr(pptr, &addr->u.torservice);
towire_wireaddr(pptr, &addr->u.torservice.address);
towire_u16(pptr, addr->u.torservice.port);
return;
case ADDR_INTERNAL_STATICTOR:
towire_wireaddr(pptr, &addr->u.torservice.address);
towire_u8_array(pptr, (const u8 *)addr->u.torservice.blob,
sizeof(addr->u.torservice.blob));
towire_u16(pptr, addr->u.torservice.port);
return;
case ADDR_INTERNAL_ALLPROTO:
towire_u16(pptr, addr->u.port);
@ -113,7 +122,15 @@ bool fromwire_wireaddr_internal(const u8 **cursor, size_t *max,
addr->u.port = fromwire_u16(cursor, max);
return *cursor != NULL;
case ADDR_INTERNAL_AUTOTOR:
return fromwire_wireaddr(cursor, max, &addr->u.torservice);
fromwire_wireaddr(cursor, max, &addr->u.torservice.address);
addr->u.torservice.port = fromwire_u16(cursor, max);
return *cursor != NULL;
case ADDR_INTERNAL_STATICTOR:
fromwire_wireaddr(cursor, max, &addr->u.torservice.address);
fromwire_u8_array(cursor, max, (u8 *)addr->u.torservice.blob,
sizeof(addr->u.torservice.blob));
addr->u.torservice.port = fromwire_u16(cursor, max);
return *cursor != NULL;
case ADDR_INTERNAL_WIREADDR:
return fromwire_wireaddr(cursor, max, &addr->u.wireaddr);
case ADDR_INTERNAL_FORPROXY:
@ -204,8 +221,11 @@ char *fmt_wireaddr_internal(const tal_t *ctx,
a->u.unresolved.name, a->u.unresolved.port);
case ADDR_INTERNAL_AUTOTOR:
return tal_fmt(ctx, "autotor:%s",
fmt_wireaddr(tmpctx, &a->u.torservice));
}
fmt_wireaddr(tmpctx, &a->u.torservice.address));
case ADDR_INTERNAL_STATICTOR:
return tal_fmt(ctx, "statictor:%s",
fmt_wireaddr(tmpctx, &a->u.torservice.address));
}
abort();
}
REGISTER_TYPE_TO_STRING(wireaddr_internal, fmt_wireaddr_internal);
@ -429,7 +449,8 @@ bool parse_wireaddr_internal(const char *arg, struct wireaddr_internal *addr,
const char **err_msg)
{
u16 splitport;
char *ip;
char *ip = NULL;
char *service_addr;
bool needed_dns = false;
/* Addresses starting with '/' are local socket paths */
@ -452,8 +473,87 @@ bool parse_wireaddr_internal(const char *arg, struct wireaddr_internal *addr,
* an onion address. */
if (strstarts(arg, "autotor:")) {
addr->itype = ADDR_INTERNAL_AUTOTOR;
return parse_wireaddr(arg + strlen("autotor:"),
&addr->u.torservice, 9051,
addr->u.torservice.port = DEFAULT_PORT;
/* Format is separated by slash. */
char **parts = tal_strsplit(tmpctx, arg, "/", STR_EMPTY_OK);
for (size_t i = 1; i < tal_count(parts)-1; i++) {
if (tal_strreg(tmpctx, parts[i], "torport")) {
char *endp = NULL;
char **parts_2 = tal_strsplit(tmpctx, parts[i], "=", STR_EMPTY_OK);
if (tal_count(parts_2) == 3) {
addr->u.torservice.port = strtol((const char *)parts_2[1], &endp, 10);
if (addr->u.torservice.port <= 0 || *endp != '\0') {
if (err_msg)
*err_msg = "Bad :torport: number";
return false;
}
} else {
if (err_msg)
*err_msg = "Bad :torport: format";
return false;
}
}
}
service_addr = tal_fmt(tmpctx, "%s", parts[0] + strlen("autotor:"));
return parse_wireaddr(service_addr,
&addr->u.torservice.address, 9051,
dns_ok ? NULL : &needed_dns,
err_msg);
}
/* 'statictor:' is a special prefix meaning talk to Tor to create
* an static onion address from a blob or node id */
if (strstarts(arg, "statictor:")) {
bool use_magic_blob = true;
addr->itype = ADDR_INTERNAL_STATICTOR;
addr->u.torservice.port = DEFAULT_PORT;
memset(&(addr->u.torservice.blob[0]), 0, sizeof(addr->u.torservice.blob));
/* Format is separated by slash. */
char **parts = tal_strsplit(tmpctx, arg, "/", STR_EMPTY_OK);
for (size_t i = 1; i < tal_count(parts)-1; i++) {
if (tal_strreg(tmpctx, parts[i], "torport")) {
char *endp = NULL;
char **parts_eq = tal_strsplit(tmpctx, parts[i], "=", STR_EMPTY_OK);
if (tal_count(parts_eq) == 3) {
addr->u.torservice.port = strtol((const char *)parts_eq[1], &endp, 10);
if (addr->u.torservice.port <= 0 || *endp != '\0') {
if (err_msg)
*err_msg = "Bad :torport: number";
return false;
}
} else {
if (err_msg)
*err_msg = "Bad :torport: format";
return false;
}
}
if (tal_strreg(tmpctx, parts[i], "torblob")) {
char **parts_eq = tal_strsplit(tmpctx, parts[i], "=", STR_EMPTY_OK);
if (tal_count(parts_eq) == 3) {
if (strlen((char *)parts_eq[1]) == 0) {
if (err_msg)
*err_msg = "Blob too short";
return false;
}
strncpy((char *)&(addr->u.torservice.blob[0]), (const char *)parts_eq[1], TOR_V3_BLOBLEN);
use_magic_blob = false;
}
}
}
if (use_magic_blob) {
/* when statictor called just with the service address and or port generate the unique onion */
strncpy((char *)&(addr->u.torservice.blob[0]), tal_fmt(tmpctx, STATIC_TOR_MAGIC_STRING), strlen(STATIC_TOR_MAGIC_STRING));
}
service_addr = tal_fmt(tmpctx, "%s", parts[0] + strlen("statictor:"));
return parse_wireaddr(service_addr,
&addr->u.torservice.address, 9051,
dns_ok ? NULL : &needed_dns,
err_msg);
}
@ -461,7 +561,7 @@ bool parse_wireaddr_internal(const char *arg, struct wireaddr_internal *addr,
splitport = port;
if (!separate_address_and_port(tmpctx, arg, &ip, &splitport)) {
if (err_msg) {
*err_msg = "Error parsing hostname";
*err_msg = tal_fmt(tmpctx, "Error parsing hostname %s %s", (char *)arg, ip);
}
return false;
}
@ -541,6 +641,7 @@ struct addrinfo *wireaddr_internal_to_addrinfo(const tal_t *ctx,
return ai;
case ADDR_INTERNAL_ALLPROTO:
case ADDR_INTERNAL_AUTOTOR:
case ADDR_INTERNAL_STATICTOR:
case ADDR_INTERNAL_FORPROXY:
break;
case ADDR_INTERNAL_WIREADDR:
@ -591,6 +692,7 @@ bool all_tor_addresses(const struct wireaddr_internal *wireaddr)
case ADDR_INTERNAL_ALLPROTO:
return false;
case ADDR_INTERNAL_AUTOTOR:
case ADDR_INTERNAL_STATICTOR:
continue;
case ADDR_INTERNAL_WIREADDR:
switch (wireaddr[i].u.wireaddr.type) {

12
common/wireaddr.h

@ -43,6 +43,8 @@ struct sockaddr_un;
#define TOR_V2_ADDRLEN 10
#define TOR_V3_ADDRLEN 35
#define LARGEST_ADDRLEN TOR_V3_ADDRLEN
#define TOR_V3_BLOBLEN 64
#define STATIC_TOR_MAGIC_STRING "gen-default-toraddress"
enum wire_addr_type {
ADDR_TYPE_IPV4 = 1,
@ -110,6 +112,7 @@ enum wireaddr_internal_type {
ADDR_INTERNAL_AUTOTOR,
ADDR_INTERNAL_FORPROXY,
ADDR_INTERNAL_WIREADDR,
ADDR_INTERNAL_STATICTOR,
};
/* For internal use, where we can also supply a local socket, wildcard. */
@ -120,8 +123,13 @@ struct wireaddr_internal {
struct wireaddr wireaddr;
/* ADDR_INTERNAL_ALLPROTO */
u16 port;
/* ADDR_INTERNAL_AUTOTOR */
struct wireaddr torservice;
/* ADDR_INTERNAL_AUTOTOR
* ADDR_INTERNAL_STATICTOR */
struct torservice {
struct wireaddr address;
u16 port;
u8 blob[TOR_V3_BLOBLEN + 1];
} torservice;
/* ADDR_INTERNAL_FORPROXY */
struct unresolved {
char name[256];

1
connectd/Makefile

@ -39,6 +39,7 @@ LIGHTNINGD_HEADERS_GEN += $(LIGHTNINGD_CONNECT_HEADERS)
CONNECTD_COMMON_OBJS := \
common/amount.o \
common/base32.o \
common/base64.o \
common/bech32.o \
common/bech32_util.o \
common/bigsize.o \

81
connectd/connectd.c

@ -56,6 +56,7 @@
#include <netdb.h>
#include <netinet/in.h>
#include <secp256k1_ecdh.h>
#include <sodium.h>
#include <sodium/randombytes.h>
#include <stdarg.h>
#include <sys/socket.h>
@ -149,7 +150,7 @@ struct daemon {
/* File descriptors to listen on once we're activated. */
struct listen_fd *listen_fds;
/* Allow to define the default behavior of tot services calls*/
/* Allow to define the default behavior of tor services calls*/
bool use_v3_autotor;
};
@ -652,6 +653,10 @@ static struct io_plan *conn_init(struct io_conn *conn,
status_failed(STATUS_FAIL_INTERNAL_ERROR,
"Can't connect to autotor address");
break;
case ADDR_INTERNAL_STATICTOR:
status_failed(STATUS_FAIL_INTERNAL_ERROR,
"Can't connect to statictor address");
break;
case ADDR_INTERNAL_FORPROXY:
status_failed(STATUS_FAIL_INTERNAL_ERROR,
"Can't connect to forproxy address");
@ -688,6 +693,7 @@ static struct io_plan *conn_proxy_init(struct io_conn *conn,
case ADDR_INTERNAL_SOCKNAME:
case ADDR_INTERNAL_ALLPROTO:
case ADDR_INTERNAL_AUTOTOR:
case ADDR_INTERNAL_STATICTOR:
break;
}
@ -731,6 +737,9 @@ static void try_connect_one_addr(struct connecting *connect)
case ADDR_INTERNAL_AUTOTOR:
status_failed(STATUS_FAIL_INTERNAL_ERROR,
"Can't connect AUTOTOR");
case ADDR_INTERNAL_STATICTOR:
status_failed(STATUS_FAIL_INTERNAL_ERROR,
"Can't connect STATICTOR");
case ADDR_INTERNAL_FORPROXY:
use_proxy = true;
break;
@ -993,6 +1002,10 @@ static struct wireaddr_internal *setup_listeners(const tal_t *ctx,
struct sockaddr_un addrun;
int fd;
struct wireaddr_internal *binding;
const u8 *blob = NULL;
struct secret random;
struct pubkey pb;
struct wireaddr *toraddr;
/* Start with empty arrays, for tal_arr_expand() */
binding = tal_arr(ctx, struct wireaddr_internal, 0);
@ -1018,7 +1031,6 @@ static struct wireaddr_internal *setup_listeners(const tal_t *ctx,
for (size_t i = 0; i < tal_count(proposed_wireaddr); i++) {
struct wireaddr_internal wa = proposed_wireaddr[i];
bool announce = (proposed_listen_announce[i] & ADDR_ANNOUNCE);
if (!(proposed_listen_announce[i] & ADDR_LISTEN))
continue;
@ -1042,6 +1054,9 @@ static struct wireaddr_internal *setup_listeners(const tal_t *ctx,
case ADDR_INTERNAL_AUTOTOR:
/* We handle these after we have all bindings. */
continue;
case ADDR_INTERNAL_STATICTOR:
/* We handle these after we have all bindings. */
continue;
/* Special case meaning IPv6 and IPv4 */
case ADDR_INTERNAL_ALLPROTO: {
bool ipv6_ok;
@ -1102,25 +1117,63 @@ static struct wireaddr_internal *setup_listeners(const tal_t *ctx,
for (size_t i = 0; i < tal_count(proposed_wireaddr); i++) {
if (!(proposed_listen_announce[i] & ADDR_LISTEN))
continue;
if (proposed_wireaddr[i].itype != ADDR_INTERNAL_AUTOTOR)
continue;
toraddr = tor_autoservice(tmpctx,
&proposed_wireaddr[i],
tor_password,
binding,
daemon->use_v3_autotor);
if (!(proposed_listen_announce[i] & ADDR_ANNOUNCE)) {
tor_autoservice(tmpctx,
&proposed_wireaddr[i].u.torservice,
tor_password,
binding,
daemon->use_v3_autotor);
continue;
};
add_announcable(announcable,
tor_autoservice(tmpctx,
&proposed_wireaddr[i].u.torservice,
tor_password,
binding,
daemon->use_v3_autotor));
add_announcable(announcable, toraddr);
}
/* Now we have bindings, set up any Tor static addresses: we will point
* it at the first bound IPv4 or IPv6 address we have. */
for (size_t i = 0; i < tal_count(proposed_wireaddr); i++) {
if (!(proposed_listen_announce[i] & ADDR_LISTEN))
continue;
if (proposed_wireaddr[i].itype != ADDR_INTERNAL_STATICTOR)
continue;
blob = proposed_wireaddr[i].u.torservice.blob;
if (tal_strreg(tmpctx, (char *)proposed_wireaddr[i].u.torservice.blob, STATIC_TOR_MAGIC_STRING)) {
if (pubkey_from_node_id(&pb, &daemon->id)) {
if (sodium_mlock(&random, sizeof(random)) != 0)
status_failed(STATUS_FAIL_INTERNAL_ERROR,
"Could not lock the random prf key memory.");
randombytes_buf((void * const)&random, 32);
/* generate static tor node address, take first 32 bytes from secret of node_id plus 32 random bytes from sodiom */
struct sha256 sha;
/* let's sha, that will clear ctx of hsm data */
sha256(&sha, hsm_do_ecdh(tmpctx, &pb), 32);
/* even if it's a secret pub derived, tor shall see only the single sha */
memcpy((void *)&blob[0], &sha, 32);
memcpy((void *)&blob[32], &random, 32);
/* clear our temp buffer, don't leak by extern libs core-dumps, our blob we/tal handle later */
sodium_munlock(&random, sizeof(random));
} else status_failed(STATUS_FAIL_INTERNAL_ERROR,
"Could not get the pub of our node id from hsm");
}
toraddr = tor_fixed_service(tmpctx,
&proposed_wireaddr[i],
tor_password,
blob,
find_local_address(binding),
0);
/* get rid of blob data on our side of tor and add jitter */
randombytes_buf((void * const)proposed_wireaddr[i].u.torservice.blob, TOR_V3_BLOBLEN);
if (!(proposed_listen_announce[i] & ADDR_ANNOUNCE)) {
continue;
};
add_announcable(announcable, toraddr);
}
/* Sort and uniquify. */
finalize_announcable(announcable);

138
connectd/tor_autoservice.c

@ -7,6 +7,7 @@
#include <ccan/str/hex/hex.h>
#include <ccan/tal/grab_file/grab_file.h>
#include <ccan/tal/str/str.h>
#include <common/base64.h>
#include <common/type_to_string.h>
#include <common/utils.h>
#include <common/wireaddr.h>
@ -21,10 +22,6 @@
#include <unistd.h>
#include <wire/wire.h>
#define MAX_TOR_COOKIE_LEN 32
#define MAX_TOR_SERVICE_READBUFFER_LEN 255
#define MAX_TOR_ONION_V2_ADDR_LEN 16
#define MAX_TOR_ONION_V3_ADDR_LEN 56
static void *buf_resize(struct membuf *mb, void *buf, size_t len)
{
@ -45,6 +42,30 @@ static void tor_send_cmd(struct rbuf *rbuf, const char *cmd)
"Writing CRLF to Tor socket");
}
static char *tor_response_line_wfail(struct rbuf *rbuf)
{
char *line = NULL;
while ((line = rbuf_read_str(rbuf, '\n')) != NULL) {
status_io(LOG_IO_IN, NULL, "torcontrol", line, strlen(line));
/* Weird response */
if (!strstarts(line, "250") && !strstarts(line, "550"))
status_failed(STATUS_FAIL_INTERNAL_ERROR,
"Tor returned '%s'", line);
/* Last line */
if (strstarts(line, "250 ") || strstarts(line, "550 "))
break;
return line + 4;
}
if (line)
return line + 4;
else
return NULL;
}
static char *tor_response_line(struct rbuf *rbuf)
{
char *line;
@ -74,13 +95,14 @@ static void discard_remaining_response(struct rbuf *rbuf)
static struct wireaddr *make_onion(const tal_t *ctx,
struct rbuf *rbuf,
const struct wireaddr *local,
bool use_v3_autotor)
bool use_v3_autotor,
u16 port)
{
char *line;
struct wireaddr *onion;
/* Now that V3 is out of Beta default to V3 autoservice onions if version is above 0.4
*/
/* Now that V3 is out of Beta default to V3 autoservice onions if version is above 0.4
*/
tor_send_cmd(rbuf, "PROTOCOLINFO 1");
while ((line = tor_response_line(rbuf)) != NULL) {
@ -101,13 +123,11 @@ static struct wireaddr *make_onion(const tal_t *ctx,
if (!use_v3_autotor) {
tor_send_cmd(rbuf,
tal_fmt(tmpctx, "ADD_ONION NEW:RSA1024 Port=%d,%s Flags=DiscardPK,Detach",
/* FIXME: We *could* allow user to set Tor port */
DEFAULT_PORT, fmt_wireaddr(tmpctx, local)));
port, fmt_wireaddr(tmpctx, local)));
} else {
tor_send_cmd(rbuf,
tal_fmt(tmpctx, "ADD_ONION NEW:ED25519-V3 Port=%d,%s Flags=DiscardPK,Detach",
/* FIXME: We *could* allow user to set Tor port */
DEFAULT_PORT, fmt_wireaddr(tmpctx, local)));
port, fmt_wireaddr(tmpctx, local)));
}
while ((line = tor_response_line(rbuf)) != NULL) {
@ -122,10 +142,10 @@ static struct wireaddr *make_onion(const tal_t *ctx,
name = tal_fmt(tmpctx, "%s.onion", line);
onion = tal(ctx, struct wireaddr);
if (!parse_wireaddr(name, onion, DEFAULT_PORT, false, NULL))
if (!parse_wireaddr(name, onion, local->port, false, NULL))
status_failed(STATUS_FAIL_INTERNAL_ERROR,
"Tor gave bad onion name '%s'", name);
status_info("New autotor service onion address: \"%s:%d\"", name, DEFAULT_PORT);
status_info("New autotor service onion address: \"%s:%d\" bound from extern port:%d", name, local->port, port);
discard_remaining_response(rbuf);
return onion;
}
@ -133,6 +153,51 @@ static struct wireaddr *make_onion(const tal_t *ctx,
"Tor didn't give us a ServiceID");
}
static struct wireaddr *make_fixed_onion(const tal_t *ctx,
struct rbuf *rbuf,
const struct wireaddr *local, const u8 *blob, u16 port)
{
char *line;
struct wireaddr *onion;
char *blob64;
blob64 = b64_encode(tmpctx, blob, 64);
tor_send_cmd(rbuf,
tal_fmt(tmpctx, "ADD_ONION ED25519-V3:%s Port=%d,%s Flags=DiscardPK",
blob64, port, fmt_wireaddr(tmpctx, local)));
while ((line = tor_response_line_wfail(rbuf))) {
const char *name;
if (strstarts(line, "Onion address collision"))
status_failed(STATUS_FAIL_INTERNAL_ERROR,
"Tor address in use");
if (!strstarts(line, "ServiceID="))
continue;
line += strlen("ServiceID=");
/* Strip the trailing CR */
if (strchr(line, '\r'))
*strchr(line, '\r') = '\0';
name = tal_fmt(tmpctx, "%s.onion", line);
onion = tal(ctx, struct wireaddr);
if (!parse_wireaddr(name, onion, local->port, false, NULL))
status_failed(STATUS_FAIL_INTERNAL_ERROR,
"Tor gave bad onion name '%s'", name);
#ifdef SUPERVERBOSE
status_info("Static Tor service onion address: \"%s:%d,%s\"from blob %s base64 %s ",
name, port ,fmt_wireaddr(tmpctx, local), blob ,blob64);
#else
status_info("Static Tor service onion address: \"%s:%d,%s\" bound from extern port %d ",
name, port ,fmt_wireaddr(tmpctx, local), port);
#endif
discard_remaining_response(rbuf);
return onion;
}
return NULL;
}
/* https://gitweb.torproject.org/torspec.git/tree/control-spec.txt:
*
* MidReplyLine = StatusCode "-" ReplyLine
@ -210,7 +275,7 @@ static void negotiate_auth(struct rbuf *rbuf, const char *tor_password)
}
/* We need to have a bound address we can tell Tor to connect to */
static const struct wireaddr *
const struct wireaddr *
find_local_address(const struct wireaddr_internal *bindings)
{
for (size_t i = 0; i < tal_count(bindings); i++) {
@ -226,7 +291,7 @@ find_local_address(const struct wireaddr_internal *bindings)
}
struct wireaddr *tor_autoservice(const tal_t *ctx,
const struct wireaddr *tor_serviceaddr,
const struct wireaddr_internal *tor_serviceaddr,
const char *tor_password,
const struct wireaddr_internal *bindings,
const bool use_v3_autotor)
@ -239,7 +304,7 @@ struct wireaddr *tor_autoservice(const tal_t *ctx,
char *buffer;
laddr = find_local_address(bindings);
ai_tor = wireaddr_to_addrinfo(tmpctx, tor_serviceaddr);
ai_tor = wireaddr_to_addrinfo(tmpctx, &tor_serviceaddr->u.torservice.address);
fd = socket(ai_tor->ai_family, SOCK_STREAM, 0);
if (fd < 0)
@ -252,7 +317,7 @@ struct wireaddr *tor_autoservice(const tal_t *ctx,
rbuf_init(&rbuf, fd, buffer, tal_count(buffer), buf_resize);
negotiate_auth(&rbuf, tor_password);
onion = make_onion(ctx, &rbuf, laddr, use_v3_autotor);
onion = make_onion(ctx, &rbuf, laddr, use_v3_autotor, tor_serviceaddr->u.torservice.port);
/*on the other hand we can stay connected until ln finish to keep onion alive and then vanish */
//because when we run with Detach flag as we now do every start of LN creates a new addr while the old
@ -263,3 +328,42 @@ struct wireaddr *tor_autoservice(const tal_t *ctx,
return onion;
}
struct wireaddr *tor_fixed_service(const tal_t *ctx,
const struct wireaddr_internal *tor_serviceaddr,
const char *tor_password,
const u8 *blob,
const struct wireaddr *bind,
const u8 index)
{
int fd;
const struct wireaddr *laddr;
struct wireaddr *onion;
struct addrinfo *ai_tor;
struct rbuf rbuf;
char *buffer;
laddr = bind;
ai_tor = wireaddr_to_addrinfo(tmpctx, &tor_serviceaddr->u.torservice.address);
fd = socket(ai_tor->ai_family, SOCK_STREAM, 0);
if (fd < 0)
err(1, "Creating stream socket for Tor");
if (connect(fd, ai_tor->ai_addr, ai_tor->ai_addrlen) != 0)
err(1, "Connecting stream socket to Tor service");
buffer = tal_arr(tmpctx, char, rbuf_good_size(fd));
rbuf_init(&rbuf, fd, buffer, tal_count(buffer), buf_resize);
negotiate_auth(&rbuf, tor_password);
onion = make_fixed_onion(ctx, &rbuf, laddr, blob, tor_serviceaddr->u.torservice.port);
/*on the other hand we can stay connected until ln finish to keep onion alive and then vanish
* because when we run with Detach flag as we now do every start of LN creates a new addr while the old
* stays valid until reboot this might not be desired so we can also drop Detach and use the
* read_partial to keep it open until LN drops
* DO NOT CLOSE FD TO KEEP ADDRESS ALIVE AS WE DO NOT DETACH WITH STATIC ADDRESS
*/
return onion;
}

13
connectd/tor_autoservice.h

@ -7,9 +7,20 @@
#include <stdlib.h>
struct wireaddr *tor_autoservice(const tal_t *ctx,
const struct wireaddr *tor_serviceaddr,
const struct wireaddr_internal *tor_serviceaddr,
const char *tor_password,
const struct wireaddr_internal *bindings,
const bool use_v3_autotor);
struct wireaddr *tor_fixed_service(const tal_t *ctx,
const struct wireaddr_internal *tor_serviceaddr,
const char *tor_password,
const u8 *blob,
const struct wireaddr *bind,
const u8 index);
const struct wireaddr *
find_local_address(const struct wireaddr_internal *bindings);
#endif /* LIGHTNING_CONNECTD_TOR_AUTOSERVICE_H */

1
devtools/gossipwith.c

@ -311,6 +311,7 @@ int main(int argc, char *argv[])
break;
case ADDR_INTERNAL_ALLPROTO:
case ADDR_INTERNAL_AUTOTOR:
case ADDR_INTERNAL_STATICTOR:
case ADDR_INTERNAL_FORPROXY:
opt_usage_exit_fail("Don't support proxy use");

1
lightningd/Makefile

@ -17,6 +17,7 @@ LIGHTNINGD_COMMON_OBJS := \
common/addr.o \
common/amount.o \
common/base32.o \
common/base64.o \
common/bech32.o \
common/bech32_util.o \
common/bigsize.o \

8
lightningd/json.c

@ -249,7 +249,13 @@ void json_add_address_internal(struct json_stream *response,
case ADDR_INTERNAL_AUTOTOR:
json_object_start(response, fieldname);
json_add_string(response, "type", "Tor generated address");
json_add_address(response, "service", &addr->u.torservice);
json_add_address(response, "service", &addr->u.torservice.address);
json_object_end(response);
return;
case ADDR_INTERNAL_STATICTOR:
json_object_start(response, fieldname);
json_add_string(response, "type", "Tor from blob generated static address");
json_add_address(response, "service", &addr->u.torservice.address);
json_object_end(response);
return;
case ADDR_INTERNAL_FORPROXY:

2
lightningd/lightningd.h

@ -68,7 +68,7 @@ struct config {
/* Minimal amount of effective funding_satoshis for accepting channels */
u64 min_capacity_sat;
/* Allow to define the default behavior of tot services calls*/
/* Allow to define the default behavior of tor services calls*/
bool use_v3_autotor;
/* This is the key we use to encrypt `hsm_secret`. */

6
lightningd/options.c

@ -9,6 +9,7 @@
#include <ccan/str/hex/hex.h>
#include <ccan/tal/path/path.h>
#include <ccan/tal/str/str.h>
#include <common/base64.h>
#include <common/derive_basepoints.h>
#include <common/features.h>
#include <common/json_command.h>
@ -136,6 +137,10 @@ static char *opt_add_announce_addr(const char *arg, struct lightningd *ld)
if (strstarts(arg, "autotor:"))
return opt_add_addr(arg, ld);
/* Check for statictor and reroute the call to --addr */
if (strstarts(arg, "statictor:"))
return opt_add_addr(arg, ld);
err = opt_add_addr_withtype(arg, ld, ADDR_ANNOUNCE, false);
if (err)
return err;
@ -603,6 +608,7 @@ static const struct config mainnet_config = {
/* Sets min_effective_htlc_capacity - at 1000$/BTC this is 10ct */
.min_capacity_sat = 10000,
/* Allow to define the default behavior of tor services calls*/
.use_v3_autotor = true,
};

Loading…
Cancel
Save