Dear Ondrej, On Wed, Oct 02, 2024 at 03:40:11AM +0200, Ondrej Zajicek wrote:
Please, use sub-block here:
transport tcp { authentication md5; password "test"; };
Sure
+ if (old->password != new->password) + { + CACHE_TRACE(D_EVENTS, cache, "MD5 authentication changed"); + return NEED_RESTART; + }
I think you need bstrcmp(old->password, new->password) here.
ah, yes. Thanks for catching that :-) How about the below? diff --git a/doc/bird.sgml b/doc/bird.sgml index e2050c13..df086445 100644 --- a/doc/bird.sgml +++ b/doc/bird.sgml @@ -5735,7 +5735,10 @@ protocol rpki [<name>] { refresh [keep] <num>; retry [keep] <num>; expire [keep] <num>; - transport tcp; + transport tcp { + authentication md5; + password "<text>"; + }; transport ssh { bird private key "</path/to/id_rsa>"; remote public key "</path/to/known_host>"; @@ -5791,15 +5794,26 @@ specify both channels. instead. This may be useful for implementing loose RPKI check for blackholes. Default: disabled. - <tag>transport tcp</tag> Unprotected transport over TCP. It's a default - transport. Should be used only on secure private networks. - Default: tcp + <tag>transport tcp { <m/TCP transport options.../ }</tag> Transport over + TCP, it's the default transport. Cannot be combined with a SSH transport. + Default: TCP, no authentication. <tag>transport ssh { <m/SSH transport options.../ }</tag> It enables a SSHv2 transport encryption. Cannot be combined with a TCP transport. Default: off </descrip> +<sect3>TCP transport options +<p> +<descrip> + <tag>authentication md5</tag> + Enable TCP-MD5 authentication (<rfc id="2385">) on the TCP transport. + + <tag>password "<m>text</m>"</tag> + Use this password for TCP-MD5 authentication of the RPKI-To-Router session. + Default: no authentication. +</descrip> + <sect3>SSH transport options <p> <descrip> diff --git a/proto/rpki/config.Y b/proto/rpki/config.Y index 769ebb2c..56dfe966 100644 --- a/proto/rpki/config.Y +++ b/proto/rpki/config.Y @@ -32,7 +32,8 @@ rpki_check_unused_transport(void) CF_DECLS CF_KEYWORDS(RPKI, REMOTE, BIRD, PRIVATE, PUBLIC, KEY, TCP, SSH, TRANSPORT, USER, - RETRY, REFRESH, EXPIRE, KEEP, IGNORE, MAX, LENGTH, LOCAL, ADDRESS) + RETRY, REFRESH, EXPIRE, KEEP, IGNORE, MAX, LENGTH, LOCAL, ADDRESS, + AUTHENTICATION, MD5, PASSWORD) %type <i> rpki_keep_interval @@ -108,7 +109,7 @@ rpki_cache_addr: text_or_ipa }; rpki_transport: - TCP rpki_transport_tcp_init + TCP rpki_transport_tcp_init rpki_transport_tcp_opts_list rpki_transport_tcp_check | SSH rpki_transport_ssh_init '{' rpki_transport_ssh_opts '}' rpki_transport_ssh_check ; @@ -119,6 +120,29 @@ rpki_transport_tcp_init: RPKI_CFG->tr_config.type = RPKI_TR_TCP; }; +rpki_transport_tcp_opts_list: + /* empty */ + | '{' rpki_transport_tcp_opts '}' + ; + +rpki_transport_tcp_opts: + /* empty */ + | rpki_transport_tcp_opts rpki_transport_tcp_item ';' + ; + +rpki_transport_tcp_item: + AUTHENTICATION MD5 { RPKI_CFG->authtype = RPKI_TRANSPORT_TCP_MD5; } + | PASSWORD text { RPKI_CFG->password = $2; } + ; + +rpki_transport_tcp_check: +{ + if (RPKI_CFG->password != NULL && RPKI_CFG->authtype != ALG_MD5) + cf_error("Only TCP-MD5 authentication is supported for TCP transport"); + if (RPKI_CFG->authtype == ALG_MD5 && RPKI_CFG->password == NULL) + cf_error("TCP-MD5 authentication password must be set"); +}; + rpki_transport_ssh_init: { #if HAVE_LIBSSH diff --git a/proto/rpki/rpki.c b/proto/rpki/rpki.c index 4ec48e3b..a5ff5ff1 100644 --- a/proto/rpki/rpki.c +++ b/proto/rpki/rpki.c @@ -673,6 +673,12 @@ rpki_reconfigure_cache(struct rpki_proto *p UNUSED, struct rpki_cache *cache, st return NEED_RESTART; } + if (bstrcmp(old->password, new->password)) + { + CACHE_TRACE(D_EVENTS, cache, "MD5 authentication changed"); + return NEED_RESTART; + } + if (old->tr_config.type != new->tr_config.type) { CACHE_TRACE(D_EVENTS, cache, "Transport type changed"); @@ -843,7 +849,10 @@ rpki_show_proto_info(struct proto *P) break; #endif case RPKI_TR_TCP: - transport_name = "Unprotected over TCP"; + if (cf->authtype == RPKI_TRANSPORT_TCP_MD5) + transport_name = "TCP-MD5"; + else + transport_name = "Unprotected over TCP"; default_port = RPKI_TCP_PORT; break; }; diff --git a/proto/rpki/rpki.h b/proto/rpki/rpki.h index e67eb0e3..0905e271 100644 --- a/proto/rpki/rpki.h +++ b/proto/rpki/rpki.h @@ -31,6 +31,10 @@ #define RPKI_VERSION_1 1 #define RPKI_MAX_VERSION RPKI_VERSION_1 +enum transportauth { + RPKI_TRANSPORT_TCP_PLAIN, + RPKI_TRANSPORT_TCP_MD5 +}; /* * RPKI Cache @@ -127,6 +131,8 @@ struct rpki_config { u8 keep_retry_interval:1; /* Do not overwrite retry interval by cache server update */ u8 keep_expire_interval:1; /* Do not overwrite expire interval by cache server update */ u8 ignore_max_length:1; /* Ignore received max length and use MAX_PREFIX_LENGTH instead */ + enum transportauth authtype; /* Authentication type */ + const char *password; /* Password used for authentication */ }; void rpki_check_config(struct rpki_config *cf); diff --git a/proto/rpki/transport.c b/proto/rpki/transport.c index 26571977..9932ad32 100644 --- a/proto/rpki/transport.c +++ b/proto/rpki/transport.c @@ -88,6 +88,9 @@ rpki_tr_open(struct rpki_tr_sock *tr) sk->tos = IP_PREC_INTERNET_CONTROL; sk->vrf = cache->p->p.vrf; + if (cf->tr_config.type == RPKI_TR_TCP && cf->authtype == RPKI_TRANSPORT_TCP_MD5 && cf->password != NULL) + sk->password = cf->password; + if (ipa_zero(sk->daddr) && sk->host) { const char *err_msg;