From patchwork Thu Jun 11 19:03:00 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: akater X-Patchwork-Id: 1307699 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=uclibc-ng.org (client-ip=89.238.66.15; helo=helium.openadk.org; envelope-from=devel-bounces@uclibc-ng.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=MWjumIk6; dkim-atps=neutral Received: from helium.openadk.org (helium.openadk.org [89.238.66.15]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 49jYQj707Lz9sRK for ; Fri, 12 Jun 2020 05:12:44 +1000 (AEST) Received: from helium.openadk.org (localhost [IPv6:::1]) by helium.openadk.org (Postfix) with ESMTP id 2B04C10190; Thu, 11 Jun 2020 21:12:40 +0200 (CEST) X-Original-To: devel@uclibc-ng.org Delivered-To: devel@helium.openadk.org Received: from mail-wm1-f68.google.com (mail-wm1-f68.google.com [209.85.128.68]) by helium.openadk.org (Postfix) with ESMTPS id D436310190 for ; Thu, 11 Jun 2020 21:12:36 +0200 (CEST) Received: by mail-wm1-f68.google.com with SMTP id j198so7605788wmj.0 for ; Thu, 11 Jun 2020 12:12:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:mime-version; bh=zEonYCnt41iUvsYKvalT0wnMYeTxDiIt5cTM0SOSMqA=; b=MWjumIk64htAPLyqU0ZRTziUvU4sNvuMxnoEwk8PTubmLP60ZLq/98btXrQzHHO083 Jm3fZgKKpqgDJF4M8yX6uccPMG16Cww/akkxZMJd06Qfx8tFjHEUdBBwUs4I4Jf6g8sD McqEXNTxjhghaUxokoAogyMbe+1KwyRGX+w4/rsrxcsLekKQUp/AarWQxVOC2CX6xjmL 6VAs1IRiwBVm7jMGhtXJ4G2FXz3NsGiFRtIcn8SyTOQkZ11A41AbYYWFNqJtCcvWzuz+ OI7AfRI3eIRhpe4udRKtoiwWy4LwI9Ccev7LeHeAO0jJ/WEqUxDNhSPvgVl6SlcUeUHt IcxQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:mime-version; bh=zEonYCnt41iUvsYKvalT0wnMYeTxDiIt5cTM0SOSMqA=; b=NfRsG2wDRjkxj/KrjJkDODXSkajUiafKTAh/OSbt9urFdk59T19MstCqJHfww5s3+w DObE+jLUouxPgoZfwpY+wUF1VZniltXjggcRVxGz5pgvw3BOCMObUITcMueaz39Z+YYT 3fEYIOSeIqvLjm5h0fiIMmQwIxoltaKyIbpaKoPpTii8wTdwp6naAq7FNmP44jIEr0cA 9AvJSNuCZFUCB4CTexD6Kh827BRZ0LlJgiX4n5iOinUZ/hUcS2rGF6oJX/8XCtkE2zUV qhNwAUzDV6A1lHCrACArhIiEbaja3cpuu0P+gm9bYx13Qm58K48t/GkPnRWE+vQp2OkF 92yw== X-Gm-Message-State: AOAM530mJiTzaWE4WCQNE9AJgW0G9mGvNxbrJ2f62kE0rlamn5T9cf+F I0a71Y3dMvKe/RhikhdTxzqTMQ5E X-Google-Smtp-Source: ABdhPJzOQOn4+OyHDyxFDPlCG5A7id7naijsOR1PMzNmFQdaPCkOphPNG0zzdIlDWRRHE8wxPhHU7g== X-Received: by 2002:a1c:44c3:: with SMTP id r186mr9296244wma.67.1591902755207; Thu, 11 Jun 2020 12:12:35 -0700 (PDT) Received: from localhost ([185.220.101.205]) by smtp.googlemail.com with ESMTPSA id u130sm5548289wmg.32.2020.06.11.12.12.33 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 11 Jun 2020 12:12:34 -0700 (PDT) From: akater To: devel@uclibc-ng.org Date: Thu, 11 Jun 2020 19:03:00 +0000 Message-ID: <87imfxqvbv.fsf@gmail.com> MIME-Version: 1.0 Subject: [uclibc-ng-devel] [PATCH?] Compiling openbsd-netcat X-BeenThere: devel@uclibc-ng.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: uClibc-ng Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: devel-bounces@uclibc-ng.org Sender: "devel" In Nov 2019, I was unable to compile openbsd-netcat on a uclibc-ng-1.0.32 based system. Note: /I don't really write C and I don't know what I'm doing/ but the following patch allowed me to compile openbsd-netcat and run it. I just pulled the bit from glibc (mostly verbatim iirc) and added corresponding config parameter. Hopefully it will be useful even if incompetent. I've been using openbsd-netcat with uclibc-ng 1.0.32 and 1.0.33 from 2019-11 to 2020-06 (now) on regular basis, and openbsd-netcat seems to work fine. --- a/include/resolv.h +++ b/include/resolv.h @@ -329,9 +329,12 @@ #endif __END_DECLS -#if 0 + +#ifdef __UCLIBC_HAS_BSD_B64_NTOP_B64_PTON__ #define b64_ntop __b64_ntop #define b64_pton __b64_pton +#endif +#if 0 #define dn_count_labels __dn_count_labels #endif #define dn_comp __dn_comp @@ -384,8 +387,12 @@ int sym_ston (const struct res_sym *, const char *, int *) __THROW; const char * sym_ntos (const struct res_sym *, int, int *) __THROW; const char * sym_ntop (const struct res_sym *, int, int *) __THROW; +#endif +#ifdef __UCLIBC_HAS_BSD_B64_NTOP_B64_PTON__ int b64_ntop (u_char const *, size_t, char *, size_t) __THROW; int b64_pton (char const *, u_char *, size_t) __THROW; +#endif +#if 0 int loc_aton (const char *ascii, u_char *binary) __THROW; const char * loc_ntoa (const u_char *binary, char *ascii) __THROW; void putlong (u_int32_t, u_char *) __THROW; --- a/extra/Configs/Config.in +++ b/extra/Configs/Config.in @@ -1036,6 +1036,14 @@ If unsure, say N. +config UCLIBC_HAS_BSD_B64_NTOP_B64_PTON + bool "Support b64_ntop(), b64_pton() (bsd-compat)" + help + Answer Y if you need additional BSD compatibility + (e.g. for openbsd-netcat). + + Most people will say N. + config UCLIBC_HAS_OBSOLETE_SYSV_SIGNAL bool "SYSV obsolete signal functions" help --- a/libc/inet/resolv.c +++ b/libc/inet/resolv.c @@ -3632,6 +3632,263 @@ } #endif +#ifdef __UCLIBC_HAS_BSD_B64_NTOP_B64_PTON__ +#define Assert(Cond) if (!(Cond)) abort() + +static const char Base64[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +static const char Pad64 = '='; + +/* (From RFC1521 and draft-ietf-dnssec-secext-03.txt) + The following encoding technique is taken from RFC 1521 by Borenstein + and Freed. It is reproduced here in a slightly edited form for + convenience. + + A 65-character subset of US-ASCII is used, enabling 6 bits to be + represented per printable character. (The extra 65th character, "=", + is used to signify a special processing function.) + + The encoding process represents 24-bit groups of input bits as output + strings of 4 encoded characters. Proceeding from left to right, a + 24-bit input group is formed by concatenating 3 8-bit input groups. + These 24 bits are then treated as 4 concatenated 6-bit groups, each + of which is translated into a single digit in the base64 alphabet. + + Each 6-bit group is used as an index into an array of 64 printable + characters. The character referenced by the index is placed in the + output string. + + Table 1: The Base64 Alphabet + + Value Encoding Value Encoding Value Encoding Value Encoding + 0 A 17 R 34 i 51 z + 1 B 18 S 35 j 52 0 + 2 C 19 T 36 k 53 1 + 3 D 20 U 37 l 54 2 + 4 E 21 V 38 m 55 3 + 5 F 22 W 39 n 56 4 + 6 G 23 X 40 o 57 5 + 7 H 24 Y 41 p 58 6 + 8 I 25 Z 42 q 59 7 + 9 J 26 a 43 r 60 8 + 10 K 27 b 44 s 61 9 + 11 L 28 c 45 t 62 + + 12 M 29 d 46 u 63 / + 13 N 30 e 47 v + 14 O 31 f 48 w (pad) = + 15 P 32 g 49 x + 16 Q 33 h 50 y + + Special processing is performed if fewer than 24 bits are available + at the end of the data being encoded. A full encoding quantum is + always completed at the end of a quantity. When fewer than 24 input + bits are available in an input group, zero bits are added (on the + right) to form an integral number of 6-bit groups. Padding at the + end of the data is performed using the '=' character. + + Since all base64 input is an integral number of octets, only the + ------------------------------------------------- + following cases can arise: + + (1) the final quantum of encoding input is an integral + multiple of 24 bits; here, the final unit of encoded + output will be an integral multiple of 4 characters + with no "=" padding, + (2) the final quantum of encoding input is exactly 8 bits; + here, the final unit of encoded output will be two + characters followed by two "=" padding characters, or + (3) the final quantum of encoding input is exactly 16 bits; + here, the final unit of encoded output will be three + characters followed by one "=" padding character. + */ + +int +b64_ntop(u_char const *src, size_t srclength, char *target, size_t targsize) { + size_t datalength = 0; + u_char input[3]; + u_char output[4]; + size_t i; + + while (2 < srclength) { + input[0] = *src++; + input[1] = *src++; + input[2] = *src++; + srclength -= 3; + + output[0] = input[0] >> 2; + output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4); + output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6); + output[3] = input[2] & 0x3f; + Assert(output[0] < 64); + Assert(output[1] < 64); + Assert(output[2] < 64); + Assert(output[3] < 64); + + if (datalength + 4 > targsize) + return (-1); + target[datalength++] = Base64[output[0]]; + target[datalength++] = Base64[output[1]]; + target[datalength++] = Base64[output[2]]; + target[datalength++] = Base64[output[3]]; + } + + /* Now we worry about padding. */ + if (0 != srclength) { + /* Get what's left. */ + input[0] = input[1] = input[2] = '\0'; + for (i = 0; i < srclength; i++) + input[i] = *src++; + + output[0] = input[0] >> 2; + output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4); + output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6); + Assert(output[0] < 64); + Assert(output[1] < 64); + Assert(output[2] < 64); + + if (datalength + 4 > targsize) + return (-1); + target[datalength++] = Base64[output[0]]; + target[datalength++] = Base64[output[1]]; + if (srclength == 1) + target[datalength++] = Pad64; + else + target[datalength++] = Base64[output[2]]; + target[datalength++] = Pad64; + } + if (datalength >= targsize) + return (-1); + target[datalength] = '\0'; /* Returned value doesn't count \0. */ + return (datalength); +} +/* libc_hidden_def (b64_ntop) */ + +/* skips all whitespace anywhere. + converts characters, four at a time, starting at (or after) + src from base - 64 numbers into three 8 bit bytes in the target area. + it returns the number of data bytes stored at the target, or -1 on error. + */ + +int +b64_pton (char const *src, u_char *target, size_t targsize) +{ + int tarindex, state, ch; + char *pos; + + state = 0; + tarindex = 0; + + while ((ch = *src++) != '\0') { + if (isspace(ch)) /* Skip whitespace anywhere. */ + continue; + + if (ch == Pad64) + break; + + pos = strchr(Base64, ch); + if (pos == 0) /* A non-base64 character. */ + return (-1); + + switch (state) { + case 0: + if (target) { + if ((size_t)tarindex >= targsize) + return (-1); + target[tarindex] = (pos - Base64) << 2; + } + state = 1; + break; + case 1: + if (target) { + if ((size_t)tarindex + 1 >= targsize) + return (-1); + target[tarindex] |= (pos - Base64) >> 4; + target[tarindex+1] = ((pos - Base64) & 0x0f) + << 4 ; + } + tarindex++; + state = 2; + break; + case 2: + if (target) { + if ((size_t)tarindex + 1 >= targsize) + return (-1); + target[tarindex] |= (pos - Base64) >> 2; + target[tarindex+1] = ((pos - Base64) & 0x03) + << 6; + } + tarindex++; + state = 3; + break; + case 3: + if (target) { + if ((size_t)tarindex >= targsize) + return (-1); + target[tarindex] |= (pos - Base64); + } + tarindex++; + state = 0; + break; + default: + abort(); + } + } + + /* + * We are done decoding Base-64 chars. Let's see if we ended + * on a byte boundary, and/or with erroneous trailing characters. + */ + + if (ch == Pad64) { /* We got a pad char. */ + ch = *src++; /* Skip it, get next. */ + switch (state) { + case 0: /* Invalid = in first position */ + case 1: /* Invalid = in second position */ + return (-1); + + case 2: /* Valid, means one byte of info */ + /* Skip any number of spaces. */ + for ((void)NULL; ch != '\0'; ch = *src++) + if (!isspace(ch)) + break; + /* Make sure there is another trailing = sign. */ + if (ch != Pad64) + return (-1); + ch = *src++; /* Skip the = */ + /* Fall through to "single trailing =" case. */ + /* FALLTHROUGH */ + + case 3: /* Valid, means two bytes of info */ + /* + * We know this char is an =. Is there anything but + * whitespace after it? + */ + for ((void)NULL; ch != '\0'; ch = *src++) + if (!isspace(ch)) + return (-1); + + /* + * Now make sure for cases 2 and 3 that the "extra" + * bits that slopped past the last full byte were + * zeros. If we don't check them, they become a + * subliminal channel. + */ + if (target && target[tarindex] != 0) + return (-1); + } + } else { + /* + * We ended by seeing the end of the string. Make sure we + * have no partial bytes lying around. + */ + if (state != 0) + return (-1); + } + + return (tarindex); +} +#endif + /* This needs to be after the use of _res in res_init, above. */ #undef _res