1 #include "config.h"
2 #include <ccan/err/err.h>
3 #include <ccan/rbuf/rbuf.h>
4 #include <ccan/read_write_all/read_write_all.h>
5 #include <ccan/tal/grab_file/grab_file.h>
6 #include <ccan/tal/str/str.h>
7 #include <common/base64.h>
8 #include <common/utils.h>
9 #include <common/wireaddr.h>
10 #include <connectd/tor_autoservice.h>
11 #include <errno.h>
12 #include <lightningd/log.h>
13 #include <netdb.h>
14 #include <unistd.h>
15
16
buf_resize(struct membuf * mb,void * buf,size_t len)17 static void *buf_resize(struct membuf *mb, void *buf, size_t len)
18 {
19 tal_resize(&buf, len);
20 return buf;
21 }
22
tor_send_cmd(struct rbuf * rbuf,const char * cmd)23 static void tor_send_cmd(struct rbuf *rbuf, const char *cmd)
24 {
25 status_io(LOG_IO_OUT, NULL, "torcontrol", cmd, strlen(cmd));
26 if (!write_all(rbuf->fd, cmd, strlen(cmd)))
27 status_failed(STATUS_FAIL_INTERNAL_ERROR,
28 "Writing '%s' to Tor socket", cmd);
29
30 status_io(LOG_IO_OUT, NULL, "torcontrol", "\r\n", 2);
31 if (!write_all(rbuf->fd, "\r\n", 2))
32 status_failed(STATUS_FAIL_INTERNAL_ERROR,
33 "Writing CRLF to Tor socket");
34 }
35
tor_response_line_wfail(struct rbuf * rbuf)36 static char *tor_response_line_wfail(struct rbuf *rbuf)
37 {
38 char *line = NULL;
39
40 while ((line = rbuf_read_str(rbuf, '\n')) != NULL) {
41 status_io(LOG_IO_IN, NULL, "torcontrol", line, strlen(line));
42
43 /* Weird response */
44 if (!strstarts(line, "250") && !strstarts(line, "550"))
45 status_failed(STATUS_FAIL_INTERNAL_ERROR,
46 "Tor returned '%s'", line);
47
48 /* Last line */
49 if (strstarts(line, "250 ") || strstarts(line, "550 "))
50 break;
51
52 return line + 4;
53 }
54 if (line)
55 return line + 4;
56 else
57 return NULL;
58 }
59
tor_response_line(struct rbuf * rbuf)60 static char *tor_response_line(struct rbuf *rbuf)
61 {
62 char *line;
63
64 while ((line = rbuf_read_str(rbuf, '\n')) != NULL) {
65 status_io(LOG_IO_IN, NULL, "torcontrol", line, strlen(line));
66
67 /* Weird response */
68 if (!strstarts(line, "250"))
69 status_failed(STATUS_FAIL_INTERNAL_ERROR,
70 "Tor returned '%s'", line);
71
72 /* Last line */
73 if (strstarts(line, "250 "))
74 break;
75
76 return line + 4;
77 }
78 return NULL;
79 }
80
discard_remaining_response(struct rbuf * rbuf)81 static void discard_remaining_response(struct rbuf *rbuf)
82 {
83 while (tor_response_line(rbuf));
84 }
85
make_onion(const tal_t * ctx,struct rbuf * rbuf,const struct wireaddr * local,bool use_v3_autotor,u16 port)86 static struct wireaddr *make_onion(const tal_t *ctx,
87 struct rbuf *rbuf,
88 const struct wireaddr *local,
89 bool use_v3_autotor,
90 u16 port)
91 {
92 char *line;
93 struct wireaddr *onion;
94
95 /* Now that V3 is out of Beta default to V3 autoservice onions if version is above 0.4
96 */
97 tor_send_cmd(rbuf, "PROTOCOLINFO 1");
98
99 while ((line = tor_response_line(rbuf)) != NULL) {
100
101 if (!strstarts(line, "VERSION Tor="))
102 continue;
103
104 if (use_v3_autotor)
105 if (strstr(line, "\"0.0") ||
106 strstr(line, "\"0.1") ||
107 strstr(line, "\"0.2") ||
108 strstr(line, "\"0.3")) {
109 use_v3_autotor = false;
110 status_unusual("Autotor: fallback to try a V2 onion service, your Tor version is smaller than 0.4.x.x");
111 }
112 };
113
114 if (!use_v3_autotor) {
115 tor_send_cmd(rbuf,
116 tal_fmt(tmpctx, "ADD_ONION NEW:RSA1024 Port=%d,%s Flags=DiscardPK,Detach",
117 port, fmt_wireaddr(tmpctx, local)));
118 } else {
119 tor_send_cmd(rbuf,
120 tal_fmt(tmpctx, "ADD_ONION NEW:ED25519-V3 Port=%d,%s Flags=DiscardPK,Detach",
121 port, fmt_wireaddr(tmpctx, local)));
122 }
123
124 while ((line = tor_response_line(rbuf)) != NULL) {
125 const char *name;
126
127 if (!strstarts(line, "ServiceID="))
128 continue;
129 line += strlen("ServiceID=");
130 /* Strip the trailing CR */
131 if (strchr(line, '\r'))
132 *strchr(line, '\r') = '\0';
133
134 name = tal_fmt(tmpctx, "%s.onion", line);
135 onion = tal(ctx, struct wireaddr);
136 if (!parse_wireaddr(name, onion, local->port, false, NULL))
137 status_failed(STATUS_FAIL_INTERNAL_ERROR,
138 "Tor gave bad onion name '%s'", name);
139 status_info("New autotor service onion address: \"%s:%d\" bound from extern port:%d", name, local->port, port);
140 discard_remaining_response(rbuf);
141 return onion;
142 }
143 status_failed(STATUS_FAIL_INTERNAL_ERROR,
144 "Tor didn't give us a ServiceID");
145 }
146
make_fixed_onion(const tal_t * ctx,struct rbuf * rbuf,const struct wireaddr * local,const u8 * blob,u16 port)147 static struct wireaddr *make_fixed_onion(const tal_t *ctx,
148 struct rbuf *rbuf,
149 const struct wireaddr *local, const u8 *blob, u16 port)
150 {
151 char *line;
152 struct wireaddr *onion;
153 char *blob64;
154
155 blob64 = b64_encode(tmpctx, blob, 64);
156
157 tor_send_cmd(rbuf,
158 tal_fmt(tmpctx, "ADD_ONION ED25519-V3:%s Port=%d,%s Flags=DiscardPK",
159 blob64, port, fmt_wireaddr(tmpctx, local)));
160
161 while ((line = tor_response_line_wfail(rbuf))) {
162 const char *name;
163 if (strstarts(line, "Onion address collision"))
164 status_failed(STATUS_FAIL_INTERNAL_ERROR,
165 "Tor address in use");
166
167 if (!strstarts(line, "ServiceID="))
168 continue;
169 line += strlen("ServiceID=");
170 /* Strip the trailing CR */
171 if (strchr(line, '\r'))
172 *strchr(line, '\r') = '\0';
173
174 name = tal_fmt(tmpctx, "%s.onion", line);
175 onion = tal(ctx, struct wireaddr);
176 if (!parse_wireaddr(name, onion, port, false, NULL))
177 status_failed(STATUS_FAIL_INTERNAL_ERROR,
178 "Tor gave bad onion name '%s'", name);
179 #ifdef SUPERVERBOSE
180 status_info("Static Tor service onion address: \"%s:%d,%s\"from blob %s base64 %s ",
181 name, port ,fmt_wireaddr(tmpctx, local), blob ,blob64);
182 #else
183 status_info("Static Tor service onion address: \"%s:%d,%s\" bound from extern port %d ",
184 name, port ,fmt_wireaddr(tmpctx, local), port);
185 #endif
186 discard_remaining_response(rbuf);
187 return onion;
188 }
189 return NULL;
190 }
191
192 /* https://gitweb.torproject.org/torspec.git/tree/control-spec.txt:
193 *
194 * MidReplyLine = StatusCode "-" ReplyLine
195 * DataReplyLine = StatusCode "+" ReplyLine CmdData
196 * EndReplyLine = StatusCode SP ReplyLine
197 * ReplyLine = [ReplyText] CRLF
198 * ReplyText = XXXX
199 * StatusCode = 3DIGIT
200 */
negotiate_auth(struct rbuf * rbuf,const char * tor_password)201 static void negotiate_auth(struct rbuf *rbuf, const char *tor_password)
202 {
203 char *line;
204 char *cookiefile = NULL;
205 int cookiefileerrno = 0;
206
207 tor_send_cmd(rbuf, "PROTOCOLINFO 1");
208
209 while ((line = tor_response_line(rbuf)) != NULL) {
210 const char *p;
211
212 if (!strstarts(line, "AUTH METHODS="))
213 continue;
214
215 if (strstr(line, "NULL")) {
216 discard_remaining_response(rbuf);
217 tor_send_cmd(rbuf, "AUTHENTICATE");
218 discard_remaining_response(rbuf);
219 return;
220 } else if (strstr(line, "HASHEDPASSWORD")
221 && strlen(tor_password)) {
222 discard_remaining_response(rbuf);
223 tor_send_cmd(rbuf,
224 tal_fmt(tmpctx, "AUTHENTICATE \"%s\"",
225 tor_password));
226 discard_remaining_response(rbuf);
227 return;
228 } else if ((p = strstr(line, "COOKIEFILE=\"")) != NULL) {
229 char *contents, *end;
230
231 p += strlen("COOKIEFILE=\"");
232 end = strstr(p, "\"");
233 if (!end)
234 status_failed(STATUS_FAIL_INTERNAL_ERROR,
235 "Tor protocolinfo bad line '%s'",
236 line);
237 *end = '\0';
238
239 /* If we can't access this, try other methods */
240 cookiefile = tal_strdup(tmpctx, p);
241 contents = grab_file(tmpctx, p);
242 if (!contents) {
243 cookiefileerrno = errno;
244 continue;
245 }
246 assert(tal_count(contents) != 0);
247 discard_remaining_response(rbuf);
248 tor_send_cmd(rbuf,
249 tal_fmt(tmpctx, "AUTHENTICATE %s",
250 tal_hexstr(tmpctx,
251 contents,
252 tal_count(contents)-1)));
253 discard_remaining_response(rbuf);
254 return;
255 }
256 }
257
258 /* Now report if we tried cookie file and it failed */
259 if (cookiefile)
260 status_failed(STATUS_FAIL_INTERNAL_ERROR,
261 "Could not open Tor cookie file '%s': %s",
262 cookiefile, strerror(cookiefileerrno));
263
264 status_failed(STATUS_FAIL_INTERNAL_ERROR,
265 "Tor protocolinfo did not give auth");
266 }
267
268 /* We need to have a bound address we can tell Tor to connect to */
269 const struct wireaddr *
find_local_address(const struct wireaddr_internal * bindings)270 find_local_address(const struct wireaddr_internal *bindings)
271 {
272 for (size_t i = 0; i < tal_count(bindings); i++) {
273 if (bindings[i].itype != ADDR_INTERNAL_WIREADDR)
274 continue;
275 if (bindings[i].u.wireaddr.type != ADDR_TYPE_IPV4
276 && bindings[i].u.wireaddr.type != ADDR_TYPE_IPV6)
277 continue;
278 return &bindings[i].u.wireaddr;
279 }
280 status_failed(STATUS_FAIL_INTERNAL_ERROR,
281 "No local address found to tell Tor to connect to");
282 }
283
tor_autoservice(const tal_t * ctx,const struct wireaddr_internal * tor_serviceaddr,const char * tor_password,const struct wireaddr_internal * bindings,const bool use_v3_autotor)284 struct wireaddr *tor_autoservice(const tal_t *ctx,
285 const struct wireaddr_internal *tor_serviceaddr,
286 const char *tor_password,
287 const struct wireaddr_internal *bindings,
288 const bool use_v3_autotor)
289 {
290 int fd;
291 const struct wireaddr *laddr;
292 struct wireaddr *onion;
293 struct addrinfo *ai_tor;
294 struct rbuf rbuf;
295 char *buffer;
296
297 laddr = find_local_address(bindings);
298 ai_tor = wireaddr_to_addrinfo(tmpctx, &tor_serviceaddr->u.torservice.address);
299
300 fd = socket(ai_tor->ai_family, SOCK_STREAM, 0);
301 if (fd < 0)
302 err(1, "Creating stream socket for Tor");
303
304 if (connect(fd, ai_tor->ai_addr, ai_tor->ai_addrlen) != 0)
305 err(1, "Connecting stream socket to Tor service");
306
307 buffer = tal_arr(tmpctx, char, rbuf_good_size(fd));
308 rbuf_init(&rbuf, fd, buffer, tal_count(buffer), buf_resize);
309
310 negotiate_auth(&rbuf, tor_password);
311 onion = make_onion(ctx, &rbuf, laddr, use_v3_autotor, tor_serviceaddr->u.torservice.port);
312
313 /*on the other hand we can stay connected until ln finish to keep onion alive and then vanish */
314 //because when we run with Detach flag as we now do every start of LN creates a new addr while the old
315 //stays valid until reboot this might not be desired so we can also drop Detach and use the
316 //read_partial to keep it open until LN drops
317 //FIXME: SAIBATO we might not want to close this conn
318 close(fd);
319
320 return onion;
321 }
322
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)323 struct wireaddr *tor_fixed_service(const tal_t *ctx,
324 const struct wireaddr_internal *tor_serviceaddr,
325 const char *tor_password,
326 const u8 *blob,
327 const struct wireaddr *bind,
328 const u8 index)
329 {
330 int fd;
331 const struct wireaddr *laddr;
332 struct wireaddr *onion;
333 struct addrinfo *ai_tor;
334 struct rbuf rbuf;
335 char *buffer;
336
337 laddr = bind;
338 ai_tor = wireaddr_to_addrinfo(tmpctx, &tor_serviceaddr->u.torservice.address);
339
340 fd = socket(ai_tor->ai_family, SOCK_STREAM, 0);
341 if (fd < 0)
342 err(1, "Creating stream socket for Tor");
343
344 if (connect(fd, ai_tor->ai_addr, ai_tor->ai_addrlen) != 0)
345 err(1, "Connecting stream socket to Tor service");
346
347 buffer = tal_arr(tmpctx, char, rbuf_good_size(fd));
348 rbuf_init(&rbuf, fd, buffer, tal_count(buffer), buf_resize);
349
350 negotiate_auth(&rbuf, tor_password);
351
352 onion = make_fixed_onion(ctx, &rbuf, laddr, blob, tor_serviceaddr->u.torservice.port);
353 /*on the other hand we can stay connected until ln finish to keep onion alive and then vanish
354 * because when we run with Detach flag as we now do every start of LN creates a new addr while the old
355 * stays valid until reboot this might not be desired so we can also drop Detach and use the
356 * read_partial to keep it open until LN drops
357 * DO NOT CLOSE FD TO KEEP ADDRESS ALIVE AS WE DO NOT DETACH WITH STATIC ADDRESS
358 */
359 return onion;
360 }
361