[Xorp-hackers] First cut app-level tcp-md5 patch

Bruce M Simpson bms@spc.org
Wed, 4 Aug 2004 21:20:08 -0700


--J2SCkAp4GZ/dPZZf
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

Hi,

I just cut this patch to begin using the TCP-MD5 support in the BSDs. It
is pretty much a straight port of the work I did on Zebra to the XORP
codebase.

I'm really looking for feedback here regarding: does this fit well with
the rest of the code? Or does it need further changes?

I haven't dealt with the PF_KEY stuff yet; that is perhaps more appropriate
as an extension of the firewall work.

Now I think this is sufficient to get things up and running in the quick
and dirty. This compiles cleanly - but the comments/style probably need
some attention. I haven't tested it in production.

The changes to auto-generated files (i.e. XRL RPC glue) can be ignored;
this is a quick diff of my dev tree on my desktop machine.

BMS

--J2SCkAp4GZ/dPZZf
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="tcpmd5-hilevel.diff"

Index: bgp/bgp.cc
===================================================================
RCS file: /usr/local/www/data/cvs/xorp/bgp/bgp.cc,v
retrieving revision 1.37
diff -u -p -r1.37 bgp.cc
--- bgp/bgp.cc	10 Jun 2004 22:40:28 -0000	1.37
+++ bgp/bgp.cc	5 Aug 2004 04:11:48 -0000
@@ -471,6 +471,21 @@ BGPMain::set_peer_state(const Iptuple& i
 }
 
 bool
+BGPMain::set_peer_md5_password(const Iptuple& iptuple, const string& password)
+{
+    BGPPeer *peer = find_peer(iptuple);
+
+    if (peer == 0) {
+	XLOG_WARNING("Could not find peer: %s", iptuple.str().c_str());
+	return false;
+    }
+
+    peer->set_md5_password(password);
+
+    return true;
+}
+
+bool
 BGPMain::activate(const Iptuple& iptuple)
 {
     BGPPeer *peer = find_peer(iptuple);
Index: bgp/bgp.hh
===================================================================
RCS file: /usr/local/www/data/cvs/xorp/bgp/bgp.hh,v
retrieving revision 1.27
diff -u -p -r1.27 bgp.hh
--- bgp/bgp.hh	10 Jun 2004 22:40:28 -0000	1.27
+++ bgp/bgp.hh	5 Aug 2004 04:11:48 -0000
@@ -125,6 +125,16 @@ public:
     bool set_peer_state(const Iptuple& iptuple, bool state);
 
     /**
+     * Set peer state.
+     *
+     * @param iptuple iptuple.
+     * @param state should the peering be enable or disabled.
+     *
+     * @ return true on success.
+     */
+    bool set_peer_md5_password(const Iptuple& iptuple, const string& password);
+
+    /**
      * Activate peer.
      *
      * Enable the peering based on the peer state.
Index: bgp/peer.cc
===================================================================
RCS file: /usr/local/www/data/cvs/xorp/bgp/peer.cc,v
retrieving revision 1.79
diff -u -p -r1.79 peer.cc
--- bgp/peer.cc	10 Jun 2004 22:40:31 -0000	1.79
+++ bgp/peer.cc	5 Aug 2004 04:11:48 -0000
@@ -23,6 +23,7 @@
 #include "libxorp/debug.h"
 #include "libxorp/xlog.h"
 #include "libxorp/timer.hh"
+#include "libcomm/comm_api.h"
 #include "xrl/interfaces/bgp_mib_traps_xif.hh"
 #include "libxorp/timespent.hh"
 
@@ -1702,3 +1703,15 @@ BGPPeer::remote_ip_ge_than(const BGPPeer
     const IPv4& other_remote_ip = peer.peerdata()->iptuple().get_peer_addr();
     return (this_remote_ip >= other_remote_ip);     
 }
+
+void 
+BGPPeer::set_md5_password(const string& password) 
+{
+    /* XXX: No PF_KEY support yet. _md5_password is just a placeholder. */
+    _md5_password = password;
+
+    if ("" == _md5_password)
+	comm_set_tcpmd5(_SocketClient->get_sock(), false);
+    else
+	comm_set_tcpmd5(_SocketClient->get_sock(), true);
+}
Index: bgp/peer.hh
===================================================================
RCS file: /usr/local/www/data/cvs/xorp/bgp/peer.hh,v
retrieving revision 1.17
diff -u -p -r1.17 peer.hh
--- bgp/peer.hh	10 Jun 2004 22:40:32 -0000	1.17
+++ bgp/peer.hh	5 Aug 2004 04:11:48 -0000
@@ -229,6 +229,10 @@ private:
     void set_next_peer_state(bool state) {_next_state = state;}
     bool get_next_peer_state() {return _next_state;}
 
