diff options
| author | Quentin Young <qlyoung@cumulusnetworks.com> | 2019-04-01 18:16:54 +0000 |
|---|---|---|
| committer | Quentin Young <qlyoung@cumulusnetworks.com> | 2019-04-16 15:26:20 +0000 |
| commit | b33e46666d390dbbbe4b5434b11df0100da94ed4 (patch) | |
| tree | cb92adbe825fa42687162530e2bdc6f838a55d9d /lib/sockopt.c | |
| parent | 0697abef9d425e0443a6746021ed012eed3cfd13 (diff) | |
lib: add support for extended TCP MD5 auth
MD5 auth on TCP is supported for prefixes in recent versions of Linux;
add complementary support for FRR.
This is a reworked version of Donald's commit to keep library
compatibility and obviate the need for changes in daemons that don't
need to support this themselves.
Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
Diffstat (limited to 'lib/sockopt.c')
| -rw-r--r-- | lib/sockopt.c | 50 |
1 files changed, 45 insertions, 5 deletions
diff --git a/lib/sockopt.c b/lib/sockopt.c index ea04f2a43e..89f3d5b594 100644 --- a/lib/sockopt.c +++ b/lib/sockopt.c @@ -587,10 +587,30 @@ int sockopt_tcp_rtt(int sock) #endif } -int sockopt_tcp_signature(int sock, union sockunion *su, const char *password) +int sockopt_tcp_signature_ext(int sock, union sockunion *su, uint16_t prefixlen, + const char *password) { +#ifndef HAVE_DECL_TCP_MD5SIG + /* + * We have been asked to enable MD5 auth for an address, but our + * platform doesn't support that + */ + return -2; +#endif + +#ifndef TCP_MD5SIG_EXT + /* + * We have been asked to enable MD5 auth for a prefix, but our platform + * doesn't support that + */ + if (prefixlen > 0) + return -2; +#endif + #if HAVE_DECL_TCP_MD5SIG int ret; + + int optname = TCP_MD5SIG; #ifndef GNU_LINUX /* * XXX Need to do PF_KEY operation here to add/remove an SA entry, @@ -643,12 +663,29 @@ int sockopt_tcp_signature(int sock, union sockunion *su, const char *password) memset(&md5sig, 0, sizeof(md5sig)); memcpy(&md5sig.tcpm_addr, su2, sizeof(*su2)); + md5sig.tcpm_keylen = keylen; if (keylen) memcpy(md5sig.tcpm_key, password, keylen); sockunion_free(susock); + + /* + * Handle support for MD5 signatures on prefixes, if available and + * requested. Technically the #ifdef check below is not needed because + * if prefixlen > 0 and we don't have support for this feature we would + * have already returned by now, but leaving it there to be explicit. + */ +#ifdef TCP_MD5SIG_EXT + if (prefixlen > 0) { + md5sig.tcpm_prefixlen = prefixlen; + md5sig.tcpm_flags = TCP_MD5SIG_FLAG_PREFIX; + optname = TCP_MD5SIG_EXT; + } +#endif /* TCP_MD5SIG_EXT */ + #endif /* GNU_LINUX */ - if ((ret = setsockopt(sock, IPPROTO_TCP, TCP_MD5SIG, &md5sig, + + if ((ret = setsockopt(sock, IPPROTO_TCP, optname, &md5sig, sizeof md5sig)) < 0) { /* ENOENT is harmless. It is returned when we clear a password @@ -663,7 +700,10 @@ int sockopt_tcp_signature(int sock, union sockunion *su, const char *password) sock, safe_strerror(errno)); } return ret; -#else /* HAVE_TCP_MD5SIG */ - return -2; -#endif /* !HAVE_TCP_MD5SIG */ +#endif /* HAVE_TCP_MD5SIG */ +} + +int sockopt_tcp_signature(int sock, union sockunion *su, const char *password) +{ + return sockopt_tcp_signature_ext(sock, su, 0, password); } |
