0
0
mirror of https://gitlab.nic.cz/labs/bird.git synced 2024-12-22 17:51:53 +00:00

backup - tcp ao works in simplest possible version, only as md5 replacement (without option to switch to md5), show info fixed

This commit is contained in:
Katerina Kubecova 2024-02-14 13:48:08 +01:00
parent 8826e6b701
commit 4a91d4961b
8 changed files with 129 additions and 89 deletions

View File

@ -107,6 +107,8 @@ int sk_setup_broadcast(sock *s);
int sk_set_ttl(sock *s, int ttl); /* Set transmit TTL for given socket */ int sk_set_ttl(sock *s, int ttl); /* Set transmit TTL for given socket */
int sk_set_min_ttl(sock *s, int ttl); /* Set minimal accepted TTL for given socket */ int sk_set_min_ttl(sock *s, int ttl); /* Set minimal accepted TTL for given socket */
int sk_set_md5_auth(sock *s, ip_addr local, ip_addr remote, int pxlen, struct iface *ifa, const char *passwd, int setkey); int sk_set_md5_auth(sock *s, ip_addr local, ip_addr remote, int pxlen, struct iface *ifa, const char *passwd, int setkey);
int sk_set_ao_auth(sock *s, ip_addr local, ip_addr remote, int pxlen, struct iface *ifa, const char *passwd, int passwd_id_loc, int passwd_id_rem, int setkey);
void log_tcp_ao_info(int fd);
int sk_set_ipv6_checksum(sock *s, int offset); int sk_set_ipv6_checksum(sock *s, int offset);
int sk_set_icmp6_filter(sock *s, int p1, int p2); int sk_set_icmp6_filter(sock *s, int p1, int p2);
void sk_log_error(sock *s, const char *p); void sk_log_error(sock *s, const char *p);

View File

@ -11,6 +11,7 @@
#include "lib/lists.h" #include "lib/lists.h"
#include "lib/ip.h" #include "lib/ip.h"
#include "sysdep/linux/tcp-ao.h"
extern list iface_list; extern list iface_list;

View File

@ -179,6 +179,7 @@ bgp_open(struct bgp_proto *p)
sk->type = SK_TCP_PASSIVE; sk->type = SK_TCP_PASSIVE;
sk->ttl = 255; sk->ttl = 255;
sk->saddr = addr; sk->saddr = addr;
// sk->daddr = p->remote_ip;
sk->sport = port; sk->sport = port;
sk->iface = ifa; sk->iface = ifa;
sk->vrf = p->p.vrf; sk->vrf = p->p.vrf;
@ -188,7 +189,9 @@ bgp_open(struct bgp_proto *p)
sk->tbsize = BGP_TX_BUFFER_SIZE; sk->tbsize = BGP_TX_BUFFER_SIZE;
sk->rx_hook = bgp_incoming_connection; sk->rx_hook = bgp_incoming_connection;
sk->err_hook = bgp_listen_sock_err; sk->err_hook = bgp_listen_sock_err;
//sk->password = p->cf->password;
log("passive connect p %i, c cf %i %s", p, p->cf, p->cf->password ? p->cf->password : "no password");
if (sk_open(sk) < 0) if (sk_open(sk) < 0)
goto err; goto err;
@ -243,10 +246,11 @@ bgp_setup_auth(struct bgp_proto *p, int enable)
prefix = net_prefix(p->cf->remote_range); prefix = net_prefix(p->cf->remote_range);
pxlen = net_pxlen(p->cf->remote_range); pxlen = net_pxlen(p->cf->remote_range);
} }
int rv = 0;
int rv = sk_set_md5_auth(p->sock->sk, if (enable)
rv = sk_set_ao_auth(p->sock->sk,
p->cf->local_ip, prefix, pxlen, p->cf->iface, p->cf->local_ip, prefix, pxlen, p->cf->iface,
enable ? p->cf->password : NULL, p->cf->setkey); p->cf->password, 123, 123, p->cf->setkey);
if (rv < 0) if (rv < 0)
sk_log_error(p->sock->sk, p->p.name); sk_log_error(p->sock->sk, p->p.name);
@ -1098,6 +1102,12 @@ bgp_active(struct bgp_proto *p)
bgp_start_timer(conn->connect_timer, delay); bgp_start_timer(conn->connect_timer, delay);
} }
void
log_ao(int fd)
{
log_tcp_ao_info(fd);
}
/** /**
* bgp_connect - initiate an outgoing connection * bgp_connect - initiate an outgoing connection
* @p: BGP instance * @p: BGP instance
@ -1124,6 +1134,7 @@ bgp_connect(struct bgp_proto *p) /* Enter Connect state and start establishing c
s->rbsize = p->cf->enable_extended_messages ? BGP_RX_BUFFER_EXT_SIZE : BGP_RX_BUFFER_SIZE; s->rbsize = p->cf->enable_extended_messages ? BGP_RX_BUFFER_EXT_SIZE : BGP_RX_BUFFER_SIZE;
s->tbsize = p->cf->enable_extended_messages ? BGP_TX_BUFFER_EXT_SIZE : BGP_TX_BUFFER_SIZE; s->tbsize = p->cf->enable_extended_messages ? BGP_TX_BUFFER_EXT_SIZE : BGP_TX_BUFFER_SIZE;
s->tos = IP_PREC_INTERNET_CONTROL; s->tos = IP_PREC_INTERNET_CONTROL;
// s->password = "abcd1234";/
s->password = p->cf->password; s->password = p->cf->password;
s->tx_hook = bgp_connected; s->tx_hook = bgp_connected;
s->flags = p->cf->free_bind ? SKF_FREEBIND : 0; s->flags = p->cf->free_bind ? SKF_FREEBIND : 0;
@ -1134,9 +1145,11 @@ bgp_connect(struct bgp_proto *p) /* Enter Connect state and start establishing c
bgp_setup_sk(conn, s); bgp_setup_sk(conn, s);
bgp_conn_set_state(conn, BS_CONNECT); bgp_conn_set_state(conn, BS_CONNECT);
log("active open p %i, c cf %i %s ", p, p->cf, p->cf->password ? p->cf->password : "no password");
if (sk_open(s) < 0) if (sk_open(s) < 0)
goto err; goto err;
//int rv = sk_set_ao_auth(s, p->local_ip, p->remote_ip, -1, s->iface, s->password ? s->password : "d3f4u1t", 1);
/* Set minimal receive TTL if needed */ /* Set minimal receive TTL if needed */
if (p->cf->ttl_security) if (p->cf->ttl_security)
if (sk_set_min_ttl(s, 256 - hops) < 0) if (sk_set_min_ttl(s, 256 - hops) < 0)