+    string _md5_password;
+    void set_md5_password(const string& password);
+    const string& get_md5_password() {return _md5_password;}
+
     bool _activated;
     void set_activate_state(bool state) {_activated = state;}
     bool get_activate_state() {return _activated;}
Index: bgp/xrl_target.cc
===================================================================
RCS file: /usr/local/www/data/cvs/xorp/bgp/xrl_target.cc,v
retrieving revision 1.26
diff -u -p -r1.26 xrl_target.cc
--- bgp/xrl_target.cc	10 Jun 2004 22:40:39 -0000	1.26
+++ bgp/xrl_target.cc	5 Aug 2004 04:11:48 -0000
@@ -286,6 +286,28 @@ XrlBgpTarget::bgp_0_2_set_peer_state(
 }
 
 XrlCmdError 
+XrlBgpTarget::bgp_0_2_set_peer_md5_password(
+	// Input values, 
+	const string&	local_ip, 
+	const uint32_t&	local_port, 
+	const string&	peer_ip, 
+	const uint32_t&	peer_port, 
+	const string& password)
+{
+    debug_msg("local ip %s local port %d peer ip %s peer port %d password %s\n",
+	  local_ip.c_str(), local_port, peer_ip.c_str(), peer_port,
+	  password.c_str());
+
+    Iptuple iptuple(local_ip.c_str(), local_port, peer_ip.c_str(), peer_port);
+
+    if(!_bgp.set_peer_md5_password(iptuple, password))
+	return XrlCmdError::COMMAND_FAILED();
+
+    return XrlCmdError::OKAY();
+}
+
+
+XrlCmdError 
 XrlBgpTarget::bgp_0_2_activate(
 	// Input values, 
 	const string&	local_ip, 
Index: bgp/xrl_target.hh
===================================================================
RCS file: /usr/local/www/data/cvs/xorp/bgp/xrl_target.hh,v
retrieving revision 1.22
diff -u -p -r1.22 xrl_target.hh
--- bgp/xrl_target.hh	10 Jun 2004 22:40:39 -0000	1.22
+++ bgp/xrl_target.hh	5 Aug 2004 04:11:48 -0000
@@ -106,6 +106,14 @@ public:
 	const uint32_t&	peer_port,
 	const bool&	state);
 
