summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--conf/cf-lex.l59
-rw-r--r--conf/confbase.Y9
-rw-r--r--filter/config.Y1
-rw-r--r--filter/data.h2
-rw-r--r--lib/Makefile2
-rw-r--r--lib/README.base6462
-rw-r--r--lib/base64.c163
-rw-r--r--lib/base64.h11
8 files changed, 307 insertions, 2 deletions
diff --git a/conf/cf-lex.l b/conf/cf-lex.l
index 9025a84d..176c1432 100644
--- a/conf/cf-lex.l
+++ b/conf/cf-lex.l
@@ -50,6 +50,7 @@
#include "conf/cf-parse.tab.h"
#include "lib/string.h"
#include "lib/hash.h"
+#include "lib/base64.h"
struct keyword {
byte *name;
@@ -124,10 +125,11 @@ static enum yytokentype cf_lex_symbol(const char *data);
%option nounput
%option noreject
-%x COMMENT CCOMM CLI QUOTED APOSTROPHED INCLUDE
+%x COMMENT CCOMM CLI QUOTED BQUOTED B64QUOTED APOSTROPHED INCLUDE
ALPHA [a-zA-Z_]
DIGIT [0-9]
+OIGIT [0-7]
XIGIT [0-9a-fA-F]
ALNUM [a-zA-Z_0-9]
WHITE [ \t]
@@ -372,6 +374,61 @@ else: {
<QUOTED>. BUFFER_PUSH(quoted_buffer) = yytext[0];
+[b]["] {
+ BEGIN(BQUOTED);
+ quoted_buffer_init();
+}
+
+<BQUOTED>\n cf_error("Unterminated byte string");
+<BQUOTED><<EOF>> cf_error("Unterminated byte string");
+<BQUOTED>["] {
+ BEGIN(INITIAL);
+ struct bytestring *bytes;
+
+ bytes = cfg_allocz(sizeof(*bytes) + quoted_buffer.used);
+ memcpy(bytes->data, quoted_buffer.data, quoted_buffer.used);
+ bytes->length = quoted_buffer.used;
+
+ cf_lval.bs = bytes;
+ return BYTESTRING;
+}
+
+<BQUOTED>. BUFFER_PUSH(quoted_buffer) = yytext[0];
+
+<BQUOTED>[\\]({OIGIT}|{OIGIT}{OIGIT}|{OIGIT}{OIGIT}{OIGIT}) {
+ char buf[4];
+ char *end = NULL;
+ memcpy(buf, yytext + 1, yyleng);
+ buf[yyleng] = 0;
+ BUFFER_PUSH(quoted_buffer) = bstrtoul10(buf, &end);
+}
+
+<BQUOTED>[\\][x]({XIGIT}|{XIGIT}{XIGIT}) {
+ char buf[3];
+ char *end = NULL;
+ memcpy(buf, yytext + 2, yyleng);
+ buf[yyleng] = 0;
+ BUFFER_PUSH(quoted_buffer) = bstrtoul16(buf, &end);
+}
+
+[b][6][4]["] {
+ BEGIN(B64QUOTED);
+ quoted_buffer_init();
+}
+
+<B64QUOTED>\n cf_error("Unterminated base64 string");
+<B64QUOTED><<EOF>> cf_error("Unterminated base64 string");
+<B64QUOTED>["] {
+ BEGIN(INITIAL);
+ cf_lval.bs = base64_decode_bs(cfg_mem, quoted_buffer.data, quoted_buffer.used, NULL);
+ if (!cf_lval.bs)
+ cf_error("Invalid base64 string");
+
+ return BYTESTRING;
+}
+
+<B64QUOTED>. BUFFER_PUSH(quoted_buffer) = yytext[0];
+
<INITIAL,COMMENT><<EOF>> { if (check_eof()) return END; }
{WHITE}+
diff --git a/conf/confbase.Y b/conf/confbase.Y
index 3dd5fed7..0c53f7ec 100644
--- a/conf/confbase.Y
+++ b/conf/confbase.Y
@@ -117,6 +117,7 @@ CF_DECLS
%type <mls> label_stack_start label_stack
%type <t> text opttext
+%type <bs> bytestring
%type <s> symbol
%type <kw> kw_sym
@@ -395,6 +396,14 @@ opttext:
| /* empty */ { $$ = NULL; }
;
+bytestring:
+ BYTESTRING
+ | CF_SYM_KNOWN {
+ if ($1->class != (SYM_CONSTANT | T_BYTESTRING)) cf_error("Bytestring constant expected");
+ $$ = SYM_VAL($1).bs;
+ }
+ ;
+
CF_CODE
diff --git a/filter/config.Y b/filter/config.Y
index a1e5e9f1..1d7763ff 100644
--- a/filter/config.Y
+++ b/filter/config.Y
@@ -729,6 +729,7 @@ constant:
}
| '[' fprefix_set ']' { $$ = f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_PREFIX_SET, .val.ti = $2, }); }
| ENUM { $$ = f_new_inst(FI_CONSTANT, (struct f_val) { .type = $1 >> 16, .val.i = $1 & 0xffff, }); }
+ | BYTESTRING { $$ = f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_BYTESTRING, .val.bs = $1, }); }
;
constructor:
diff --git a/filter/data.h b/filter/data.h
index b3767f7b..091b3963 100644
--- a/filter/data.h
+++ b/filter/data.h
@@ -58,6 +58,7 @@ enum f_type {
T_LCLIST = 0x29, /* Large community list */
T_RD = 0x2a, /* Route distinguisher for VPN addresses */
T_PATH_MASK_ITEM = 0x2b, /* Path mask item for path mask constructors */
+ T_BYTESTRING = 0x2c,
T_SET = 0x80,
T_PREFIX_SET = 0x81,
@@ -78,6 +79,7 @@ struct f_val {
const struct adata *ad;
const struct f_path_mask *path_mask;
struct f_path_mask_item pmi;
+ const struct bytestring *bs;
} val;
};
diff --git a/lib/Makefile b/lib/Makefile
index 812f721c..0310eca2 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -1,4 +1,4 @@
-src := bitmap.c bitops.c blake2s.c blake2b.c checksum.c event.c flowspec.c idm.c ip.c lists.c mac.c md5.c mempool.c net.c patmatch.c printf.c resource.c sha1.c sha256.c sha512.c slab.c slists.c strtoul.c tbf.c timer.c xmalloc.c
+src := base64.c bitmap.c bitops.c blake2s.c blake2b.c checksum.c event.c flowspec.c idm.c ip.c lists.c mac.c md5.c mempool.c net.c patmatch.c printf.c resource.c sha1.c sha256.c sha512.c slab.c slists.c strtoul.c tbf.c timer.c xmalloc.c
obj := $(src-o-files)
$(all-daemon)
diff --git a/lib/README.base64 b/lib/README.base64
new file mode 100644
index 00000000..0c131123
--- /dev/null
+++ b/lib/README.base64
@@ -0,0 +1,62 @@
+base64.c was downloaded on 31 Aug 2021 from
+http://web.mit.edu/freebsd/head/contrib/wpa/src/utils/base64.c
+
+and the following text on 31 Aug 2021 from
+http://web.mit.edu/freebsd/head/contrib/wpa/
+
+wpa_supplicant and hostapd
+--------------------------
+
+Copyright (c) 2002-2012, Jouni Malinen <j@w1.fi> and contributors
+All Rights Reserved.
+
+These programs are licensed under the BSD license (the one with
+advertisement clause removed).
+
+If you are submitting changes to the project, please see CONTRIBUTIONS
+file for more instructions.
+
+
+This package may include either wpa_supplicant, hostapd, or both. See
+README file respective subdirectories (wpa_supplicant/README or
+hostapd/README) for more details.
+
+Source code files were moved around in v0.6.x releases and compared to
+earlier releases, the programs are now built by first going to a
+subdirectory (wpa_supplicant or hostapd) and creating build
+configuration (.config) and running 'make' there (for Linux/BSD/cygwin
+builds).
+
+
+License
+-------
+
+This software may be distributed, used, and modified under the terms of
+BSD license:
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+3. Neither the name(s) of the above-listed copyright holder(s) nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/lib/base64.c b/lib/base64.c
new file mode 100644
index 00000000..d5f3ae9b
--- /dev/null
+++ b/lib/base64.c
@@ -0,0 +1,163 @@
+/*
+ * Base64 encoding/decoding (RFC1341)
+ * Copyright (c) 2005-2011, Jouni Malinen <j@w1.fi>
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README.base64 for more details.
+ */
+
+#include "nest/bird.h"
+#include "conf/conf.h"
+#include "lib/resource.h"
+#include "lib/base64.h"
+
+static const unsigned char base64_table[65] =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+/**
+ * base64_encode - Base64 encode
+ * @src: Data to be encoded
+ * @len: Length of the data to be encoded
+ * @out_len: Pointer to output length variable, or %NULL if not used
+ * Returns: Allocated buffer of out_len bytes of encoded data,
+ * or %NULL on failure
+ *
+ * Caller is responsible for freeing the returned buffer. Returned buffer is
+ * nul terminated to make it easier to use as a C string. The nul terminator is
+ * not included in out_len.
+ */
+struct bytestring * base64_encode(linpool *pool,
+ const unsigned char *src, size_t len,
+ size_t *out_len)
+{
+ unsigned char *pos;
+ struct bytestring *out;
+ const unsigned char *end, *in;
+ size_t olen;
+ int line_len;
+
+ olen = len * 4 / 3 + 4; /* 3-byte blocks to 4-byte */
+ olen += olen / 72; /* line feeds */
+ olen++; /* nul termination */
+ if (olen < len)
+ return NULL; /* integer overflow */
+ out = lp_alloc(pool, sizeof(struct bytestring) + olen);
+ if (out == NULL)
+ return NULL;
+
+ end = src + len;
+ in = src;
+ pos = out->data;
+ line_len = 0;
+ while (end - in >= 3) {
+ *pos++ = base64_table[in[0] >> 2];
+ *pos++ = base64_table[((in[0] & 0x03) << 4) | (in[1] >> 4)];
+ *pos++ = base64_table[((in[1] & 0x0f) << 2) | (in[2] >> 6)];
+ *pos++ = base64_table[in[2] & 0x3f];
+ in += 3;
+ line_len += 4;
+ if (line_len >= 72) {
+ *pos++ = '\n';
+ line_len = 0;
+ }
+ }
+
+ if (end - in) {
+ *pos++ = base64_table[in[0] >> 2];
+ if (end - in == 1) {
+ *pos++ = base64_table[(in[0] & 0x03) << 4];
+ *pos++ = '=';
+ } else {
+ *pos++ = base64_table[((in[0] & 0x03) << 4) |
+ (in[1] >> 4)];
+ *pos++ = base64_table[(in[1] & 0x0f) << 2];
+ }
+ *pos++ = '=';
+ line_len += 4;
+ }
+
+ if (line_len)
+ *pos++ = '\n';
+
+ *pos = '\0';
+ out->length = pos - out->data;
+ if (out_len)
+ *out_len = out->length;
+ return out;
+}
+
+
+/**
+ * base64_decode - Base64 decode
+ * @src: Data to be decoded
+ * @len: Length of the data to be decoded
+ * @out_len: Pointer to output length variable
+ * Returns: Allocated buffer of out_len bytes of decoded data,
+ * or %NULL on failure
+ *
+ * Caller is responsible for freeing the returned buffer.
+ */
+struct bytestring * base64_decode_bs(linpool *pool,
+ const unsigned char *src, size_t len,
+ size_t *out_len)
+{
+ unsigned char dtable[256], *pos, block[4], tmp;
+ size_t i, count, olen;
+ int pad = 0;
+ struct bytestring *out;
+
+ memset(dtable, 0x80, 256);
+ for (i = 0; i < sizeof(base64_table) - 1; i++)
+ dtable[base64_table[i]] = (unsigned char) i;
+ dtable['='] = 0;
+
+ count = 0;
+ for (i = 0; i < len; i++) {
+ if (dtable[src[i]] != 0x80)
+ count++;
+ }
+
+ if (count == 0 || count % 4)
+ return NULL;
+
+ olen = count / 4 * 3;
+ out = lp_alloc(pool, sizeof(struct bytestring) + olen);
+ if (out == NULL)
+ return NULL;
+ pos = out->data;
+
+ count = 0;
+ for (i = 0; i < len; i++) {
+ tmp = dtable[src[i]];
+ if (tmp == 0x80)
+ continue;
+
+ if (src[i] == '=')
+ pad++;
+ block[count] = tmp;
+ count++;
+ if (count == 4) {
+ *pos++ = (block[0] << 2) | (block[1] >> 4);
+ *pos++ = (block[1] << 4) | (block[2] >> 2);
+ *pos++ = (block[2] << 6) | block[3];
+ count = 0;
+ if (pad) {
+ if (pad == 1)
+ pos--;
+ else if (pad == 2)
+ pos -= 2;
+ else {
+ /* Invalid padding */
+ //os_free(out);
+ return NULL;
+ }
+ break;
+ }
+ }
+ }
+
+ out->length = pos - out->data;
+ if (out_len)
+ *out_len = out->length;
+ return out;
+}
diff --git a/lib/base64.h b/lib/base64.h
new file mode 100644
index 00000000..8ca4dd9b
--- /dev/null
+++ b/lib/base64.h
@@ -0,0 +1,11 @@
+#ifndef _BIRD_BASE64_H_
+#define _BIRD_BASE64_H_
+
+#include "lib/resource.h"
+
+struct bytestring * base64_encode_bs(linpool *pool, const unsigned char *src, size_t len,
+ size_t *out_len);
+struct bytestring * base64_decode_bs(linpool *pool, const unsigned char *src, size_t len,
+ size_t *out_len);
+
+#endif /* _BIRD_BASE64_H_ */