mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-11-08 12:18:42 +00:00
tcp ao looks working, but there are no tests yet
This commit is contained in:
parent
e27110ba8a
commit
026d89bd93
7927
configure~
Executable file
7927
configure~
Executable file
File diff suppressed because it is too large
Load Diff
@ -87,7 +87,10 @@ typedef struct birdsock {
|
|||||||
node n;
|
node n;
|
||||||
void *rbuf_alloc, *tbuf_alloc;
|
void *rbuf_alloc, *tbuf_alloc;
|
||||||
const char *password; /* Password for MD5 authentication */
|
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 */
|
const char *err; /* Error message */
|
||||||
struct ssh_sock *ssh; /* Used in SK_SSH */
|
struct ssh_sock *ssh; /* Used in SK_SSH */
|
||||||
} sock;
|
} 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 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_info(int sock_fd);
|
||||||
void log_tcp_ao_get_key(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_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);
|
||||||
|
116
proto/bgp/bgp.c
116
proto/bgp/bgp.c
@ -192,7 +192,7 @@ bgp_open(struct bgp_proto *p)
|
|||||||
if (sk_open(sk) < 0)
|
if (sk_open(sk) < 0)
|
||||||
goto err;
|
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 = mb_allocz(proto_pool, sizeof(struct bgp_socket));
|
||||||
bs->sk = sk;
|
bs->sk = sk;
|
||||||
bs->uc = 1;
|
bs->uc = 1;
|
||||||
@ -247,16 +247,29 @@ bgp_setup_auth(struct bgp_proto *p, int enable)
|
|||||||
int rv = 0;
|
int rv = 0;
|
||||||
if (p->cf->ao_key)
|
if (p->cf->ao_key)
|
||||||
{
|
{
|
||||||
log("set ao auth [%s]", p->cf->ao_key->master_key);
|
if (enable)
|
||||||
struct ao_key *key = p->cf->ao_key;
|
{
|
||||||
p->sock->sk->ao_key = key;
|
log("set ao auth [%s]", p->cf->ao_key->master_key);
|
||||||
do {
|
struct ao_key *key = p->cf->ao_key;
|
||||||
rv = sk_set_ao_auth(p->sock->sk,
|
do {
|
||||||
|
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,
|
||||||
key->master_key, key->local_id, key->remote_id, key->cipher, 0);
|
key->master_key, key->local_id, key->remote_id, key->cipher, 0);
|
||||||
key = key->next_key;
|
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)
|
else if (enable)
|
||||||
rv = sk_set_md5_auth(p->sock->sk,
|
rv = sk_set_md5_auth(p->sock->sk,
|
||||||
@ -1084,7 +1097,6 @@ bgp_setup_conn(struct bgp_proto *p, struct bgp_conn *conn)
|
|||||||
conn->channels_to_send = 0;
|
conn->channels_to_send = 0;
|
||||||
conn->last_channel = 0;
|
conn->last_channel = 0;
|
||||||
conn->last_channel_count = 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->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);
|
conn->hold_timer = tm_new_init(p->p.pool, bgp_hold_timeout, conn, 0, 0);
|
||||||
@ -1148,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->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->ao_key = p->cf->ao_key;
|
s->ao_key_init = p->cf->ao_key;
|
||||||
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;
|
||||||
BGP_TRACE(D_EVENTS, "Connecting to %I%J from local address %I%J",
|
BGP_TRACE(D_EVENTS, "Connecting to %I%J from local address %I%J",
|
||||||
@ -1163,7 +1174,7 @@ bgp_connect(struct bgp_proto *p) /* Enter Connect state and start establishing c
|
|||||||
if (sk_open(s) < 0)
|
if (sk_open(s) < 0)
|
||||||
goto err;
|
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 */
|
/* Set minimal receive TTL if needed */
|
||||||
if (p->cf->ttl_security)
|
if (p->cf->ttl_security)
|
||||||
@ -1242,6 +1253,16 @@ bgp_incoming_connection(sock *sk, uint dummy UNUSED)
|
|||||||
rfree(sk);
|
rfree(sk);
|
||||||
return 0;
|
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
|
* BIRD should keep multiple incoming connections in OpenSent state (for
|
||||||
@ -1284,6 +1305,11 @@ bgp_incoming_connection(sock *sk, uint dummy UNUSED)
|
|||||||
if (sk_set_min_ttl(sk, 256 - hops) < 0)
|
if (sk_set_min_ttl(sk, 256 - hops) < 0)
|
||||||
goto err;
|
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)
|
if (p->cf->enable_extended_messages)
|
||||||
{
|
{
|
||||||
sk->rbsize = BGP_RX_BUFFER_EXT_SIZE;
|
sk->rbsize = BGP_RX_BUFFER_EXT_SIZE;
|
||||||
@ -2165,11 +2191,62 @@ int compare_aos(struct ao_key *a, struct ao_key *b)
|
|||||||
return strcmp(a->master_key, b->master_key);
|
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)
|
int reconfigure_tcp_ao(struct bgp_proto old_proto, struct bgp_config new)
|
||||||
{
|
{
|
||||||
log("in reconf ao");
|
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_passiv = old_proto.sock->sk;
|
||||||
sock *s_activ = old_proto.conn->sk;
|
sock *s_activ = old_proto.conn->sk;
|
||||||
|
|
||||||
int key_in_use_rem = get_current_key_id(s_activ->fd);
|
int key_in_use_rem = get_current_key_id(s_activ->fd);
|
||||||
|
|
||||||
if (key_in_use_rem == -1)
|
if (key_in_use_rem == -1)
|
||||||
@ -2177,6 +2254,8 @@ int reconfigure_tcp_ao(struct bgp_proto old_proto, struct bgp_config new)
|
|||||||
log("Unable to detect currently used key");
|
log("Unable to detect currently used key");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
int rnext_id = get_rnext_key_id(s_activ->fd);
|
||||||
|
log("old rnext %i", rnext_id);
|
||||||
|
|
||||||
struct ao_key *old_aos[256];
|
struct ao_key *old_aos[256];
|
||||||
memset(&old_aos, 0, sizeof(struct ao_key*)*256);
|
memset(&old_aos, 0, sizeof(struct ao_key*)*256);
|
||||||
@ -2207,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];
|
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_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);
|
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);
|
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;
|
old_aos[ao_key->local_id] = 0;
|
||||||
@ -2216,15 +2295,13 @@ int reconfigure_tcp_ao(struct bgp_proto old_proto, struct bgp_config new)
|
|||||||
{
|
{
|
||||||
if (old_rem_id[ao_key->remote_id])
|
if (old_rem_id[ao_key->remote_id])
|
||||||
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);
|
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);
|
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)
|
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
|
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
|
||||||
}
|
}
|
||||||
@ -2242,6 +2319,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);
|
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");
|
log("no big changes in ao");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -307,7 +307,6 @@ struct bgp_conn {
|
|||||||
u8 last_channel_count; /* Number of times the last channel was used in succession */
|
u8 last_channel_count; /* Number of times the last channel was used in succession */
|
||||||
int notify_code, notify_subcode, notify_size;
|
int notify_code, notify_subcode, notify_size;
|
||||||
byte *notify_data;
|
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 */
|
uint hold_time, keepalive_time; /* Times calculated from my and neighbor's requirements */
|
||||||
};
|
};
|
||||||
|
@ -3425,24 +3425,28 @@ bgp_rx(sock *sk, uint size)
|
|||||||
{
|
{
|
||||||
struct bgp_conn *conn = sk->data;
|
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)
|
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.
|
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_ao(sk->fd);
|
||||||
log("%i", sk->ao_key);
|
|
||||||
}
|
}
|
||||||
else //todo delete after debug
|
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_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 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 *pkt_start = sk->rbuf;
|
||||||
byte *end = pkt_start + size;
|
byte *end = pkt_start + size;
|
||||||
uint i, len;
|
uint i, len;
|
||||||
|
BIN
sysdep/linux/.sysio.h.swp
Normal file
BIN
sysdep/linux/.sysio.h.swp
Normal file
Binary file not shown.
@ -234,7 +234,7 @@ void log_tcp_ao_info(int sock_fd)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
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);
|
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;
|
return tmp.rnext;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
int get_num_ao_keys(int sock_fd)
|
||||||
log_tcp_ao_get_key(int sock_fd)
|
|
||||||
{
|
{
|
||||||
struct tcp_ao_getsockopt_ext tmp;
|
struct tcp_ao_getsockopt_ext tmp;
|
||||||
memset(&tmp, 0, sizeof(struct tcp_ao_getsockopt_ext));
|
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))
|
if (getsockopt(sock_fd, IPPROTO_TCP, TCP_AO_GET_KEYS, &tmp, &len))
|
||||||
{
|
{
|
||||||
log("log tcp ao get keys failed with err code %i", errno);
|
log("tcp ao get keys failed with err code %i", errno);
|
||||||
return;
|
return -1;
|
||||||
}
|
}
|
||||||
|
return tmp.nkeys;
|
||||||
int nkeys = 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];
|
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);
|
memset(tm_all, 0, sizeof(struct tcp_ao_getsockopt_ext)*nkeys);
|
||||||
tm_all[0].nkeys = nkeys;
|
tm_all[0].nkeys = nkeys;
|
||||||
tm_all[0].get_all = 1;
|
tm_all[0].get_all = 1;
|
||||||
@ -301,13 +308,11 @@ log_tcp_ao_get_key(int sock_fd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
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;
|
struct tcp_ao_add_ext ao;
|
||||||
memset(&ao, 0, sizeof(struct tcp_ao_add_ext));
|
memset(&ao, 0, sizeof(struct tcp_ao_add_ext));
|
||||||
if (!s->ao_key)
|
log(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>in sk set ao, pass %s fd %i sk %i %i", passwd, s->fd, s);
|
||||||
bug("no ao key");
|
|
||||||
log(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>in sk set ao, pass %s fd %i sk %i %i", passwd, s->fd, s, s->ao_key);
|
|
||||||
/* int af;
|
/* int af;
|
||||||
if (ipa_is_ip4(remote))
|
if (ipa_is_ip4(remote))
|
||||||
af = AF_INET;
|
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));
|
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)
|
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);
|
log_tcp_ao_get_key(s->fd);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -359,46 +372,79 @@ ao_delete_key(sock *s, ip_addr remote, int pxlen, struct iface *ifa, int passwd_
|
|||||||
del.prefix = 128;
|
del.prefix = 128;
|
||||||
|
|
||||||
if (setsockopt(s->fd, IPPROTO_TCP, TCP_AO_DEL_KEY, &del, sizeof(del)) < 0)
|
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);
|
bug("tcp ao deletion err %i", errno);
|
||||||
|
}
|
||||||
log("tcp ao key %i %i deleted", passwd_id_loc, passwd_id_rem);
|
log("tcp ao key %i %i deleted", passwd_id_loc, passwd_id_rem);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
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;
|
struct tcp_ao_info_opt_ext tmp;
|
||||||
memset(&tmp, 0, sizeof(struct tcp_ao_info_opt_ext));
|
memset(&tmp, 0, sizeof(struct tcp_ao_info_opt_ext));
|
||||||
tmp.set_rnext = 1;
|
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 change master key failed with err code %i", errno);
|
||||||
log_tcp_ao_get_key(sock_fd);
|
log_tcp_ao_get_key(s->fd);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
log("tried to change master");
|
log("tried to change master");
|
||||||
|
s->desired_ao_key = next_master_id_rem;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
int check_ao_keys_id(int sock_fd, struct ao_key *keys)
|
||||||
save_to_repair(int sock_fd)
|
|
||||||
{
|
{
|
||||||
struct tcp_ao_repair_ext replace_me; //TODO not ignore replace_me
|
int errors = 0;
|
||||||
socklen_t len = sizeof(replace_me);
|
int expected_keys[256]; //can not have char, because we must support 0 key id
|
||||||
memset(&replace_me, 0, sizeof(struct tcp_ao_repair_ext));
|
memset(expected_keys, 0, sizeof(int)*256);
|
||||||
if (getsockopt(sock_fd, IPPROTO_TCP, TCP_AO_REPAIR, &replace_me, &len) < 0)
|
for (struct ao_key *key = keys; key; key = key->next_key)
|
||||||
bug("geting tcp ao img not succeed %i", errno);
|
expected_keys[key->local_id] = key->remote_id + 1; // the + 1 because we do not want 0 id be 0
|
||||||
log("got tcp ao img");
|
int nkeys = get_num_ao_keys(sock_fd);
|
||||||
}
|
if(nkeys == -1)
|
||||||
|
{
|
||||||
|
cf_warn("TCP AO: unable to get num of keys");
|
||||||
void
|
return 1;
|
||||||
repair_tcp_ao(int sock_fd, struct iface *ifa)
|
}
|
||||||
{
|
struct tcp_ao_getsockopt_ext tm_all[nkeys];
|
||||||
//if (setsockopt(sock_fd, SOL_TCP, TCP_AO_REPAIR, &ifa->tcp_ao_img, sizeof(ifa->tcp_ao_img)) < 0)
|
socklen_t len = sizeof(struct tcp_ao_getsockopt_ext);
|
||||||
// bug("tcp ao err %i", errno);
|
memset(tm_all, 0, sizeof(struct tcp_ao_getsockopt_ext)*nkeys);
|
||||||
log("tcp ao repair skiped");
|
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
|
static inline int
|
||||||
|
@ -1097,8 +1097,7 @@ sk_passive_connected(sock *s, int type)
|
|||||||
t->tos = s->tos;
|
t->tos = s->tos;
|
||||||
t->vrf = s->vrf;
|
t->vrf = s->vrf;
|
||||||
t->rbsize = s->rbsize;
|
t->rbsize = s->rbsize;
|
||||||
t->tbsize = s->tbsize;
|
t->tbsize = s->tbsize;
|
||||||
t->ao_key = s->ao_key;
|
|
||||||
|
|
||||||
if (type == SK_TCP)
|
if (type == SK_TCP)
|
||||||
{
|
{
|
||||||
@ -1459,12 +1458,10 @@ 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->ao_key)
|
if (s->ao_key_init)
|
||||||
{
|
{
|
||||||
log("set ao, %s", s->ao_key->cipher);
|
struct ao_key *key = s->ao_key_init;
|
||||||
struct ao_key *key = s->ao_key;
|
|
||||||
do {
|
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)
|
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;
|
goto err;
|
||||||
|
Loading…
Reference in New Issue
Block a user