View File

@ -539,6 +539,8 @@ bgp_parse_error(struct bgp_parse_state *s, uint subcode)
longjmp(s->err_jmpbuf, 1); longjmp(s->err_jmpbuf, 1);
} }
void log_ao(int fd);
void bgp_start_timer(timer *t, uint value); void bgp_start_timer(timer *t, uint value);
void bgp_check_config(struct bgp_config *c); void bgp_check_config(struct bgp_config *c);

View File

@ -3423,6 +3423,8 @@ bgp_rx_packet(struct bgp_conn *conn, byte *pkt, uint len)
int int
bgp_rx(sock *sk, uint size) bgp_rx(sock *sk, uint size)
{ {
log("......................................got %i", size);
log_ao(sk->fd);
struct bgp_conn *conn = sk->data; struct bgp_conn *conn = sk->data;
byte *pkt_start = sk->rbuf; byte *pkt_start = sk->rbuf;
byte *end = pkt_start + size; byte *end = pkt_start + size;

View File

@ -176,11 +176,11 @@ sk_prepare_cmsgs4(sock *s, struct msghdr *msg, void *cbuf, size_t cbuflen)
/* /*
* Miscellaneous Linux socket syscalls * Miscellaneous Linux socket syscalls
*/ */
int int
sk_set_md5_auth(sock *s, ip_addr local, ip_addr remote, int pxlen, struct iface *ifa, const char *passwd, int setkey UNUSED) // local UNUSED sk_set_md5_auth(sock *s, ip_addr local UNUSED, ip_addr remote, int pxlen, struct iface *ifa, const char *passwd, int setkey UNUSED)
{ {
struct tcp_md5sig_ext md5; struct tcp_md5sig_ext md5;
log("md5 password is %i, socket fd %i", passwd, s->fd);
memset(&md5, 0, sizeof(md5)); memset(&md5, 0, sizeof(md5));
sockaddr_fill((sockaddr *) &md5.tcpm_addr, s->af, remote, ifa, 0); sockaddr_fill((sockaddr *) &md5.tcpm_addr, s->af, remote, ifa, 0);
@ -198,87 +198,7 @@ sk_set_md5_auth(sock *s, ip_addr local, ip_addr remote, int pxlen, struct iface
if (pxlen < 0) if (pxlen < 0)
{ {
struct tcp_ao_add_ext ao;
memset(&ao, 0, sizeof(struct tcp_ao_add_ext));
sockaddr_fill((sockaddr *) &ao.addr, s->af, remote, ifa, 0);
ao.set_current = 0;
ao.set_rnext = 0;
if (pxlen >= 0)
ao.prefix = pxlen;
else if(s->af == AF_INET)
ao.prefix = 32;
else
ao.prefix = 128;
ao.sndid = 100;
ao.rcvid = 100;
ao.maclen = 0;
ao.keyflags = 0;
ao.ifindex = 0;
strncpy(ao.alg_name, DEFAULT_TEST_ALGO, 64);
if (passwd != NULL)
{
ao.keylen = strlen(passwd);
memcpy(ao.key, passwd, (strlen(passwd) > TCP_AO_MAXKEYLEN_) ? TCP_AO_MAXKEYLEN_ : strlen(passwd));
}
else
{
log("no passwd was given, lets use default.");
ao.keylen = strlen("1cx4c6b");
memcpy(ao.key, "1cx4c6b", (strlen("1cx4c6b") > TCP_AO_MAXKEYLEN_) ? TCP_AO_MAXKEYLEN_ : strlen("1cx4c6b"));
}
int IPPROTO_TCP_ = 6;
log("socket: fd %i", s->fd);
if (setsockopt(s->fd, IPPROTO_TCP, TCP_AO_ADD_KEY, &ao, sizeof(ao)) < 0)
bug("tcp ao err %i", errno);
log("ok");
/*if (setsockopt(s->fd, SOL_TCP, TCP_MD5SIG_EXT, &md5, sizeof(md5)) < 0)
if (errno == ENOPROTOOPT)
ERR_MSG("Kernel does not support TCP MD5 signatures");
else
ERR("TCP_MD5SIG");*/
}
else
{
md5.tcpm_flags = TCP_MD5SIG_FLAG_PREFIX;
md5.tcpm_prefixlen = pxlen;
if (setsockopt(s->fd, SOL_TCP, TCP_MD5SIG_EXT, &md5, sizeof(md5)) < 0) if (setsockopt(s->fd, SOL_TCP, TCP_MD5SIG_EXT, &md5, sizeof(md5)) < 0)
{
if (errno == ENOPROTOOPT)
ERR_MSG("Kernel does not support extended TCP MD5 signatures");
else
ERR("TCP_MD5SIG_EXT");
}
}
return 0;
}
/**int
sk_set_tcpao_auth(sock *s, ip_addr local UNUSED, ip_addr remote, int pxlen, struct iface *ifa, const char *passwd, int setkey UNUSED)
{
struct tcp_ao_add *ao;
memset(&ao, 0, sizeof(struct tcp_ao_add));
sockaddr_fill((sockaddr *) &md5.tcpm_addr, s->af, remote, ifa, 0);
if (passwd)
{
int len = strlen(passwd);
if (len > TCP_MD5SIG_MAXKEYLEN)
ERR_MSG("The password for TCP MD5 Signature is too long");
md5.tcpm_keylen = len;
memcpy(&md5.tcpm_key, passwd, len);
}
if (pxlen < 0)
{
if (setsockopt(s->fd, SOL_TCP, TCP_MD5SIG, &md5, sizeof(md5)) < 0)
if (errno == ENOPROTOOPT) if (errno == ENOPROTOOPT)
ERR_MSG("Kernel does not support TCP MD5 signatures"); ERR_MSG("Kernel does not support TCP MD5 signatures");
else else
@ -299,7 +219,96 @@ sk_set_tcpao_auth(sock *s, ip_addr local UNUSED, ip_addr remote, int pxlen, stru
} }
return 0; return 0;
}**/ }
void log_tcp_ao_info(int sock_fd)
{
struct tcp_ao_info_opt_ext tmp;
memset(&tmp, 0, sizeof(struct tcp_ao_info_opt_ext));
socklen_t len = sizeof(tmp);
log("socket: fd %i", sock_fd);
if (getsockopt(sock_fd, IPPROTO_TCP, TCP_AO_INFO, &tmp, &len))
{
log("log tcp ao info failed with err code %i", errno);
return;
}
else
log("current key id %i, set current %i, ao required %i ", tmp.current_key, tmp.set_current, tmp.ao_required);
}
int
sk_set_ao_auth(sock *s, ip_addr local, ip_addr remote, int pxlen, struct iface *ifa, const char *passwd, int passwd_id_loc, int passwd_id_rem, int setkey UNUSED)
{
struct tcp_ao_add_ext ao;
memset(&ao, 0, sizeof(struct tcp_ao_add_ext));
log("af %i %I %I (%i or %i) %s %i", s->af, remote, local, AF_INET, AF_INET6, passwd, passwd[0]);
/* int af;
if (ipa_is_ip4(remote))
af = AF_INET;
else
af = AF_INET6;*/
sockaddr_fill((sockaddr *) &ao.addr, s->af, remote, ifa, 0);
ao.set_current = 0;
ao.set_rnext = 0;
if (pxlen >= 0)
ao.prefix = pxlen;
else if(s->af == AF_INET)
ao.prefix = 32;
else
ao.prefix = 128;
ao.sndid = passwd_id_rem;
ao.rcvid = passwd_id_loc;
ao.maclen = 0;
ao.keyflags = 0;
ao.ifindex = 0;
strncpy(ao.alg_name, DEFAULT_TEST_ALGO, 64);
ao.keylen = strlen(passwd);
memcpy(ao.key, passwd, (strlen(passwd) > TCP_AO_MAXKEYLEN_) ? TCP_AO_MAXKEYLEN_ : strlen(passwd));
int IPPROTO_TCP_ = 6;
if (setsockopt(s->fd, IPPROTO_TCP, TCP_AO_ADD_KEY, &ao, sizeof(ao)) < 0)
bug("tcp ao err %i", errno);
log_tcp_ao_info(s->fd);
return 0;
}
void
save_to_repair(int sock_fd)
{
struct tcp_ao_repair_ext replace_me; //TODO not ignore replace_me
socklen_t len = sizeof(replace_me);
memset(&replace_me, 0, sizeof(struct tcp_ao_repair_ext));
if (getsockopt(sock_fd, IPPROTO_TCP, TCP_AO_REPAIR, &replace_me, &len) < 0)
bug("geting tcp ao img not succeed %i", errno);
log("got tcp ao img");
}
void
repair_tcp_ao(int sock_fd, struct iface *ifa)
{
//if (setsockopt(sock_fd, SOL_TCP, TCP_AO_REPAIR, &ifa->tcp_ao_img, sizeof(ifa->tcp_ao_img)) < 0)
// bug("tcp ao err %i", errno);
log("tcp ao repair skiped");
}
void
change_ao_keys(sock *s, int passwd_id_loc, int passwd_id_rem )
{
struct tcp_ao_info_opt_ext tmp;
tmp.rnext = passwd_id_loc;
socklen_t len = sizeof(tmp);
if (setsockopt(s->fd, IPPROTO_TCP, TCP_AO_INFO, &tmp, &len))
{
log("log tcp ao key change failed with err code %i", errno);
return;
}
}
static inline int static inline int
sk_set_min_ttl4(sock *s, int ttl) sk_set_min_ttl4(sock *s, int ttl)

View File

@ -1,4 +1,7 @@
#ifndef TCP_AO_STRUCTS
#define TCP_AO_STRUCTS
#define TCP_AO_MAXKEYLEN_ 80 #define TCP_AO_MAXKEYLEN_ 80
#define DEFAULT_TEST_ALGO "cmac(aes128)" #define DEFAULT_TEST_ALGO "cmac(aes128)"
@ -93,3 +96,5 @@ struct tcp_ao_repair_ext { /* {s,g}etsockopt(TCP_AO_REPAIR) */
u32 snd_sne; u32 snd_sne;
u32 rcv_sne; u32 rcv_sne;
} __attribute__((aligned(8))); } __attribute__((aligned(8)));
#endif /* TCP_AO_STRUCTS*/

View File

@ -1341,6 +1341,7 @@ sk_open(sock *s)
int bind_port = 0; int bind_port = 0;
ip_addr bind_addr = IPA_NONE; ip_addr bind_addr = IPA_NONE;
sockaddr sa; sockaddr sa;
log("opening sock");
if (s->type <= SK_IP) if (s->type <= SK_IP)
{ {
@ -1457,11 +1458,16 @@ sk_open(sock *s)
if (bind(fd, &sa.sa, SA_LEN(sa)) < 0) if (bind(fd, &sa.sa, SA_LEN(sa)) < 0)
ERR2("bind"); ERR2("bind");
} }
//s->password = "abcd1234";
if (s->password) if (s->password) //TODO condition if it should be ao or md5
if (sk_set_md5_auth(s, s->saddr, s->daddr, -1, s->iface, s->password, 0) < 0) {
log("set ao");
if (sk_set_ao_auth(s, s->saddr, s->daddr, -1, s->iface, s->password, 123, 123, 0) < 0)
goto err; goto err;
}
else
log("no password given");
switch (s->type) switch (s->type)
{ {
case SK_TCP_ACTIVE: case SK_TCP_ACTIVE: