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);  }  | 
