From 35f88b305ab6a0e27b5ff1b445f63f544986e14e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toke=20H=C3=B8iland-J=C3=B8rgensen?= Date: Wed, 14 Apr 2021 21:39:43 +0200 Subject: [PATCH] Nest: Allow specifying security keys as hex bytes as well as strings Add support for specifying a password in hexadecimal format, The result is the same whether a password is specified as a quoted string or a hex-encoded byte string, this just makes it more convenient to input high-entropy byte strings as MAC keys. --- conf/cf-lex.l | 31 +++++++++++++++++++++++++++++++ conf/conf.h | 5 +++++ conf/confbase.Y | 2 ++ doc/bird.sgml | 7 ++++++- lib/string.h | 1 + lib/strtoul.c | 27 +++++++++++++++++++++++++++ nest/config.Y | 38 +++++++++++++++++++++----------------- 7 files changed, 93 insertions(+), 18 deletions(-) diff --git a/conf/cf-lex.l b/conf/cf-lex.l index 05288b1a..704a1750 100644 --- a/conf/cf-lex.l +++ b/conf/cf-lex.l @@ -255,6 +255,37 @@ WHITE [ \t] return IP4; } +{XIGIT}{2}(:{XIGIT}{2}|{XIGIT}{2}){15,} { + char *s = yytext; + size_t len = 0, i; + struct bytestring *bytes; + byte *b; + + while (*s) { + len++; + s += 2; + if (*s == ':') + s++; + } + bytes = cfg_allocz(sizeof(*bytes) + len); + + bytes->length = len; + b = &bytes->data[0]; + s = yytext; + errno = 0; + for (i = 0; i < len; i++) { + *b = bstrtobyte16(s); + if (errno == ERANGE) + cf_error("Invalid hex string"); + b++; + s += 2; + if (*s == ':') + s++; + } + cf_lval.bs = bytes; + return BYTESTRING; +} + ({XIGIT}*::|({XIGIT}*:){3,})({XIGIT}*|{DIGIT}+\.{DIGIT}+\.{DIGIT}+\.{DIGIT}+) { if (!ip6_pton(yytext, &cf_lval.ip6)) cf_error("Invalid IPv6 address %s", yytext); diff --git a/conf/conf.h b/conf/conf.h index 860d267a..3bc37959 100644 --- a/conf/conf.h +++ b/conf/conf.h @@ -136,6 +136,11 @@ struct sym_scope { int active; /* Currently entered */ }; +struct bytestring { + size_t length; + byte data[]; +}; + #define SYM_MAX_LEN 64 /* Remember to update cf_symbol_class_name() */ diff --git a/conf/confbase.Y b/conf/confbase.Y index d98f0fee..6985783b 100644 --- a/conf/confbase.Y +++ b/conf/confbase.Y @@ -92,6 +92,7 @@ CF_DECLS struct channel_limit cl; struct timeformat *tf; mpls_label_stack *mls; + struct bytestring *bs; } %token END CLI_MARKER INVALID_TOKEN ELSECOL DDOT @@ -103,6 +104,7 @@ CF_DECLS %token VPN_RD %token CF_SYM_KNOWN CF_SYM_UNDEFINED %token TEXT +%token BYTESTRING %type ipa_scope %type expr bool pxlen4 diff --git a/doc/bird.sgml b/doc/bird.sgml index bd1ed7ed..01725128 100644 --- a/doc/bird.sgml +++ b/doc/bird.sgml @@ -776,7 +776,7 @@ agreement"). protocol packets are processed in the local TX queues. This option is Linux specific. Default value is 7 (highest priority, privileged traffic). - + Specifies a password that can be used by the protocol as a shared secret key. Password option can be used more times to specify more passwords. If more passwords are specified, it is a protocol-dependent decision @@ -784,6 +784,11 @@ agreement"). authentication is enabled, authentication can be enabled by separate, protocol-dependent password = key; + this_p_item->length = length; + this_p_item->genfrom = 0; + this_p_item->gento = TIME_INFINITY; + this_p_item->accfrom = 0; + this_p_item->accto = TIME_INFINITY; + this_p_item->id = id; + this_p_item->alg = ALG_UNDEFINED; + add_tail(this_p_list, &this_p_item->n); +} static inline void reset_passwords(void) @@ -490,23 +509,8 @@ password_item: ; password_item_begin: - PASSWORD text { - if (!this_p_list) { - this_p_list = cfg_allocz(sizeof(list)); - init_list(this_p_list); - password_id = 1; - } - this_p_item = cfg_allocz(sizeof(struct password_item)); - this_p_item->password = $2; - this_p_item->length = strlen($2); - this_p_item->genfrom = 0; - this_p_item->gento = TIME_INFINITY; - this_p_item->accfrom = 0; - this_p_item->accto = TIME_INFINITY; - this_p_item->id = password_id++; - this_p_item->alg = ALG_UNDEFINED; - add_tail(this_p_list, &this_p_item->n); - } + PASSWORD text { init_password($2, strlen($2), password_id++); } + | PASSWORD BYTESTRING { init_password($2->data, $2->length, password_id++); } ; password_item_params: