From d5e4d525633bf8b52984f55491c187622332b897 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 10 May 2018 08:48:24 +0930 Subject: [PATCH] common/base32: make this a simple tal-wrapper around ccan/base32. And use it in wireaddr. We fix up the double '.onion' in the test case, which seems like an error? Signed-off-by: Rusty Russell --- common/base32.c | 71 +++++++------------------------ common/base32.h | 6 +-- common/test/run-ip_port_parsing.c | 2 +- common/wireaddr.c | 36 ++++++++-------- 4 files changed, 37 insertions(+), 78 deletions(-) diff --git a/common/base32.c b/common/base32.c index 7530aa798..51c13619e 100644 --- a/common/base32.c +++ b/common/base32.c @@ -1,63 +1,24 @@ +#include #include -#include -/* This is a rework of what i found on the Net about base32 - * - * so Orum (shallot) and Markus Gutschke (Google.inc) should be mentioned here - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ +/* We want lower-case conversion please */ +static const char base32_lower[] = "abcdefghijklmnopqrstuvwxyz234567="; -#define BASE32DATA "abcdefghijklmnopqrstuvwxyz234567" - -char *b32_encode(char *dst, u8 * src, u8 ver) +char *b32_encode(const tal_t *ctx, const void *data, size_t len) { - u16 byte = 0, poff = 0; - for (; byte < ((ver == 2) ? 16 : 56); poff += 5) { - if (poff > 7) { - poff -= 8; - src++; - } - dst[byte++] = - BASE32DATA[(htobe16(*(u16 *) src) >> (11 - poff)) & (u16) - 0x001F]; - } - dst[byte] = 0; - return dst; + char *str = tal_arr(ctx, char, base32_str_size(len)); + + base32_chars = base32_lower; + base32_encode(data, len, str, tal_len(str)); + return str; } -//FIXME quiknditry - -void b32_decode(u8 * dst, u8 * src, u8 ver) +u8 *b32_decode(const tal_t *ctx, const char *str, size_t len) { - int rem = 0; - int i; - u8 *p = src; - int buf; - u8 ch; - for (i = 0; i < ((ver == 2) ? 16 : 56); p++) { - ch = *p; - buf <<= 5; - if ((ch >= 'a' && ch <= 'z')) { - ch = (ch & 0x1F) - 1; - } else if (ch != '.') { - ch -= '2' - 0x1A; - } else return; - buf = buf | ch; - rem = rem + 5; - if (rem >= 8) { - dst[i++] = buf >> (rem - 8); - rem -= 8; - } - } + u8 *ret = tal_arr(ctx, u8, base32_data_size(str, len)); + + base32_chars = base32_lower; + if (!base32_decode(str, len, ret, tal_len(ret))) + return tal_free(ret); + return ret; } diff --git a/common/base32.h b/common/base32.h index 39456aedf..dd81c3e42 100644 --- a/common/base32.h +++ b/common/base32.h @@ -2,9 +2,9 @@ #define LIGHTNING_COMMON_BASE32_H #include "config.h" #include +#include - -char *b32_encode(char *dst, u8 * src, u8 ver); -void b32_decode(u8 * dst, u8 * src, u8 ver); +char *b32_encode(const tal_t *ctx, const void *data, size_t len); +u8 *b32_decode(const tal_t *ctx, const char *str, size_t len); #endif /* LIGHTNING_COMMON_BASE32_H */ diff --git a/common/test/run-ip_port_parsing.c b/common/test/run-ip_port_parsing.c index ea7e4b2df..d9ce6d8ad 100644 --- a/common/test/run-ip_port_parsing.c +++ b/common/test/run-ip_port_parsing.c @@ -113,7 +113,7 @@ int main(void) assert(parse_wireaddr("odpzvneidqdf5hdq.onion:49150", &addr, 1, NULL)); assert(addr.port == 49150); - assert(parse_wireaddr("odpzvneidqdf5hdq.onion.onion", &addr, 1, NULL)); + assert(parse_wireaddr("odpzvneidqdf5hdq.onion", &addr, 1, NULL)); assert(addr.port == 1); tal_free(tmpctx); return 0; diff --git a/common/wireaddr.c b/common/wireaddr.c index bd5cd242e..28af08d80 100644 --- a/common/wireaddr.c +++ b/common/wireaddr.c @@ -181,8 +181,8 @@ REGISTER_TYPE_TO_STRING(wireaddr_internal, fmt_wireaddr_internal); char *fmt_wireaddr_without_port(const tal_t * ctx, const struct wireaddr *a) { - char addrstr[LARGEST_ADDRLEN]; char *ret, *hex; + char addrstr[LARGEST_ADDRLEN]; switch (a->type) { case ADDR_TYPE_IPV4: @@ -194,11 +194,9 @@ char *fmt_wireaddr_without_port(const tal_t * ctx, const struct wireaddr *a) return "Unprintable-ipv6-address"; return tal_fmt(ctx, "[%s]", addrstr); case ADDR_TYPE_TOR_V2: - return tal_fmt(ctx, "%.16s.onion", - b32_encode(addrstr, (u8 *) a->addr, 2)); case ADDR_TYPE_TOR_V3: - return tal_fmt(ctx, "%.56s.onion", - b32_encode(addrstr, (u8 *) a->addr, 3)); + return tal_fmt(ctx, "%s.onion", + b32_encode(tmpctx, a->addr, a->addrlen)); case ADDR_TYPE_PADDING: break; } @@ -271,26 +269,26 @@ bool wireaddr_from_hostname(struct wireaddr *addr, const char *hostname, struct addrinfo *addrinfo; struct addrinfo hints; int gai_err; - u8 tor_dec_bytes[TOR_V3_ADDRLEN]; bool res = false; /* Don't do lookup on onion addresses. */ if (strends(hostname, ".onion")) { - if (strlen(hostname) < 25) { //FIXME bool is_V2_or_V3_TOR(addr); + u8 *dec = b32_decode(tmpctx, hostname, + strlen(hostname) - strlen(".onion")); + if (tal_len(dec) == TOR_V2_ADDRLEN) addr->type = ADDR_TYPE_TOR_V2; - addr->addrlen = TOR_V2_ADDRLEN; - addr->port = port; - b32_decode((u8 *) tor_dec_bytes, (u8 *)hostname, 2); - memcpy(&addr->addr, tor_dec_bytes, addr->addrlen); - return true; - } else { - addr->type = ADDR_TYPE_TOR_V3; - addr->addrlen = TOR_V3_ADDRLEN; - addr->port = port; - b32_decode((u8 *) tor_dec_bytes, (u8 *)hostname, 3); - memcpy(&addr->addr, tor_dec_bytes, addr->addrlen); - return true; + else if (tal_len(dec) == TOR_V3_ADDRLEN) + addr->type = ADDR_TYPE_TOR_V3; + else { + if (err_msg) + *err_msg = "Invalid Tor address"; + return false; } + + addr->addrlen = tal_len(dec); + addr->port = port; + memcpy(&addr->addr, dec, tal_len(dec)); + return true; } memset(&hints, 0, sizeof(hints));