mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-12-22 09:41:54 +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:
parent
8826e6b701
commit
4a91d4961b
@ -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_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_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_icmp6_filter(sock *s, int p1, int p2);
|
||||
void sk_log_error(sock *s, const char *p);
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
#include "lib/lists.h"
|
||||
#include "lib/ip.h"
|
||||
#include "sysdep/linux/tcp-ao.h"
|
||||
|
||||
extern list iface_list;
|
||||
|
||||
|
@ -179,6 +179,7 @@ bgp_open(struct bgp_proto *p)
|
||||
sk->type = SK_TCP_PASSIVE;
|
||||
sk->ttl = 255;
|
||||
sk->saddr = addr;
|
||||
// sk->daddr = p->remote_ip;
|
||||
sk->sport = port;
|
||||
sk->iface = ifa;
|
||||
sk->vrf = p->p.vrf;
|
||||
@ -188,7 +189,9 @@ bgp_open(struct bgp_proto *p)
|
||||
sk->tbsize = BGP_TX_BUFFER_SIZE;
|
||||
sk->rx_hook = bgp_incoming_connection;
|
||||
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)
|
||||
goto err;
|
||||
|
||||
@ -243,10 +246,11 @@ bgp_setup_auth(struct bgp_proto *p, int enable)
|
||||
prefix = net_prefix(p->cf->remote_range);
|
||||
pxlen = net_pxlen(p->cf->remote_range);
|
||||
}
|
||||
|
||||
int rv = sk_set_md5_auth(p->sock->sk,
|
||||
int rv = 0;
|
||||
if (enable)
|
||||
rv = sk_set_ao_auth(p->sock->sk,
|
||||
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)
|
||||
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);
|
||||
}
|
||||
|
||||
void
|
||||
log_ao(int fd)
|
||||
{
|
||||
log_tcp_ao_info(fd);
|
||||
}
|
||||
|
||||
/**
|
||||
* bgp_connect - initiate an outgoing connection
|
||||
* @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->tbsize = p->cf->enable_extended_messages ? BGP_TX_BUFFER_EXT_SIZE : BGP_TX_BUFFER_SIZE;
|
||||
s->tos = IP_PREC_INTERNET_CONTROL;
|
||||
// s->password = "abcd1234";/
|
||||
s->password = p->cf->password;
|
||||
s->tx_hook = bgp_connected;
|
||||
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_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)
|
||||
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 */
|
||||
if (p->cf->ttl_security)
|
||||
if (sk_set_min_ttl(s, 256 - hops) < 0)
|
||||
|
@ -539,6 +539,8 @@ bgp_parse_error(struct bgp_parse_state *s, uint subcode)
|
||||
longjmp(s->err_jmpbuf, 1);
|
||||
}
|
||||
|
||||
void log_ao(int fd);
|
||||
|
||||
|
||||
void bgp_start_timer(timer *t, uint value);
|
||||
void bgp_check_config(struct bgp_config *c);
|
||||
|
@ -3423,6 +3423,8 @@ bgp_rx_packet(struct bgp_conn *conn, byte *pkt, uint len)
|
||||
int
|
||||
bgp_rx(sock *sk, uint size)
|
||||
{
|
||||
log("......................................got %i", size);
|
||||
log_ao(sk->fd);
|
||||
struct bgp_conn *conn = sk->data;
|
||||
byte *pkt_start = sk->rbuf;
|
||||
byte *end = pkt_start + size;
|
||||
|
@ -176,11 +176,11 @@ sk_prepare_cmsgs4(sock *s, struct msghdr *msg, void *cbuf, size_t cbuflen)
|
||||
/*
|
||||
* Miscellaneous Linux socket syscalls
|
||||
*/
|
||||
|
||||
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;
|
||||
log("md5 password is %i, socket fd %i", passwd, s->fd);
|
||||
|
||||
memset(&md5, 0, sizeof(md5));
|
||||
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)
|
||||
{
|
||||
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 (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)
|
||||
ERR_MSG("Kernel does not support TCP MD5 signatures");
|
||||
else
|
||||
@ -299,7 +219,96 @@ sk_set_tcpao_auth(sock *s, ip_addr local UNUSED, ip_addr remote, int pxlen, stru
|
||||
}
|
||||
|
||||
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
|
||||
sk_set_min_ttl4(sock *s, int ttl)
|
||||
|
@ -1,4 +1,7 @@
|
||||
|
||||
#ifndef TCP_AO_STRUCTS
|
||||
#define TCP_AO_STRUCTS
|
||||
|
||||
#define TCP_AO_MAXKEYLEN_ 80
|
||||
|
||||
#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 rcv_sne;
|
||||
} __attribute__((aligned(8)));
|
||||
|
||||
#endif /* TCP_AO_STRUCTS*/
|
||||
|
@ -1341,6 +1341,7 @@ sk_open(sock *s)
|
||||
int bind_port = 0;
|
||||
ip_addr bind_addr = IPA_NONE;
|
||||
sockaddr sa;
|
||||
log("opening sock");
|
||||
|
||||
if (s->type <= SK_IP)
|
||||
{
|
||||
@ -1457,11 +1458,16 @@ sk_open(sock *s)
|
||||
if (bind(fd, &sa.sa, SA_LEN(sa)) < 0)
|
||||
ERR2("bind");
|
||||
}
|
||||
//s->password = "abcd1234";
|
||||
|
||||
if (s->password)
|
||||
if (sk_set_md5_auth(s, s->saddr, s->daddr, -1, s->iface, s->password, 0) < 0)
|
||||
if (s->password) //TODO condition if it should be ao or md5
|
||||
{
|
||||
log("set ao");
|
||||
if (sk_set_ao_auth(s, s->saddr, s->daddr, -1, s->iface, s->password, 123, 123, 0) < 0)
|
||||
goto err;
|
||||
|
||||
}
|
||||
else
|
||||
log("no password given");
|
||||
switch (s->type)
|
||||
{
|
||||
case SK_TCP_ACTIVE:
|
||||
|
Loading…
Reference in New Issue
Block a user