mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2025-01-05 08:31:53 +00:00
repaired bgp/config.Y, tests are passing with good passwords, failing with wrong
This commit is contained in:
parent
4a91d4961b
commit
e3dc32e064
19
lib/socket.h
19
lib/socket.h
@ -36,6 +36,17 @@ struct ssh_sock {
|
|||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
struct ao_key
|
||||||
|
{
|
||||||
|
int local_id;
|
||||||
|
int remote_id;
|
||||||
|
const char *cipher;
|
||||||
|
const char *master_key;
|
||||||
|
int requested;
|
||||||
|
struct linpool *lp;
|
||||||
|
struct ao_key *next_key;
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct birdsock {
|
typedef struct birdsock {
|
||||||
resource r;
|
resource r;
|
||||||
pool *pool; /* Pool where incoming connections should be allocated (for SK_xxx_PASSIVE) */
|
pool *pool; /* Pool where incoming connections should be allocated (for SK_xxx_PASSIVE) */
|
||||||
@ -77,6 +88,7 @@ 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 */
|
||||||
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;
|
||||||
@ -107,8 +119,11 @@ 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_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);
|
||||||
|
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 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);
|
||||||
|
@ -236,7 +236,7 @@ bgp_close(struct bgp_proto *p)
|
|||||||
static inline int
|
static inline int
|
||||||
bgp_setup_auth(struct bgp_proto *p, int enable)
|
bgp_setup_auth(struct bgp_proto *p, int enable)
|
||||||
{
|
{
|
||||||
if (p->cf->password)
|
if (p->cf->password || p->cf->ao_key)
|
||||||
{
|
{
|
||||||
ip_addr prefix = p->cf->remote_ip;
|
ip_addr prefix = p->cf->remote_ip;
|
||||||
int pxlen = -1;
|
int pxlen = -1;
|
||||||
@ -247,10 +247,22 @@ bgp_setup_auth(struct bgp_proto *p, int enable)
|
|||||||
pxlen = net_pxlen(p->cf->remote_range);
|
pxlen = net_pxlen(p->cf->remote_range);
|
||||||
}
|
}
|
||||||
int rv = 0;
|
int rv = 0;
|
||||||
if (enable)
|
if (p->cf->ao_key)
|
||||||
rv = sk_set_ao_auth(p->sock->sk,
|
{
|
||||||
|
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,
|
p->cf->local_ip, prefix, pxlen, p->cf->iface,
|
||||||
p->cf->password, 123, 123, p->cf->setkey);
|
key->master_key, key->local_id, key->remote_id, key->cipher);
|
||||||
|
key = key->next_key;
|
||||||
|
|
||||||
|
} while(key);
|
||||||
|
}
|
||||||
|
else if (enable)
|
||||||
|
rv = sk_set_md5_auth(p->sock->sk,
|
||||||
|
p->cf->local_ip, prefix, pxlen, p->cf->iface,
|
||||||
|
p->cf->password, 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);
|
||||||
@ -1105,7 +1117,10 @@ bgp_active(struct bgp_proto *p)
|
|||||||
void
|
void
|
||||||
log_ao(int fd)
|
log_ao(int fd)
|
||||||
{
|
{
|
||||||
|
log("the two ao logs");
|
||||||
log_tcp_ao_info(fd);
|
log_tcp_ao_info(fd);
|
||||||
|
log_tcp_ao_get_key(fd);
|
||||||
|
ao_try_change_master(fd, 101);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1136,6 +1151,7 @@ bgp_connect(struct bgp_proto *p) /* Enter Connect state and start establishing c
|
|||||||
s->tos = IP_PREC_INTERNET_CONTROL;
|
s->tos = IP_PREC_INTERNET_CONTROL;
|
||||||
// s->password = "abcd1234";/
|
// s->password = "abcd1234";/
|
||||||
s->password = p->cf->password;
|
s->password = p->cf->password;
|
||||||
|
s->ao_key = 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",
|
||||||
|
@ -134,6 +134,7 @@ struct bgp_config {
|
|||||||
u32 disable_after_cease; /* Disable it when cease is received, bitfield */
|
u32 disable_after_cease; /* Disable it when cease is received, bitfield */
|
||||||
|
|
||||||
const char *password; /* Password used for MD5 authentication */
|
const char *password; /* Password used for MD5 authentication */
|
||||||
|
struct ao_key *ao_key; /* Keys for tcp ao authentication */
|
||||||
net_addr *remote_range; /* Allowed neighbor range for dynamic BGP */
|
net_addr *remote_range; /* Allowed neighbor range for dynamic BGP */
|
||||||
const char *dynamic_name; /* Name pattern for dynamic BGP */
|
const char *dynamic_name; /* Name pattern for dynamic BGP */
|
||||||
int dynamic_name_digits; /* Minimum number of digits for dynamic names */
|
int dynamic_name_digits; /* Minimum number of digits for dynamic names */
|
||||||
|
@ -32,7 +32,8 @@ CF_KEYWORDS(BGP, LOCAL, NEIGHBOR, AS, HOLD, TIME, CONNECT, RETRY, KEEPALIVE,
|
|||||||
LIVED, STALE, IMPORT, IBGP, EBGP, MANDATORY, INTERNAL, EXTERNAL, SETS,
|
LIVED, STALE, IMPORT, IBGP, EBGP, MANDATORY, INTERNAL, EXTERNAL, SETS,
|
||||||
DYNAMIC, RANGE, NAME, DIGITS, BGP_AIGP, AIGP, ORIGINATE, COST, ENFORCE,
|
DYNAMIC, RANGE, NAME, DIGITS, BGP_AIGP, AIGP, ORIGINATE, COST, ENFORCE,
|
||||||
FIRST, FREE, VALIDATE, BASE, ROLE, ROLES, PEER, PROVIDER, CUSTOMER,
|
FIRST, FREE, VALIDATE, BASE, ROLE, ROLES, PEER, PROVIDER, CUSTOMER,
|
||||||
RS_SERVER, RS_CLIENT, REQUIRE, BGP_OTC, GLOBAL)
|
RS_SERVER, RS_CLIENT, REQUIRE, BGP_OTC, GLOBAL, AUTHENTICATE, MANUAL,
|
||||||
|
KEY, MASTER, DEPRECATED, REQUIRED, CIPHER, LOCAL, REMOTE)
|
||||||
|
|
||||||
%type <i> bgp_nh
|
%type <i> bgp_nh
|
||||||
%type <i32> bgp_afi
|
%type <i32> bgp_afi
|
||||||
@ -191,7 +192,8 @@ bgp_proto:
|
|||||||
| bgp_proto ENABLE EXTENDED MESSAGES bool ';' { BGP_CFG->enable_extended_messages = $5; }
|
| bgp_proto ENABLE EXTENDED MESSAGES bool ';' { BGP_CFG->enable_extended_messages = $5; }
|
||||||
| bgp_proto ADVERTISE HOSTNAME bool ';' { BGP_CFG->enable_hostname = $4; }
|
| bgp_proto ADVERTISE HOSTNAME bool ';' { BGP_CFG->enable_hostname = $4; }
|
||||||
| bgp_proto CAPABILITIES bool ';' { BGP_CFG->capabilities = $3; }
|
| bgp_proto CAPABILITIES bool ';' { BGP_CFG->capabilities = $3; }
|
||||||
| bgp_proto PASSWORD text ';' { BGP_CFG->password = $3; }
|
| bgp_proto PASSWORD text ';' { log("%s", $3); BGP_CFG->password = $3; }
|
||||||
|
| bgp_proto AUTHENTICATE MANUAL '{' ao_keys '}'
|
||||||
| bgp_proto SETKEY bool ';' { BGP_CFG->setkey = $3; }
|
| bgp_proto SETKEY bool ';' { BGP_CFG->setkey = $3; }
|
||||||
| bgp_proto PASSIVE bool ';' { BGP_CFG->passive = $3; }
|
| bgp_proto PASSIVE bool ';' { BGP_CFG->passive = $3; }
|
||||||
| bgp_proto INTERPRET COMMUNITIES bool ';' { BGP_CFG->interpret_communities = $4; }
|
| bgp_proto INTERPRET COMMUNITIES bool ';' { BGP_CFG->interpret_communities = $4; }
|
||||||
@ -231,6 +233,47 @@ bgp_afi:
|
|||||||
| FLOW6 { $$ = BGP_AF_FLOW6; }
|
| FLOW6 { $$ = BGP_AF_FLOW6; }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
ao_keys:
|
||||||
|
KEY '{' ao_first_item ao_key '}'
|
||||||
|
| KEY '{' ao_first_item ao_key '}' ao_keys
|
||||||
|
;
|
||||||
|
|
||||||
|
ao_key:
|
||||||
|
ao_item
|
||||||
|
| ao_item ao_key
|
||||||
|
;
|
||||||
|
|
||||||
|
ao_first_item:
|
||||||
|
LOCAL ID expr ';' {
|
||||||
|
struct linpool *lp;
|
||||||
|
if (BGP_CFG->ao_key)
|
||||||
|
lp = BGP_CFG->ao_key->lp;
|
||||||
|
else
|
||||||
|
lp = lp_new(rp_new(&root_pool, "ao struct pool"));
|
||||||
|
struct ao_key *new_key = lp_alloc(lp, sizeof(struct ao_key));
|
||||||
|
new_key->lp = lp;
|
||||||
|
new_key->next_key = BGP_CFG->ao_key;
|
||||||
|
BGP_CFG->ao_key = new_key;
|
||||||
|
BGP_CFG->ao_key->requested = 0;
|
||||||
|
BGP_CFG->ao_key->local_id = $3;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
ao_item:
|
||||||
|
REMOTE ID expr ';' {log("remote id %i", $3); BGP_CFG->ao_key->remote_id = $3; }
|
||||||
|
| CIPHER text ';' { char *c = lp_alloc(BGP_CFG->ao_key->lp, strlen($2));
|
||||||
|
memcpy(c, $2, strlen($2));
|
||||||
|
BGP_CFG->ao_key->cipher = c;
|
||||||
|
log("ciph[%s]", $2); }
|
||||||
|
| MASTER KEY text ';' {
|
||||||
|
char *k = lp_alloc(BGP_CFG->ao_key->lp, strlen($3));
|
||||||
|
memcpy(k, $3, strlen($3));
|
||||||
|
BGP_CFG->ao_key->master_key = k;
|
||||||
|
log("key[%s]", BGP_CFG->ao_key->master_key);}
|
||||||
|
| DEPRECATED ';' { BGP_CFG->ao_key->requested = -1; }
|
||||||
|
| REQUIRED ';' { BGP_CFG->ao_key->requested = 1; }
|
||||||
|
;
|
||||||
|
|
||||||
bgp_channel_start: bgp_afi
|
bgp_channel_start: bgp_afi
|
||||||
{
|
{
|
||||||
const struct bgp_af_desc *desc = bgp_get_af_desc($1);
|
const struct bgp_af_desc *desc = bgp_get_af_desc($1);
|
||||||
|
@ -3423,7 +3423,6 @@ 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);
|
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;
|
||||||
|
@ -234,14 +234,36 @@ void log_tcp_ao_info(int sock_fd)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
log("current key id %i, set current %i, ao required %i ", tmp.current_key, tmp.set_current, tmp.ao_required);
|
log("current key id %i, next key %i,\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);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
log_tcp_ao_get_key(int sock_fd)
|
||||||
|
{
|
||||||
|
struct tcp_ao_getsockopt_ext tmp;
|
||||||
|
memset(&tmp, 0, sizeof(struct tcp_ao_getsockopt_ext));
|
||||||
|
socklen_t len = sizeof(tmp);
|
||||||
|
tmp.nkeys = 1;
|
||||||
|
tmp.get_all = 1;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
log("cipher %s key %s num of keys %i", tmp.alg_name, tmp.key, tmp.nkeys);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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, int setkey UNUSED)
|
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)
|
||||||
{
|
{
|
||||||
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));
|
||||||
|
log("in sk set ao");
|
||||||
|
log("%s %i %i", passwd, passwd_id_loc, passwd_id_rem);
|
||||||
log("af %i %I %I (%i or %i) %s %i", s->af, remote, local, AF_INET, AF_INET6, passwd, passwd[0]);
|
log("af %i %I %I (%i or %i) %s %i", s->af, remote, local, AF_INET, AF_INET6, passwd, passwd[0]);
|
||||||
/* int af;
|
/* int af;
|
||||||
if (ipa_is_ip4(remote))
|
if (ipa_is_ip4(remote))
|
||||||
@ -263,7 +285,7 @@ sk_set_ao_auth(sock *s, ip_addr local, ip_addr remote, int pxlen, struct iface *
|
|||||||
ao.keyflags = 0;
|
ao.keyflags = 0;
|
||||||
ao.ifindex = 0;
|
ao.ifindex = 0;
|
||||||
|
|
||||||
strncpy(ao.alg_name, DEFAULT_TEST_ALGO, 64);
|
strncpy(ao.alg_name, (cipher) ? cipher : DEFAULT_TEST_ALGO, 64);
|
||||||
|
|
||||||
ao.keylen = strlen(passwd);
|
ao.keylen = strlen(passwd);
|
||||||
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));
|
||||||
@ -276,6 +298,24 @@ sk_set_ao_auth(sock *s, ip_addr local, ip_addr remote, int pxlen, struct iface *
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ao_try_change_master(int sock_fd, int next_master_id )
|
||||||
|
{
|
||||||
|
struct tcp_ao_info_opt_ext tmp;
|
||||||
|
memset(&tmp, 0, sizeof(struct tcp_ao_info_opt_ext));
|
||||||
|
socklen_t len = sizeof(tmp);
|
||||||
|
tmp.set_rnext = 1;
|
||||||
|
tmp.rnext = next_master_id;
|
||||||
|
|
||||||
|
if (setsockopt(sock_fd, IPPROTO_TCP, TCP_AO_INFO, &tmp, &len))
|
||||||
|
{
|
||||||
|
log(" tcp ao change master key failed with err code %i", errno);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
log("tried to change master");
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
save_to_repair(int sock_fd)
|
save_to_repair(int sock_fd)
|
||||||
{
|
{
|
||||||
@ -296,20 +336,6 @@ repair_tcp_ao(int sock_fd, struct iface *ifa)
|
|||||||
log("tcp ao repair skiped");
|
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)
|
||||||
{
|
{
|
||||||
|
@ -1460,9 +1460,19 @@ sk_open(sock *s)
|
|||||||
}
|
}
|
||||||
//s->password = "abcd1234";
|
//s->password = "abcd1234";
|
||||||
|
|
||||||
if (s->password) //TODO condition if it should be ao or md5
|
if (s->ao_key)
|
||||||
{
|
{
|
||||||
log("set ao");
|
log("set ao, %s", s->ao_key->cipher);
|
||||||
|
struct ao_key *key = s->ao_key;
|
||||||
|
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) < 0)
|
||||||
|
goto err;
|
||||||
|
key = key->next_key;
|
||||||
|
} while (key);
|
||||||
|
}
|
||||||
|
if (s->password)
|
||||||
|
{
|
||||||
|
log("set md5");
|
||||||
if (sk_set_ao_auth(s, s->saddr, s->daddr, -1, s->iface, s->password, 123, 123, 0) < 0)
|
if (sk_set_ao_auth(s, s->saddr, s->daddr, -1, s->iface, s->password, 123, 123, 0) < 0)
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user