]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
tcp ao looks working, but there are no tests yet
authorKaterina Kubecova <katerina.kubecova@nic.cz>
Wed, 28 Feb 2024 15:15:28 +0000 (16:15 +0100)
committerKaterina Kubecova <katerina.kubecova@nic.cz>
Wed, 28 Feb 2024 15:15:28 +0000 (16:15 +0100)
lib/socket.h
proto/bgp/bgp.c
proto/bgp/bgp.h
proto/bgp/packets.c
sysdep/linux/sysio.h
sysdep/unix/io.c

index 3772cb5ca6b583aa65332361d084030e5f2e956f..98398ca5fda74d5d1aa1cff156e1088829f188d4 100644 (file)
@@ -87,7 +87,10 @@ typedef struct birdsock {
   node n;
   void *rbuf_alloc, *tbuf_alloc;
   const char *password;                        /* Password for MD5 authentication */
-  struct ao_key *ao_key;               /* Key for tcp ao authentication */
+  struct ao_key *ao_key_init;          /* Key for tcp ao authentication icialization. */
+  char use_ao;
+  int last_used_ao_key;                /* Last ID the other site requested */
+  int desired_ao_key;                  /* ID of requested ao key */
   const char *err;                     /* Error message */
   struct ssh_sock *ssh;                        /* Used in SK_SSH */
 } sock;
