mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-07 07:48:07 +00:00
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>
This commit is contained in:
parent
0697abef9d
commit
b33e46666d
@ -587,10 +587,30 @@ int sockopt_tcp_rtt(int sock)
|
|||||||
#endif
|
#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
|
#if HAVE_DECL_TCP_MD5SIG
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
int optname = TCP_MD5SIG;
|
||||||
#ifndef GNU_LINUX
|
#ifndef GNU_LINUX
|
||||||
/*
|
/*
|
||||||
* XXX Need to do PF_KEY operation here to add/remove an SA entry,
|
* 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));
|
memset(&md5sig, 0, sizeof(md5sig));
|
||||||
memcpy(&md5sig.tcpm_addr, su2, sizeof(*su2));
|
memcpy(&md5sig.tcpm_addr, su2, sizeof(*su2));
|
||||||
|
|
||||||
md5sig.tcpm_keylen = keylen;
|
md5sig.tcpm_keylen = keylen;
|
||||||
if (keylen)
|
if (keylen)
|
||||||
memcpy(md5sig.tcpm_key, password, keylen);
|
memcpy(md5sig.tcpm_key, password, keylen);
|
||||||
sockunion_free(susock);
|
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 */
|
#endif /* GNU_LINUX */
|
||||||
if ((ret = setsockopt(sock, IPPROTO_TCP, TCP_MD5SIG, &md5sig,
|
|
||||||
|
if ((ret = setsockopt(sock, IPPROTO_TCP, optname, &md5sig,
|
||||||
sizeof md5sig))
|
sizeof md5sig))
|
||||||
< 0) {
|
< 0) {
|
||||||
/* ENOENT is harmless. It is returned when we clear a password
|
/* 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));
|
sock, safe_strerror(errno));
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
#else /* HAVE_TCP_MD5SIG */
|
#endif /* HAVE_TCP_MD5SIG */
|
||||||
return -2;
|
}
|
||||||
#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);
|
||||||
}
|
}
|
||||||
|
@ -100,9 +100,43 @@ extern void sockopt_iphdrincl_swab_htosys(struct ip *iph);
|
|||||||
extern void sockopt_iphdrincl_swab_systoh(struct ip *iph);
|
extern void sockopt_iphdrincl_swab_systoh(struct ip *iph);
|
||||||
|
|
||||||
extern int sockopt_tcp_rtt(int);
|
extern int sockopt_tcp_rtt(int);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TCP MD5 signature option. This option allows TCP MD5 to be enabled on
|
||||||
|
* addresses.
|
||||||
|
*
|
||||||
|
* sock
|
||||||
|
* Socket to enable option on.
|
||||||
|
*
|
||||||
|
* su
|
||||||
|
* Sockunion specifying address to enable option on.
|
||||||
|
*
|
||||||
|
* password
|
||||||
|
* MD5 auth password
|
||||||
|
*/
|
||||||
extern int sockopt_tcp_signature(int sock, union sockunion *su,
|
extern int sockopt_tcp_signature(int sock, union sockunion *su,
|
||||||
const char *password);
|
const char *password);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Extended TCP MD5 signature option. This option allows TCP MD5 to be enabled
|
||||||
|
* on prefixes.
|
||||||
|
*
|
||||||
|
* sock
|
||||||
|
* Socket to enable option on.
|
||||||
|
*
|
||||||
|
* su
|
||||||
|
* Sockunion specifying address (or prefix) to enable option on.
|
||||||
|
*
|
||||||
|
* prefixlen
|
||||||
|
* 0 - su is an address; fall back to non-extended mode
|
||||||
|
* Else - su is a prefix; prefixlen is the mask length
|
||||||
|
*
|
||||||
|
* password
|
||||||
|
* MD5 auth password
|
||||||
|
*/
|
||||||
|
extern int sockopt_tcp_signature_ext(int sock, union sockunion *su,
|
||||||
|
uint16_t prefixlen, const char *password);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user