openvpn_management_server_unittest.cc revision 3273da7039841d15fc160cc69c036e3124803744
1// Copyright (c) 2012 The Chromium OS Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "shill/openvpn_management_server.h" 6 7#include <netinet/in.h> 8 9#include <chromeos/dbus/service_constants.h> 10#include <gtest/gtest.h> 11 12#include "shill/glib.h" 13#include "shill/key_value_store.h" 14#include "shill/mock_event_dispatcher.h" 15#include "shill/mock_openvpn_driver.h" 16#include "shill/mock_sockets.h" 17 18using base::Bind; 19using base::Unretained; 20using std::string; 21using std::vector; 22using testing::_; 23using testing::Assign; 24using testing::InSequence; 25using testing::Return; 26using testing::ReturnNew; 27 28namespace shill { 29 30namespace { 31MATCHER_P(VoidStringEq, value, "") { 32 return value == reinterpret_cast<const char *>(arg); 33} 34} // namespace {} 35 36class OpenVPNManagementServerTest : public testing::Test { 37 public: 38 OpenVPNManagementServerTest() 39 : server_(&driver_, &glib_) {} 40 41 virtual ~OpenVPNManagementServerTest() {} 42 43 protected: 44 static const int kConnectedSocket; 45 46 void SetSockets() { server_.sockets_ = &sockets_; } 47 void SetDispatcher() { server_.dispatcher_ = &dispatcher_; } 48 void ExpectNotStarted() { EXPECT_FALSE(server_.IsStarted()); } 49 50 void SetConnectedSocket() { 51 server_.connected_socket_ = kConnectedSocket; 52 SetSockets(); 53 } 54 55 void ExpectSend(const string &value) { 56 EXPECT_CALL(sockets_, 57 Send(kConnectedSocket, VoidStringEq(value), value.size(), 0)) 58 .WillOnce(Return(value.size())); 59 } 60 61 void ExpectStaticChallengeResponse() { 62 driver_.args()->SetString(flimflam::kOpenVPNUserProperty, "jojo"); 63 driver_.args()->SetString(flimflam::kOpenVPNPasswordProperty, "yoyo"); 64 driver_.args()->SetString(flimflam::kOpenVPNOTPProperty, "123456"); 65 SetConnectedSocket(); 66 ExpectSend("username \"Auth\" jojo\n"); 67 ExpectSend("password \"Auth\" \"SCRV1:eW95bw==:MTIzNDU2\"\n"); 68 } 69 70 void ExpectAuthenticationResponse() { 71 driver_.args()->SetString(flimflam::kOpenVPNUserProperty, "jojo"); 72 driver_.args()->SetString(flimflam::kOpenVPNPasswordProperty, "yoyo"); 73 SetConnectedSocket(); 74 ExpectSend("username \"Auth\" jojo\n"); 75 ExpectSend("password \"Auth\" \"yoyo\"\n"); 76 } 77 78 void ExpectPINResponse() { 79 driver_.args()->SetString(flimflam::kOpenVPNPinProperty, "987654"); 80 SetConnectedSocket(); 81 ExpectSend("password \"User-Specific TPM Token FOO\" \"987654\"\n"); 82 } 83 84 void ExpectHoldRelease() { 85 SetConnectedSocket(); 86 ExpectSend("hold release\n"); 87 } 88 89 void ExpectRestart() { 90 SetConnectedSocket(); 91 ExpectSend("signal SIGUSR1\n"); 92 } 93 94 InputData CreateInputDataFromString(const string &str) { 95 InputData data( 96 reinterpret_cast<unsigned char *>(const_cast<char *>(str.data())), 97 str.size()); 98 return data; 99 } 100 101 void SendSignal(const string &signal) { 102 server_.SendSignal(signal); 103 } 104 105 void OnInput(InputData *data) { 106 server_.OnInput(data); 107 } 108 109 void ProcessMessage(const string &message) { 110 server_.ProcessMessage(message); 111 } 112 113 bool ProcessSuccessMessage(const string &message) { 114 return server_.ProcessSuccessMessage(message); 115 } 116 117 bool ProcessStateMessage(const string &message) { 118 return server_.ProcessStateMessage(message); 119 } 120 121 bool GetHoldWaiting() { return server_.hold_waiting_; } 122 123 GLib glib_; 124 MockOpenVPNDriver driver_; 125 OpenVPNManagementServer server_; 126 MockSockets sockets_; 127 MockEventDispatcher dispatcher_; 128}; 129 130// static 131const int OpenVPNManagementServerTest::kConnectedSocket = 555; 132 133TEST_F(OpenVPNManagementServerTest, StartStarted) { 134 SetSockets(); 135 EXPECT_TRUE(server_.Start(NULL, NULL, NULL)); 136} 137 138TEST_F(OpenVPNManagementServerTest, StartSocketFail) { 139 EXPECT_CALL(sockets_, Socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) 140 .WillOnce(Return(-1)); 141 EXPECT_FALSE(server_.Start(NULL, &sockets_, NULL)); 142 ExpectNotStarted(); 143} 144 145TEST_F(OpenVPNManagementServerTest, StartGetSockNameFail) { 146 const int kSocket = 123; 147 EXPECT_CALL(sockets_, Socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) 148 .WillOnce(Return(kSocket)); 149 EXPECT_CALL(sockets_, Bind(kSocket, _, _)).WillOnce(Return(0)); 150 EXPECT_CALL(sockets_, Listen(kSocket, 1)).WillOnce(Return(0)); 151 EXPECT_CALL(sockets_, GetSockName(kSocket, _, _)).WillOnce(Return(-1)); 152 EXPECT_CALL(sockets_, Close(kSocket)).WillOnce(Return(0)); 153 EXPECT_FALSE(server_.Start(NULL, &sockets_, NULL)); 154 ExpectNotStarted(); 155} 156 157TEST_F(OpenVPNManagementServerTest, Start) { 158 const int kSocket = 123; 159 EXPECT_CALL(sockets_, Socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) 160 .WillOnce(Return(kSocket)); 161 EXPECT_CALL(sockets_, Bind(kSocket, _, _)).WillOnce(Return(0)); 162 EXPECT_CALL(sockets_, Listen(kSocket, 1)).WillOnce(Return(0)); 163 EXPECT_CALL(sockets_, GetSockName(kSocket, _, _)).WillOnce(Return(0)); 164 EXPECT_CALL(dispatcher_, 165 CreateReadyHandler(kSocket, IOHandler::kModeInput, _)) 166 .WillOnce(ReturnNew<IOHandler>()); 167 vector<string> options; 168 EXPECT_TRUE(server_.Start(&dispatcher_, &sockets_, &options)); 169 EXPECT_EQ(&sockets_, server_.sockets_); 170 EXPECT_EQ(kSocket, server_.socket_); 171 EXPECT_TRUE(server_.ready_handler_.get()); 172 EXPECT_EQ(&dispatcher_, server_.dispatcher_); 173 EXPECT_FALSE(options.empty()); 174} 175 176TEST_F(OpenVPNManagementServerTest, Stop) { 177 SetSockets(); 178 server_.input_handler_.reset(new IOHandler()); 179 const int kConnectedSocket = 234; 180 server_.connected_socket_ = kConnectedSocket; 181 EXPECT_CALL(sockets_, Close(kConnectedSocket)).WillOnce(Return(0)); 182 SetDispatcher(); 183 server_.ready_handler_.reset(new IOHandler()); 184 const int kSocket = 345; 185 server_.socket_ = kSocket; 186 EXPECT_CALL(sockets_, Close(kSocket)).WillOnce(Return(0)); 187 server_.Stop(); 188 EXPECT_FALSE(server_.input_handler_.get()); 189 EXPECT_EQ(-1, server_.connected_socket_); 190 EXPECT_FALSE(server_.dispatcher_); 191 EXPECT_FALSE(server_.ready_handler_.get()); 192 EXPECT_EQ(-1, server_.socket_); 193 ExpectNotStarted(); 194} 195 196TEST_F(OpenVPNManagementServerTest, OnReadyAcceptFail) { 197 const int kSocket = 333; 198 SetSockets(); 199 EXPECT_CALL(sockets_, Accept(kSocket, NULL, NULL)).WillOnce(Return(-1)); 200 server_.OnReady(kSocket); 201 EXPECT_EQ(-1, server_.connected_socket_); 202} 203 204TEST_F(OpenVPNManagementServerTest, OnReady) { 205 const int kSocket = 111; 206 SetConnectedSocket(); 207 SetDispatcher(); 208 EXPECT_CALL(sockets_, Accept(kSocket, NULL, NULL)) 209 .WillOnce(Return(kConnectedSocket)); 210 server_.ready_handler_.reset(new IOHandler()); 211 EXPECT_CALL(dispatcher_, CreateInputHandler(kConnectedSocket, _, _)) 212 .WillOnce(ReturnNew<IOHandler>()); 213 ExpectSend("state on\n"); 214 server_.OnReady(kSocket); 215 EXPECT_EQ(kConnectedSocket, server_.connected_socket_); 216 EXPECT_FALSE(server_.ready_handler_.get()); 217 EXPECT_TRUE(server_.input_handler_.get()); 218} 219 220TEST_F(OpenVPNManagementServerTest, OnInput) { 221 { 222 string s; 223 InputData data = CreateInputDataFromString(s); 224 OnInput(&data); 225 } 226 { 227 string s = "foo\n" 228 ">INFO:...\n" 229 ">PASSWORD:Need 'Auth' SC:user/password/otp\n" 230 ">PASSWORD:Need 'User-Specific TPM Token FOO' ...\n" 231 ">PASSWORD:Verification Failed: .\n" 232 ">STATE:123,RECONNECTING,detail,...,...\n" 233 ">HOLD:Waiting for hold release\n" 234 "SUCCESS: Hold released."; 235 InputData data = CreateInputDataFromString(s); 236 ExpectStaticChallengeResponse(); 237 ExpectPINResponse(); 238 EXPECT_CALL(driver_, Cleanup(Service::kStateFailure)); 239 EXPECT_CALL(driver_, OnReconnecting(_)); 240 EXPECT_FALSE(GetHoldWaiting()); 241 OnInput(&data); 242 EXPECT_TRUE(GetHoldWaiting()); 243 } 244} 245 246TEST_F(OpenVPNManagementServerTest, OnInputStop) { 247 string s = 248 ">PASSWORD:Verification Failed: .\n" 249 ">STATE:123,RECONNECTING,detail,...,..."; 250 InputData data = CreateInputDataFromString(s); 251 SetSockets(); 252 // Stops the server after the first message is processed. 253 EXPECT_CALL(driver_, Cleanup(Service::kStateFailure)) 254 .WillOnce(Assign(&server_.sockets_, reinterpret_cast<Sockets *>(NULL))); 255 // The second message should not be processed. 256 EXPECT_CALL(driver_, OnReconnecting(_)).Times(0); 257 OnInput(&data); 258} 259 260TEST_F(OpenVPNManagementServerTest, ProcessMessage) { 261 ProcessMessage("foo"); 262 ProcessMessage(">INFO:"); 263 264 EXPECT_CALL(driver_, OnReconnecting(_)); 265 ProcessMessage(">STATE:123,RECONNECTING,detail,...,..."); 266} 267 268TEST_F(OpenVPNManagementServerTest, ProcessSuccessMessage) { 269 EXPECT_FALSE(ProcessSuccessMessage("foo")); 270 EXPECT_TRUE(ProcessSuccessMessage("SUCCESS: foo")); 271} 272 273TEST_F(OpenVPNManagementServerTest, ProcessInfoMessage) { 274 EXPECT_FALSE(server_.ProcessInfoMessage("foo")); 275 EXPECT_TRUE(server_.ProcessInfoMessage(">INFO:foo")); 276} 277 278TEST_F(OpenVPNManagementServerTest, ProcessStateMessage) { 279 EXPECT_FALSE(ProcessStateMessage("foo")); 280 EXPECT_TRUE(ProcessStateMessage(">STATE:123,WAIT,detail,...,...")); 281 { 282 InSequence seq; 283 EXPECT_CALL(driver_, 284 OnReconnecting(OpenVPNDriver::kReconnectReasonUnknown)); 285 EXPECT_CALL(driver_, 286 OnReconnecting(OpenVPNDriver::kReconnectReasonTLSError)); 287 } 288 EXPECT_TRUE(ProcessStateMessage(">STATE:123,RECONNECTING,detail,...,...")); 289 EXPECT_TRUE(ProcessStateMessage(">STATE:123,RECONNECTING,tls-error,...,...")); 290} 291 292TEST_F(OpenVPNManagementServerTest, ProcessNeedPasswordMessageAuthSC) { 293 ExpectStaticChallengeResponse(); 294 EXPECT_TRUE( 295 server_.ProcessNeedPasswordMessage( 296 ">PASSWORD:Need 'Auth' SC:user/password/otp")); 297 EXPECT_FALSE(driver_.args()->ContainsString(flimflam::kOpenVPNOTPProperty)); 298} 299 300TEST_F(OpenVPNManagementServerTest, ProcessNeedPasswordMessageAuth) { 301 ExpectAuthenticationResponse(); 302 EXPECT_TRUE( 303 server_.ProcessNeedPasswordMessage( 304 ">PASSWORD:Need 'Auth' username/password")); 305} 306 307TEST_F(OpenVPNManagementServerTest, ProcessNeedPasswordMessageTPMToken) { 308 ExpectPINResponse(); 309 EXPECT_TRUE( 310 server_.ProcessNeedPasswordMessage( 311 ">PASSWORD:Need 'User-Specific TPM Token FOO' ...")); 312} 313 314TEST_F(OpenVPNManagementServerTest, ProcessNeedPasswordMessageUnknown) { 315 EXPECT_FALSE(server_.ProcessNeedPasswordMessage("foo")); 316} 317 318TEST_F(OpenVPNManagementServerTest, ParseNeedPasswordTag) { 319 EXPECT_EQ("", OpenVPNManagementServer::ParseNeedPasswordTag("")); 320 EXPECT_EQ("", OpenVPNManagementServer::ParseNeedPasswordTag(" ")); 321 EXPECT_EQ("", OpenVPNManagementServer::ParseNeedPasswordTag("'")); 322 EXPECT_EQ("", OpenVPNManagementServer::ParseNeedPasswordTag("''")); 323 EXPECT_EQ("bar", 324 OpenVPNManagementServer::ParseNeedPasswordTag("foo'bar'zoo")); 325 EXPECT_EQ("bar", OpenVPNManagementServer::ParseNeedPasswordTag("foo'bar'")); 326 EXPECT_EQ("bar", OpenVPNManagementServer::ParseNeedPasswordTag("'bar'zoo")); 327 EXPECT_EQ("bar", 328 OpenVPNManagementServer::ParseNeedPasswordTag("foo'bar'zoo'moo")); 329} 330 331TEST_F(OpenVPNManagementServerTest, PerformStaticChallengeNoCreds) { 332 EXPECT_CALL(driver_, Cleanup(Service::kStateFailure)).Times(3); 333 server_.PerformStaticChallenge("Auth"); 334 driver_.args()->SetString(flimflam::kOpenVPNUserProperty, "jojo"); 335 server_.PerformStaticChallenge("Auth"); 336 driver_.args()->SetString(flimflam::kOpenVPNPasswordProperty, "yoyo"); 337 server_.PerformStaticChallenge("Auth"); 338} 339 340TEST_F(OpenVPNManagementServerTest, PerformStaticChallenge) { 341 ExpectStaticChallengeResponse(); 342 server_.PerformStaticChallenge("Auth"); 343 EXPECT_FALSE(driver_.args()->ContainsString(flimflam::kOpenVPNOTPProperty)); 344} 345 346TEST_F(OpenVPNManagementServerTest, PerformAuthenticationNoCreds) { 347 EXPECT_CALL(driver_, Cleanup(Service::kStateFailure)).Times(2); 348 server_.PerformAuthentication("Auth"); 349 driver_.args()->SetString(flimflam::kOpenVPNUserProperty, "jojo"); 350 server_.PerformAuthentication("Auth"); 351} 352 353TEST_F(OpenVPNManagementServerTest, PerformAuthentication) { 354 ExpectAuthenticationResponse(); 355 server_.PerformAuthentication("Auth"); 356} 357 358TEST_F(OpenVPNManagementServerTest, ProcessHoldMessage) { 359 EXPECT_FALSE(server_.hold_release_); 360 EXPECT_FALSE(server_.hold_waiting_); 361 362 EXPECT_FALSE(server_.ProcessHoldMessage("foo")); 363 364 EXPECT_TRUE(server_.ProcessHoldMessage(">HOLD:Waiting for hold release")); 365 EXPECT_FALSE(server_.hold_release_); 366 EXPECT_TRUE(server_.hold_waiting_); 367 368 ExpectHoldRelease(); 369 server_.hold_release_ = true; 370 server_.hold_waiting_ = false; 371 EXPECT_TRUE(server_.ProcessHoldMessage(">HOLD:Waiting for hold release")); 372 EXPECT_TRUE(server_.hold_release_); 373 EXPECT_FALSE(server_.hold_waiting_); 374} 375 376TEST_F(OpenVPNManagementServerTest, SupplyTPMTokenNoPIN) { 377 EXPECT_CALL(driver_, Cleanup(Service::kStateFailure)); 378 server_.SupplyTPMToken("User-Specific TPM Token FOO"); 379} 380 381TEST_F(OpenVPNManagementServerTest, SupplyTPMToken) { 382 ExpectPINResponse(); 383 server_.SupplyTPMToken("User-Specific TPM Token FOO"); 384} 385 386TEST_F(OpenVPNManagementServerTest, Send) { 387 const char kMessage[] = "foo\n"; 388 SetConnectedSocket(); 389 ExpectSend(kMessage); 390 server_.Send(kMessage); 391} 392 393TEST_F(OpenVPNManagementServerTest, SendState) { 394 SetConnectedSocket(); 395 ExpectSend("state off\n"); 396 server_.SendState("off"); 397} 398 399TEST_F(OpenVPNManagementServerTest, SendUsername) { 400 SetConnectedSocket(); 401 ExpectSend("username \"Auth\" joesmith\n"); 402 server_.SendUsername("Auth", "joesmith"); 403} 404 405TEST_F(OpenVPNManagementServerTest, SendPassword) { 406 SetConnectedSocket(); 407 ExpectSend("password \"Auth\" \"foo\\\"bar\"\n"); 408 server_.SendPassword("Auth", "foo\"bar"); 409} 410 411TEST_F(OpenVPNManagementServerTest, ProcessFailedPasswordMessage) { 412 EXPECT_FALSE(server_.ProcessFailedPasswordMessage("foo")); 413 EXPECT_CALL(driver_, Cleanup(Service::kStateFailure)); 414 EXPECT_TRUE( 415 server_.ProcessFailedPasswordMessage(">PASSWORD:Verification Failed: .")); 416} 417 418TEST_F(OpenVPNManagementServerTest, SendSignal) { 419 SetConnectedSocket(); 420 ExpectSend("signal SIGUSR2\n"); 421 SendSignal("SIGUSR2"); 422} 423 424TEST_F(OpenVPNManagementServerTest, Restart) { 425 ExpectRestart(); 426 server_.Restart(); 427} 428 429TEST_F(OpenVPNManagementServerTest, SendHoldRelease) { 430 ExpectHoldRelease(); 431 server_.SendHoldRelease(); 432} 433 434TEST_F(OpenVPNManagementServerTest, Hold) { 435 EXPECT_FALSE(server_.hold_release_); 436 EXPECT_FALSE(server_.hold_waiting_); 437 438 server_.ReleaseHold(); 439 EXPECT_TRUE(server_.hold_release_); 440 EXPECT_FALSE(server_.hold_waiting_); 441 442 server_.Hold(); 443 EXPECT_FALSE(server_.hold_release_); 444 EXPECT_FALSE(server_.hold_waiting_); 445 446 server_.hold_waiting_ = true; 447 ExpectHoldRelease(); 448 server_.ReleaseHold(); 449 EXPECT_TRUE(server_.hold_release_); 450 EXPECT_FALSE(server_.hold_waiting_); 451} 452 453TEST_F(OpenVPNManagementServerTest, EscapeToQuote) { 454 EXPECT_EQ("", OpenVPNManagementServer::EscapeToQuote("")); 455 EXPECT_EQ("foo './", OpenVPNManagementServer::EscapeToQuote("foo './")); 456 EXPECT_EQ("\\\\", OpenVPNManagementServer::EscapeToQuote("\\")); 457 EXPECT_EQ("\\\"", OpenVPNManagementServer::EscapeToQuote("\"")); 458 EXPECT_EQ("\\\\\\\"foo\\\\bar\\\"", 459 OpenVPNManagementServer::EscapeToQuote("\\\"foo\\bar\"")); 460} 461 462} // namespace shill 463