]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
backup - tcp ao works in simplest possible version, only as md5 replacement (without...
authorKaterina Kubecova <katerina.kubecova@nic.cz>
Wed, 14 Feb 2024 12:48:08 +0000 (13:48 +0100)
committerKaterina Kubecova <katerina.kubecova@nic.cz>
Wed, 14 Feb 2024 12:48:08 +0000 (13:48 +0100)
lib/socket.h
nest/iface.h
proto/bgp/bgp.c
proto/bgp/bgp.h
proto/bgp/packets.c
sysdep/linux/sysio.h
sysdep/linux/tcp-ao.h
sysdep/unix/io.c

index 0b6ac5898d6d0db42bf393b8d06fb7e8f2fbc39b..32a7caed27c3d0a0d128ee902125947f1803c126 100644 (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_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);
index f8e9285053c11afe013666747920edbcc65168ea..86c538ce8fe55307a689a65632a1567a4064ad16 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "lib/lists.h"
 #include "lib/ip.h"
+#include "sysdep/linux/tcp-ao.h"
 
 extern list iface_list;
 
index f668b3717fda4a2f61b36773c0596cc710d5d531..6d39b10763fa60a8a30ddb8741b7199920686f01 100644 (file)
@@ -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)
index 1ba3de5e2e4e899d827f7b64a45ee33f9add225e..840862f6bca719240071bc4db6699fe8f08972da 100644 (file)
@@ -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);
index 054e6c3c14a4f343f810dd535585fbae8578c88b..f48ebcdc06a8fe59b89ba5d91baa6bd5f3fdba84 100644 (file)
@@ -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;
index 2edbd0b590e83f25df2375bdb9973aaaf4b72dd1..ad17af9412b9feecca74a8c5f27ba27cc01680e0 100644 (file)
@@ -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,47 +198,11 @@ 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 (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");*/
+       ERR("TCP_MD5SIG");
   }
   else
   {
@@ -257,49 +221,94 @@ sk_set_md5_auth(sock *s, ip_addr local, ip_addr remote, int pxlen, struct iface
   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)
+void log_tcp_ao_info(int sock_fd)
 {
-  struct tcp_ao_add *ao;
+  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);
 
-  memset(&ao, 0, sizeof(struct tcp_ao_add));
-  sockaddr_fill((sockaddr *) &md5.tcpm_addr, s->af, remote, ifa, 0);
-
-  if (passwd)
+  if (getsockopt(sock_fd, IPPROTO_TCP, TCP_AO_INFO, &tmp, &len))
   {
-    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);
+     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);
+}
 
-  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
-       ERR("TCP_MD5SIG");
-  }
+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
-  {
-    md5.tcpm_flags = TCP_MD5SIG_FLAG_PREFIX;
-    md5.tcpm_prefixlen = pxlen;
+    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;
+}
 
-    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");
-    }
+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;
   }
 
-  return 0;
-}**/
+}
 
 static inline int
 sk_set_min_ttl4(sock *s, int ttl)
index 523952cc6e8f47f80d4f495695abdfc1bfca31b2..ab4df93ed0366da7d17d58b09a503605f5f5bd6f 100644 (file)
@@ -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*/
index 6aedcfb669191ae60c198d6b3620a9123afc8e9a..7f51a712574351157c340903c0521b9fe8dc9f19 100644 (file)
@@ -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: