]> git.ipfire.org Git - thirdparty/bacula.git/commitdiff
Add bin_to_base32() function
authorEric Bollengier <eric@baculasystems.com>
Fri, 13 Aug 2021 08:17:00 +0000 (10:17 +0200)
committerEric Bollengier <eric@baculasystems.com>
Fri, 30 Jun 2023 16:33:45 +0000 (18:33 +0200)
bacula/src/lib/Makefile.in
bacula/src/lib/base32.c [new file with mode: 0644]
bacula/src/lib/protos.h

index 212ce734f888c2d3d8df3a92a72c8df97bdd0f17..42458205619a605760f65c05fc612882241a1d47 100644 (file)
@@ -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 (file)
index 0000000..33e22e9
--- /dev/null
@@ -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
index fe56350f0cd6790bbb7181cf8974304e407f6c6b..d84306339bbec408068207d336a913ce754e5bac 100644 (file)
@@ -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);