mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-11-09 20:58:44 +00:00
working version of ao tcp
This commit is contained in:
parent
21213be523
commit
eb03a09348
@ -6,6 +6,8 @@
|
|||||||
* Can be freely distributed and used under the terms of the GNU GPL.
|
* Can be freely distributed and used under the terms of the GNU GPL.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "sysdep/linux/tcp-ao.h"
|
||||||
|
|
||||||
#ifndef IPV6_MINHOPCOUNT
|
#ifndef IPV6_MINHOPCOUNT
|
||||||
#define IPV6_MINHOPCOUNT 73
|
#define IPV6_MINHOPCOUNT 73
|
||||||
#endif
|
#endif
|
||||||
@ -22,6 +24,15 @@
|
|||||||
#define TCP_MD5SIG_FLAG_PREFIX 1
|
#define TCP_MD5SIG_FLAG_PREFIX 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef TCP_AO_ADD_KEY
|
||||||
|
#define TCP_AO_ADD_KEY 38 /* Add/Set MKT */
|
||||||
|
#define TCP_AO_DEL_KEY 39 /* Delete MKT */
|
||||||
|
#define TCP_AO_INFO 40 /* Set/list TCP-AO per-socket options */
|
||||||
|
#define TCP_AO_GET_KEYS 41 /* List MKT(s) */
|
||||||
|
#define TCP_AO_REPAIR 42 /* Get/Set SNEs and ISNs */
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
/* We redefine the tcp_md5sig structure with different name to avoid collision with older headers */
|
/* We redefine the tcp_md5sig structure with different name to avoid collision with older headers */
|
||||||
struct tcp_md5sig_ext {
|
struct tcp_md5sig_ext {
|
||||||
struct sockaddr_storage tcpm_addr; /* Address associated */
|
struct sockaddr_storage tcpm_addr; /* Address associated */
|
||||||
@ -166,7 +177,7 @@ sk_prepare_cmsgs4(sock *s, struct msghdr *msg, void *cbuf, size_t cbuflen)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
sk_set_md5_auth(sock *s, ip_addr local UNUSED, ip_addr remote, int pxlen, struct iface *ifa, const char *passwd, int setkey UNUSED)
|
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
|
||||||
{
|
{
|
||||||
struct tcp_md5sig_ext md5;
|
struct tcp_md5sig_ext md5;
|
||||||
|
|
||||||
@ -184,6 +195,69 @@ sk_set_md5_auth(sock *s, ip_addr local UNUSED, ip_addr remote, int pxlen, struct
|
|||||||
memcpy(&md5.tcpm_key, passwd, len);
|
memcpy(&md5.tcpm_key, passwd, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
ao.prefix = -1;
|
||||||
|
ao.sndid = 100;
|
||||||
|
ao.rcvid = 100;
|
||||||
|
ao.maclen = 0;
|
||||||
|
ao.keyflags = 0;
|
||||||
|
ao.keylen = strlen(passwd);
|
||||||
|
ao.ifindex = 0;
|
||||||
|
|
||||||
|
memcpy(ao.key, passwd, (strlen(passwd) > TCP_AO_MAXKEYLEN_) ? TCP_AO_MAXKEYLEN_ : strlen(passwd));
|
||||||
|
|
||||||
|
int IPPROTO_TCP_ = 6;
|
||||||
|
if (setsockopt(s->fd, SOL_TCP, TCP_AO_ADD_KEY, &md5, sizeof(md5)) < 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 (pxlen < 0)
|
||||||
{
|
{
|
||||||
if (setsockopt(s->fd, SOL_TCP, TCP_MD5SIG, &md5, sizeof(md5)) < 0)
|
if (setsockopt(s->fd, SOL_TCP, TCP_MD5SIG, &md5, sizeof(md5)) < 0)
|
||||||
@ -207,7 +281,7 @@ sk_set_md5_auth(sock *s, ip_addr local UNUSED, ip_addr remote, int pxlen, struct
|
|||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}**/
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
sk_set_min_ttl4(sock *s, int ttl)
|
sk_set_min_ttl4(sock *s, int ttl)
|
||||||
|
95
sysdep/linux/tcp-ao.h
Normal file
95
sysdep/linux/tcp-ao.h
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
|
||||||
|
#define TCP_AO_MAXKEYLEN_ 80
|
||||||
|
|
||||||
|
#define DEFAULT_TEST_ALGO "cmac(aes128)"
|
||||||
|
|
||||||
|
struct tcp_ao_add_ext { /* setsockopt(TCP_AO_ADD_KEY) */
|
||||||
|
struct sockaddr_storage addr; /* peer's address for the key */
|
||||||
|
char alg_name[64]; /* crypto hash algorithm to use */
|
||||||
|
s32 ifindex; /* L3 dev index for VRF */
|
||||||
|
u32 set_current :1, /* set key as Current_key at once */
|
||||||
|
set_rnext :1, /* request it from peer with RNext_key */
|
||||||
|
reserved :30; /* must be 0 */
|
||||||
|
u16 reserved2; /* padding, must be 0 */
|
||||||
|
u8 prefix; /* peer's address prefix */
|
||||||
|
u8 sndid; /* SendID for outgoing segments */
|
||||||
|
u8 rcvid; /* RecvID to match for incoming seg */
|
||||||
|
u8 maclen; /* length of authentication code (hash) */
|
||||||
|
u8 keyflags; /* see TCP_AO_KEYF_ */
|
||||||
|
u8 keylen; /* length of ::key */
|
||||||
|
u8 key[TCP_AO_MAXKEYLEN_];
|
||||||
|
} __attribute__((aligned(8)));
|
||||||
|
|
||||||
|
struct tcp_ao_del_ext { /* setsockopt(TCP_AO_DEL_KEY) */
|
||||||
|
struct sockaddr_storage addr; /* peer's address for the key */
|
||||||
|
s32 ifindex; /* L3 dev index for VRF */
|
||||||
|
u32 set_current :1, /* corresponding ::current_key */
|
||||||
|
set_rnext :1, /* corresponding ::rnext */
|
||||||
|
del_async :1, /* only valid for listen sockets */
|
||||||
|
reserved :29; /* must be 0 */
|
||||||
|
u16 reserved2; /* padding, must be 0 */
|
||||||
|
u8 prefix; /* peer's address prefix */
|
||||||
|
u8 sndid; /* SendID for outgoing segments */
|
||||||
|
u8 rcvid; /* RecvID to match for incoming seg */
|
||||||
|
u8 current_key; /* KeyID to set as Current_key */
|
||||||
|
u8 rnext; /* KeyID to set as Rnext_key */
|
||||||
|
u8 keyflags; /* see TCP_AO_KEYF_ */
|
||||||
|
} __attribute__((aligned(8)));
|
||||||
|
|
||||||
|
struct tcp_ao_info_opt_ext { /* setsockopt(TCP_AO_INFO), getsockopt(TCP_AO_INFO) */
|
||||||
|
/* Here 'in' is for setsockopt(), 'out' is for getsockopt() */
|
||||||
|
u32 set_current :1, /* in/out: corresponding ::current_key */
|
||||||
|
set_rnext :1, /* in/out: corresponding ::rnext */
|
||||||
|
ao_required :1, /* in/out: don't accept non-AO connects */
|
||||||
|
set_counters :1, /* in: set/clear ::pkt_* counters */
|
||||||
|
accept_icmps :1, /* in/out: accept incoming ICMPs */
|
||||||
|
reserved :27; /* must be 0 */
|
||||||
|
u16 reserved2; /* padding, must be 0 */
|
||||||
|
u8 current_key; /* in/out: KeyID of Current_key */
|
||||||
|
u8 rnext; /* in/out: keyid of RNext_key */
|
||||||
|
u64 pkt_good; /* in/out: verified segments */
|
||||||
|
u64 pkt_bad; /* in/out: failed verification */
|
||||||
|
u64 pkt_key_not_found; /* in/out: could not find a key to verify */
|
||||||
|
u64 pkt_ao_required; /* in/out: segments missing TCP-AO sign */
|
||||||
|
u64 pkt_dropped_icmp; /* in/out: ICMPs that were ignored */
|
||||||
|
} __attribute__((aligned(8)));
|
||||||
|
|
||||||
|
struct tcp_ao_getsockopt_ext { /* getsockopt(TCP_AO_GET_KEYS) */
|
||||||
|
struct sockaddr_storage addr; /* in/out: dump keys for peer
|
||||||
|
* with this address/prefix
|
||||||
|
*/
|
||||||
|
char alg_name[64]; /* out: crypto hash algorithm */
|
||||||
|
u8 key[TCP_AO_MAXKEYLEN_];
|
||||||
|
u32 nkeys; /* in: size of the userspace buffer
|
||||||
|
* @optval, measured in @optlen - the
|
||||||
|
* sizeof(struct tcp_ao_getsockopt)
|
||||||
|
* out: number of keys that matched
|
||||||
|
*/
|
||||||
|
u16 is_current :1, /* in: match and dump Current_key,
|
||||||
|
* out: the dumped key is Current_key
|
||||||
|
*/
|
||||||
|
|
||||||
|
is_rnext :1, /* in: match and dump RNext_key,
|
||||||
|
* out: the dumped key is RNext_key
|
||||||
|
*/
|
||||||
|
get_all :1, /* in: dump all keys */
|
||||||
|
reserved :13; /* padding, must be 0 */
|
||||||
|
u8 sndid; /* in/out: dump keys with SendID */
|
||||||
|
u8 rcvid; /* in/out: dump keys with RecvID */
|
||||||
|
u8 prefix; /* in/out: dump keys with address/prefix */
|
||||||
|
u8 maclen; /* out: key's length of authentication
|
||||||
|
* code (hash)
|
||||||
|
*/
|
||||||
|
u8 keyflags; /* in/out: see TCP_AO_KEYF_ */
|
||||||
|
u8 keylen; /* out: length of ::key */
|
||||||
|
s32 ifindex; /* in/out: L3 dev index for VRF */
|
||||||
|
u64 pkt_good; /* out: verified segments */
|
||||||
|
u64 pkt_bad; /* out: segments that failed verification */
|
||||||
|
} __attribute__((aligned(8)));
|
||||||
|
|
||||||
|
struct tcp_ao_repair_ext { /* {s,g}etsockopt(TCP_AO_REPAIR) */
|
||||||
|
u32 snt_isn; //should be __be32 alias fdt32_t - 32-bit, big-endian, unsigned integer
|
||||||
|
u32 rcv_isn; //should be __be32 alias fdt32_t - 32-bit, big-endian, unsigned integer
|
||||||
|
u32 snd_sne;
|
||||||
|
u32 rcv_sne;
|
||||||
|
} __attribute__((aligned(8)));
|
Loading…
Reference in New Issue
Block a user