@@ -125,7 +128,8 @@ int sk_set_ao_auth(sock *s, ip_addr local, ip_addr remote, int pxlen, struct ifa
 void ao_delete_key(sock *s, ip_addr remote, int pxlen, struct iface *ifa, int passwd_id_rem, int passwd_id_loc);
 void log_tcp_ao_info(int sock_fd);
 void log_tcp_ao_get_key(int sock_fd);
-void ao_try_change_master(int sock_fd, int next_key_id);
+int check_ao_keys_id(int sock_fd, struct ao_key *key);
+void ao_try_change_master(sock *s, int next_key_id_loc, int next_id_rem);
 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 02c1b8ef6ce7d1f71964b8991e3f249a9c6f27a6..dac9f7ec5079310b5057f016319ed7abec803780 100644 (file)
@@ -192,7 +192,7 @@ bgp_open(struct bgp_proto *p)
   if (sk_open(sk) < 0)
     goto err;
   
-  log("____________________________________________________________________________%i %i", sk->fd, sk->ao_key);
+  log("____________________________________________________________________________%i %i", sk->fd, sk->ao_key_init);
   bs = mb_allocz(proto_pool, sizeof(struct bgp_socket));
   bs->sk = sk;
   bs->uc = 1;
@@ -223,14 +223,6 @@ bgp_close(struct bgp_proto *p)
 
   ASSERT(bs && bs->uc);
 
-  log("in bgp close");
-  struct ao_key *key = bs->sk->ao_key;
-  while (key)
-  {
-    log("delete %i", key->local_id);
-    ao_delete_key(bs->sk, p->remote_ip, -1, bs->sk->iface, key->local_id, key->remote_id);
-    key = key->next_key;
-  }
   if (--bs->uc)
     return;
 
@@ -255,16 +247,29 @@ bgp_setup_auth(struct bgp_proto *p, int enable)
     int rv = 0;
     if (p->cf->ao_key)
     {
-      log("set ao auth [%s]", p->cf->ao_key->master_key);
-      struct ao_key *key = p->cf->ao_key;
-      p->sock->sk->ao_key = key;
-      do {
-        rv = sk_set_ao_auth(p->sock->sk,
+      if (enable)
+      {
+        log("set ao auth [%s]", p->cf->ao_key->master_key);
+        struct ao_key *key = p->cf->ao_key;
+        do {
+          rv = sk_set_ao_auth(p->sock->sk,
                             p->cf->local_ip, prefix, pxlen, p->cf->iface,
-                            key->master_key, key->local_id, key->remote_id, key->cipher, 0);
-       key = key->next_key;
+                            key->master_key, key->local_id, key->remote_id, key->cipher, 0);
+         key = key->next_key;
 
-      } while(key);
+        } while(key);
+      }
+      else
+      {
+        log("in bgp close");
+        struct ao_key *key = p->cf->ao_key;
+        while (key)
+        {
+          log("delete %i", key->local_id);
+          ao_delete_key(p->sock->sk, p->remote_ip, -1, p->sock->sk->iface, key->local_id, key->remote_id);
+          key = key->next_key;
+        }
+      }
     }
     else if (enable)
       rv = sk_set_md5_auth(p->sock->sk,
@@ -1092,7 +1097,6 @@ bgp_setup_conn(struct bgp_proto *p, struct bgp_conn *conn)
   conn->channels_to_send = 0;
   conn->last_channel = 0;
   conn->last_channel_count = 0;
-  conn->last_used_ao_key = -1;
 
   conn->connect_timer  = tm_new_init(p->p.pool, bgp_connect_timeout,    conn, 0, 0);
   conn->hold_timer     = tm_new_init(p->p.pool, bgp_hold_timeout,       conn, 0, 0);
@@ -1156,9 +1160,8 @@ 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->ao_key = p->cf->ao_key;
+  s->ao_key_init = p->cf->ao_key;
   s->tx_hook = bgp_connected;
   s->flags = p->cf->free_bind ? SKF_FREEBIND : 0;
   BGP_TRACE(D_EVENTS, "Connecting to %I%J from local address %I%J",
@@ -1171,7 +1174,7 @@ bgp_connect(struct bgp_proto *p)  /* Enter Connect state and start establishing c
   if (sk_open(s) < 0)
     goto err;
 
-  log("a..........................................................................................fd %i key %i %I", s->fd, s->ao_key, s->daddr);
+  log("a..........................................................................................fd %i %I", s->fd, s->daddr);
 
   /* Set minimal receive TTL if needed */
   if (p->cf->ttl_security)
@@ -1250,6 +1253,16 @@ bgp_incoming_connection(sock *sk, uint dummy UNUSED)
     rfree(sk);
     return 0;
   }
+  if (p->cf->ao_key)
+  {
+    if (get_current_key_id(sk->fd) == -1)
+    {
+      log(L_WARN "BGP: Connection from address %I%J (port %d) has no TCP AO key",
+          sk->daddr, ipa_is_link_local(sk->daddr) ? sk->iface : NULL, sk->dport);
+      rfree(sk);
+      return 0;
+    }
+  }
 
   /*
    * BIRD should keep multiple incoming connections in OpenSent state (for
@@ -1292,6 +1305,11 @@ bgp_incoming_connection(sock *sk, uint dummy UNUSED)
     if (sk_set_min_ttl(sk, 256 - hops) < 0)
       goto err;
 
+  if (p->cf->ao_key)
+  {
+     if (check_ao_keys_id(sk->fd, p->cf->ao_key) == 0)  
+       sk->use_ao = 1;
+  }
   if (p->cf->enable_extended_messages)
   {
     sk->rbsize = BGP_RX_BUFFER_EXT_SIZE;
@@ -2173,11 +2191,62 @@ int compare_aos(struct ao_key *a, struct ao_key *b)
   return strcmp(a->master_key, b->master_key);
 }
 
+int reconfigure_ao_without_conn(struct bgp_proto old_proto, struct bgp_config new)
+{
+  log("in reconf dead ao");
+
+  sock *s_passiv = old_proto.sock->sk;
+
+  struct ao_key *old_aos[256];
+  memset(&old_aos, 0, sizeof(struct ao_key*)*256);
+  struct ao_key *old_aos_rem[256];
+  memset(&old_aos_rem, 0, sizeof(struct ao_key*)*256);
+
+  for(struct ao_key *ao_key = old_proto.cf->ao_key; ao_key; ao_key = ao_key->next_key)
+  {
+     old_aos[ao_key->local_id] = ao_key;
+     old_aos_rem[ao_key->remote_id] = ao_key;
+  }
+
+  for(struct ao_key *ao_key = new.ao_key; ao_key; ao_key = ao_key->next_key)
+  {
+     if(old_aos[ao_key->local_id])
+     {
+       if(compare_aos(ao_key, old_aos[ao_key->local_id]))
+       {
+        struct ao_key *old_key = old_aos[ao_key->local_id];
+         ao_delete_key(s_passiv,  old_proto.remote_ip, -1, s_passiv->iface, old_key->local_id, old_key->remote_id);
+         sk_set_ao_auth(s_passiv, old_proto.local_ip, old_proto.remote_ip, -1, s_passiv->iface, ao_key->master_key, ao_key->local_id, ao_key->remote_id, ao_key->cipher, ao_key->required == 1);
+       }
+       old_aos[ao_key->local_id] = 0;
+     }
+     else if(old_aos_rem[ao_key->remote_id])
+     {
+       struct ao_key *old_key = old_aos_rem[ao_key->remote_id];
+       ao_delete_key(s_passiv,  old_proto.remote_ip, -1, s_passiv->iface, old_key->local_id, old_key->remote_id);
+       sk_set_ao_auth(s_passiv, old_proto.local_ip, old_proto.remote_ip, -1, s_passiv->iface, ao_key->master_key, ao_key->local_id, ao_key->remote_id, ao_key->cipher, ao_key->required == 1);
+       old_aos[old_key->local_id] = 0;
+     }
+     else
+       sk_set_ao_auth(s_passiv, old_proto.local_ip, old_proto.remote_ip, -1, s_passiv->iface, ao_key->master_key, ao_key->local_id, ao_key->remote_id, ao_key->cipher, ao_key->required == 1);
+  }
+  for(int i = 0; i<256; i++)
+  {
+     if (old_aos[i])
+       ao_delete_key(s_passiv, old_proto.remote_ip, -1, s_passiv->iface, old_aos[i]->local_id, old_aos[i]->remote_id);
+  }
+
+  return 1;
+}
+
 int reconfigure_tcp_ao(struct bgp_proto old_proto, struct bgp_config new)
 {
   log("in reconf ao");
+  if (!old_proto.conn)
+    return reconfigure_ao_without_conn(old_proto, new); // Connection was not (re)established, so we can not change it.
   sock *s_passiv = old_proto.sock->sk;
   sock *s_activ = old_proto.conn->sk;
+
   int key_in_use_rem = get_current_key_id(s_activ->fd);
 
   if (key_in_use_rem == -1)
@@ -2185,6 +2254,8 @@ int reconfigure_tcp_ao(struct bgp_proto old_proto, struct bgp_config new)
       log("Unable to detect currently used key");
       return 0;
     }
+  int rnext_id = get_rnext_key_id(s_activ->fd);
+  log("old rnext %i", rnext_id);
 
   struct ao_key *old_aos[256];
   memset(&old_aos, 0, sizeof(struct ao_key*)*256);
@@ -2215,7 +2286,7 @@ int reconfigure_tcp_ao(struct bgp_proto old_proto, struct bgp_config new)
         struct ao_key *old_key = old_aos[ao_key->local_id];
         ao_delete_key(s_activ,  old_proto.remote_ip, -1, s_activ->iface, old_key->local_id, old_key->remote_id);
          ao_delete_key(s_passiv,  old_proto.remote_ip, -1, s_passiv->iface, old_key->local_id, old_key->remote_id);
-        sk_set_ao_auth(s_activ, old_proto.local_ip, old_proto.remote_ip, -1, s_activ->iface, ao_key->master_key, ao_key->local_id, ao_key->remote_id, ao_key->cipher, ao_key->required == 1);
+        sk_set_ao_auth(s_activ, old_proto.local_ip, old_proto.remote_ip, -1, s_activ->iface, ao_key->master_key, ao_key->local_id, ao_key->remote_id, ao_key->cipher, 0);
          sk_set_ao_auth(s_passiv, old_proto.local_ip, old_proto.remote_ip, -1, s_passiv->iface, ao_key->master_key, ao_key->local_id, ao_key->remote_id, ao_key->cipher, 0);
        }
        old_aos[ao_key->local_id] = 0;
@@ -2231,15 +2302,13 @@ int reconfigure_tcp_ao(struct bgp_proto old_proto, struct bgp_config new)
         }
          cf_warn("TCP AO reconfiguration: Reusing remote id %i with new local id %i. This might break your connection.", ao_key->remote_id, ao_key->local_id);
        }
-       sk_set_ao_auth(s_activ, old_proto.local_ip, old_proto.remote_ip, -1, s_activ->iface, ao_key->master_key, ao_key->local_id, ao_key->remote_id, ao_key->cipher, ao_key->required == 1);
+       sk_set_ao_auth(s_activ, old_proto.local_ip, old_proto.remote_ip, -1, s_activ->iface, ao_key->master_key, ao_key->local_id, ao_key->remote_id, ao_key->cipher, 0);
        sk_set_ao_auth(s_passiv, old_proto.local_ip, old_proto.remote_ip, -1, s_passiv->iface, ao_key->master_key, ao_key->local_id, ao_key->remote_id, ao_key->cipher, 0);
      }
-     s_activ->ao_key = new.ao_key; 
-     s_passiv->ao_key = new.ao_key;
 
-    if (ao_key->required == 1 && (ao_key->local_id != get_rnext_key_id(s_activ->fd)))
+    if (ao_key->required == 1 && (ao_key->local_id != rnext_id))
     {
-      ao_try_change_master(s_activ->fd, ao_key->local_id);
+      ao_try_change_master(s_activ, ao_key->local_id, ao_key->remote_id);
       if (old_proto.conn->hold_timer->expires != 0)
         bgp_schedule_packet(old_proto.conn, NULL, PKT_KEEPALIVE); // According to RFC we should not send keepalive shortly after another, but since reconfiguration is rare, this is harmless
     }
@@ -2257,6 +2326,7 @@ int reconfigure_tcp_ao(struct bgp_proto old_proto, struct bgp_config new)
        ao_delete_key(s_passiv, old_proto.remote_ip, -1, s_passiv->iface, old_aos[i]->local_id, old_aos[i]->remote_id);
      }
   }
+
   log("no big changes in ao");
   return 1;
 }
index d117364b0f7c4ecbeb01c41e1b9af37ba7aa533b..b5a730c5e918c0ddbd59f086bcc03743f55f1619 100644 (file)
@@ -307,7 +307,6 @@ struct bgp_conn {
   u8 last_channel_count;               /* Number of times the last channel was used in succession */
   int notify_code, notify_subcode, notify_size;
   byte *notify_data;
-  int last_used_ao_key;                        /* ID of last ao authentication key, which was used */
 
   uint hold_time, keepalive_time;      /* Times calculated from my and neighbor's requirements */
 };
index 229b099bdac155067fc5978f46d91a60872cd76c..7bdadc636da30fca0c7c94ff9dd0b8f1c8ab8caf 100644 (file)
@@ -3425,25 +3425,28 @@ bgp_rx(sock *sk, uint size)
 {
   struct bgp_conn *conn = sk->data;
   
-  if (sk->ao_key)
+  if (sk->use_ao && sk->desired_ao_key != sk->last_used_ao_key)
   {
-    if (get_current_key_id(sk->fd) != conn->last_used_ao_key)
+    int new_rnext = get_current_key_id(sk->fd); 
+    if (new_rnext != sk->last_used_ao_key)
     {
       if (conn->hold_timer->expires != 0)
         bgp_schedule_packet(conn, NULL, PKT_KEEPALIVE); // We might send this keepalive shortly after another. RFC says we should wait, but since reconfiguration is rare, this is harmless.
-      conn->last_used_ao_key = get_current_key_id(sk->fd);
+      sk->last_used_ao_key = new_rnext;
+      log("Expected desired rnext %i, arrived %i", sk->desired_ao_key, new_rnext);
       log_ao(sk->fd);
-      log("%i", sk->ao_key);
     }
     else //todo delete after debug
     {
+      log("Nothing happend %i %i", get_current_key_id(sk->fd), sk->last_used_ao_key);
       log_ao(sk->fd);
-      log("%i %i", get_current_key_id(sk->fd), conn->last_used_ao_key);
-      log("fd %i sk %i key %i", sk->fd, sk, sk->ao_key);
     }
   }
   else
-    log("no ao");
+  {
+    log("No ao or not expecting changes %i %i", get_current_key_id(sk->fd), sk->last_used_ao_key);
+    log_ao(sk->fd);
+  }
   byte *pkt_start = sk->rbuf;
   byte *end = pkt_start + size;
   uint i, len;
index 4252623d795d059b065d5358bea7d119dcb7a84a..8aa2f3522e759cb16c210d9dd88ccc8c7365ae10 100644 (file)
@@ -234,7 +234,7 @@ void log_tcp_ao_info(int sock_fd)
      return;
   }
   else
-    log("current key id %i, next key %i,\n set current %i, ao required %i\n good packets %i, bad packets %i",
+    log("current key id %i (rem), next key %i (loc),\n set current %i, ao required %i\n good packets %i, bad packets %i",
                    tmp.current_key, tmp.rnext, tmp.set_current, tmp.ao_required, tmp.pkt_good, tmp.pkt_bad);
 }
 
@@ -268,8 +268,7 @@ int get_rnext_key_id(int sock_fd)
     return tmp.rnext;
 }
 
-void
-log_tcp_ao_get_key(int sock_fd)
+int get_num_ao_keys(int sock_fd)
 {
   struct tcp_ao_getsockopt_ext tmp;
   memset(&tmp, 0, sizeof(struct tcp_ao_getsockopt_ext));
@@ -279,12 +278,20 @@ log_tcp_ao_get_key(int sock_fd)
 
   if (getsockopt(sock_fd, IPPROTO_TCP, TCP_AO_GET_KEYS, &tmp, &len))
   {
-     log("log tcp ao get keys failed with err code %i", errno);
-     return;
+     log("tcp ao get keys failed with err code %i", errno);
+     return -1;
   }
-  
-  int nkeys = tmp.nkeys;
+  return tmp.nkeys;
+}
+
+void
+log_tcp_ao_get_key(int sock_fd)
+{  
+  int nkeys = get_num_ao_keys(sock_fd);
+  if (nkeys < 0)
+    return;
   struct tcp_ao_getsockopt_ext tm_all[nkeys];
+  socklen_t len = sizeof(struct tcp_ao_getsockopt_ext);
   memset(tm_all, 0, sizeof(struct tcp_ao_getsockopt_ext)*nkeys);
   tm_all[0].nkeys = nkeys;
   tm_all[0].get_all = 1;
@@ -301,13 +308,11 @@ log_tcp_ao_get_key(int sock_fd)
 }
 
 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, const char* cipher, int set_current)