+    XrlCmdError bgp_0_2_set_peer_md5_password(
+	// Input values,
+	const string&	local_ip,
+	const uint32_t&	local_port,
+	const string&	peer_ip,
+	const uint32_t&	peer_port,
+	const string&	password);
+
     XrlCmdError bgp_0_2_activate(
 	// Input values,
 	const string&	local_ip,
Index: etc/templates/bgp.tp
===================================================================
RCS file: /usr/local/www/data/cvs/xorp/etc/templates/bgp.tp,v
retrieving revision 1.32
diff -u -p -r1.32 bgp.tp
--- etc/templates/bgp.tp	9 Jun 2004 22:40:49 -0000	1.32
+++ etc/templates/bgp.tp	5 Aug 2004 04:11:48 -0000
@@ -14,6 +14,7 @@ protocols {
 	    next-hop: ipv4;
 	    holdtime: u32 = 120;
 	    enabled: bool = true;
+	    md5-password: txt = "";
 	}
 
 	/*
@@ -87,6 +88,10 @@ protocols {
 		%set:;
 	    }
 
+	    md5-password {
+		%set:;
+	    }
+
 	    as {
 	        %allow-range: $(@) "0" "65535";
 		%set:;
@@ -210,6 +215,10 @@ protocols {
 		%help: short "Enable this peering.";
 	    }
 
+	    md5-password {
+		%help: short "Enable and set the password for TCP-MD5 authentication with this peer.";
+	    }
+
 	    set-parameter {
 	    }
 
Index: xrl/interfaces/bgp.xif
===================================================================
RCS file: /usr/local/www/data/cvs/xorp/xrl/interfaces/bgp.xif,v
retrieving revision 1.18
diff -u -p -r1.18 bgp.xif
--- xrl/interfaces/bgp.xif	30 May 2004 23:17:33 -0000	1.18
+++ xrl/interfaces/bgp.xif	5 Aug 2004 04:11:49 -0000
@@ -131,6 +131,23 @@ interface bgp/0.2 {
 		& toggle:bool
 
 	/**
+         * Set the peer md5 password.
+	 *
+	 * @param local IP address.
+	 * @param local server port.
+	 * @param peer IP address.
+	 * @param peer port.
+         * @param password the password to use for TCP-MD5 authentication.
+	 */
+	set_peer_md5_password \
+		? \
+		local_ip:txt \
+	        & local_port:u32 \
+		& peer_ip:txt \
+		& peer_port:u32 \
+		& password:txt
+
+	/**
          * Enable or disable the peering based on the peer state.
 	 *
 	 * @param local IP address.
Index: xrl/interfaces/bgp_xif.cc
===================================================================
RCS file: /usr/local/www/data/cvs/xorp/xrl/interfaces/bgp_xif.cc,v
retrieving revision 1.26
diff -u -p -r1.26 bgp_xif.cc
--- xrl/interfaces/bgp_xif.cc	10 Jun 2004 22:41:58 -0000	1.26
+++ xrl/interfaces/bgp_xif.cc	5 Aug 2004 04:11:49 -0000
@@ -422,6 +422,46 @@ XrlBgpV0p2Client::unmarshall_set_peer_st
 }
 
 bool
+XrlBgpV0p2Client::send_set_peer_md5_password(
+	const char*	the_tgt,
+	const string&	local_ip,
+	const uint32_t&	local_port,
+	const string&	peer_ip,
+	const uint32_t&	peer_port,
+	const string&	password,
+	const SetPeerMd5PasswordCB&	cb
+)
+{
+    Xrl x(the_tgt, "bgp/0.2/set_peer_md5_password");
+    x.args().add("local_ip", local_ip);
+    x.args().add("local_port", local_port);
+    x.args().add("peer_ip", peer_ip);
+    x.args().add("peer_port", peer_port);
+    x.args().add("password", password);
+    return _sender->send(x, callback(this, &XrlBgpV0p2Client::unmarshall_set_peer_md5_password, cb));
+}
+
+
+/* Unmarshall set_peer_md5_password */
+void
+XrlBgpV0p2Client::unmarshall_set_peer_md5_password(
+	const XrlError&	e,
+	XrlArgs*	a,
+	SetPeerMd5PasswordCB		cb
+)
+{
+    if (e != XrlError::OKAY()) {
+	cb->dispatch(e);
+	return;
+    } else if (a && a->size() != 0) {
+	XLOG_ERROR("Wrong number of arguments (%u != %u)", (uint32_t)a->size(), 0);
+	cb->dispatch(XrlError::BAD_ARGS());
+	return;
+    }
+    cb->dispatch(e);
+}
+
+bool
 XrlBgpV0p2Client::send_activate(
 	const char*	the_tgt,
 	const string&	local_ip,
Index: xrl/interfaces/bgp_xif.hh
===================================================================
RCS file: /usr/local/www/data/cvs/xorp/xrl/interfaces/bgp_xif.hh,v
retrieving revision 1.26
diff -u -p -r1.26 bgp_xif.hh
--- xrl/interfaces/bgp_xif.hh	10 Jun 2004 22:41:58 -0000	1.26
+++ xrl/interfaces/bgp_xif.hh	5 Aug 2004 04:11:49 -0000
@@ -213,6 +213,26 @@ public:
 	const SetPeerStateCB&	cb
     );
 
+    typedef XorpCallback1<void, const XrlError&>::RefPtr SetPeerMd5PasswordCB;
+    /**
+     *  Send Xrl intended to:
+     *
+     *  Set the peer md5 password.
+     *
+     *  @param tgt_name Xrl Target name
+     *
+     *  @param password the password to use for TCP-MD5 authentication.
+     */
+    bool send_set_peer_md5_password(
+	const char*	target_name,
+	const string&	local_ip,
+	const uint32_t&	local_port,
+	const string&	peer_ip,
+	const uint32_t&	peer_port,
+	const string&	password,
+	const SetPeerMd5PasswordCB&	cb
+    );
+
     typedef XorpCallback1<void, const XrlError&>::RefPtr ActivateCB;
     /**
      *  Send Xrl intended to:
@@ -626,6 +646,12 @@ private:
 	SetPeerStateCB		cb
     );
 
+    void unmarshall_set_peer_md5_password(
+	const XrlError&	e,
+	XrlArgs*	a,
+	SetPeerMd5PasswordCB		cb
+    );
+
     void unmarshall_activate(
 	const XrlError&	e,
 	XrlArgs*	a,
Index: xrl/targets/bgp.xrls
===================================================================
RCS file: /usr/local/www/data/cvs/xorp/xrl/targets/bgp.xrls,v
retrieving revision 1.28
diff -u -p -r1.28 bgp.xrls
--- xrl/targets/bgp.xrls	3 Aug 2004 05:21:28 -0000	1.28
+++ xrl/targets/bgp.xrls	5 Aug 2004 04:11:49 -0000
@@ -99,6 +99,13 @@ finder://bgp/bgp/0.2/disable_peer?local_
 finder://bgp/bgp/0.2/set_peer_state?local_ip:txt&local_port:u32&peer_ip:txt&peer_port:u32&toggle:bool
 
 /**
+ *  Set the peer md5 password.
+ *
+ *  @param password the password to use for TCP-MD5 authentication.
+ */
+finder://bgp/bgp/0.2/set_peer_md5_password?local_ip:txt&local_port:u32&peer_ip:txt&peer_port:u32&password:txt
+
+/**
  *  Enable or disable the peering based on the peer state.
  */
 finder://bgp/bgp/0.2/activate?local_ip:txt&local_port:u32&peer_ip:txt&peer_port:u32
Index: xrl/targets/bgp_base.cc
===================================================================
RCS file: /usr/local/www/data/cvs/xorp/xrl/targets/bgp_base.cc,v
retrieving revision 1.29
diff -u -p -r1.29 bgp_base.cc
--- xrl/targets/bgp_base.cc	10 Jun 2004 22:42:08 -0000	1.29
+++ xrl/targets/bgp_base.cc	5 Aug 2004 04:11:49 -0000
@@ -518,6 +518,35 @@ XrlBgpTargetBase::handle_bgp_0_2_set_pee
 }
 
 const XrlCmdError
+XrlBgpTargetBase::handle_bgp_0_2_set_peer_md5_password(const XrlArgs& xa_inputs, XrlArgs* /* pxa_outputs */)
+{
+    if (xa_inputs.size() != 5) {
+	XLOG_ERROR("Wrong number of arguments (%u != %u) handling %s",
+            5, (uint32_t)xa_inputs.size(), "bgp/0.2/set_peer_md5_password");
+	return XrlCmdError::BAD_ARGS();
+    }
+
+    /* Return value declarations */
+    try {
+	XrlCmdError e = bgp_0_2_set_peer_md5_password(
+	    xa_inputs.get_string("local_ip"),
+	    xa_inputs.get_uint32("local_port"),
+	    xa_inputs.get_string("peer_ip"),
+	    xa_inputs.get_uint32("peer_port"),
+	    xa_inputs.get_string("password"));
+	if (e != XrlCmdError::OKAY()) {
+	    XLOG_WARNING("Handling method for %s failed: %s",
+            		 "bgp/0.2/set_peer_md5_password", e.str().c_str());
+	    return e;
+        }
+    } catch (const XrlArgs::XrlAtomNotFound& e) {
+	XLOG_ERROR("Argument not found");
+	return XrlCmdError::BAD_ARGS();
+    }
+    return XrlCmdError::OKAY();
+}
+
+const XrlCmdError
 XrlBgpTargetBase::handle_bgp_0_2_activate(const XrlArgs& xa_inputs, XrlArgs* /* pxa_outputs */)
 {
     if (xa_inputs.size() != 4) {
@@ -1626,6 +1655,10 @@ XrlBgpTargetBase::add_handlers()
 	    callback(this, &XrlBgpTargetBase::handle_bgp_0_2_set_peer_state)) == false) {
 	    XLOG_ERROR("Failed to xrl handler finder://%s/%s", "bgp", "bgp/0.2/set_peer_state");
 	}
