Looks good. Ethan
On Fri, Sep 23, 2011 at 14:24, Ben Pfaff <[email protected]> wrote: > --- > debian/ovs-monitor-ipsec | 52 ++++++----- > tests/automake.mk | 1 + > tests/ovs-monitor-ipsec.at | 222 > ++++++++++++++++++++++++++++++++++++++++++++ > tests/testsuite.at | 1 + > 4 files changed, 254 insertions(+), 22 deletions(-) > create mode 100644 tests/ovs-monitor-ipsec.at > > diff --git a/debian/ovs-monitor-ipsec b/debian/ovs-monitor-ipsec > index c123188..1eefa8e 100755 > --- a/debian/ovs-monitor-ipsec > +++ b/debian/ovs-monitor-ipsec > @@ -52,7 +52,9 @@ try: > except socket.error, e: > logging.basicConfig() > s_log.warn("failed to connect to syslog (%s)" % e) > +s_log.addHandler(logging.StreamHandler()) > > +root_prefix = '' # Prefix for absolute file names, for > testing. > setkey = "/usr/sbin/setkey" > > # Class to configure the racoon daemon, which handles IKE negotiation > @@ -121,11 +123,12 @@ path certificate "%s"; > self.psk_hosts = {} > self.cert_hosts = {} > > - if not os.path.isdir(self.cert_dir): > + if not os.path.isdir(root_prefix + self.cert_dir): > os.mkdir(self.cert_dir) > > # Clean out stale peer certs from previous runs > - for ovs_cert in glob.glob("%s/ovs-*.pem" % self.cert_dir): > + for ovs_cert in glob.glob("%s%s/ovs-*.pem" > + % (root_prefix, self.cert_dir)): > try: > os.remove(ovs_cert) > except OSError: > @@ -135,20 +138,22 @@ path certificate "%s"; > self.commit() > > def reload(self): > - exitcode = subprocess.call(["/etc/init.d/racoon", "reload"]) > + exitcode = subprocess.call([root_prefix + "/etc/init.d/racoon", > + "reload"]) > if exitcode != 0: > # Racoon is finicky about its configuration file and will > # refuse to start if it sees something it doesn't like > # (e.g., a certificate file doesn't exist). Try restarting > # the process before giving up. > s_log.warning("attempting to restart racoon") > - exitcode = subprocess.call(["/etc/init.d/racoon", "restart"]) > + exitcode = subprocess.call([root_prefix + "/etc/init.d/racoon", > + "restart"]) > if exitcode != 0: > s_log.warning("couldn't reload racoon") > > def commit(self): > # Rewrite the Racoon configuration file > - conf_file = open(self.conf_file, 'w') > + conf_file = open(root_prefix + self.conf_file, 'w') > conf_file.write(Racoon.conf_header % (self.psk_file, self.cert_dir)) > > for host, vals in self.cert_hosts.iteritems(): > @@ -163,7 +168,7 @@ path certificate "%s"; > > # Rewrite the pre-shared keys file; it must only be readable by root. > orig_umask = os.umask(0077) > - psk_file = open(Racoon.psk_file, 'w') > + psk_file = open(root_prefix + Racoon.psk_file, 'w') > os.umask(orig_umask) > > psk_file.write("# Generated by Open vSwitch...do not modify by hand!") > @@ -184,10 +189,10 @@ path certificate "%s"; > def _verify_certs(self, vals): > # Racoon will refuse to start if the certificate files don't > # exist, so verify that they're there. > - if not os.path.isfile(vals["certificate"]): > + if not os.path.isfile(root_prefix + vals["certificate"]): > raise error.Error("'certificate' file does not exist: %s" > % vals["certificate"]) > - elif not os.path.isfile(vals["private_key"]): > + elif not os.path.isfile(root_prefix + vals["private_key"]): > raise error.Error("'private_key' file does not exist: %s" > % vals["private_key"]) > > @@ -197,11 +202,11 @@ path certificate "%s"; > if vals["peer_cert"].find("-----BEGIN CERTIFICATE-----") == -1: > raise error.Error("'peer_cert' is not in valid PEM format") > > - cert = open(vals["certificate"]).read() > + cert = open(root_prefix + vals["certificate"]).read() > if cert.find("-----BEGIN CERTIFICATE-----") == -1: > raise error.Error("'certificate' is not in valid PEM format") > > - cert = open(vals["private_key"]).read() > + cert = open(root_prefix + vals["private_key"]).read() > if cert.find("-----BEGIN RSA PRIVATE KEY-----") == -1: > raise error.Error("'private_key' is not in valid PEM format") > > @@ -226,7 +231,7 @@ path certificate "%s"; > # The peer's certificate comes to us in PEM format as a string. > # Write that string to a file for Racoon to use. > peer_cert_file = "%s/ovs-%s.pem" % (self.cert_dir, host) > - f = open(peer_cert_file, "w") > + f = open(root_prefix + peer_cert_file, "w") > f.write(vals["peer_cert"]) > f.close() > > @@ -240,7 +245,7 @@ path certificate "%s"; > del self.cert_hosts[host] > self.commit() > try: > - os.remove(peer_cert_file) > + os.remove(root_prefix + peer_cert_file) > except OSError: > pass > > @@ -270,10 +275,11 @@ class IPsec: > > def call_setkey(self, cmds): > try: > - p = subprocess.Popen([setkey, "-c"], stdin=subprocess.PIPE, > - stdout=subprocess.PIPE) > + p = subprocess.Popen([root_prefix + setkey, "-c"], > + stdin=subprocess.PIPE, > + stdout=subprocess.PIPE) > except: > - s_log.error("could not call setkey") > + s_log.error("could not call %s%s" % (root_prefix, setkey)) > sys.exit(1) > > # xxx It is safer to pass the string into the communicate() > @@ -289,7 +295,7 @@ class IPsec: > # older entry could be in a "dying" state. > spi_list = [] > host_line = "%s %s" % (local_ip, remote_ip) > - results = self.call_setkey("dump ;").split("\n") > + results = self.call_setkey("dump ;\n").split("\n") > for i in range(len(results)): > if results[i].strip() == host_line: > # The SPI is in the line following the host pair > @@ -300,7 +306,7 @@ class IPsec: > return spi_list > > def sad_flush(self): > - self.call_setkey("flush;") > + self.call_setkey("flush;\n") > > def sad_del(self, local_ip, remote_ip): > # To delete all SAD entries, we should be able to use setkey's > @@ -322,18 +328,18 @@ class IPsec: > self.call_setkey(cmds) > > def spd_flush(self): > - self.call_setkey("spdflush;") > + self.call_setkey("spdflush;\n") > > def spd_add(self, local_ip, remote_ip): > cmds = ("spdadd %s %s gre -P out ipsec esp/transport//require;\n" % > (local_ip, remote_ip)) > - cmds += ("spdadd %s %s gre -P in ipsec esp/transport//require;" % > + cmds += ("spdadd %s %s gre -P in ipsec esp/transport//require;\n" % > (remote_ip, local_ip)) > self.call_setkey(cmds) > > def spd_del(self, local_ip, remote_ip): > cmds = "spddelete %s %s gre -P out;\n" % (local_ip, remote_ip) > - cmds += "spddelete %s %s gre -P in;" % (remote_ip, local_ip) > + cmds += "spddelete %s %s gre -P in;\n" % (remote_ip, local_ip) > self.call_setkey(cmds) > > def add_entry(self, local_ip, remote_ip, vals): > @@ -401,8 +407,10 @@ def usage(): > print "usage: %s [OPTIONS] DATABASE" % sys.argv[0] > print "where DATABASE is a socket on which ovsdb-server is listening." > ovs.daemon.usage() > - print "Other options:" > - print " -h, --help display this help message" > + print """\ > +Other options: > + --root-prefix=DIR Use DIR as alternate root directory (for testing). > + -h, --help Display this help message.""" > sys.exit(0) > > def update_ipsec(ipsec, interfaces, new_interfaces): > diff --git a/tests/automake.mk b/tests/automake.mk > index 9b094de..dcf6026 100644 > --- a/tests/automake.mk > +++ b/tests/automake.mk > @@ -51,6 +51,7 @@ TESTSUITE_AT = \ > tests/ovsdb-monitor.at \ > tests/ovsdb-idl.at \ > tests/ovs-vsctl.at \ > + tests/ovs-monitor-ipsec.at \ > tests/interface-reconfigure.at > TESTSUITE = $(srcdir)/tests/testsuite > DISTCLEANFILES += tests/atconfig tests/atlocal > diff --git a/tests/ovs-monitor-ipsec.at b/tests/ovs-monitor-ipsec.at > new file mode 100644 > index 0000000..ad1e96e > --- /dev/null > +++ b/tests/ovs-monitor-ipsec.at > @@ -0,0 +1,222 @@ > +AT_BANNER([ovs-monitor-ipsec]) > + > +AT_SETUP([ovs-monitor-ipsec]) > +AT_SKIP_IF([test $HAVE_PYTHON = no]) > + > +OVS_PKGDATADIR=`pwd`; export OVS_PKGDATADIR > +cp "$top_srcdir/vswitchd/vswitch.ovsschema" . > + > +trap 'kill `cat pid ovs-monitor-ipsec.pid`' 0 > + > +mkdir etc etc/init.d etc/racoon etc/racoon/certs > +mkdir usr usr/sbin > + > +AT_DATA([etc/init.d/racoon], [dnl > +#! /bin/sh > +echo "racoon: $@" >&3 > +exit 0 > +]) > +chmod +x etc/init.d/racoon > + > +AT_DATA([usr/sbin/setkey], [dnl > +#! /bin/sh > +exec >&3 > +echo "setkey:" > +while read line; do > + echo "> $line" > +done > +]) > +chmod +x usr/sbin/setkey > + > +touch etc/racoon/certs/ovs-stale.pem > + > +ovs_vsctl () { > + ovs-vsctl --timeout=5 --no-wait -vreconnect:ANY:emer --db=unix:socket > "$@" > +} > +trim () { # Removes blank lines and lines starting with # from input. > + sed -e '/^#/d' -e '/^[ ]*$/d' "$@" > +} > + > +### > +### Start ovsdb-server. > +### > +OVS_VSCTL_SETUP > + > +### > +### Start ovs-monitor-ipsec and wait for it to delete the stale cert. > +### > +AT_CHECK( > + [$PYTHON $top_srcdir/debian/ovs-monitor-ipsec "--root-prefix=`pwd`" \ > + "--pidfile-name=`pwd`/ovs-monitor-ipsec.pid" \ > + unix:socket 2>log 3>actions &]) > +AT_CAPTURE_FILE([log]) > +AT_CAPTURE_FILE([actions]) > +OVS_WAIT_UNTIL([test ! -f etc/racoon/certs/ovs-stale.pem]) > + > +### > +### Add an ipsec_gre psk interface and check what ovs-monitor-ipsec does > +### > +AT_CHECK([ovs_vsctl \ > + -- add-br br0 \ > + -- add-port br0 gre0 \ > + -- set interface gre0 type=ipsec_gre \ > + options:remote_ip=1.2.3.4 \ > + options:psk=swordfish]) > +OVS_WAIT_UNTIL([test -f actions && grep 'spdadd 1.2.3.4' actions >/dev/null]) > +AT_CHECK([cat actions], [0], [dnl > +setkey: > +> flush; > +setkey: > +> spdflush; > +racoon: reload > +racoon: reload > +setkey: > +> spdadd 0.0.0.0/0 1.2.3.4 gre -P out ipsec esp/transport//require; > +> spdadd 1.2.3.4 0.0.0.0/0 gre -P in ipsec esp/transport//require; > +]) > +AT_CHECK([trim etc/racoon/psk.txt], [0], [1.2.3.4 swordfish > +]) > +AT_CHECK([trim etc/racoon/racoon.conf], [0], [dnl > +path pre_shared_key "/etc/racoon/psk.txt"; > +path certificate "/etc/racoon/certs"; > +remote 1.2.3.4 { > + exchange_mode main; > + nat_traversal on; > + proposal { > + encryption_algorithm aes; > + hash_algorithm sha1; > + authentication_method pre_shared_key; > + dh_group 2; > + } > +} > +sainfo anonymous { > + pfs_group 2; > + lifetime time 1 hour; > + encryption_algorithm aes; > + authentication_algorithm hmac_sha1, hmac_md5; > + compression_algorithm deflate; > +} > +]) > + > +### > +### Delete the ipsec_gre interface and check what ovs-monitor-ipsec does > +### > +AT_CHECK([ovs_vsctl del-port gre0]) > +OVS_WAIT_UNTIL([test `wc -l < actions` -ge 17]) > +AT_CHECK([sed '1,9d' actions], [0], [dnl > +racoon: reload > +setkey: > +> spddelete 0.0.0.0/0 1.2.3.4 gre -P out; > +> spddelete 1.2.3.4 0.0.0.0/0 gre -P in; > +setkey: > +> dump ; > +setkey: > +> dump ; > +]) > +AT_CHECK([trim etc/racoon/psk.txt], [0], []) > +AT_CHECK([trim etc/racoon/racoon.conf], [0], [dnl > +path pre_shared_key "/etc/racoon/psk.txt"; > +path certificate "/etc/racoon/certs"; > +sainfo anonymous { > + pfs_group 2; > + lifetime time 1 hour; > + encryption_algorithm aes; > + authentication_algorithm hmac_sha1, hmac_md5; > + compression_algorithm deflate; > +} > +]) > + > +### > +### Add ipsec_gre certificate interface and check what ovs-monitor-ipsec does > +### > +AT_DATA([cert.pem], [dnl > +-----BEGIN CERTIFICATE----- > +(not a real certificate) > +-----END CERTIFICATE----- > +]) > +AT_DATA([key.pem], [dnl > +-----BEGIN RSA PRIVATE KEY----- > +(not a real private key) > +-----END RSA PRIVATE KEY----- > +]) > +AT_CHECK([ovs_vsctl \ > + -- add-port br0 gre1 \ > + -- set Interface gre1 type=ipsec_gre \ > + options:remote_ip=2.3.4.5 \ > + options:peer_cert='"-----BEGIN CERTIFICATE----- > +(not a real peer certificate) > +-----END CERTIFICATE----- > +"' \ > + options:certificate='"/cert.pem"' \ > + options:private_key='"/key.pem"']) > +OVS_WAIT_UNTIL([test `wc -l < actions` -ge 21]) > +AT_CHECK([sed '1,17d' actions], [0], [dnl > +racoon: reload > +setkey: > +> spdadd 0.0.0.0/0 2.3.4.5 gre -P out ipsec esp/transport//require; > +> spdadd 2.3.4.5 0.0.0.0/0 gre -P in ipsec esp/transport//require; > +]) > +AT_CHECK([trim etc/racoon/psk.txt], [0], []) > +AT_CHECK([trim etc/racoon/racoon.conf], [0], [dnl > +path pre_shared_key "/etc/racoon/psk.txt"; > +path certificate "/etc/racoon/certs"; > +remote 2.3.4.5 { > + exchange_mode main; > + nat_traversal on; > + ike_frag on; > + certificate_type x509 "/cert.pem" "/key.pem"; > + my_identifier asn1dn; > + peers_identifier asn1dn; > + peers_certfile x509 "/etc/racoon/certs/ovs-2.3.4.5.pem"; > + verify_identifier on; > + proposal { > + encryption_algorithm aes; > + hash_algorithm sha1; > + authentication_method rsasig; > + dh_group 2; > + } > +} > +sainfo anonymous { > + pfs_group 2; > + lifetime time 1 hour; > + encryption_algorithm aes; > + authentication_algorithm hmac_sha1, hmac_md5; > + compression_algorithm deflate; > +} > +]) > +AT_CHECK([cat etc/racoon/certs/ovs-2.3.4.5.pem], [0], [dnl > +-----BEGIN CERTIFICATE----- > +(not a real peer certificate) > +-----END CERTIFICATE----- > +]) > + > +### > +### Delete the ipsec_gre certificate interface. > +### > +AT_CHECK([ovs_vsctl del-port gre1]) > +OVS_WAIT_UNTIL([test `wc -l < actions` -ge 29]) > +AT_CHECK([sed '1,21d' actions], [0], [dnl > +racoon: reload > +setkey: > +> spddelete 0.0.0.0/0 2.3.4.5 gre -P out; > +> spddelete 2.3.4.5 0.0.0.0/0 gre -P in; > +setkey: > +> dump ; > +setkey: > +> dump ; > +]) > +AT_CHECK([trim etc/racoon/psk.txt], [0], []) > +AT_CHECK([trim etc/racoon/racoon.conf], [0], [dnl > +path pre_shared_key "/etc/racoon/psk.txt"; > +path certificate "/etc/racoon/certs"; > +sainfo anonymous { > + pfs_group 2; > + lifetime time 1 hour; > + encryption_algorithm aes; > + authentication_algorithm hmac_sha1, hmac_md5; > + compression_algorithm deflate; > +} > +]) > +AT_CHECK([test ! -f etc/racoon/certs/ovs-2.3.4.5.pem]) > + > +AT_CLEANUP > diff --git a/tests/testsuite.at b/tests/testsuite.at > index ea5208f..19b7802 100644 > --- a/tests/testsuite.at > +++ b/tests/testsuite.at > @@ -64,4 +64,5 @@ m4_include([tests/ofproto.at]) > m4_include([tests/ofproto-dpif.at]) > m4_include([tests/ovsdb.at]) > m4_include([tests/ovs-vsctl.at]) > +m4_include([tests/ovs-monitor-ipsec.at]) > m4_include([tests/interface-reconfigure.at]) > -- > 1.7.4.4 > > _______________________________________________ > dev mailing list > [email protected] > http://openvswitch.org/mailman/listinfo/dev > _______________________________________________ dev mailing list [email protected] http://openvswitch.org/mailman/listinfo/dev