+sk_set_ao_auth(sock *s, ip_addr local UNUSED, ip_addr remote, int pxlen, struct iface *ifa, const char *passwd, int passwd_id_loc, int passwd_id_rem, const char* cipher, int set_current)
 {
   struct tcp_ao_add_ext ao;
   memset(&ao, 0, sizeof(struct tcp_ao_add_ext));
-  if (!s->ao_key)
-    bug("no ao key");
-  log(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>in sk set ao, pass %s fd %i sk %i %i", passwd, s->fd, s, s->ao_key);
+  log(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>in sk set ao, pass %s fd %i sk %i %i", passwd, s->fd, s);
  /* int af;
   if (ipa_is_ip4(remote))
     af = AF_INET;
@@ -337,8 +342,16 @@ sk_set_ao_auth(sock *s, ip_addr local, ip_addr remote, int pxlen, struct iface *
   memcpy(ao.key, passwd, (strlen(passwd) > TCP_AO_MAXKEYLEN_) ? TCP_AO_MAXKEYLEN_ : strlen(passwd));
 
   if (setsockopt(s->fd, IPPROTO_TCP, TCP_AO_ADD_KEY, &ao, sizeof(ao)) < 0)
-    bug("tcp ao err %i", errno);
+  {
+     if (errno == ENOPROTOOPT)
+       ERR_MSG("Kernel does not support extended TCP AO signatures");
+      else
+       ERR("TCP_AOSIG_EXT");
+  }
   
+  s->use_ao = 1;
+  if (set_current)
+    s->desired_ao_key = passwd_id_rem;
   log_tcp_ao_get_key(s->fd);
   return 0;
 }
@@ -359,46 +372,79 @@ ao_delete_key(sock *s, ip_addr remote, int pxlen, struct iface *ifa, int passwd_
     del.prefix = 128;
 
   if (setsockopt(s->fd, IPPROTO_TCP, TCP_AO_DEL_KEY, &del, sizeof(del)) < 0)
+  {
+    log("log keys for debug delete error key %i %i", passwd_id_loc, passwd_id_rem);
+    log_tcp_ao_get_key(s->fd);
     bug("tcp ao deletion err %i", errno);
+  }
   log("tcp ao key %i %i deleted", passwd_id_loc, passwd_id_rem);
 }
 
 void
-ao_try_change_master(int sock_fd, int next_master_id )
+ao_try_change_master(sock *s, int next_master_id_loc, int next_master_id_rem)
 {
   struct tcp_ao_info_opt_ext tmp;
   memset(&tmp, 0, sizeof(struct tcp_ao_info_opt_ext));
   tmp.set_rnext = 1;
-  tmp.rnext = next_master_id;
+  tmp.rnext = next_master_id_loc;
 
-  if (setsockopt(sock_fd, IPPROTO_TCP, TCP_AO_INFO, &tmp, sizeof(tmp)))
+  if (setsockopt(s->fd, IPPROTO_TCP, TCP_AO_INFO, &tmp, sizeof(tmp)))
   {
      log(" tcp ao change master key failed with err code %i", errno);
-     log_tcp_ao_get_key(sock_fd);
+     log_tcp_ao_get_key(s->fd);
      return;
   }
   else
     log("tried to change master");
-}
+  s->desired_ao_key = next_master_id_rem;
 
-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)
+int check_ao_keys_id(int sock_fd, struct ao_key *keys)
 {
-  //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");
+  int errors = 0;
+  int expected_keys[256]; //can not have char, because we must support 0 key id
+  memset(expected_keys, 0, sizeof(int)*256);
+  for (struct ao_key *key = keys; key; key = key->next_key)
+    expected_keys[key->local_id] = key->remote_id + 1; // the + 1 because we do not want 0 id be 0
+  int nkeys = get_num_ao_keys(sock_fd);
+  if(nkeys == -1)
+  {
+    cf_warn("TCP AO: unable to get num of keys");
+    return 1;
+  }
+  struct tcp_ao_getsockopt_ext tm_all[nkeys];
+  socklen_t len = sizeof(struct tcp_ao_getsockopt_ext);
+  memset(tm_all, 0, sizeof(struct tcp_ao_getsockopt_ext)*nkeys);
+  tm_all[0].nkeys = nkeys;
+  tm_all[0].get_all = 1;
+  if (getsockopt(sock_fd, IPPROTO_TCP, TCP_AO_GET_KEYS, tm_all, &len))  // len should be still size of one struct. Because kernel net/ipv4/tcp_ao.c line 2165
+  {
+     cf_warn("log tcp ao get keys failed with err code %i", errno);
+     return 1;
+  }
+  for (int i = 0; i< nkeys; i++)
+  {
+    struct tcp_ao_getsockopt_ext sock_key = tm_all[i];
+    if (expected_keys[sock_key.rcvid] - 1 != sock_key.sndid)
+    {
+      if (expected_keys[sock_key.rcvid] == 0) 
+        cf_warn("TCP AO: unexpected ao key %i %i", sock_key.rcvid, sock_key.sndid);
+      else
+       cf_warn("TCP AO: expected key local id %i has different remote id than expected (%i vs %i)", sock_key.rcvid, expected_keys[sock_key.rcvid] - 1, sock_key.sndid);
+      errors++;
+    }     
+     expected_keys[sock_key.rcvid] = 0;  
+  }
+  for (int i = 0; i < 256; i++)
+  {
+    if (expected_keys[i] != 0)
+    {
+      cf_warn("TCP AO: key %i %i is not in socket", i, expected_keys - 1);
+      errors++;
+    }
+  }
+  return errors;
 }
 
 static inline int
index 6057b6e1813fc0da031c60bcfa7b7aaf9d32ea9e..992d44042825f70c566462229a4304947695dd5a 100644 (file)
@@ -1097,8 +1097,7 @@ sk_passive_connected(sock *s, int type)
   t->tos = s->tos;
   t->vrf = s->vrf;
   t->rbsize = s->rbsize;
-  t->tbsize = s->tbsize;
-  t->ao_key = s->ao_key;
+  t->tbsize = s->tbsize; 
 
   if (type == SK_TCP)
   {
@@ -1459,12 +1458,10 @@ sk_open(sock *s)
     if (bind(fd, &sa.sa, SA_LEN(sa)) < 0)
       ERR2("bind");
   }
-  //s->password = "abcd1234";
 
-  if (s->ao_key)
+  if (s->ao_key_init)
   {
-    log("set ao, %s", s->ao_key->cipher);
-    struct ao_key *key = s->ao_key;
+    struct ao_key *key = s->ao_key_init;
     do {
       if (sk_set_ao_auth(s, s->saddr, s->daddr, -1, s->iface, key->master_key, key->local_id, key->remote_id, key->cipher, key->required == 1) < 0)
         goto err;