vpn-manager: accept a hostname for remote host
Change-Id: Iefe53207cf8df8bfbe32c3b69409348e23ac1bb2
BUG=chromium-os:13472
TEST=connect-vpn with remote host name instead of ip address
Review URL: http://codereview.chromium.org/6731015
diff --git a/ipsec_manager.cc b/ipsec_manager.cc
index 287d62b..73e3966 100644
--- a/ipsec_manager.cc
+++ b/ipsec_manager.cc
@@ -53,6 +53,7 @@
IpsecManager::IpsecManager()
: ServiceManager(kIpsecServiceName),
force_local_address_(NULL),
+ force_remote_address_(NULL),
output_fd_(-1),
ike_version_(0),
ipsec_group_(0),
@@ -64,16 +65,16 @@
}
bool IpsecManager::Initialize(int ike_version,
- const std::string& remote_address,
+ const std::string& remote_host,
const std::string& psk_file,
const std::string& server_ca_file,
const std::string& client_key_file,
const std::string& client_cert_file) {
- if (remote_address.empty()) {
- LOG(ERROR) << "Missing remote address to IPsec layer";
+ if (remote_host.empty()) {
+ LOG(ERROR) << "Missing remote host to IPsec layer";
return false;
}
- remote_address_ = remote_address;
+ remote_host_ = remote_host;
if (psk_file.empty()) {
if (server_ca_file.empty() && client_key_file.empty() &&
@@ -128,21 +129,54 @@
return true;
}
-bool IpsecManager::GetLocalAddressForRemote(
- const std::string& remote_address_text,
+bool IpsecManager::ConvertSockAddrToIPString(
+ const struct sockaddr& socket_address,
+ std::string* output) {
+ char str[INET6_ADDRSTRLEN] = { 0 };
+ switch (socket_address.sa_family) {
+ case AF_INET:
+ if (!inet_ntop(AF_INET, &reinterpret_cast<const sockaddr_in*>(
+ &socket_address)->sin_addr, str, INET6_ADDRSTRLEN)) {
+ LOG(ERROR) << "inet_ntop failed";
+ return false;
+ }
+ break;
+ case AF_INET6:
+ if (!inet_ntop(AF_INET6, &reinterpret_cast<const sockaddr_in6*>(
+ &socket_address)->sin6_addr, str, INET6_ADDRSTRLEN)) {
+ LOG(ERROR) << "inet_ntop failed";
+ return false;
+ }
+ break;
+ default:
+ LOG(ERROR) << "Unknown address family";
+ return false;
+ }
+ *output = str;
+ return true;
+}
+
+bool IpsecManager::GetAddressesFromRemoteHost(
+ const std::string& remote_host,
+ std::string* remote_address_text,
std::string* local_address_text) {
static const char kService[] = "80";
if (force_local_address_ != NULL) {
*local_address_text = force_local_address_;
+ *remote_address_text = force_remote_address_;
return true;
}
struct addrinfo *remote_address;
- int s = getaddrinfo(remote_address_text.c_str(), kService, NULL,
+ int s = getaddrinfo(remote_host.c_str(), kService, NULL,
&remote_address);
if (s != 0) {
LOG(ERROR) << "getaddrinfo failed: " << gai_strerror(s);
return false;
}
+ if (!ConvertSockAddrToIPString(*remote_address->ai_addr,
+ remote_address_text)) {
+ return false;
+ }
int sock = HANDLE_EINTR(socket(AF_INET, SOCK_DGRAM, 0));
if (sock < 0) {
LOG(ERROR) << "Unable to create socket";
@@ -157,34 +191,14 @@
bool result = false;
struct sockaddr local_address;
socklen_t addr_len = sizeof(local_address);
- char str[INET6_ADDRSTRLEN] = { 0 };
if (getsockname(sock, &local_address, &addr_len) != 0) {
int saved_errno = errno;
LOG(ERROR) << "getsockname failed on socket connecting to "
<< remote_address_text << ": " << saved_errno;
goto error_label;
}
- // convert local_address to local_address_text.
- switch (local_address.sa_family) {
- case AF_INET:
- if (!inet_ntop(AF_INET, &reinterpret_cast<sockaddr_in*>(
- &local_address)->sin_addr, str, INET6_ADDRSTRLEN)) {
- LOG(ERROR) << "inet_ntop failed on " << remote_address_text;
- goto error_label;
- }
- break;
- case AF_INET6:
- if (!inet_ntop(AF_INET6, &reinterpret_cast<sockaddr_in6*>(
- &local_address)->sin6_addr, str, INET6_ADDRSTRLEN)) {
- LOG(ERROR) << "inet_ntop failed on " << remote_address_text;
- goto error_label;
- }
- break;
- default:
- LOG(ERROR) << "Unknown address family converting " << remote_address_text;
- goto error_label;
- }
- *local_address_text = str;
+ if (!ConvertSockAddrToIPString(local_address, local_address_text))
+ goto error_label;
LOG(INFO) << "Remote address " << remote_address_text << " has local address "
<< *local_address_text;
result = true;
@@ -203,14 +217,16 @@
return false;
}
std::string local_address;
- if (!GetLocalAddressForRemote(remote_address_, &local_address)) {
+ std::string remote_address;
+ if (!GetAddressesFromRemoteHost(remote_host_, &remote_address,
+ &local_address)) {
LOG(ERROR) << "Local IP address could not be determined for PSK mode";
return false;
}
TrimWhitespaceASCII(psk, TRIM_TRAILING, &psk);
*formatted =
StringPrintf("%s %s : PSK \"%s\"\n", local_address.c_str(),
- remote_address_.c_str(), psk.c_str());
+ remote_address.c_str(), psk.c_str());
return true;
}
@@ -276,7 +292,7 @@
AppendStringSetting(&config, "left", "%defaultroute");
AppendStringSetting(&config, "leftprotoport", FLAGS_leftprotoport);
AppendStringSetting(&config, "leftupdown", IPSEC_UPDOWN);
- AppendStringSetting(&config, "right", remote_address_);
+ AppendStringSetting(&config, "right", remote_host_);
AppendStringSetting(&config, "rightprotoport", FLAGS_rightprotoport);
AppendStringSetting(&config, "type", FLAGS_type);
AppendStringSetting(&config, "auto", "start");
diff --git a/ipsec_manager.h b/ipsec_manager.h
index 9497177..7334405 100644
--- a/ipsec_manager.h
+++ b/ipsec_manager.h
@@ -25,12 +25,12 @@
IpsecManager();
// Initialize the object to control IKE version |ike_version| daemon,
- // connecting to the give |remote_address|, with given paths to
+ // connecting to the give |remote_hostname|, with given paths to
// pre-shared key file |psk_file|, server certificate authority file
// |server_ca_file|, client key file |client_key_file|, and client
// certificate file |client_cert_file|.
bool Initialize(int ike_version,
- const std::string& remote_address,
+ const std::string& remote_hostname,
const std::string& psk_file,
const std::string& server_ca_file,
const std::string& client_key_file,
@@ -54,14 +54,17 @@
FRIEND_TEST(IpsecManagerTest, PollNothingIfRunning);
FRIEND_TEST(IpsecManagerTestIkeV1Psk, FormatPsk);
FRIEND_TEST(IpsecManagerTestIkeV1Psk, FormatStarterConfigFile);
- FRIEND_TEST(IpsecManagerTestIkeV1Psk, GetLocalAddressForRemote);
+ FRIEND_TEST(IpsecManagerTestIkeV1Psk, GetAddressesFromRemoteHost);
FRIEND_TEST(IpsecManagerTestIkeV1Psk, Start);
FRIEND_TEST(IpsecManagerTestIkeV1Psk, StartStarterAlreadyRunning);
FRIEND_TEST(IpsecManagerTestIkeV1Psk, StartStarterNotYetRunning);
FRIEND_TEST(IpsecManagerTestIkeV1Psk, WriteConfigFiles);
- bool GetLocalAddressForRemote(const std::string& remote_address_text,
- std::string* local_address_text);
+ bool ConvertSockAddrToIPString(const struct sockaddr& socket_address,
+ std::string* output);
+ bool GetAddressesFromRemoteHost(const std::string& remote_hostname,
+ std::string* remote_address_text,
+ std::string* local_address_text);
bool FormatPsk(const FilePath& input_file, std::string* formatted);
void KillCurrentlyRunning();
bool WriteConfigFiles();
@@ -70,8 +73,10 @@
bool StartStarter();
bool SetIpsecGroup(const FilePath& file_path);
- // for testing, always return this value from GetLocalAddressForRemote.
+ // for testing, always return these values from
+ // GetAddressesFromRemoteHostname.
const char* force_local_address_;
+ const char* force_remote_address_;
// ipsec daemon stderr pipe file descriptor.
int output_fd_;
// IKE key exchange version to use.
@@ -91,8 +96,8 @@
std::string ipsec_prefix_;
// File containing starter process's process id.
std::string starter_pid_file_;
- // Remote IP of IPsec connection.
- std::string remote_address_;
+ // Remote hostname of IPsec connection.
+ std::string remote_host_;
// File containing the IPsec pre-shared key.
std::string psk_file_;
// File containing the server certificate authority.
diff --git a/ipsec_manager_test.cc b/ipsec_manager_test.cc
index 37701f2..0e67a9c 100644
--- a/ipsec_manager_test.cc
+++ b/ipsec_manager_test.cc
@@ -32,7 +32,7 @@
file_util::CreateDirectory(test_path_);
stateful_container_ = test_path_.Append("etc");
file_util::CreateDirectory(stateful_container_);
- remote_ = "1.2.3.4";
+ remote_ = "vpnserver";
ServiceManager::temp_path_ = new FilePath(test_path_);
psk_file_ = test_path_.Append("psk").value();
server_ca_file_ = test_path_.Append("server.ca").value();
@@ -52,6 +52,7 @@
ipsec_.ipsec_run_path_ = ipsec_run_path_;
ipsec_.ipsec_up_file_ = ipsec_up_file_;
ipsec_.force_local_address_ = "5.6.7.8";
+ ipsec_.force_remote_address_ = "1.2.3.4";
}
void SetStartStarterExpectations(bool already_running);
@@ -183,11 +184,15 @@
TEST_F(IpsecManagerTestIkeV1Psk, Initialize) {
}
-TEST_F(IpsecManagerTestIkeV1Psk, GetLocalAddressForRemote) {
+TEST_F(IpsecManagerTestIkeV1Psk, GetAddressesFromRemoteHost) {
ipsec_.force_local_address_ = NULL;
std::string local_address;
- EXPECT_TRUE(ipsec_.GetLocalAddressForRemote("127.0.0.1", &local_address));
+ std::string remote_address;
+ EXPECT_TRUE(ipsec_.GetAddressesFromRemoteHost("localhost",
+ &remote_address,
+ &local_address));
EXPECT_EQ("127.0.0.1", local_address);
+ EXPECT_EQ("127.0.0.1", remote_address);
}
TEST_F(IpsecManagerTestIkeV1Psk, FormatPsk) {
@@ -230,7 +235,7 @@
"\tleft=%defaultroute\n"
"\tleftprotoport=17/1701\n"
"\tleftupdown=/usr/libexec/l2tpipsec_vpn/pluto_updown\n"
- "\tright=1.2.3.4\n"
+ "\tright=vpnserver\n"
"\trightprotoport=17/1701\n"
"\ttype=transport\n"
"\tauto=start\n";
diff --git a/l2tp_manager.cc b/l2tp_manager.cc
index 7d0e3fa..6b1794d 100644
--- a/l2tp_manager.cc
+++ b/l2tp_manager.cc
@@ -37,8 +37,8 @@
l2tpd_(new ProcessImpl) {
}
-bool L2tpManager::Initialize(const std::string& remote_address) {
- remote_address_ = remote_address;
+bool L2tpManager::Initialize(const std::string& remote_host) {
+ remote_host_ = remote_host;
if (FLAGS_user.empty()) {
LOG(ERROR) << "l2tp layer requires user name";
return false;
@@ -66,7 +66,7 @@
const std::string& ppp_config_path) {
std::string l2tpd_config;
l2tpd_config.append(StringPrintf("[lac %s]\n", kL2tpConnectionName));
- AddString(&l2tpd_config, "lns", remote_address_);
+ AddString(&l2tpd_config, "lns", remote_host_);
AddBool(&l2tpd_config, "require chap", FLAGS_require_chap);
AddBool(&l2tpd_config, "refuse pap", FLAGS_refuse_pap);
AddBool(&l2tpd_config, "require authentication",
diff --git a/l2tp_manager.h b/l2tp_manager.h
index bb86228..b6602f3 100644
--- a/l2tp_manager.h
+++ b/l2tp_manager.h
@@ -26,10 +26,10 @@
public:
L2tpManager();
- // Initialize the object using |remote_address|. Returns false if
+ // Initialize the object using |remote_host|. Returns false if
// an illegal set of parameters has been given. Has no side effects
// other than setting up the object.
- bool Initialize(const std::string& remote_address);
+ bool Initialize(const std::string& remote_host);
virtual bool Start();
virtual void Stop();
@@ -65,8 +65,8 @@
int output_fd_;
// Start time of the l2tp daemon.
base::TimeTicks start_ticks_;
- // Remote address for L2TP connection.
- std::string remote_address_;
+ // Remote host for L2TP connection.
+ std::string remote_host_;
// Last partial line read from output_fd_.
std::string partial_output_line_;
// Path to a file whose existence indicates the ppp device is up.
diff --git a/l2tp_manager_test.cc b/l2tp_manager_test.cc
index a0b115d..90baed3 100644
--- a/l2tp_manager_test.cc
+++ b/l2tp_manager_test.cc
@@ -28,7 +28,7 @@
ServiceManager::temp_path_ = new FilePath(test_path_);
file_util::Delete(test_path_, true);
file_util::CreateDirectory(test_path_);
- remote_ = "1.2.3.4";
+ remote_hostname_ = "vpnserver";
control_path_ = test_path_.Append("control");
pppd_config_path_ = test_path_.Append("pppd.config");
ppp_interface_path_ = test_path_.Append("ppp0");
@@ -38,11 +38,11 @@
l2tp_.ppp_interface_path_ = ppp_interface_path_;
FLAGS_pppd_plugin = "";
FLAGS_user = "me";
- EXPECT_TRUE(l2tp_.Initialize(remote_));
+ EXPECT_TRUE(l2tp_.Initialize(remote_hostname_));
}
protected:
- std::string remote_;
+ std::string remote_hostname_;
FilePath test_path_;
FilePath control_path_;
FilePath pppd_config_path_;
@@ -54,7 +54,7 @@
TEST_F(L2tpManagerTest, FormatL2tpdConfiguration) {
static const char kBaseExpected[] =
"[lac managed]\n"
- "lns = 1.2.3.4\n"
+ "lns = vpnserver\n"
"require chap = yes\n"
"refuse pap = yes\n"
"require authentication = yes\n"
diff --git a/l2tpipsec_vpn.cc b/l2tpipsec_vpn.cc
index 24a57a7..d9264dc 100644
--- a/l2tpipsec_vpn.cc
+++ b/l2tpipsec_vpn.cc
@@ -22,7 +22,7 @@
DEFINE_string(client_cert_file, "", "File with IPsec client certificate");
DEFINE_string(client_key_file, "", "File with IPsec client private key");
DEFINE_string(psk_file, "", "File with IPsec pre-shared key");
-DEFINE_string(remote_address, "", "VPN server address");
+DEFINE_string(remote_host, "", "VPN server hostname");
DEFINE_string(server_ca_file, "", "File with IPsec server CA");
#pragma GCC diagnostic error "-Wstrict-aliasing"
@@ -111,14 +111,14 @@
ServiceManager::InitializeDirectories(&temp_dir);
if (!ipsec.Initialize(1,
- FLAGS_remote_address,
+ FLAGS_remote_host,
FLAGS_psk_file,
FLAGS_server_ca_file,
FLAGS_client_key_file,
FLAGS_client_cert_file)) {
return 1;
}
- if (!l2tp.Initialize(FLAGS_remote_address)) {
+ if (!l2tp.Initialize(FLAGS_remote_host)) {
return 1;
}
ServiceManager::SetLayerOrder(&ipsec, &l2tp);