shill: vpn: Add support for the OpenVPN.TLSAuthContents property.
BUG=chromium-os:28793
TEST=unit tests
Change-Id: Ib168fb506487e87a87fbb8c631d723b4f0241dc7
Reviewed-on: https://gerrit.chromium.org/gerrit/19452
Tested-by: Darin Petkov <petkov@chromium.org>
Reviewed-by: Sam Leffler <sleffler@chromium.org>
Reviewed-by: Paul Stewart <pstew@chromium.org>
Commit-Ready: Darin Petkov <petkov@chromium.org>
diff --git a/openvpn_driver.cc b/openvpn_driver.cc
index 5c1f6a5..6373d87 100644
--- a/openvpn_driver.cc
+++ b/openvpn_driver.cc
@@ -6,6 +6,7 @@
#include <arpa/inet.h>
+#include <base/file_util.h>
#include <base/logging.h>
#include <base/string_number_conversions.h>
#include <base/string_split.h>
@@ -124,7 +125,12 @@
}
void OpenVPNDriver::Cleanup(Service::ConnectState state) {
+ VLOG(2) << __func__ << "(" << Service::ConnectStateToString(state) << ")";
management_server_->Stop();
+ if (!tls_auth_file_.empty()) {
+ file_util::Delete(tls_auth_file_, false);
+ tls_auth_file_.clear();
+ }
if (child_watch_tag_) {
glib_->SourceRemove(child_watch_tag_);
child_watch_tag_ = 0;
@@ -403,11 +409,22 @@
AppendValueOption(flimflam::kOpenVPNProtoProperty, "--proto", options);
AppendValueOption(flimflam::kOpenVPNPortProperty, "--port", options);
AppendValueOption(kOpenVPNTLSAuthProperty, "--tls-auth", options);
-
- // TODO(petkov): Implement this.
- LOG_IF(ERROR, args_.ContainsString(flimflam::kOpenVPNTLSAuthContentsProperty))
- << "Support for --tls-auth not implemented yet.";
-
+ {
+ string contents =
+ args_.LookupString(flimflam::kOpenVPNTLSAuthContentsProperty, "");
+ if (!contents.empty()) {
+ if (!file_util::CreateTemporaryFile(&tls_auth_file_) ||
+ file_util::WriteFile(
+ tls_auth_file_, contents.data(), contents.size()) !=
+ static_cast<int>(contents.size())) {
+ Error::PopulateAndLog(
+ error, Error::kInternalError, "Unable to setup tls-auth file.");
+ return;
+ }
+ options->push_back("--tls-auth");
+ options->push_back(tls_auth_file_.value());
+ }
+ }
AppendValueOption(
flimflam::kOpenVPNTLSRemoteProperty, "--tls-remote", options);
AppendValueOption(flimflam::kOpenVPNCipherProperty, "--cipher", options);
diff --git a/openvpn_driver.h b/openvpn_driver.h
index 1470454..74a156f 100644
--- a/openvpn_driver.h
+++ b/openvpn_driver.h
@@ -9,6 +9,7 @@
#include <string>
#include <vector>
+#include <base/file_path.h>
#include <base/memory/scoped_ptr.h>
#include <gtest/gtest_prod.h> // for FRIEND_TEST
@@ -161,6 +162,7 @@
scoped_ptr<RPCTask> rpc_task_;
std::string tunnel_interface_;
VPNRefPtr device_;
+ FilePath tls_auth_file_;
// The PID of the spawned openvpn process. May be 0 if no process has been
// spawned yet or the process has died.
diff --git a/openvpn_driver_unittest.cc b/openvpn_driver_unittest.cc
index 832cb1a..15a7ed0 100644
--- a/openvpn_driver_unittest.cc
+++ b/openvpn_driver_unittest.cc
@@ -352,7 +352,9 @@
TEST_F(OpenVPNDriverTest, InitOptions) {
static const char kHost[] = "192.168.2.254";
+ static const char kTLSAuthContents[] = "SOME-RANDOM-CONTENTS\n";
args_.SetString(flimflam::kProviderHostProperty, kHost);
+ args_.SetString(flimflam::kOpenVPNTLSAuthContentsProperty, kTLSAuthContents);
SetArgs();
driver_->rpc_task_.reset(new RPCTask(&control_, this));
driver_->tunnel_interface_ = kInterfaceName;
@@ -376,6 +378,12 @@
ExpectInFlags(options, "--dev", kInterfaceName);
EXPECT_EQ("openvpn", options.back());
EXPECT_EQ(kInterfaceName, driver_->tunnel_interface_);
+ ASSERT_FALSE(driver_->tls_auth_file_.empty());
+ ExpectInFlags(options, "--tls-auth", driver_->tls_auth_file_.value());
+ string contents;
+ EXPECT_TRUE(
+ file_util::ReadFileToString(driver_->tls_auth_file_, &contents));
+ EXPECT_EQ(kTLSAuthContents, contents);
}
}
@@ -437,6 +445,8 @@
}
TEST_F(OpenVPNDriverTest, Cleanup) {
+ driver_->Cleanup(Service::kStateIdle); // Ensure no crash.
+
const unsigned int kTag = 123;
const int kPID = 123456;
driver_->child_watch_tag_ = kTag;
@@ -445,6 +455,11 @@
driver_->tunnel_interface_ = kInterfaceName;
driver_->device_ = device_;
driver_->service_ = service_;
+ FilePath tls_auth_file;
+ EXPECT_TRUE(file_util::CreateTemporaryFile(&tls_auth_file));
+ EXPECT_FALSE(tls_auth_file.empty());
+ EXPECT_TRUE(file_util::PathExists(tls_auth_file));
+ driver_->tls_auth_file_ = tls_auth_file;
// Stop will be called twice -- once by Cleanup and once by the destructor.
EXPECT_CALL(*management_server_, Stop()).Times(2);
EXPECT_CALL(glib_, SourceRemove(kTag));
@@ -459,6 +474,8 @@
EXPECT_TRUE(driver_->tunnel_interface_.empty());
EXPECT_FALSE(driver_->device_);
EXPECT_FALSE(driver_->service_);
+ EXPECT_FALSE(file_util::PathExists(tls_auth_file));
+ EXPECT_TRUE(driver_->tls_auth_file_.empty());
}
TEST_F(OpenVPNDriverTest, SpawnOpenVPN) {