1 // 2 // Copyright (C) 2012 The Android Open Source Project 3 // 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 // 16 17 #include "shill/vpn/openvpn_management_server.h" 18 19 #include <arpa/inet.h> 20 #include <netinet/in.h> 21 22 #include <base/bind.h> 23 #include <base/strings/string_number_conversions.h> 24 #include <base/strings/string_split.h> 25 #include <base/strings/string_util.h> 26 #include <base/strings/stringprintf.h> 27 #include <brillo/data_encoding.h> 28 #if defined(__ANDROID__) 29 #include <dbus/service_constants.h> 30 #else 31 #include <chromeos/dbus/service_constants.h> 32 #endif // __ANDROID__ 33 34 #include "shill/error.h" 35 #include "shill/event_dispatcher.h" 36 #include "shill/logging.h" 37 #include "shill/net/sockets.h" 38 #include "shill/vpn/openvpn_driver.h" 39 40 using base::Bind; 41 using base::IntToString; 42 using base::SplitString; 43 using base::StringPrintf; 44 using base::Unretained; 45 using std::string; 46 using std::vector; 47 48 namespace shill { 49 50 namespace Logging { 51 static auto kModuleLogScope = ScopeLogger::kVPN; 52 static string ObjectID(OpenVPNManagementServer* o) { 53 return o->GetServiceRpcIdentifier(); 54 } 55 } 56 57 namespace { 58 const char kPasswordTagAuth[] = "Auth"; 59 } // namespace 60 61 const char OpenVPNManagementServer::kStateReconnecting[] = "RECONNECTING"; 62 const char OpenVPNManagementServer::kStateResolve[] = "RESOLVE"; 63 64 OpenVPNManagementServer::OpenVPNManagementServer(OpenVPNDriver* driver) 65 : driver_(driver), 66 sockets_(nullptr), 67 socket_(-1), 68 dispatcher_(nullptr), 69 connected_socket_(-1), 70 hold_waiting_(false), 71 hold_release_(false) {} 72 73 OpenVPNManagementServer::~OpenVPNManagementServer() { 74 OpenVPNManagementServer::Stop(); 75 } 76 77 bool OpenVPNManagementServer::Start(EventDispatcher* dispatcher, 78 Sockets* sockets, 79 vector<vector<string>>* options) { 80 SLOG(this, 2) << __func__; 81 if (IsStarted()) { 82 return true; 83 } 84 85 int socket = sockets->Socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 86 if (socket < 0) { 87 PLOG(ERROR) << "Unable to create management server socket."; 88 return false; 89 } 90 91 struct sockaddr_in addr; 92 socklen_t addrlen = sizeof(addr); 93 memset(&addr, 0, sizeof(addr)); 94 addr.sin_family = AF_INET; 95 addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); 96 if (sockets->Bind( 97 socket, reinterpret_cast<struct sockaddr*>(&addr), addrlen) < 0 || 98 sockets->Listen(socket, 1) < 0 || 99 sockets->GetSockName( 100 socket, reinterpret_cast<struct sockaddr*>(&addr), &addrlen) < 0) { 101 PLOG(ERROR) << "Socket setup failed."; 102 sockets->Close(socket); 103 return false; 104 } 105 106 SLOG(this, 2) << "Listening socket: " << socket; 107 sockets_ = sockets; 108 socket_ = socket; 109 ready_handler_.reset( 110 dispatcher->CreateReadyHandler( 111 socket, IOHandler::kModeInput, 112 Bind(&OpenVPNManagementServer::OnReady, Unretained(this)))); 113 dispatcher_ = dispatcher; 114 115 // Append openvpn management API options. 116 driver_->AppendOption("management", inet_ntoa(addr.sin_addr), 117 IntToString(ntohs(addr.sin_port)), options); 118 driver_->AppendOption("management-client", options); 119 driver_->AppendOption("management-hold", options); 120 hold_release_ = false; 121 hold_waiting_ = false; 122 123 driver_->AppendOption("management-query-passwords", options); 124 if (driver_->AppendValueOption(kOpenVPNStaticChallengeProperty, 125 "static-challenge", 126 options)) { 127 options->back().push_back("1"); // Force echo. 128 } 129 return true; 130 } 131 132 void OpenVPNManagementServer::Stop() { 133 SLOG(this, 2) << __func__; 134 if (!IsStarted()) { 135 return; 136 } 137 state_.clear(); 138 input_handler_.reset(); 139 if (connected_socket_ >= 0) { 140 sockets_->Close(connected_socket_); 141 connected_socket_ = -1; 142 } 143 dispatcher_ = nullptr; 144 ready_handler_.reset(); 145 if (socket_ >= 0) { 146 sockets_->Close(socket_); 147 socket_ = -1; 148 } 149 sockets_ = nullptr; 150 } 151 152 void OpenVPNManagementServer::ReleaseHold() { 153 SLOG(this, 2) << __func__; 154 hold_release_ = true; 155 if (!hold_waiting_) { 156 return; 157 } 158 LOG(INFO) << "Releasing hold."; 159 hold_waiting_ = false; 160 SendHoldRelease(); 161 } 162 163 void OpenVPNManagementServer::Hold() { 164 SLOG(this, 2) << __func__; 165 hold_release_ = false; 166 } 167 168 void OpenVPNManagementServer::Restart() { 169 LOG(INFO) << "Restart."; 170 SendSignal("SIGUSR1"); 171 } 172 173 std::string OpenVPNManagementServer::GetServiceRpcIdentifier() { 174 return driver_->GetServiceRpcIdentifier(); 175 } 176 177 void OpenVPNManagementServer::OnReady(int fd) { 178 SLOG(this, 2) << __func__ << "(" << fd << ")"; 179 connected_socket_ = sockets_->Accept(fd, nullptr, nullptr); 180 if (connected_socket_ < 0) { 181 PLOG(ERROR) << "Connected socket accept failed."; 182 return; 183 } 184 ready_handler_.reset(); 185 input_handler_.reset(dispatcher_->CreateInputHandler( 186 connected_socket_, 187 Bind(&OpenVPNManagementServer::OnInput, Unretained(this)), 188 Bind(&OpenVPNManagementServer::OnInputError, Unretained(this)))); 189 SendState("on"); 190 } 191 192 void OpenVPNManagementServer::OnInput(InputData* data) { 193 SLOG(this, 2) << __func__ << "(" << data->len << ")"; 194 vector<string> messages = SplitString( 195 string(reinterpret_cast<char*>(data->buf), data->len), "\n", 196 base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); 197 for (vector<string>::const_iterator it = messages.begin(); 198 it != messages.end() && IsStarted(); ++it) { 199 ProcessMessage(*it); 200 } 201 } 202 203 void OpenVPNManagementServer::OnInputError(const std::string& error_msg) { 204 LOG(ERROR) << error_msg; 205 driver_->FailService(Service::kFailureInternal, Service::kErrorDetailsNone); 206 } 207 208 void OpenVPNManagementServer::ProcessMessage(const string& message) { 209 SLOG(this, 2) << __func__ << "(" << message << ")"; 210 if (message.empty()) { 211 return; 212 } 213 if (!ProcessInfoMessage(message) && 214 !ProcessNeedPasswordMessage(message) && 215 !ProcessFailedPasswordMessage(message) && 216 !ProcessAuthTokenMessage(message) && 217 !ProcessStateMessage(message) && 218 !ProcessHoldMessage(message) && 219 !ProcessSuccessMessage(message)) { 220 LOG(WARNING) << "Message ignored: " << message; 221 } 222 } 223 224 bool OpenVPNManagementServer::ProcessInfoMessage(const string& message) { 225 if (!base::StartsWith(message, ">INFO:", base::CompareCase::SENSITIVE)) { 226 return false; 227 } 228 LOG(INFO) << message; 229 return true; 230 } 231 232 bool OpenVPNManagementServer::ProcessNeedPasswordMessage( 233 const string& message) { 234 if (!base::StartsWith(message, ">PASSWORD:Need ", 235 base::CompareCase::SENSITIVE)) { 236 return false; 237 } 238 LOG(INFO) << "Processing need-password message."; 239 string tag = ParsePasswordTag(message); 240 if (tag == kPasswordTagAuth) { 241 if (message.find("SC:") != string::npos) { 242 PerformStaticChallenge(tag); 243 } else { 244 PerformAuthentication(tag); 245 } 246 } else if (base::StartsWith(tag, "User-Specific TPM Token", 247 base::CompareCase::SENSITIVE)) { 248 SupplyTPMToken(tag); 249 } else { 250 NOTIMPLEMENTED() << ": Unsupported need-password message: " << message; 251 driver_->FailService(Service::kFailureInternal, Service::kErrorDetailsNone); 252 } 253 return true; 254 } 255 256 // static 257 string OpenVPNManagementServer::ParseSubstring(const string& message, 258 const string& start, 259 const string& end) { 260 SLOG(VPN, nullptr, 2) << __func__ << "(" << message 261 << ", " << start << ", " << end << ")"; 262 DCHECK(!start.empty() && !end.empty()); 263 size_t start_pos = message.find(start); 264 if (start_pos == string::npos) { 265 return string(); 266 } 267 size_t end_pos = message.find(end, start_pos + start.size()); 268 if (end_pos == string::npos) { 269 return string(); 270 } 271 return message.substr(start_pos + start.size(), 272 end_pos - start_pos - start.size()); 273 } 274 275 // static 276 string OpenVPNManagementServer::ParsePasswordTag(const string& message) { 277 return ParseSubstring(message, "'", "'"); 278 } 279 280 // static 281 string OpenVPNManagementServer::ParsePasswordFailedReason( 282 const string& message) { 283 return ParseSubstring(message, "['", "']"); 284 } 285 286 void OpenVPNManagementServer::PerformStaticChallenge(const string& tag) { 287 LOG(INFO) << "Perform static challenge: " << tag; 288 string user = driver_->args()->LookupString(kOpenVPNUserProperty, ""); 289 string password = driver_->args()->LookupString(kOpenVPNPasswordProperty, ""); 290 string otp = driver_->args()->LookupString(kOpenVPNOTPProperty, ""); 291 string token = driver_->args()->LookupString(kOpenVPNTokenProperty, ""); 292 if (user.empty() || (token.empty() && (password.empty() || otp.empty()))) { 293 NOTIMPLEMENTED() << ": Missing credentials:" 294 << (user.empty() ? " no-user" : "") 295 << (token.empty() ? " no-token" : "") 296 << (password.empty() ? " no-password" : "") 297 << (otp.empty() ? " no-otp" : ""); 298 driver_->FailService(Service::kFailureInternal, Service::kErrorDetailsNone); 299 return; 300 } 301 302 string password_encoded; 303 if (!token.empty()) { 304 password_encoded = token; 305 // Don't reuse token. 306 driver_->args()->RemoveString(kOpenVPNTokenProperty); 307 } else { 308 string b64_password(brillo::data_encoding::Base64Encode(password)); 309 string b64_otp(brillo::data_encoding::Base64Encode(otp)); 310 password_encoded = StringPrintf("SCRV1:%s:%s", 311 b64_password.c_str(), 312 b64_otp.c_str()); 313 // Don't reuse OTP. 314 driver_->args()->RemoveString(kOpenVPNOTPProperty); 315 } 316 SendUsername(tag, user); 317 SendPassword(tag, password_encoded); 318 } 319 320 void OpenVPNManagementServer::PerformAuthentication(const string& tag) { 321 LOG(INFO) << "Perform authentication: " << tag; 322 string user = driver_->args()->LookupString(kOpenVPNUserProperty, ""); 323 string password = driver_->args()->LookupString(kOpenVPNPasswordProperty, ""); 324 if (user.empty() || password.empty()) { 325 NOTIMPLEMENTED() << ": Missing credentials:" 326 << (user.empty() ? " no-user" : "") 327 << (password.empty() ? " no-password" : ""); 328 driver_->FailService(Service::kFailureInternal, Service::kErrorDetailsNone); 329 return; 330 } 331 SendUsername(tag, user); 332 SendPassword(tag, password); 333 } 334 335 void OpenVPNManagementServer::SupplyTPMToken(const string& tag) { 336 SLOG(this, 2) << __func__ << "(" << tag << ")"; 337 string pin = driver_->args()->LookupString(kOpenVPNPinProperty, ""); 338 if (pin.empty()) { 339 NOTIMPLEMENTED() << ": Missing PIN."; 340 driver_->FailService(Service::kFailureInternal, Service::kErrorDetailsNone); 341 return; 342 } 343 SendPassword(tag, pin); 344 } 345 346 bool OpenVPNManagementServer::ProcessFailedPasswordMessage( 347 const string& message) { 348 if (!base::StartsWith(message, ">PASSWORD:Verification Failed:", 349 base::CompareCase::SENSITIVE)) { 350 return false; 351 } 352 LOG(INFO) << message; 353 string reason; 354 if (ParsePasswordTag(message) == kPasswordTagAuth) { 355 reason = ParsePasswordFailedReason(message); 356 } 357 driver_->FailService(Service::kFailureConnect, reason); 358 return true; 359 } 360 361 bool OpenVPNManagementServer::ProcessAuthTokenMessage(const string& message) { 362 if (!base::StartsWith(message, ">PASSWORD:Auth-Token:", 363 base::CompareCase::SENSITIVE)) { 364 return false; 365 } 366 LOG(INFO) << "Auth-Token message ignored."; 367 return true; 368 } 369 370 // >STATE:* message support. State messages are of the form: 371 // >STATE:<date>,<state>,<detail>,<local-ip>,<remote-ip> 372 // where: 373 // <date> is the current time (since epoch) in seconds 374 // <state> is one of: 375 // INITIAL, CONNECTING, WAIT, AUTH, GET_CONFIG, ASSIGN_IP, ADD_ROUTES, 376 // CONNECTED, RECONNECTING, EXITING, RESOLVE, TCP_CONNECT 377 // <detail> is a free-form string giving details about the state change 378 // <local-ip> is a dotted-quad for the local IPv4 address (when available) 379 // <remote-ip> is a dotted-quad for the remote IPv4 address (when available) 380 bool OpenVPNManagementServer::ProcessStateMessage(const string& message) { 381 if (!base::StartsWith(message, ">STATE:", base::CompareCase::SENSITIVE)) { 382 return false; 383 } 384 vector<string> details = SplitString(message, ",", base::TRIM_WHITESPACE, 385 base::SPLIT_WANT_ALL); 386 if (details.size() > 1) { 387 state_ = details[1]; 388 LOG(INFO) << "OpenVPN state: " << state_; 389 if (state_ == kStateReconnecting) { 390 OpenVPNDriver::ReconnectReason reason = 391 OpenVPNDriver::kReconnectReasonUnknown; 392 if (details.size() > 2 && details[2] == "tls-error") { 393 reason = OpenVPNDriver::kReconnectReasonTLSError; 394 } 395 driver_->OnReconnecting(reason); 396 } 397 } 398 399 return true; 400 } 401 402 bool OpenVPNManagementServer::ProcessHoldMessage(const string& message) { 403 if (!base::StartsWith(message, ">HOLD:Waiting for hold release", 404 base::CompareCase::SENSITIVE)) { 405 return false; 406 } 407 LOG(INFO) << "Client waiting for hold release."; 408 hold_waiting_ = true; 409 if (hold_release_) { 410 ReleaseHold(); 411 } 412 return true; 413 } 414 415 bool OpenVPNManagementServer::ProcessSuccessMessage(const string& message) { 416 if (!base::StartsWith(message, "SUCCESS: ", base::CompareCase::SENSITIVE)) { 417 return false; 418 } 419 LOG(INFO) << message; 420 return true; 421 } 422 423 // static 424 string OpenVPNManagementServer::EscapeToQuote(const string& str) { 425 string escaped; 426 for (string::const_iterator it = str.begin(); it != str.end(); ++it) { 427 if (*it == '\\' || *it == '"') { 428 escaped += '\\'; 429 } 430 escaped += *it; 431 } 432 return escaped; 433 } 434 435 void OpenVPNManagementServer::Send(const string& data) { 436 SLOG(this, 2) << __func__; 437 ssize_t len = sockets_->Send(connected_socket_, data.data(), data.size(), 0); 438 PLOG_IF(ERROR, len < 0 || static_cast<size_t>(len) != data.size()) 439 << "Send failed."; 440 } 441 442 void OpenVPNManagementServer::SendState(const string& state) { 443 SLOG(this, 2) << __func__ << "(" << state << ")"; 444 Send(StringPrintf("state %s\n", state.c_str())); 445 } 446 447 void OpenVPNManagementServer::SendUsername(const string& tag, 448 const string& username) { 449 SLOG(this, 2) << __func__; 450 Send(StringPrintf("username \"%s\" %s\n", tag.c_str(), username.c_str())); 451 } 452 453 void OpenVPNManagementServer::SendPassword(const string& tag, 454 const string& password) { 455 SLOG(this, 2) << __func__; 456 Send(StringPrintf("password \"%s\" \"%s\"\n", 457 tag.c_str(), 458 EscapeToQuote(password).c_str())); 459 } 460 461 void OpenVPNManagementServer::SendSignal(const string& signal) { 462 SLOG(this, 2) << __func__ << "(" << signal << ")"; 463 Send(StringPrintf("signal %s\n", signal.c_str())); 464 } 465 466 void OpenVPNManagementServer::SendHoldRelease() { 467 SLOG(this, 2) << __func__; 468 Send("hold release\n"); 469 } 470 471 } // namespace shill 472