+	if (_cmds->add_handler("bgp/0.2/set_peer_md5_password",
+	    callback(this, &XrlBgpTargetBase::handle_bgp_0_2_set_peer_md5_password)) == false) {
+	    XLOG_ERROR("Failed to xrl handler finder://%s/%s", "bgp", "bgp/0.2/set_peer_md5_password");
+	}
 	if (_cmds->add_handler("bgp/0.2/activate",
 	    callback(this, &XrlBgpTargetBase::handle_bgp_0_2_activate)) == false) {
 	    XLOG_ERROR("Failed to xrl handler finder://%s/%s", "bgp", "bgp/0.2/activate");
@@ -1755,6 +1788,7 @@ XrlBgpTargetBase::remove_handlers()
 	_cmds->remove_handler("bgp/0.2/enable_peer");
 	_cmds->remove_handler("bgp/0.2/disable_peer");
 	_cmds->remove_handler("bgp/0.2/set_peer_state");
+	_cmds->remove_handler("bgp/0.2/set_peer_md5_password");
 	_cmds->remove_handler("bgp/0.2/activate");
 	_cmds->remove_handler("bgp/0.2/set_parameter");
 	_cmds->remove_handler("bgp/0.2/next_hop_rewrite_filter");
Index: xrl/targets/bgp_base.hh
===================================================================
RCS file: /usr/local/www/data/cvs/xorp/xrl/targets/bgp_base.hh,v
retrieving revision 1.34
diff -u -p -r1.34 bgp_base.hh
--- xrl/targets/bgp_base.hh	3 Aug 2004 05:21:28 -0000	1.34
+++ xrl/targets/bgp_base.hh	5 Aug 2004 04:11:49 -0000
@@ -235,6 +235,21 @@ protected:
     /**
      *  Pure-virtual function that needs to be implemented to:
      *
+     *  Set the peer md5 password.
+     *
+     *  @param password the password to use for TCP-MD5 authentication.
+     */
+    virtual XrlCmdError bgp_0_2_set_peer_md5_password(
+	// Input values,
+	const string&	local_ip,
+	const uint32_t&	local_port,
+	const string&	peer_ip,
+	const uint32_t&	peer_port,
+	const string&	password) = 0;
+
+    /**
+     *  Pure-virtual function that needs to be implemented to:
+     *
      *  Enable or disable the peering based on the peer state.
      */
     virtual XrlCmdError bgp_0_2_activate(
@@ -671,6 +686,8 @@ private:
 
     const XrlCmdError handle_bgp_0_2_set_peer_state(const XrlArgs& in, XrlArgs* out);
 
+    const XrlCmdError handle_bgp_0_2_set_peer_md5_password(const XrlArgs& in, XrlArgs* out);
+
     const XrlCmdError handle_bgp_0_2_activate(const XrlArgs& in, XrlArgs* out);
 
     const XrlCmdError handle_bgp_0_2_set_parameter(const XrlArgs& in, XrlArgs* out);

--J2SCkAp4GZ/dPZZf--