diff options
author | Michael H. Warfield <mhw@WittsEnd.com> | 2008-04-15 21:49:45 +0000 |
---|---|---|
committer | Tom Grennan <tgrennan@vyatta.com> | 2008-04-15 21:59:57 +0000 |
commit | 4c9782da0f5484e52a00bb769813b5988e857c38 (patch) | |
tree | 4cea02479b67f00728724727a6c001e05f25a4a3 /bgpd/bgp_network.c | |
parent | c1bdabf8dd2f22a33fdc35b70b93e871f179445d (diff) | |
download | quagga-4c9782da0f5484e52a00bb769813b5988e857c38.tar.bz2 quagga-4c9782da0f5484e52a00bb769813b5988e857c38.tar.xz |
TCP MD5SIG patch
from http://www.gossamer-threads.com/lists/quagga/dev/15611
[clear_shim] Re: [quagga-users 9315] New md5 signature patch for bgp... quagga_md5_bsd_linux_v9.diff Remove Highlighting [In reply to]
mhw at wittsend ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Jan 28, 2008, 12:55 PM And, of course, the moment I send off a patch against 0.99.9 and claim
it should patch the CVS, I find out it does not.
Post #2 of 3 (192
views) On Mon, 2008-01-28 at 14:50 -0500, Michael H. Warfield wrote:
Permalink > Hello all!
> Building on the efforts of Leigh Brown and the earlier works on an MD5
> signature patch for bgpd, I've incorporated the autoconf efforts by
> Sargun Dhillon on top of my own changes for IPv6 along with filling in a
> few missing spots in the autoconf stuff myself. Leigh had released a v7
> and I subsequently released a v8 patch for md5 signatures for Linux and
> BSD to deal with conflicts with IPv6. This is now a v9 patch
> incorporating some of the changes from Sargun and adding a few of my own
> to complete the autoconf changes.
> This patch is still against 0.99.9 but should patch cleanly against
> CVS.
Attached is the patch against CVS. It does NOT have a patch for
config.h.in (that was a mistake on my part, it's not in CVS, it's
generated but it's not regenerated if you are working from the releases
and don't rerun autoheader) and fixes a problem with a header file and
some alignments.
[cl] > This adds a configure option, --enable-tcp-md5, to enable tcp md5 [cl]
> signatures. This is not qualified against the operating system on which
> it is being built. The patch should work on BSD and Linux. Other
> operation systems are a crap shoot. I don't know. I presume some other
> errors will occur on other operating systems which do not support MD5
> signatures in this manner. Since they're not supported now, this is no
> great loss. Someone might want to test this in other environments,
> though, and enhance it for those other environments.
>
> Attached...
>
> quagga_md5_bsd_linux_v9.diff
>
> http://www.wittsend.com/mhw/md5sig/quagga_md5_bsd_linux_v9.diff
>
> Is there anything left that needs to be done before this can be
> committed to CVS? Can someone with commit privs please do the honors?
Mike
--
Michael H. Warfield (AI4NB) | (770) 985-6132 | mhw[at]WittsEnd.com
/\/\|=mhw=|\/\/ | (678) 463-0932 | http://www.wittsend.com/mhw/
NIC whois: MHW9 | An optimist believes we live in the best of all
PGP Key: 0xDF1DD471 | possible worlds. A pessimist is sure of it!
Attachments: [unknown] quagga_cvs_md5_bsd_linux_v9.diff (18.4 KB)
<http://www.gossamer-threads.com/lists/engine?do=post_attachment;postatt_id=1184;list=quagga>
[unknown] signature.asc (0.30 KB)
<http://www.gossamer-threads.com/lists/engine?do=post_attachment;postatt_id=1185;list=quagga>
Signed-off-by: Tom Grennan <tgrennan@vyatta.com>
Diffstat (limited to 'bgpd/bgp_network.c')
-rw-r--r-- | bgpd/bgp_network.c | 115 |
1 files changed, 115 insertions, 0 deletions
diff --git a/bgpd/bgp_network.c b/bgpd/bgp_network.c index 8452545d..4289ce20 100644 --- a/bgpd/bgp_network.c +++ b/bgpd/bgp_network.c @@ -22,6 +22,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA #include "thread.h" #include "sockunion.h" +#include "sockopt.h" #include "memory.h" #include "log.h" #include "if.h" @@ -38,6 +39,34 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA extern struct zebra_privs_t bgpd_privs; +#if defined(HAVE_TCP_MD5SIG) +/* + * Set MD5 key for the socket, for the given IPv4 peer address. + * If the password is NULL or zero-length, the option will be disabled. + */ +int +bgp_md5_set (int sock, struct sockaddr_in *sin, const char *password) +{ + int ret, en; + + if ( bgpd_privs.change (ZPRIVS_RAISE) ) + zlog_err ("bgp_md5_set: could not raise privs"); + + ret = sockopt_tcp_signature (sock, sin, password); + en = errno; + + if (bgpd_privs.change (ZPRIVS_LOWER) ) + zlog_err ("bgp_md5_set: could not lower privs"); + + if (ret < 0) + zlog (NULL, LOG_WARNING, "can't set TCP_MD5SIG option on socket %d: %s", + sock, safe_strerror (en)); + + return ret; +} + +#endif /* HAVE_TCP_MD5SIG */ + /* Accept bgp connection. */ static int bgp_accept (struct thread *thread) @@ -238,6 +267,12 @@ bgp_connect (struct peer *peer) sockopt_reuseaddr (peer->fd); sockopt_reuseport (peer->fd); +#ifdef HAVE_TCP_MD5SIG + if (CHECK_FLAG (peer->flags, PEER_FLAG_PASSWORD)) + if (sockunion_family (&peer->su) == AF_INET) + bgp_md5_set (peer->fd, &peer->su.sin, peer->password); +#endif /* HAVE_TCP_MD5SIG */ + /* Bind socket. */ bgp_bind (peer); @@ -288,6 +323,10 @@ bgp_socket (struct bgp *bgp, unsigned short port, char *address) struct addrinfo req; struct addrinfo *ainfo; struct addrinfo *ainfo_save; +#if defined(HAVE_TCP_MD5SIG) && defined(IPV6_V6ONLY) + struct sockaddr_in sin; + int socklen, on = 1; +#endif int sock = 0; char port_str[BUFSIZ]; @@ -323,6 +362,21 @@ bgp_socket (struct bgp *bgp, unsigned short port, char *address) sockopt_reuseaddr (sock); sockopt_reuseport (sock); +#if defined(HAVE_TCP_MD5SIG) && defined(IPV6_V6ONLY) +/* We can not apply MD5SIG to an IPv6 socket. If this is an AF_INET6 + socket, we'll have to create another socket for IPv4*/ + + if (ainfo->ai_family == AF_INET6) { +/* Mark this one for IPv6 only */ + ret = setsockopt (sock, IPPROTO_IPV6, IPV6_V6ONLY, + (void *) &on, sizeof (on)); + if( ret < 0 ) { + en = errno; + zlog_err ("setsockopt V6ONLY: %s", safe_strerror (en)); + } + } +#endif + if (bgpd_privs.change (ZPRIVS_RAISE) ) zlog_err ("bgp_socket: could not raise privs"); @@ -346,7 +400,65 @@ bgp_socket (struct bgp *bgp, unsigned short port, char *address) continue; } +#if defined(HAVE_TCP_MD5SIG) && defined(IPV6_V6ONLY) + thread_add_read (master, bgp_accept, bgp, sock); + + if (ainfo->ai_family != AF_INET6) + continue; + + /* If first socket was an IPv6 socket, we need to create an IPv4 + socket for use by the TCP_MD5SIG logic. This code is blatently + copied and modified from the alternate IPv4 only code from below... */ + + sock = socket (AF_INET, SOCK_STREAM, 0); + if (sock < 0) + { + zlog_err ("socket: %s", safe_strerror (errno)); + continue; + } + + sockopt_reuseaddr (sock); + sockopt_reuseport (sock); + + memset (&sin, 0, sizeof (struct sockaddr_in)); + + sin.sin_family = AF_INET; + sin.sin_port = htons (port); + socklen = sizeof (struct sockaddr_in); +#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN + sin.sin_len = socklen; +#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */ + + if ( bgpd_privs.change (ZPRIVS_RAISE) ) + zlog_err ("bgp_socket: could not raise privs"); + + ret = bind (sock, (struct sockaddr *) &sin, socklen); + en = errno; + if (bgpd_privs.change (ZPRIVS_LOWER) ) + zlog_err ("bgp_bind_address: could not lower privs"); + + if (ret < 0) + { + zlog_err ("bind: %s", safe_strerror (en)); + close(sock); + continue; + } + + ret = listen (sock, 3); + if (ret < 0) + { + zlog_err ("listen: %s", safe_strerror (errno)); + close (sock); + continue; + } +#endif + +#ifdef HAVE_TCP_MD5SIG + bm->sock = sock; +#endif /* HAVE_TCP_MD5SIG */ + thread_add_read (master, bgp_accept, bgp, sock); + } while ((ainfo = ainfo->ai_next) != NULL); @@ -413,6 +525,9 @@ bgp_socket (struct bgp *bgp, unsigned short port, char *address) close (sock); return ret; } +#ifdef HAVE_TCP_MD5SIG + bm->sock = sock; +#endif /* HAVE_TCP_MD5SIG */ thread_add_read (bm->master, bgp_accept, bgp, sock); |