diff --git a/lib/socket.h b/lib/socket.h index 0b6ac589..32a7caed 100644 --- a/lib/socket.h +++ b/lib/socket.h @@ -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); diff --git a/nest/iface.h b/nest/iface.h index f8e92850..86c538ce 100644 --- a/nest/iface.h +++ b/nest/iface.h @@ -11,6 +11,7 @@ #include "lib/lists.h" #include "lib/ip.h" +#include "sysdep/linux/tcp-ao.h" extern list iface_list; diff --git a/proto/bgp/bgp.c b/proto/bgp/bgp.c index f668b371..6d39b107 100644 --- a/proto/bgp/bgp.c +++ b/proto/bgp/bgp.c @@ -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) diff --git a/proto/bgp/bgp.h b/proto/bgp/bgp.h index 1ba3de5e..840862f6 100644 --- a/proto/bgp/bgp.h +++ b/proto/bgp/bgp.h @@ -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); diff --git a/proto/bgp/packets.c b/proto/bgp/packets.c index 054e6c3c..f48ebcdc 100644 --- a/proto/bgp/packets.c +++ b/proto/bgp/packets.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; diff --git a/sysdep/linux/sysio.h b/sysdep/linux/sysio.h index 2edbd0b5..ad17af94 100644 --- a/sysdep/linux/sysio.h +++ b/sysdep/linux/sysio.h @@ -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) diff --git a/sysdep/linux/tcp-ao.h b/sysdep/linux/tcp-ao.h index 523952cc..ab4df93e 100644 --- a/sysdep/linux/tcp-ao.h +++ b/sysdep/linux/tcp-ao.h @@ -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*/ diff --git a/sysdep/unix/io.c b/sysdep/unix/io.c index 6aedcfb6..7f51a712 100644 --- a/sysdep/unix/io.c +++ b/sysdep/unix/io.c @@ -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: