Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(318)

Side by Side Diff: ipsec_manager.cc

Issue 6731015: vpn-manager: accept a hostname for remote host (Closed) Base URL: ssh://git@gitrw.chromium.org:9222/vpn-manager.git@master
Patch Set: Created 9 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium OS Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "vpn-manager/ipsec_manager.h" 5 #include "vpn-manager/ipsec_manager.h"
6 6
7 #include <arpa/inet.h> // for inet_ntop and inet_pton 7 #include <arpa/inet.h> // for inet_ntop and inet_pton
8 #include <grp.h> 8 #include <grp.h>
9 #include <netdb.h> // for getaddrinfo 9 #include <netdb.h> // for getaddrinfo
10 #include <sys/types.h> 10 #include <sys/types.h>
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
46 46
47 // Give IPsec layer 2 seconds to shut down before killing it. 47 // Give IPsec layer 2 seconds to shut down before killing it.
48 const int kTermTimeout = 2; 48 const int kTermTimeout = 2;
49 49
50 using ::chromeos::Process; 50 using ::chromeos::Process;
51 using ::chromeos::ProcessImpl; 51 using ::chromeos::ProcessImpl;
52 52
53 IpsecManager::IpsecManager() 53 IpsecManager::IpsecManager()
54 : ServiceManager(kIpsecServiceName), 54 : ServiceManager(kIpsecServiceName),
55 force_local_address_(NULL), 55 force_local_address_(NULL),
56 force_remote_address_(NULL),
56 output_fd_(-1), 57 output_fd_(-1),
57 ike_version_(0), 58 ike_version_(0),
58 ipsec_group_(0), 59 ipsec_group_(0),
59 stateful_container_(kStatefulContainer), 60 stateful_container_(kStatefulContainer),
60 ipsec_run_path_(kIpsecRunPath), 61 ipsec_run_path_(kIpsecRunPath),
61 ipsec_up_file_(kIpsecUpFile), 62 ipsec_up_file_(kIpsecUpFile),
62 starter_pid_file_(kStarterPidFile), 63 starter_pid_file_(kStarterPidFile),
63 starter_(new ProcessImpl) { 64 starter_(new ProcessImpl) {
64 } 65 }
65 66
66 bool IpsecManager::Initialize(int ike_version, 67 bool IpsecManager::Initialize(int ike_version,
67 const std::string& remote_address, 68 const std::string& remote_host,
68 const std::string& psk_file, 69 const std::string& psk_file,
69 const std::string& server_ca_file, 70 const std::string& server_ca_file,
70 const std::string& client_key_file, 71 const std::string& client_key_file,
71 const std::string& client_cert_file) { 72 const std::string& client_cert_file) {
72 if (remote_address.empty()) { 73 if (remote_host.empty()) {
73 LOG(ERROR) << "Missing remote address to IPsec layer"; 74 LOG(ERROR) << "Missing remote host to IPsec layer";
74 return false; 75 return false;
75 } 76 }
76 remote_address_ = remote_address; 77 remote_host_ = remote_host;
77 78
78 if (psk_file.empty()) { 79 if (psk_file.empty()) {
79 if (server_ca_file.empty() && client_key_file.empty() && 80 if (server_ca_file.empty() && client_key_file.empty() &&
80 client_cert_file.empty()) { 81 client_cert_file.empty()) {
81 LOG(ERROR) << "Must specify either PSK or certificates for IPsec layer"; 82 LOG(ERROR) << "Must specify either PSK or certificates for IPsec layer";
82 return false; 83 return false;
83 } 84 }
84 85
85 // Must be a certificate based connection. 86 // Must be a certificate based connection.
86 if (!file_util::PathExists(FilePath(server_ca_file))) { 87 if (!file_util::PathExists(FilePath(server_ca_file))) {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
121 LOG(ERROR) << "Unsupported IKE version" << ike_version; 122 LOG(ERROR) << "Unsupported IKE version" << ike_version;
122 return false; 123 return false;
123 } 124 }
124 ike_version_ = ike_version; 125 ike_version_ = ike_version;
125 126
126 file_util::Delete(FilePath(kIpsecUpFile), false); 127 file_util::Delete(FilePath(kIpsecUpFile), false);
127 128
128 return true; 129 return true;
129 } 130 }
130 131
131 bool IpsecManager::GetLocalAddressForRemote( 132 bool IpsecManager::ConvertSockAddrToIPString(struct sockaddr* socket_address,
132 const std::string& remote_address_text, 133 std::string* output) {
134 // convert local_address to local_address_text.
petkov 2011/03/24 16:52:22 Convert
135 char str[INET6_ADDRSTRLEN] = { 0 };
136 switch (socket_address->sa_family) {
137 case AF_INET:
138 if (!inet_ntop(AF_INET, &reinterpret_cast<sockaddr_in*>(
139 socket_address)->sin_addr, str, INET6_ADDRSTRLEN)) {
140 LOG(ERROR) << "inet_ntop failed";
141 return false;
142 }
143 break;
144 case AF_INET6:
145 if (!inet_ntop(AF_INET6, &reinterpret_cast<sockaddr_in6*>(
146 socket_address)->sin6_addr, str, INET6_ADDRSTRLEN)) {
147 LOG(ERROR) << "inet_ntop failed";
148 return false;
149 }
150 break;
151 default:
152 LOG(ERROR) << "Unknown address family";
153 return false;
154 }
155 *output = str;
156 return true;
157 }
158
159 bool IpsecManager::GetAddressesFromRemoteHost(
160 const std::string& remote_host,
161 std::string* remote_address_text,
133 std::string* local_address_text) { 162 std::string* local_address_text) {
134 static const char kService[] = "80"; 163 static const char kService[] = "80";
135 if (force_local_address_ != NULL) { 164 if (force_local_address_ != NULL) {
136 *local_address_text = force_local_address_; 165 *local_address_text = force_local_address_;
166 *remote_address_text = force_remote_address_;
137 return true; 167 return true;
138 } 168 }
139 struct addrinfo *remote_address; 169 struct addrinfo *remote_address;
140 int s = getaddrinfo(remote_address_text.c_str(), kService, NULL, 170 int s = getaddrinfo(remote_host.c_str(), kService, NULL,
141 &remote_address); 171 &remote_address);
142 if (s != 0) { 172 if (s != 0) {
143 LOG(ERROR) << "getaddrinfo failed: " << gai_strerror(s); 173 LOG(ERROR) << "getaddrinfo failed: " << gai_strerror(s);
144 return false; 174 return false;
145 } 175 }
176 if (!ConvertSockAddrToIPString(remote_address->ai_addr,
177 remote_address_text)) {
178 return false;
179 }
146 int sock = HANDLE_EINTR(socket(AF_INET, SOCK_DGRAM, 0)); 180 int sock = HANDLE_EINTR(socket(AF_INET, SOCK_DGRAM, 0));
147 if (sock < 0) { 181 if (sock < 0) {
148 LOG(ERROR) << "Unable to create socket"; 182 LOG(ERROR) << "Unable to create socket";
149 return false; 183 return false;
150 } 184 }
151 if (HANDLE_EINTR( 185 if (HANDLE_EINTR(
152 connect(sock, remote_address->ai_addr, sizeof(sockaddr))) != 0) { 186 connect(sock, remote_address->ai_addr, sizeof(sockaddr))) != 0) {
153 LOG(ERROR) << "Unable to connect"; 187 LOG(ERROR) << "Unable to connect";
154 HANDLE_EINTR(close(sock)); 188 HANDLE_EINTR(close(sock));
155 return false; 189 return false;
156 } 190 }
157 bool result = false; 191 bool result = false;
158 struct sockaddr local_address; 192 struct sockaddr local_address;
159 socklen_t addr_len = sizeof(local_address); 193 socklen_t addr_len = sizeof(local_address);
160 char str[INET6_ADDRSTRLEN] = { 0 };
161 if (getsockname(sock, &local_address, &addr_len) != 0) { 194 if (getsockname(sock, &local_address, &addr_len) != 0) {
162 int saved_errno = errno; 195 int saved_errno = errno;
163 LOG(ERROR) << "getsockname failed on socket connecting to " 196 LOG(ERROR) << "getsockname failed on socket connecting to "
164 << remote_address_text << ": " << saved_errno; 197 << remote_address_text << ": " << saved_errno;
165 goto error_label; 198 goto error_label;
166 } 199 }
167 // convert local_address to local_address_text. 200 if (!ConvertSockAddrToIPString(&local_address, local_address_text))
168 switch (local_address.sa_family) { 201 goto error_label;
169 case AF_INET:
170 if (!inet_ntop(AF_INET, &reinterpret_cast<sockaddr_in*>(
171 &local_address)->sin_addr, str, INET6_ADDRSTRLEN)) {
172 LOG(ERROR) << "inet_ntop failed on " << remote_address_text;
173 goto error_label;
174 }
175 break;
176 case AF_INET6:
177 if (!inet_ntop(AF_INET6, &reinterpret_cast<sockaddr_in6*>(
178 &local_address)->sin6_addr, str, INET6_ADDRSTRLEN)) {
179 LOG(ERROR) << "inet_ntop failed on " << remote_address_text;
180 goto error_label;
181 }
182 break;
183 default:
184 LOG(ERROR) << "Unknown address family converting " << remote_address_text;
185 goto error_label;
186 }
187 *local_address_text = str;
188 LOG(INFO) << "Remote address " << remote_address_text << " has local address " 202 LOG(INFO) << "Remote address " << remote_address_text << " has local address "
189 << *local_address_text; 203 << *local_address_text;
190 result = true; 204 result = true;
191 205
192 error_label: 206 error_label:
193 HANDLE_EINTR(close(sock)); 207 HANDLE_EINTR(close(sock));
194 freeaddrinfo(remote_address); 208 freeaddrinfo(remote_address);
195 return result; 209 return result;
196 } 210 }
197 211
198 bool IpsecManager::FormatPsk(const FilePath& input_file, 212 bool IpsecManager::FormatPsk(const FilePath& input_file,
199 std::string* formatted) { 213 std::string* formatted) {
200 std::string psk; 214 std::string psk;
201 if (!file_util::ReadFileToString(input_file, &psk)) { 215 if (!file_util::ReadFileToString(input_file, &psk)) {
202 LOG(ERROR) << "Unable to read PSK from " << input_file.value(); 216 LOG(ERROR) << "Unable to read PSK from " << input_file.value();
203 return false; 217 return false;
204 } 218 }
205 std::string local_address; 219 std::string local_address;
206 if (!GetLocalAddressForRemote(remote_address_, &local_address)) { 220 std::string remote_address;
221 if (!GetAddressesFromRemoteHost(remote_host_, &remote_address,
222 &local_address)) {
207 LOG(ERROR) << "Local IP address could not be determined for PSK mode"; 223 LOG(ERROR) << "Local IP address could not be determined for PSK mode";
208 return false; 224 return false;
209 } 225 }
210 TrimWhitespaceASCII(psk, TRIM_TRAILING, &psk); 226 TrimWhitespaceASCII(psk, TRIM_TRAILING, &psk);
211 *formatted = 227 *formatted =
212 StringPrintf("%s %s : PSK \"%s\"\n", local_address.c_str(), 228 StringPrintf("%s %s : PSK \"%s\"\n", local_address.c_str(),
213 remote_address_.c_str(), psk.c_str()); 229 remote_address.c_str(), psk.c_str());
214 return true; 230 return true;
215 } 231 }
216 232
217 void IpsecManager::KillCurrentlyRunning() { 233 void IpsecManager::KillCurrentlyRunning() {
218 if (!file_util::PathExists(FilePath(starter_pid_file_))) 234 if (!file_util::PathExists(FilePath(starter_pid_file_)))
219 return; 235 return;
220 starter_->ResetPidByFile(starter_pid_file_); 236 starter_->ResetPidByFile(starter_pid_file_);
221 if (Process::ProcessExists(starter_->pid())) 237 if (Process::ProcessExists(starter_->pid()))
222 starter_->Reset(0); 238 starter_->Reset(0);
223 else 239 else
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
269 config.append("conn managed\n"); 285 config.append("conn managed\n");
270 AppendStringSetting(&config, "ike", FLAGS_ike); 286 AppendStringSetting(&config, "ike", FLAGS_ike);
271 AppendStringSetting(&config, "keyexchange", 287 AppendStringSetting(&config, "keyexchange",
272 ike_version_ == 1 ? "ikev1" : "ikev2"); 288 ike_version_ == 1 ? "ikev1" : "ikev2");
273 if (!psk_file_.empty()) AppendStringSetting(&config, "authby", "psk"); 289 if (!psk_file_.empty()) AppendStringSetting(&config, "authby", "psk");
274 AppendBoolSetting(&config, "pfs", FLAGS_pfs); 290 AppendBoolSetting(&config, "pfs", FLAGS_pfs);
275 AppendBoolSetting(&config, "rekey", FLAGS_rekey); 291 AppendBoolSetting(&config, "rekey", FLAGS_rekey);
276 AppendStringSetting(&config, "left", "%defaultroute"); 292 AppendStringSetting(&config, "left", "%defaultroute");
277 AppendStringSetting(&config, "leftprotoport", FLAGS_leftprotoport); 293 AppendStringSetting(&config, "leftprotoport", FLAGS_leftprotoport);
278 AppendStringSetting(&config, "leftupdown", IPSEC_UPDOWN); 294 AppendStringSetting(&config, "leftupdown", IPSEC_UPDOWN);
279 AppendStringSetting(&config, "right", remote_address_); 295 AppendStringSetting(&config, "right", remote_host_);
280 AppendStringSetting(&config, "rightprotoport", FLAGS_rightprotoport); 296 AppendStringSetting(&config, "rightprotoport", FLAGS_rightprotoport);
281 AppendStringSetting(&config, "type", FLAGS_type); 297 AppendStringSetting(&config, "type", FLAGS_type);
282 AppendStringSetting(&config, "auto", "start"); 298 AppendStringSetting(&config, "auto", "start");
283 return config; 299 return config;
284 } 300 }
285 301
286 bool IpsecManager::SetIpsecGroup(const FilePath& file_path) { 302 bool IpsecManager::SetIpsecGroup(const FilePath& file_path) {
287 return chown(file_path.value().c_str(), getuid(), ipsec_group_) == 0; 303 return chown(file_path.value().c_str(), getuid(), ipsec_group_) == 0;
288 } 304 }
289 305
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
407 return; 423 return;
408 } 424 }
409 425
410 if (!starter_->Kill(SIGTERM, kTermTimeout)) { 426 if (!starter_->Kill(SIGTERM, kTermTimeout)) {
411 starter_->Kill(SIGKILL, 0); 427 starter_->Kill(SIGKILL, 0);
412 OnStopped(true); 428 OnStopped(true);
413 return; 429 return;
414 } 430 }
415 OnStopped(false); 431 OnStopped(false);
416 } 432 }
OLDNEW
« ipsec_manager.h ('K') | « ipsec_manager.h ('k') | ipsec_manager_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698