From: Eric Bollengier Date: Fri, 13 Aug 2021 08:17:00 +0000 (+0200) Subject: Add bin_to_base32() function X-Git-Tag: Beta-15.0.0~915 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=24351019ce1973f96ad41a6a6b613673ae8180ef;p=thirdparty%2Fbacula.git Add bin_to_base32() function --- diff --git a/bacula/src/lib/Makefile.in b/bacula/src/lib/Makefile.in index 212ce734f..424582056 100644 --- a/bacula/src/lib/Makefile.in +++ b/bacula/src/lib/Makefile.in @@ -50,7 +50,7 @@ INCLUDE_FILES = ../baconfig.h ../bacula.h ../bc_types.h \ # # libbac # -LIBBAC_SRCS = attr.c base64.c berrno.c bsys.c binflate.c bget_msg.c \ +LIBBAC_SRCS = attr.c base64.c base32.c berrno.c bsys.c binflate.c bget_msg.c \ authenticatebase.cc \ bnet.c bnet_server.c bsock.c bpipe.c bsnprintf.c bstat.c btime.c \ cram-md5.c crypto.c daemon.c edit.c fnmatch.c \ @@ -172,6 +172,14 @@ base64_test: Makefile libbac.la base64.c unittests.o $(RMF) base64.o $(CXX) $(DEFS) $(DEBUG) -c $(CPPFLAGS) -I$(srcdir) -I$(basedir) $(DINCLUDE) $(CFLAGS) base64.c +base32_test: Makefile libbac.la base32.c unittests.o + $(RMF) base32.o + $(CXX) -DTEST_PROGRAM $(DEFS) $(DEBUG) -c $(CPPFLAGS) -I$(srcdir) -I$(basedir) $(DINCLUDE) $(CFLAGS) base32.c + $(LIBTOOL_LINK) $(CXX) $(LDFLAGS) -L. -o $@ base32.o unittests.o $(DLIB) -lbac -lm $(LIBS) $(OPENSSL_LIBS) + $(LIBTOOL_INSTALL) $(INSTALL_PROGRAM) $@ $(DESTDIR)$(sbindir)/ + $(RMF) base32.o + $(CXX) $(DEFS) $(DEBUG) -c $(CPPFLAGS) -I$(srcdir) -I$(basedir) $(DINCLUDE) $(CFLAGS) base32.c + edit_test: Makefile libbac.la edit.c unittests.o $(RMF) edit.o $(CXX) -DTEST_PROGRAM $(DEFS) $(DEBUG) -c $(CPPFLAGS) -I$(srcdir) -I$(basedir) $(DINCLUDE) $(CFLAGS) edit.c diff --git a/bacula/src/lib/base32.c b/bacula/src/lib/base32.c new file mode 100644 index 000000000..33e22e98b --- /dev/null +++ b/bacula/src/lib/base32.c @@ -0,0 +1,102 @@ +/* + Bacula(R) - The Network Backup Solution + + Copyright (C) 2000-2023 Kern Sibbald + + The original author of Bacula is Kern Sibbald, with contributions + from many others, a complete list can be found in the file AUTHORS. + + You may use this file and others of this release according to the + license defined in the LICENSE file, which includes the Affero General + Public License, v3.0 ("AGPLv3") and some additional permissions and + terms pursuant to its AGPLv3 Section 7. + + This notice must be preserved when any source code is + conveyed and/or propagated. + + Bacula(R) is a registered trademark of Kern Sibbald. +*/ + +/* Base32 is used by various One Time Password authentication apps + * such as google authenticator. + * + * + * Base32 is described in rfc4648. + * + * When encoding, the output buffer must be 5/8 + 1 bigger than the + * input + */ + +#include "bacula.h" + +static uint8_t const base32_digits[32] = +{ + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', + 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', + '2', '3', '4', '5', '6', '7' +}; + +/* The encoding process represents 40-bit groups of input bits as output + * strings of 8 encoded characters. Proceeding from left to right, a + * 40-bit input group is formed by concatenating 5 8bit input groups. + * These 40 bits are then treated as 8 concatenated 5-bit groups, each + * of which is translated into a single character in the base 32 + * alphabet. + */ +int bin_to_base32(const uint8_t *buf, int buflen, char *bin, int binlen) +{ + int j = 0; + uint32_t buffer; + int next, rem; + + if (buflen < 0) { + return -1; + } + + if (buflen > 0) { + buffer = buf[0]; + next = 1; + rem = 8; + while (j < binlen && (rem > 0 || next < buflen)) { + if (rem < 5) { + if (next < buflen) { + buffer <<= 8; + buffer |= buf[next++] & 0xFF; + rem += 8; + + } else { + int pad = 5 - rem; + buffer <<= pad; + rem += pad; + } + } + int index = 0x1F & (buffer >> (rem - 5)); + rem -= 5; + bin[j++] = base32_digits[index]; + } + } + + if (j < binlen) { + bin[j] = '\0'; + + } else { // Buffer too small + return -1; + } + return j; +} + +#ifdef TEST_PROGRAM + +#include "unittests.h" + +int main(int argc, char **argv) +{ + Unittests t("base32"); + uint8_t buf[512]; + ok(bin_to_base32("test1", strlen("test1"), buf, sizeof(buf)) > 0, "test bin_to_base32()"); + is(buf, "ORSXG5BR", "Check result of base32 encoding"); + is(bin_to_base32("test1", strlen("test1"), buf, 3), -1, "test bin_to_base32() with small buffer"); + return report(); +} + +#endif diff --git a/bacula/src/lib/protos.h b/bacula/src/lib/protos.h index fe56350f0..d84306339 100644 --- a/bacula/src/lib/protos.h +++ b/bacula/src/lib/protos.h @@ -36,6 +36,9 @@ int unpack_attributes_record(JCR *jcr, int32_t stream, char *rec, int32_t void build_attr_output_fnames(JCR *jcr, ATTR *attr); void print_ls_output(JCR *jcr, ATTR *attr, int message_type=M_RESTORED); +/* base32.c */ +int bin_to_base32(const uint8_t *buf, int buflen, char *bin, int binlen); + /* base64.c */ void base64_init (void); int to_base64 (int64_t value, char *where);