summaryrefslogtreecommitdiff
path: root/usr.sbin/bgpd
diff options
context:
space:
mode:
authorClaudio Jeker <claudio@cvs.openbsd.org>2024-10-09 10:01:30 +0000
committerClaudio Jeker <claudio@cvs.openbsd.org>2024-10-09 10:01:30 +0000
commitfda95ded0712cc490f848930197a2998203bc55e (patch)
tree7fc753a24d50f8739ccc6513c9c7bf06b0417c72 /usr.sbin/bgpd
parent25b323ce240ffd001e1258937ef58fe45a862182 (diff)
Make it possible to configure tcp md5 and ipsec on rtr as well
Single out the auth_config yacc rules. Even though this requires an extra merge_auth_conf() function to handle manual IPsec setups but even with that this seems like a net gain. There is no rtr cache that does tcp md5 on OpenBSD so those bits remain untested for now. OK tb@
Diffstat (limited to 'usr.sbin/bgpd')
-rw-r--r--usr.sbin/bgpd/parse.y287
-rw-r--r--usr.sbin/bgpd/printconf.c64
2 files changed, 187 insertions, 164 deletions
diff --git a/usr.sbin/bgpd/parse.y b/usr.sbin/bgpd/parse.y
index 166c0e79438..954bc5c882a 100644
--- a/usr.sbin/bgpd/parse.y
+++ b/usr.sbin/bgpd/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.469 2024/10/01 11:49:24 claudio Exp $ */
+/* $OpenBSD: parse.y,v 1.470 2024/10/09 10:01:29 claudio Exp $ */
/*
* Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -187,6 +187,7 @@ static int push_unary_numop(enum comp_ops, long long);
static int push_binary_numop(enum comp_ops, long long, long long);
static int geticmptypebyname(char *, uint8_t);
static int geticmpcodebyname(u_long, char *, uint8_t);
+static int merge_auth_conf(struct auth_config *, struct auth_config *);
static struct bgpd_config *conf;
static struct network_head *netconf;
@@ -228,6 +229,7 @@ typedef struct {
} prefix;
struct filter_prefixlen prefixlen;
struct prefixset_item *prefixset_item;
+ struct auth_config authconf;
struct {
enum auth_enc_alg enc_alg;
uint8_t enc_key_len;
@@ -293,6 +295,7 @@ typedef struct {
%type <v.filter_prefix> filter_prefix filter_prefix_l filter_prefix_h
%type <v.filter_prefix> filter_prefix_m
%type <v.u8> unaryop equalityop binaryop filter_as_type
+%type <v.authconf> authconf
%type <v.encspec> encspec
%type <v.aspa_elm> aspa_tas aspa_tas_l
%%
@@ -732,6 +735,10 @@ rtropt : DESCR STRING {
}
currtr->min_version = $2;
}
+ | authconf {
+ if (merge_auth_conf(&currtr->auth, &$1) == 0)
+ YYERROR;
+ }
;
conf_main : AS as4number {
@@ -2075,142 +2082,9 @@ peeropts : REMOTEAS as4number {
curpeer->conf.max_out_prefix = $2;
curpeer->conf.max_out_prefix_restart = $4;
}
- | TCP MD5SIG PASSWORD string {
- if (curpeer->auth_conf.method) {
- yyerror("auth method cannot be redefined");
- free($4);
- YYERROR;
- }
- if (strlcpy(curpeer->auth_conf.md5key, $4,
- sizeof(curpeer->auth_conf.md5key)) >=
- sizeof(curpeer->auth_conf.md5key)) {
- yyerror("tcp md5sig password too long: max %zu",
- sizeof(curpeer->auth_conf.md5key) - 1);
- free($4);
- YYERROR;
- }
- curpeer->auth_conf.method = AUTH_MD5SIG;
- curpeer->auth_conf.md5key_len = strlen($4);
- free($4);
- }
- | TCP MD5SIG KEY string {
- if (curpeer->auth_conf.method) {
- yyerror("auth method cannot be redefined");
- free($4);
- YYERROR;
- }
-
- if (str2key($4, curpeer->auth_conf.md5key,
- sizeof(curpeer->auth_conf.md5key)) == -1) {
- free($4);
- YYERROR;
- }
- curpeer->auth_conf.method = AUTH_MD5SIG;
- curpeer->auth_conf.md5key_len = strlen($4) / 2;
- free($4);
- }
- | IPSEC espah IKE {
- if (curpeer->auth_conf.method) {
- yyerror("auth method cannot be redefined");
- YYERROR;
- }
- if ($2)
- curpeer->auth_conf.method = AUTH_IPSEC_IKE_ESP;
- else
- curpeer->auth_conf.method = AUTH_IPSEC_IKE_AH;
- }
- | IPSEC espah inout SPI NUMBER STRING STRING encspec {
- enum auth_alg auth_alg;
- uint8_t keylen;
-
- if (curpeer->auth_conf.method &&
- (((curpeer->auth_conf.spi_in && $3 == 1) ||
- (curpeer->auth_conf.spi_out && $3 == 0)) ||
- ($2 == 1 && curpeer->auth_conf.method !=
- AUTH_IPSEC_MANUAL_ESP) ||
- ($2 == 0 && curpeer->auth_conf.method !=
- AUTH_IPSEC_MANUAL_AH))) {
- yyerror("auth method cannot be redefined");
- free($6);
- free($7);
- YYERROR;
- }
-
- if (!strcmp($6, "sha1")) {
- auth_alg = AUTH_AALG_SHA1HMAC;
- keylen = 20;
- } else if (!strcmp($6, "md5")) {
- auth_alg = AUTH_AALG_MD5HMAC;
- keylen = 16;
- } else {
- yyerror("unknown auth algorithm \"%s\"", $6);
- free($6);
- free($7);
+ | authconf {
+ if (merge_auth_conf(&curpeer->auth_conf, &$1) == 0)
YYERROR;
- }
- free($6);
-
- if (strlen($7) / 2 != keylen) {
- yyerror("auth key len: must be %u bytes, "
- "is %zu bytes", keylen, strlen($7) / 2);
- free($7);
- YYERROR;
- }
-
- if ($2)
- curpeer->auth_conf.method =
- AUTH_IPSEC_MANUAL_ESP;
- else {
- if ($8.enc_alg) {
- yyerror("\"ipsec ah\" doesn't take "
- "encryption keys");
- free($7);
- YYERROR;
- }
- curpeer->auth_conf.method =
- AUTH_IPSEC_MANUAL_AH;
- }
-
- if ($5 <= SPI_RESERVED_MAX || $5 > UINT_MAX) {
- yyerror("bad spi number %lld", $5);
- free($7);
- YYERROR;
- }
-
- if ($3 == 1) {
- if (str2key($7, curpeer->auth_conf.auth_key_in,
- sizeof(curpeer->auth_conf.auth_key_in)) ==
- -1) {
- free($7);
- YYERROR;
- }
- curpeer->auth_conf.spi_in = $5;
- curpeer->auth_conf.auth_alg_in = auth_alg;
- curpeer->auth_conf.enc_alg_in = $8.enc_alg;
- memcpy(&curpeer->auth_conf.enc_key_in,
- &$8.enc_key,
- sizeof(curpeer->auth_conf.enc_key_in));
- curpeer->auth_conf.enc_keylen_in =
- $8.enc_key_len;
- curpeer->auth_conf.auth_keylen_in = keylen;
- } else {
- if (str2key($7, curpeer->auth_conf.auth_key_out,
- sizeof(curpeer->auth_conf.auth_key_out)) ==
- -1) {
- free($7);
- YYERROR;
- }
- curpeer->auth_conf.spi_out = $5;
- curpeer->auth_conf.auth_alg_out = auth_alg;
- curpeer->auth_conf.enc_alg_out = $8.enc_alg;
- memcpy(&curpeer->auth_conf.enc_key_out,
- &$8.enc_key,
- sizeof(curpeer->auth_conf.enc_key_out));
- curpeer->auth_conf.enc_keylen_out =
- $8.enc_key_len;
- curpeer->auth_conf.auth_keylen_out = keylen;
- }
- free($7);
}
| TTLSECURITY yesno {
curpeer->conf.ttlsec = $2;
@@ -2357,6 +2231,111 @@ nettype : STATIC { $$ = 1; }
| CONNECTED { $$ = 0; }
;
+authconf : TCP MD5SIG PASSWORD string {
+ memset(&$$, 0, sizeof($$));
+ if (strlcpy($$.md5key, $4, sizeof($$.md5key)) >=
+ sizeof($$.md5key)) {
+ yyerror("tcp md5sig password too long: max %zu",
+ sizeof($$.md5key) - 1);
+ free($4);
+ YYERROR;
+ }
+ $$.method = AUTH_MD5SIG;
+ $$.md5key_len = strlen($4);
+ free($4);
+ }
+ | TCP MD5SIG KEY string {
+ memset(&$$, 0, sizeof($$));
+ if (str2key($4, $$.md5key, sizeof($$.md5key)) == -1) {
+ free($4);
+ YYERROR;
+ }
+ $$.method = AUTH_MD5SIG;
+ $$.md5key_len = strlen($4) / 2;
+ free($4);
+ }
+ | IPSEC espah IKE {
+ memset(&$$, 0, sizeof($$));
+ if ($2)
+ $$.method = AUTH_IPSEC_IKE_ESP;
+ else
+ $$.method = AUTH_IPSEC_IKE_AH;
+ }
+ | IPSEC espah inout SPI NUMBER STRING STRING encspec {
+ enum auth_alg auth_alg;
+ uint8_t keylen;
+
+ memset(&$$, 0, sizeof($$));
+ if (!strcmp($6, "sha1")) {
+ auth_alg = AUTH_AALG_SHA1HMAC;
+ keylen = 20;
+ } else if (!strcmp($6, "md5")) {
+ auth_alg = AUTH_AALG_MD5HMAC;
+ keylen = 16;
+ } else {
+ yyerror("unknown auth algorithm \"%s\"", $6);
+ free($6);
+ free($7);
+ YYERROR;
+ }
+ free($6);
+
+ if (strlen($7) / 2 != keylen) {
+ yyerror("auth key len: must be %u bytes, "
+ "is %zu bytes", keylen, strlen($7) / 2);
+ free($7);
+ YYERROR;
+ }
+
+ if ($2)
+ $$.method = AUTH_IPSEC_MANUAL_ESP;
+ else {
+ if ($8.enc_alg) {
+ yyerror("\"ipsec ah\" doesn't take "
+ "encryption keys");
+ free($7);
+ YYERROR;
+ }
+ $$.method = AUTH_IPSEC_MANUAL_AH;
+ }
+
+ if ($5 <= SPI_RESERVED_MAX || $5 > UINT_MAX) {
+ yyerror("bad spi number %lld", $5);
+ free($7);
+ YYERROR;
+ }
+
+ if ($3 == 1) {
+ if (str2key($7, $$.auth_key_in,
+ sizeof($$.auth_key_in)) == -1) {
+ free($7);
+ YYERROR;
+ }
+ $$.spi_in = $5;
+ $$.auth_alg_in = auth_alg;
+ $$.enc_alg_in = $8.enc_alg;
+ memcpy(&$$.enc_key_in, &$8.enc_key,
+ sizeof($$.enc_key_in));
+ $$.enc_keylen_in = $8.enc_key_len;
+ $$.auth_keylen_in = keylen;
+ } else {
+ if (str2key($7, $$.auth_key_out,
+ sizeof($$.auth_key_out)) == -1) {
+ free($7);
+ YYERROR;
+ }
+ $$.spi_out = $5;
+ $$.auth_alg_out = auth_alg;
+ $$.enc_alg_out = $8.enc_alg;
+ memcpy(&$$.enc_key_out, &$8.enc_key,
+ sizeof($$.enc_key_out));
+ $$.enc_keylen_out = $8.enc_key_len;
+ $$.auth_keylen_out = keylen;
+ }
+ free($7);
+ }
+ ;
+
espah : ESP { $$ = 1; }
| AH { $$ = 0; }
;
@@ -6033,3 +6012,39 @@ geticmpcodebyname(u_long type, char *w, uint8_t aid)
}
return -1;
}
+
+static int
+merge_auth_conf(struct auth_config *to, struct auth_config *from)
+{
+ if (to->method != 0) {
+ /* extra magic for manual ipsec rules */
+ if (to->method == from->method &&
+ (to->method == AUTH_IPSEC_MANUAL_ESP ||
+ to->method == AUTH_IPSEC_MANUAL_AH)) {
+ if (to->spi_in == 0 && from->spi_in != 0) {
+ to->spi_in = from->spi_in;
+ to->auth_alg_in = from->auth_alg_in;
+ to->enc_alg_in = from->enc_alg_in;
+ memcpy(to->enc_key_in, from->enc_key_in,
+ sizeof(to->enc_key_in));
+ to->enc_keylen_in = from->enc_keylen_in;
+ to->auth_keylen_in = from->auth_keylen_in;
+ return 1;
+ } else if (to->spi_out == 0 && from->spi_out != 0) {
+ to->spi_out = from->spi_out;
+ to->auth_alg_out = from->auth_alg_out;
+ to->enc_alg_out = from->enc_alg_out;
+ memcpy(to->enc_key_out, from->enc_key_out,
+ sizeof(to->enc_key_out));
+ to->enc_keylen_out = from->enc_keylen_out;
+ to->auth_keylen_out = from->auth_keylen_out;
+ return 1;
+ }
+ }
+ yyerror("auth method cannot be redefined");
+ return 0;
+ }
+ *to = *from;
+ return 1;
+}
+
diff --git a/usr.sbin/bgpd/printconf.c b/usr.sbin/bgpd/printconf.c
index e34380ffd38..a62311e7b62 100644
--- a/usr.sbin/bgpd/printconf.c
+++ b/usr.sbin/bgpd/printconf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: printconf.c,v 1.175 2024/10/01 11:49:24 claudio Exp $ */
+/* $OpenBSD: printconf.c,v 1.176 2024/10/09 10:01:29 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -712,6 +712,39 @@ print_aspa(struct aspa_tree *a)
printf("\n}\n\n");
}
+static void
+print_auth(struct auth_config *auth, const char *c)
+{
+ char *method;
+
+ if (auth->method == AUTH_MD5SIG)
+ printf("%s\ttcp md5sig\n", c);
+ else if (auth->method == AUTH_IPSEC_MANUAL_ESP ||
+ auth->method == AUTH_IPSEC_MANUAL_AH) {
+ if (auth->method == AUTH_IPSEC_MANUAL_ESP)
+ method = "esp";
+ else
+ method = "ah";
+
+ printf("%s\tipsec %s in spi %u %s XXXXXX", c, method,
+ auth->spi_in, print_auth_alg(auth->auth_alg_in));
+ if (auth->enc_alg_in)
+ printf(" %s XXXXXX", print_enc_alg(auth->enc_alg_in));
+ printf("\n");
+
+ printf("%s\tipsec %s out spi %u %s XXXXXX", c, method,
+ auth->spi_out, print_auth_alg(auth->auth_alg_out));
+ if (auth->enc_alg_out)
+ printf(" %s XXXXXX",
+ print_enc_alg(auth->enc_alg_out));
+ printf("\n");
+ } else if (auth->method == AUTH_IPSEC_IKE_AH)
+ printf("%s\tipsec ah ike\n", c);
+ else if (auth->method == AUTH_IPSEC_IKE_ESP)
+ printf("%s\tipsec esp ike\n", c);
+
+}
+
void
print_rtrs(struct rtr_config_head *rh)
{
@@ -723,6 +756,7 @@ print_rtrs(struct rtr_config_head *rh)
printf("\tport %u\n", r->remote_port);
if (r->local_addr.aid != AID_UNSPEC)
printf("local-addr %s\n", log_addr(&r->local_addr));
+ print_auth(&r->auth, "");
printf("}\n\n");
}
}
@@ -731,9 +765,7 @@ void
print_peer(struct peer *peer, struct bgpd_config *conf, const char *c)
{
struct in_addr ina;
- char *method;
struct peer_config *p = &peer->conf;
- struct auth_config *auth = &peer->auth_conf;
if ((p->remote_addr.aid == AID_INET && p->remote_masklen != 32) ||
(p->remote_addr.aid == AID_INET6 && p->remote_masklen != 128))
@@ -832,31 +864,7 @@ print_peer(struct peer *peer, struct bgpd_config *conf, const char *c)
if (p->flags & PEERFLAG_LOG_UPDATES)
printf("%s\tlog updates\n", c);
- if (auth->method == AUTH_MD5SIG)
- printf("%s\ttcp md5sig\n", c);
- else if (auth->method == AUTH_IPSEC_MANUAL_ESP ||
- auth->method == AUTH_IPSEC_MANUAL_AH) {
- if (auth->method == AUTH_IPSEC_MANUAL_ESP)
- method = "esp";
- else
- method = "ah";
-
- printf("%s\tipsec %s in spi %u %s XXXXXX", c, method,
- auth->spi_in, print_auth_alg(auth->auth_alg_in));
- if (auth->enc_alg_in)
- printf(" %s XXXXXX", print_enc_alg(auth->enc_alg_in));
- printf("\n");
-
- printf("%s\tipsec %s out spi %u %s XXXXXX", c, method,
- auth->spi_out, print_auth_alg(auth->auth_alg_out));
- if (auth->enc_alg_out)
- printf(" %s XXXXXX",
- print_enc_alg(auth->enc_alg_out));
- printf("\n");
- } else if (auth->method == AUTH_IPSEC_IKE_AH)
- printf("%s\tipsec ah ike\n", c);
- else if (auth->method == AUTH_IPSEC_IKE_ESP)
- printf("%s\tipsec esp ike\n", c);
+ print_auth(&peer->auth_conf, c);
if (p->ttlsec)
printf("%s\tttl-security yes\n", c);