1c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu//
2c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// Copyright (C) 2012 The Android Open Source Project
3c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu//
4c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// Licensed under the Apache License, Version 2.0 (the "License");
5c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// you may not use this file except in compliance with the License.
6c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// You may obtain a copy of the License at
7c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu//
8c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu//      http://www.apache.org/licenses/LICENSE-2.0
9c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu//
10c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// Unless required by applicable law or agreed to in writing, software
11c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// distributed under the License is distributed on an "AS IS" BASIS,
12c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// See the License for the specific language governing permissions and
14c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// limitations under the License.
15c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu//
161c1152030c1bab9f91450b508777feac8c162e60Darin Petkov
172240e8c03451c6b6f21eb8944d8a1c0747ac10b3Ben Chan#include "shill/vpn/openvpn_management_server.h"
181c1152030c1bab9f91450b508777feac8c162e60Darin Petkov
19271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov#include <netinet/in.h>
20271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov
21289a5a5e18bb1a676b3dfce111af4c2c00c7776eSamuel Tan#if defined(__ANDROID__)
22289a5a5e18bb1a676b3dfce111af4c2c00c7776eSamuel Tan#include <dbus/service_constants.h>
23289a5a5e18bb1a676b3dfce111af4c2c00c7776eSamuel Tan#else
24683942b7e07f1c27a0d89267d5344c2bde7b2b86Darin Petkov#include <chromeos/dbus/service_constants.h>
25289a5a5e18bb1a676b3dfce111af4c2c00c7776eSamuel Tan#endif  // __ANDROID__
261c1152030c1bab9f91450b508777feac8c162e60Darin Petkov#include <gtest/gtest.h>
271c1152030c1bab9f91450b508777feac8c162e60Darin Petkov
281c1152030c1bab9f91450b508777feac8c162e60Darin Petkov#include "shill/key_value_store.h"
29271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov#include "shill/mock_event_dispatcher.h"
308d6b59704591ba9fad57751858835dc332dbdd37Peter Qiu#include "shill/net/mock_sockets.h"
312240e8c03451c6b6f21eb8944d8a1c0747ac10b3Ben Chan#include "shill/vpn/mock_openvpn_driver.h"
32271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov
333273da7039841d15fc160cc69c036e3124803744Darin Petkovusing base::Bind;
343273da7039841d15fc160cc69c036e3124803744Darin Petkovusing base::Unretained;
35271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkovusing std::string;
364646302299227516f4979bb27b46ce6249f6ec2fDarin Petkovusing std::vector;
37271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkovusing testing::_;
38e08084d3bc985fe937e7afb8e6fd08463cb9c792Darin Petkovusing testing::Assign;
390cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkovusing testing::InSequence;
40271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkovusing testing::Return;
41271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkovusing testing::ReturnNew;
421c1152030c1bab9f91450b508777feac8c162e60Darin Petkov
431c1152030c1bab9f91450b508777feac8c162e60Darin Petkovnamespace shill {
441c1152030c1bab9f91450b508777feac8c162e60Darin Petkov
45271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkovnamespace {
46271fe5247103d0b76c48796c6f10ba45c6db59c4Darin PetkovMATCHER_P(VoidStringEq, value, "") {
47e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewart  return value == reinterpret_cast<const char*>(arg);
48271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov}
498a5322984f2d81bcbfd8d44c59747a11bd9b904bAlex Vakulenko}  // namespace
50271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov
511c1152030c1bab9f91450b508777feac8c162e60Darin Petkovclass OpenVPNManagementServerTest : public testing::Test {
521c1152030c1bab9f91450b508777feac8c162e60Darin Petkov public:
531c1152030c1bab9f91450b508777feac8c162e60Darin Petkov  OpenVPNManagementServerTest()
54bad1c10ffd2d4ac14f7bd9f4ef6a8982e711f566mukesh agrawal      : server_(&driver_) {}
551c1152030c1bab9f91450b508777feac8c162e60Darin Petkov
561c1152030c1bab9f91450b508777feac8c162e60Darin Petkov  virtual ~OpenVPNManagementServerTest() {}
571c1152030c1bab9f91450b508777feac8c162e60Darin Petkov
58a42afe3a1621b8262d5404ecfaf200d3d76bd454Darin Petkov protected:
59a42afe3a1621b8262d5404ecfaf200d3d76bd454Darin Petkov  static const int kConnectedSocket;
60a42afe3a1621b8262d5404ecfaf200d3d76bd454Darin Petkov
61271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov  void SetSockets() { server_.sockets_ = &sockets_; }
62271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov  void SetDispatcher() { server_.dispatcher_ = &dispatcher_; }
63ffd33062a8c8240e67d8e6b144b1c40c20e6a700Darin Petkov  void ExpectNotStarted() { EXPECT_FALSE(server_.IsStarted()); }
64271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov
65683942b7e07f1c27a0d89267d5344c2bde7b2b86Darin Petkov  void SetConnectedSocket() {
66683942b7e07f1c27a0d89267d5344c2bde7b2b86Darin Petkov    server_.connected_socket_ = kConnectedSocket;
67683942b7e07f1c27a0d89267d5344c2bde7b2b86Darin Petkov    SetSockets();
68683942b7e07f1c27a0d89267d5344c2bde7b2b86Darin Petkov  }
69683942b7e07f1c27a0d89267d5344c2bde7b2b86Darin Petkov
70e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewart  void ExpectSend(const string& value) {
71683942b7e07f1c27a0d89267d5344c2bde7b2b86Darin Petkov    EXPECT_CALL(sockets_,
72683942b7e07f1c27a0d89267d5344c2bde7b2b86Darin Petkov                Send(kConnectedSocket, VoidStringEq(value), value.size(), 0))
73271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov        .WillOnce(Return(value.size()));
74271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov  }
75271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov
76b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart  void ExpectOTPStaticChallengeResponse() {
777372878af066cc079ad88a7b004ca3f769952de2Ben Chan    driver_.args()->SetString(kOpenVPNUserProperty, "jojo");
787372878af066cc079ad88a7b004ca3f769952de2Ben Chan    driver_.args()->SetString(kOpenVPNPasswordProperty, "yoyo");
797372878af066cc079ad88a7b004ca3f769952de2Ben Chan    driver_.args()->SetString(kOpenVPNOTPProperty, "123456");
80683942b7e07f1c27a0d89267d5344c2bde7b2b86Darin Petkov    SetConnectedSocket();
81683942b7e07f1c27a0d89267d5344c2bde7b2b86Darin Petkov    ExpectSend("username \"Auth\" jojo\n");
82683942b7e07f1c27a0d89267d5344c2bde7b2b86Darin Petkov    ExpectSend("password \"Auth\" \"SCRV1:eW95bw==:MTIzNDU2\"\n");
83683942b7e07f1c27a0d89267d5344c2bde7b2b86Darin Petkov  }
84683942b7e07f1c27a0d89267d5344c2bde7b2b86Darin Petkov
85b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart  void ExpectTokenStaticChallengeResponse() {
86b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart    driver_.args()->SetString(kOpenVPNUserProperty, "jojo");
87b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart    driver_.args()->SetString(kOpenVPNTokenProperty, "toto");
88b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart    SetConnectedSocket();
89b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart    ExpectSend("username \"Auth\" jojo\n");
905351cbdddf2bfb1a8d9f8fea3d571f397248a5d8Paul Stewart    ExpectSend("password \"Auth\" \"toto\"\n");
91b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart  }
92b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart
93daaa553671f46e46dd5737eb67bfbc7c12c89dc2Darin Petkov  void ExpectAuthenticationResponse() {
947372878af066cc079ad88a7b004ca3f769952de2Ben Chan    driver_.args()->SetString(kOpenVPNUserProperty, "jojo");
957372878af066cc079ad88a7b004ca3f769952de2Ben Chan    driver_.args()->SetString(kOpenVPNPasswordProperty, "yoyo");
96daaa553671f46e46dd5737eb67bfbc7c12c89dc2Darin Petkov    SetConnectedSocket();
97daaa553671f46e46dd5737eb67bfbc7c12c89dc2Darin Petkov    ExpectSend("username \"Auth\" jojo\n");
98daaa553671f46e46dd5737eb67bfbc7c12c89dc2Darin Petkov    ExpectSend("password \"Auth\" \"yoyo\"\n");
99daaa553671f46e46dd5737eb67bfbc7c12c89dc2Darin Petkov  }
100daaa553671f46e46dd5737eb67bfbc7c12c89dc2Darin Petkov
101e0d5dd1ef481599ece78f8ff4a84485eb1134b85Darin Petkov  void ExpectPINResponse() {
1027372878af066cc079ad88a7b004ca3f769952de2Ben Chan    driver_.args()->SetString(kOpenVPNPinProperty, "987654");
103e0d5dd1ef481599ece78f8ff4a84485eb1134b85Darin Petkov    SetConnectedSocket();
104e0d5dd1ef481599ece78f8ff4a84485eb1134b85Darin Petkov    ExpectSend("password \"User-Specific TPM Token FOO\" \"987654\"\n");
105e0d5dd1ef481599ece78f8ff4a84485eb1134b85Darin Petkov  }
106e0d5dd1ef481599ece78f8ff4a84485eb1134b85Darin Petkov
107a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin Petkov  void ExpectHoldRelease() {
108a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin Petkov    SetConnectedSocket();
109a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin Petkov    ExpectSend("hold release\n");
110a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin Petkov  }
111a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin Petkov
112a42afe3a1621b8262d5404ecfaf200d3d76bd454Darin Petkov  void ExpectRestart() {
113a42afe3a1621b8262d5404ecfaf200d3d76bd454Darin Petkov    SetConnectedSocket();
114a42afe3a1621b8262d5404ecfaf200d3d76bd454Darin Petkov    ExpectSend("signal SIGUSR1\n");
115a42afe3a1621b8262d5404ecfaf200d3d76bd454Darin Petkov  }
116a42afe3a1621b8262d5404ecfaf200d3d76bd454Darin Petkov
117e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewart  InputData CreateInputDataFromString(const string& str) {
118271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov    InputData data(
119e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewart        reinterpret_cast<unsigned char*>(const_cast<char*>(str.data())),
120271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov        str.size());
121271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov    return data;
122271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov  }
123271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov
124e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewart  void SendSignal(const string& signal) {
125a42afe3a1621b8262d5404ecfaf200d3d76bd454Darin Petkov    server_.SendSignal(signal);
126a42afe3a1621b8262d5404ecfaf200d3d76bd454Darin Petkov  }
127a42afe3a1621b8262d5404ecfaf200d3d76bd454Darin Petkov
128e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewart  void OnInput(InputData* data) {
1290cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov    server_.OnInput(data);
1300cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov  }
1310cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov
132e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewart  void ProcessMessage(const string& message) {
1330cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov    server_.ProcessMessage(message);
1340cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov  }
1350cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov
136e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewart  bool ProcessSuccessMessage(const string& message) {
137a42afe3a1621b8262d5404ecfaf200d3d76bd454Darin Petkov    return server_.ProcessSuccessMessage(message);
138a42afe3a1621b8262d5404ecfaf200d3d76bd454Darin Petkov  }
139683942b7e07f1c27a0d89267d5344c2bde7b2b86Darin Petkov
140e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewart  bool ProcessStateMessage(const string& message) {
1410cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov    return server_.ProcessStateMessage(message);
1420cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov  }
1430cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov
144e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewart  bool ProcessAuthTokenMessage(const string& message) {
14516e70320bf24928d787de97bfb999de8dac9915aDarin Petkov    return server_.ProcessAuthTokenMessage(message);
14616e70320bf24928d787de97bfb999de8dac9915aDarin Petkov  }
14716e70320bf24928d787de97bfb999de8dac9915aDarin Petkov
1480cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov  bool GetHoldWaiting() { return server_.hold_waiting_; }
1490cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov
150aba893217c9cf1dd0d39c4dee89a23d3b1a3f4c1Darin Petkov  static string ParseSubstring(
151e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewart      const string& message, const string& start, const string& end) {
152aba893217c9cf1dd0d39c4dee89a23d3b1a3f4c1Darin Petkov    return OpenVPNManagementServer::ParseSubstring(message, start, end);
153aba893217c9cf1dd0d39c4dee89a23d3b1a3f4c1Darin Petkov  }
154aba893217c9cf1dd0d39c4dee89a23d3b1a3f4c1Darin Petkov
155e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewart  static string ParsePasswordTag(const string& message) {
156aba893217c9cf1dd0d39c4dee89a23d3b1a3f4c1Darin Petkov    return OpenVPNManagementServer::ParsePasswordTag(message);
157aba893217c9cf1dd0d39c4dee89a23d3b1a3f4c1Darin Petkov  }
158aba893217c9cf1dd0d39c4dee89a23d3b1a3f4c1Darin Petkov
159e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewart  static string ParsePasswordFailedReason(const string& message) {
160aba893217c9cf1dd0d39c4dee89a23d3b1a3f4c1Darin Petkov    return OpenVPNManagementServer::ParsePasswordFailedReason(message);
161aba893217c9cf1dd0d39c4dee89a23d3b1a3f4c1Darin Petkov  }
162aba893217c9cf1dd0d39c4dee89a23d3b1a3f4c1Darin Petkov
163e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewart  void SetClientState(const string& state) {
1641c049c794175356e5b6c2b6bbb5ef4a12fbfe9a3Darin Petkov    server_.state_ = state;
1651c049c794175356e5b6c2b6bbb5ef4a12fbfe9a3Darin Petkov  }
1661c049c794175356e5b6c2b6bbb5ef4a12fbfe9a3Darin Petkov
1671c1152030c1bab9f91450b508777feac8c162e60Darin Petkov  MockOpenVPNDriver driver_;
168271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov  MockSockets sockets_;
169271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov  MockEventDispatcher dispatcher_;
1707efde5b3b20f36716b10bdd9691823443704caf1mukesh agrawal  OpenVPNManagementServer server_;  // Destroy before anything it references.
1711c1152030c1bab9f91450b508777feac8c162e60Darin Petkov};
1721c1152030c1bab9f91450b508777feac8c162e60Darin Petkov
173683942b7e07f1c27a0d89267d5344c2bde7b2b86Darin Petkov// static
174683942b7e07f1c27a0d89267d5344c2bde7b2b86Darin Petkovconst int OpenVPNManagementServerTest::kConnectedSocket = 555;
175683942b7e07f1c27a0d89267d5344c2bde7b2b86Darin Petkov
176271fe5247103d0b76c48796c6f10ba45c6db59c4Darin PetkovTEST_F(OpenVPNManagementServerTest, StartStarted) {
177271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov  SetSockets();
1784168b2c8d57755ea6b16763745379e0529541a3fBen Chan  EXPECT_TRUE(server_.Start(nullptr, nullptr, nullptr));
179271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov}
180271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov
181271fe5247103d0b76c48796c6f10ba45c6db59c4Darin PetkovTEST_F(OpenVPNManagementServerTest, StartSocketFail) {
182271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov  EXPECT_CALL(sockets_, Socket(AF_INET, SOCK_STREAM, IPPROTO_TCP))
183271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov      .WillOnce(Return(-1));
1844168b2c8d57755ea6b16763745379e0529541a3fBen Chan  EXPECT_FALSE(server_.Start(nullptr, &sockets_, nullptr));
185271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov  ExpectNotStarted();
186271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov}
187271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov
188271fe5247103d0b76c48796c6f10ba45c6db59c4Darin PetkovTEST_F(OpenVPNManagementServerTest, StartGetSockNameFail) {
189271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov  const int kSocket = 123;
190271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov  EXPECT_CALL(sockets_, Socket(AF_INET, SOCK_STREAM, IPPROTO_TCP))
191271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov      .WillOnce(Return(kSocket));
192271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov  EXPECT_CALL(sockets_, Bind(kSocket, _, _)).WillOnce(Return(0));
193271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov  EXPECT_CALL(sockets_, Listen(kSocket, 1)).WillOnce(Return(0));
194271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov  EXPECT_CALL(sockets_, GetSockName(kSocket, _, _)).WillOnce(Return(-1));
195271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov  EXPECT_CALL(sockets_, Close(kSocket)).WillOnce(Return(0));
1964168b2c8d57755ea6b16763745379e0529541a3fBen Chan  EXPECT_FALSE(server_.Start(nullptr, &sockets_, nullptr));
197271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov  ExpectNotStarted();
198271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov}
199271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov
20078f6326aeee06b6684ac545e956e35facbd4b2faDarin PetkovTEST_F(OpenVPNManagementServerTest, Start) {
201406c473d5680f42b067dbda0a9b011b162130effPaul Stewart  const string kStaticChallenge = "static-challenge";
2027372878af066cc079ad88a7b004ca3f769952de2Ben Chan  driver_.args()->SetString(kOpenVPNStaticChallengeProperty, kStaticChallenge);
203271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov  const int kSocket = 123;
204271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov  EXPECT_CALL(sockets_, Socket(AF_INET, SOCK_STREAM, IPPROTO_TCP))
205271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov      .WillOnce(Return(kSocket));
206271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov  EXPECT_CALL(sockets_, Bind(kSocket, _, _)).WillOnce(Return(0));
207271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov  EXPECT_CALL(sockets_, Listen(kSocket, 1)).WillOnce(Return(0));
208271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov  EXPECT_CALL(sockets_, GetSockName(kSocket, _, _)).WillOnce(Return(0));
209271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov  EXPECT_CALL(dispatcher_,
2103273da7039841d15fc160cc69c036e3124803744Darin Petkov              CreateReadyHandler(kSocket, IOHandler::kModeInput, _))
211271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov      .WillOnce(ReturnNew<IOHandler>());
212406c473d5680f42b067dbda0a9b011b162130effPaul Stewart  vector<vector<string>> options;
2134646302299227516f4979bb27b46ce6249f6ec2fDarin Petkov  EXPECT_TRUE(server_.Start(&dispatcher_, &sockets_, &options));
214271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov  EXPECT_EQ(&sockets_, server_.sockets_);
215271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov  EXPECT_EQ(kSocket, server_.socket_);
216271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov  EXPECT_TRUE(server_.ready_handler_.get());
217271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov  EXPECT_EQ(&dispatcher_, server_.dispatcher_);
218406c473d5680f42b067dbda0a9b011b162130effPaul Stewart  vector<vector<string>> expected_options {
219b26347a48e976a890210bb5fcc28892ac7df42e9Paul Stewart      { "management", "127.0.0.1", "0" },
220b26347a48e976a890210bb5fcc28892ac7df42e9Paul Stewart      { "management-client" },
221b26347a48e976a890210bb5fcc28892ac7df42e9Paul Stewart      { "management-hold" },
222b26347a48e976a890210bb5fcc28892ac7df42e9Paul Stewart      { "management-query-passwords" },
223b26347a48e976a890210bb5fcc28892ac7df42e9Paul Stewart      { "static-challenge", kStaticChallenge, "1" }
224406c473d5680f42b067dbda0a9b011b162130effPaul Stewart  };
225406c473d5680f42b067dbda0a9b011b162130effPaul Stewart  EXPECT_EQ(expected_options, options);
226271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov}
227271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov
228271fe5247103d0b76c48796c6f10ba45c6db59c4Darin PetkovTEST_F(OpenVPNManagementServerTest, Stop) {
2291c049c794175356e5b6c2b6bbb5ef4a12fbfe9a3Darin Petkov  EXPECT_TRUE(server_.state().empty());
230271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov  SetSockets();
231271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov  server_.input_handler_.reset(new IOHandler());
232271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov  const int kConnectedSocket = 234;
233271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov  server_.connected_socket_ = kConnectedSocket;
234271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov  EXPECT_CALL(sockets_, Close(kConnectedSocket)).WillOnce(Return(0));
235271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov  SetDispatcher();
236271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov  server_.ready_handler_.reset(new IOHandler());
237271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov  const int kSocket = 345;
238271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov  server_.socket_ = kSocket;
2391c049c794175356e5b6c2b6bbb5ef4a12fbfe9a3Darin Petkov  SetClientState(OpenVPNManagementServer::kStateReconnecting);
240271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov  EXPECT_CALL(sockets_, Close(kSocket)).WillOnce(Return(0));
241271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov  server_.Stop();
242271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov  EXPECT_FALSE(server_.input_handler_.get());
243271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov  EXPECT_EQ(-1, server_.connected_socket_);
244271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov  EXPECT_FALSE(server_.dispatcher_);
245271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov  EXPECT_FALSE(server_.ready_handler_.get());
246271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov  EXPECT_EQ(-1, server_.socket_);
2471c049c794175356e5b6c2b6bbb5ef4a12fbfe9a3Darin Petkov  EXPECT_TRUE(server_.state().empty());
248271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov  ExpectNotStarted();
249271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov}
250271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov
251271fe5247103d0b76c48796c6f10ba45c6db59c4Darin PetkovTEST_F(OpenVPNManagementServerTest, OnReadyAcceptFail) {
252271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov  const int kSocket = 333;
253271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov  SetSockets();
2544168b2c8d57755ea6b16763745379e0529541a3fBen Chan  EXPECT_CALL(sockets_, Accept(kSocket, nullptr, nullptr)).WillOnce(Return(-1));
255271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov  server_.OnReady(kSocket);
256271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov  EXPECT_EQ(-1, server_.connected_socket_);
257271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov}
258271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov
259271fe5247103d0b76c48796c6f10ba45c6db59c4Darin PetkovTEST_F(OpenVPNManagementServerTest, OnReady) {
260271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov  const int kSocket = 111;
261683942b7e07f1c27a0d89267d5344c2bde7b2b86Darin Petkov  SetConnectedSocket();
262271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov  SetDispatcher();
2634168b2c8d57755ea6b16763745379e0529541a3fBen Chan  EXPECT_CALL(sockets_, Accept(kSocket, nullptr, nullptr))
264271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov      .WillOnce(Return(kConnectedSocket));
265271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov  server_.ready_handler_.reset(new IOHandler());
2663273da7039841d15fc160cc69c036e3124803744Darin Petkov  EXPECT_CALL(dispatcher_, CreateInputHandler(kConnectedSocket, _, _))
267271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov      .WillOnce(ReturnNew<IOHandler>());
268683942b7e07f1c27a0d89267d5344c2bde7b2b86Darin Petkov  ExpectSend("state on\n");
269271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov  server_.OnReady(kSocket);
270271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov  EXPECT_EQ(kConnectedSocket, server_.connected_socket_);
271271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov  EXPECT_FALSE(server_.ready_handler_.get());
272271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov  EXPECT_TRUE(server_.input_handler_.get());
273271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov}
274271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov
275271fe5247103d0b76c48796c6f10ba45c6db59c4Darin PetkovTEST_F(OpenVPNManagementServerTest, OnInput) {
276271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov  {
277271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov    string s;
278271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov    InputData data = CreateInputDataFromString(s);
2790cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov    OnInput(&data);
280271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov  }
281271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov  {
282271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov    string s = "foo\n"
283271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov        ">INFO:...\n"
284683942b7e07f1c27a0d89267d5344c2bde7b2b86Darin Petkov        ">PASSWORD:Need 'Auth' SC:user/password/otp\n"
285e0d5dd1ef481599ece78f8ff4a84485eb1134b85Darin Petkov        ">PASSWORD:Need 'User-Specific TPM Token FOO' ...\n"
2860440b9b420d3a532af111b86c5c7c6cb87bc269aDarin Petkov        ">PASSWORD:Verification Failed: .\n"
28716e70320bf24928d787de97bfb999de8dac9915aDarin Petkov        ">PASSWORD:Auth-Token:ToKeN==\n"
288a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin Petkov        ">STATE:123,RECONNECTING,detail,...,...\n"
289a42afe3a1621b8262d5404ecfaf200d3d76bd454Darin Petkov        ">HOLD:Waiting for hold release\n"
290a42afe3a1621b8262d5404ecfaf200d3d76bd454Darin Petkov        "SUCCESS: Hold released.";
291271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov    InputData data = CreateInputDataFromString(s);
292b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart    ExpectOTPStaticChallengeResponse();
293e0d5dd1ef481599ece78f8ff4a84485eb1134b85Darin Petkov    ExpectPINResponse();
2941c049c794175356e5b6c2b6bbb5ef4a12fbfe9a3Darin Petkov    EXPECT_CALL(driver_, FailService(Service::kFailureConnect,
2951c049c794175356e5b6c2b6bbb5ef4a12fbfe9a3Darin Petkov                                     Service::kErrorDetailsNone));
2960cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov    EXPECT_CALL(driver_, OnReconnecting(_));
2970cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov    EXPECT_FALSE(GetHoldWaiting());
2980cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov    OnInput(&data);
2990cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov    EXPECT_TRUE(GetHoldWaiting());
300271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov  }
301271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov}
302271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov
303e08084d3bc985fe937e7afb8e6fd08463cb9c792Darin PetkovTEST_F(OpenVPNManagementServerTest, OnInputStop) {
304e08084d3bc985fe937e7afb8e6fd08463cb9c792Darin Petkov  string s =
305e08084d3bc985fe937e7afb8e6fd08463cb9c792Darin Petkov      ">PASSWORD:Verification Failed: .\n"
306e08084d3bc985fe937e7afb8e6fd08463cb9c792Darin Petkov      ">STATE:123,RECONNECTING,detail,...,...";
307e08084d3bc985fe937e7afb8e6fd08463cb9c792Darin Petkov  InputData data = CreateInputDataFromString(s);
308e08084d3bc985fe937e7afb8e6fd08463cb9c792Darin Petkov  SetSockets();
309e08084d3bc985fe937e7afb8e6fd08463cb9c792Darin Petkov  // Stops the server after the first message is processed.
3101c049c794175356e5b6c2b6bbb5ef4a12fbfe9a3Darin Petkov  EXPECT_CALL(driver_, FailService(Service::kFailureConnect,
3111c049c794175356e5b6c2b6bbb5ef4a12fbfe9a3Darin Petkov                                   Service::kErrorDetailsNone))
3124168b2c8d57755ea6b16763745379e0529541a3fBen Chan      .WillOnce(Assign(&server_.sockets_, nullptr));
313e08084d3bc985fe937e7afb8e6fd08463cb9c792Darin Petkov  // The second message should not be processed.
3140cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov  EXPECT_CALL(driver_, OnReconnecting(_)).Times(0);
3150cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov  OnInput(&data);
316e08084d3bc985fe937e7afb8e6fd08463cb9c792Darin Petkov}
317e08084d3bc985fe937e7afb8e6fd08463cb9c792Darin Petkov
318271fe5247103d0b76c48796c6f10ba45c6db59c4Darin PetkovTEST_F(OpenVPNManagementServerTest, ProcessMessage) {
3190cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov  ProcessMessage("foo");
3200cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov  ProcessMessage(">INFO:");
321271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov
3220cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov  EXPECT_CALL(driver_, OnReconnecting(_));
3230cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov  ProcessMessage(">STATE:123,RECONNECTING,detail,...,...");
324271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov}
325271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov
326a42afe3a1621b8262d5404ecfaf200d3d76bd454Darin PetkovTEST_F(OpenVPNManagementServerTest, ProcessSuccessMessage) {
327a42afe3a1621b8262d5404ecfaf200d3d76bd454Darin Petkov  EXPECT_FALSE(ProcessSuccessMessage("foo"));
328a42afe3a1621b8262d5404ecfaf200d3d76bd454Darin Petkov  EXPECT_TRUE(ProcessSuccessMessage("SUCCESS: foo"));
329a42afe3a1621b8262d5404ecfaf200d3d76bd454Darin Petkov}
330a42afe3a1621b8262d5404ecfaf200d3d76bd454Darin Petkov
331271fe5247103d0b76c48796c6f10ba45c6db59c4Darin PetkovTEST_F(OpenVPNManagementServerTest, ProcessInfoMessage) {
332271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov  EXPECT_FALSE(server_.ProcessInfoMessage("foo"));
333a42afe3a1621b8262d5404ecfaf200d3d76bd454Darin Petkov  EXPECT_TRUE(server_.ProcessInfoMessage(">INFO:foo"));
334271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov}
335271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov
336271fe5247103d0b76c48796c6f10ba45c6db59c4Darin PetkovTEST_F(OpenVPNManagementServerTest, ProcessStateMessage) {
3371c049c794175356e5b6c2b6bbb5ef4a12fbfe9a3Darin Petkov  EXPECT_TRUE(server_.state().empty());
3380cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov  EXPECT_FALSE(ProcessStateMessage("foo"));
3391c049c794175356e5b6c2b6bbb5ef4a12fbfe9a3Darin Petkov  EXPECT_TRUE(server_.state().empty());
3400cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov  EXPECT_TRUE(ProcessStateMessage(">STATE:123,WAIT,detail,...,..."));
3411c049c794175356e5b6c2b6bbb5ef4a12fbfe9a3Darin Petkov  EXPECT_EQ("WAIT", server_.state());
3420cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov  {
3430cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov    InSequence seq;
3440cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov    EXPECT_CALL(driver_,
3450cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov                OnReconnecting(OpenVPNDriver::kReconnectReasonUnknown));
3460cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov    EXPECT_CALL(driver_,
3470cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov                OnReconnecting(OpenVPNDriver::kReconnectReasonTLSError));
3480cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov  }
3490cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov  EXPECT_TRUE(ProcessStateMessage(">STATE:123,RECONNECTING,detail,...,..."));
3501c049c794175356e5b6c2b6bbb5ef4a12fbfe9a3Darin Petkov  EXPECT_EQ(OpenVPNManagementServer::kStateReconnecting, server_.state());
3510cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov  EXPECT_TRUE(ProcessStateMessage(">STATE:123,RECONNECTING,tls-error,...,..."));
352271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov}
353271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov
354683942b7e07f1c27a0d89267d5344c2bde7b2b86Darin PetkovTEST_F(OpenVPNManagementServerTest, ProcessNeedPasswordMessageAuthSC) {
355b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart  ExpectOTPStaticChallengeResponse();
356683942b7e07f1c27a0d89267d5344c2bde7b2b86Darin Petkov  EXPECT_TRUE(
357683942b7e07f1c27a0d89267d5344c2bde7b2b86Darin Petkov      server_.ProcessNeedPasswordMessage(
358683942b7e07f1c27a0d89267d5344c2bde7b2b86Darin Petkov          ">PASSWORD:Need 'Auth' SC:user/password/otp"));
3597372878af066cc079ad88a7b004ca3f769952de2Ben Chan  EXPECT_FALSE(driver_.args()->ContainsString(kOpenVPNOTPProperty));
360683942b7e07f1c27a0d89267d5344c2bde7b2b86Darin Petkov}
361683942b7e07f1c27a0d89267d5344c2bde7b2b86Darin Petkov
362daaa553671f46e46dd5737eb67bfbc7c12c89dc2Darin PetkovTEST_F(OpenVPNManagementServerTest, ProcessNeedPasswordMessageAuth) {
363daaa553671f46e46dd5737eb67bfbc7c12c89dc2Darin Petkov  ExpectAuthenticationResponse();
364daaa553671f46e46dd5737eb67bfbc7c12c89dc2Darin Petkov  EXPECT_TRUE(
365daaa553671f46e46dd5737eb67bfbc7c12c89dc2Darin Petkov      server_.ProcessNeedPasswordMessage(
366daaa553671f46e46dd5737eb67bfbc7c12c89dc2Darin Petkov          ">PASSWORD:Need 'Auth' username/password"));
367daaa553671f46e46dd5737eb67bfbc7c12c89dc2Darin Petkov}
368daaa553671f46e46dd5737eb67bfbc7c12c89dc2Darin Petkov
369e0d5dd1ef481599ece78f8ff4a84485eb1134b85Darin PetkovTEST_F(OpenVPNManagementServerTest, ProcessNeedPasswordMessageTPMToken) {
370e0d5dd1ef481599ece78f8ff4a84485eb1134b85Darin Petkov  ExpectPINResponse();
371e0d5dd1ef481599ece78f8ff4a84485eb1134b85Darin Petkov  EXPECT_TRUE(
372e0d5dd1ef481599ece78f8ff4a84485eb1134b85Darin Petkov      server_.ProcessNeedPasswordMessage(
373e0d5dd1ef481599ece78f8ff4a84485eb1134b85Darin Petkov          ">PASSWORD:Need 'User-Specific TPM Token FOO' ..."));
374e0d5dd1ef481599ece78f8ff4a84485eb1134b85Darin Petkov}
375e0d5dd1ef481599ece78f8ff4a84485eb1134b85Darin Petkov
376e0d5dd1ef481599ece78f8ff4a84485eb1134b85Darin PetkovTEST_F(OpenVPNManagementServerTest, ProcessNeedPasswordMessageUnknown) {
377e0d5dd1ef481599ece78f8ff4a84485eb1134b85Darin Petkov  EXPECT_FALSE(server_.ProcessNeedPasswordMessage("foo"));
378e0d5dd1ef481599ece78f8ff4a84485eb1134b85Darin Petkov}
379e0d5dd1ef481599ece78f8ff4a84485eb1134b85Darin Petkov
380aba893217c9cf1dd0d39c4dee89a23d3b1a3f4c1Darin PetkovTEST_F(OpenVPNManagementServerTest, ParseSubstring) {
381aba893217c9cf1dd0d39c4dee89a23d3b1a3f4c1Darin Petkov  EXPECT_EQ("", ParseSubstring("", "'", "'"));
382aba893217c9cf1dd0d39c4dee89a23d3b1a3f4c1Darin Petkov  EXPECT_EQ("", ParseSubstring(" ", "'", "'"));
383aba893217c9cf1dd0d39c4dee89a23d3b1a3f4c1Darin Petkov  EXPECT_EQ("", ParseSubstring("'", "'", "'"));
384aba893217c9cf1dd0d39c4dee89a23d3b1a3f4c1Darin Petkov  EXPECT_EQ("", ParseSubstring("''", "'", "'"));
385aba893217c9cf1dd0d39c4dee89a23d3b1a3f4c1Darin Petkov  EXPECT_EQ("", ParseSubstring("] [", "[", "]"));
386aba893217c9cf1dd0d39c4dee89a23d3b1a3f4c1Darin Petkov  EXPECT_EQ("", ParseSubstring("[]", "[", "]"));
387aba893217c9cf1dd0d39c4dee89a23d3b1a3f4c1Darin Petkov  EXPECT_EQ("bar", ParseSubstring("foo['bar']zoo", "['", "']"));
388aba893217c9cf1dd0d39c4dee89a23d3b1a3f4c1Darin Petkov  EXPECT_EQ("bar", ParseSubstring("foo['bar']", "['", "']"));
389aba893217c9cf1dd0d39c4dee89a23d3b1a3f4c1Darin Petkov  EXPECT_EQ("bar", ParseSubstring("['bar']zoo", "['", "']"));
390aba893217c9cf1dd0d39c4dee89a23d3b1a3f4c1Darin Petkov  EXPECT_EQ("bar", ParseSubstring("['bar']['zoo']", "['", "']"));
391aba893217c9cf1dd0d39c4dee89a23d3b1a3f4c1Darin Petkov}
392aba893217c9cf1dd0d39c4dee89a23d3b1a3f4c1Darin Petkov
393aba893217c9cf1dd0d39c4dee89a23d3b1a3f4c1Darin PetkovTEST_F(OpenVPNManagementServerTest, ParsePasswordTag) {
394aba893217c9cf1dd0d39c4dee89a23d3b1a3f4c1Darin Petkov  EXPECT_EQ("", ParsePasswordTag(""));
395aba893217c9cf1dd0d39c4dee89a23d3b1a3f4c1Darin Petkov  EXPECT_EQ("Auth",
396aba893217c9cf1dd0d39c4dee89a23d3b1a3f4c1Darin Petkov            ParsePasswordTag(
397aba893217c9cf1dd0d39c4dee89a23d3b1a3f4c1Darin Petkov                ">PASSWORD:Verification Failed: 'Auth' "
398aba893217c9cf1dd0d39c4dee89a23d3b1a3f4c1Darin Petkov                "['REVOKED: client certificate has been revoked']"));
399aba893217c9cf1dd0d39c4dee89a23d3b1a3f4c1Darin Petkov}
400aba893217c9cf1dd0d39c4dee89a23d3b1a3f4c1Darin Petkov
401aba893217c9cf1dd0d39c4dee89a23d3b1a3f4c1Darin PetkovTEST_F(OpenVPNManagementServerTest, ParsePasswordFailedReason) {
402aba893217c9cf1dd0d39c4dee89a23d3b1a3f4c1Darin Petkov  EXPECT_EQ("", ParsePasswordFailedReason(""));
403aba893217c9cf1dd0d39c4dee89a23d3b1a3f4c1Darin Petkov  EXPECT_EQ("REVOKED: client certificate has been revoked",
404aba893217c9cf1dd0d39c4dee89a23d3b1a3f4c1Darin Petkov            ParsePasswordFailedReason(
405aba893217c9cf1dd0d39c4dee89a23d3b1a3f4c1Darin Petkov                ">PASSWORD:Verification Failed: 'Auth' "
406aba893217c9cf1dd0d39c4dee89a23d3b1a3f4c1Darin Petkov                "['REVOKED: client certificate has been revoked']"));
407e0d5dd1ef481599ece78f8ff4a84485eb1134b85Darin Petkov}
408e0d5dd1ef481599ece78f8ff4a84485eb1134b85Darin Petkov
409683942b7e07f1c27a0d89267d5344c2bde7b2b86Darin PetkovTEST_F(OpenVPNManagementServerTest, PerformStaticChallengeNoCreds) {
4101c049c794175356e5b6c2b6bbb5ef4a12fbfe9a3Darin Petkov  EXPECT_CALL(driver_, FailService(Service::kFailureInternal,
411b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart                                   Service::kErrorDetailsNone)).Times(4);
412e0d5dd1ef481599ece78f8ff4a84485eb1134b85Darin Petkov  server_.PerformStaticChallenge("Auth");
4137372878af066cc079ad88a7b004ca3f769952de2Ben Chan  driver_.args()->SetString(kOpenVPNUserProperty, "jojo");
414e0d5dd1ef481599ece78f8ff4a84485eb1134b85Darin Petkov  server_.PerformStaticChallenge("Auth");
4157372878af066cc079ad88a7b004ca3f769952de2Ben Chan  driver_.args()->SetString(kOpenVPNPasswordProperty, "yoyo");
416e0d5dd1ef481599ece78f8ff4a84485eb1134b85Darin Petkov  server_.PerformStaticChallenge("Auth");
417b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart  driver_.args()->Clear();
418b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart  driver_.args()->SetString(kOpenVPNTokenProperty, "toto");
419b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart  server_.PerformStaticChallenge("Auth");
420683942b7e07f1c27a0d89267d5344c2bde7b2b86Darin Petkov}
421683942b7e07f1c27a0d89267d5344c2bde7b2b86Darin Petkov
422b57682315ba47f8c567b6673f5aa7b87f367a4edPaul StewartTEST_F(OpenVPNManagementServerTest, PerformStaticChallengeOTP) {
423b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart  ExpectOTPStaticChallengeResponse();
424e0d5dd1ef481599ece78f8ff4a84485eb1134b85Darin Petkov  server_.PerformStaticChallenge("Auth");
4257372878af066cc079ad88a7b004ca3f769952de2Ben Chan  EXPECT_FALSE(driver_.args()->ContainsString(kOpenVPNOTPProperty));
426683942b7e07f1c27a0d89267d5344c2bde7b2b86Darin Petkov}
427683942b7e07f1c27a0d89267d5344c2bde7b2b86Darin Petkov
428b57682315ba47f8c567b6673f5aa7b87f367a4edPaul StewartTEST_F(OpenVPNManagementServerTest, PerformStaticChallengeToken) {
429b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart  ExpectTokenStaticChallengeResponse();
430b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart  server_.PerformStaticChallenge("Auth");
431b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart  EXPECT_FALSE(driver_.args()->ContainsString(kOpenVPNTokenProperty));
432b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart}
433b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart
434daaa553671f46e46dd5737eb67bfbc7c12c89dc2Darin PetkovTEST_F(OpenVPNManagementServerTest, PerformAuthenticationNoCreds) {
4351c049c794175356e5b6c2b6bbb5ef4a12fbfe9a3Darin Petkov  EXPECT_CALL(driver_, FailService(Service::kFailureInternal,
4361c049c794175356e5b6c2b6bbb5ef4a12fbfe9a3Darin Petkov                                   Service::kErrorDetailsNone)).Times(2);
437daaa553671f46e46dd5737eb67bfbc7c12c89dc2Darin Petkov  server_.PerformAuthentication("Auth");
4387372878af066cc079ad88a7b004ca3f769952de2Ben Chan  driver_.args()->SetString(kOpenVPNUserProperty, "jojo");
439daaa553671f46e46dd5737eb67bfbc7c12c89dc2Darin Petkov  server_.PerformAuthentication("Auth");
440daaa553671f46e46dd5737eb67bfbc7c12c89dc2Darin Petkov}
441daaa553671f46e46dd5737eb67bfbc7c12c89dc2Darin Petkov
442daaa553671f46e46dd5737eb67bfbc7c12c89dc2Darin PetkovTEST_F(OpenVPNManagementServerTest, PerformAuthentication) {
443daaa553671f46e46dd5737eb67bfbc7c12c89dc2Darin Petkov  ExpectAuthenticationResponse();
444daaa553671f46e46dd5737eb67bfbc7c12c89dc2Darin Petkov  server_.PerformAuthentication("Auth");
445daaa553671f46e46dd5737eb67bfbc7c12c89dc2Darin Petkov}
446daaa553671f46e46dd5737eb67bfbc7c12c89dc2Darin Petkov
447a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin PetkovTEST_F(OpenVPNManagementServerTest, ProcessHoldMessage) {
448a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin Petkov  EXPECT_FALSE(server_.hold_release_);
449a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin Petkov  EXPECT_FALSE(server_.hold_waiting_);
450a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin Petkov
451a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin Petkov  EXPECT_FALSE(server_.ProcessHoldMessage("foo"));
452a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin Petkov
453a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin Petkov  EXPECT_TRUE(server_.ProcessHoldMessage(">HOLD:Waiting for hold release"));
454a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin Petkov  EXPECT_FALSE(server_.hold_release_);
455a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin Petkov  EXPECT_TRUE(server_.hold_waiting_);
456a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin Petkov
457a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin Petkov  ExpectHoldRelease();
458a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin Petkov  server_.hold_release_ = true;
459a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin Petkov  server_.hold_waiting_ = false;
460a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin Petkov  EXPECT_TRUE(server_.ProcessHoldMessage(">HOLD:Waiting for hold release"));
461a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin Petkov  EXPECT_TRUE(server_.hold_release_);
462a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin Petkov  EXPECT_FALSE(server_.hold_waiting_);
463a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin Petkov}
464a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin Petkov
465e0d5dd1ef481599ece78f8ff4a84485eb1134b85Darin PetkovTEST_F(OpenVPNManagementServerTest, SupplyTPMTokenNoPIN) {
4661c049c794175356e5b6c2b6bbb5ef4a12fbfe9a3Darin Petkov  EXPECT_CALL(driver_, FailService(Service::kFailureInternal,
4671c049c794175356e5b6c2b6bbb5ef4a12fbfe9a3Darin Petkov                                   Service::kErrorDetailsNone));
468e0d5dd1ef481599ece78f8ff4a84485eb1134b85Darin Petkov  server_.SupplyTPMToken("User-Specific TPM Token FOO");
469e0d5dd1ef481599ece78f8ff4a84485eb1134b85Darin Petkov}
470e0d5dd1ef481599ece78f8ff4a84485eb1134b85Darin Petkov
471e0d5dd1ef481599ece78f8ff4a84485eb1134b85Darin PetkovTEST_F(OpenVPNManagementServerTest, SupplyTPMToken) {
472e0d5dd1ef481599ece78f8ff4a84485eb1134b85Darin Petkov  ExpectPINResponse();
473e0d5dd1ef481599ece78f8ff4a84485eb1134b85Darin Petkov  server_.SupplyTPMToken("User-Specific TPM Token FOO");
474e0d5dd1ef481599ece78f8ff4a84485eb1134b85Darin Petkov}
475e0d5dd1ef481599ece78f8ff4a84485eb1134b85Darin Petkov
476271fe5247103d0b76c48796c6f10ba45c6db59c4Darin PetkovTEST_F(OpenVPNManagementServerTest, Send) {
477271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov  const char kMessage[] = "foo\n";
478683942b7e07f1c27a0d89267d5344c2bde7b2b86Darin Petkov  SetConnectedSocket();
479683942b7e07f1c27a0d89267d5344c2bde7b2b86Darin Petkov  ExpectSend(kMessage);
480271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov  server_.Send(kMessage);
481271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov}
482271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov
483271fe5247103d0b76c48796c6f10ba45c6db59c4Darin PetkovTEST_F(OpenVPNManagementServerTest, SendState) {
484683942b7e07f1c27a0d89267d5344c2bde7b2b86Darin Petkov  SetConnectedSocket();
485683942b7e07f1c27a0d89267d5344c2bde7b2b86Darin Petkov  ExpectSend("state off\n");
486271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov  server_.SendState("off");
4871c1152030c1bab9f91450b508777feac8c162e60Darin Petkov}
4881c1152030c1bab9f91450b508777feac8c162e60Darin Petkov
489683942b7e07f1c27a0d89267d5344c2bde7b2b86Darin PetkovTEST_F(OpenVPNManagementServerTest, SendUsername) {
490683942b7e07f1c27a0d89267d5344c2bde7b2b86Darin Petkov  SetConnectedSocket();
491683942b7e07f1c27a0d89267d5344c2bde7b2b86Darin Petkov  ExpectSend("username \"Auth\" joesmith\n");
492683942b7e07f1c27a0d89267d5344c2bde7b2b86Darin Petkov  server_.SendUsername("Auth", "joesmith");
493683942b7e07f1c27a0d89267d5344c2bde7b2b86Darin Petkov}
494683942b7e07f1c27a0d89267d5344c2bde7b2b86Darin Petkov
495683942b7e07f1c27a0d89267d5344c2bde7b2b86Darin PetkovTEST_F(OpenVPNManagementServerTest, SendPassword) {
496683942b7e07f1c27a0d89267d5344c2bde7b2b86Darin Petkov  SetConnectedSocket();
497daaa553671f46e46dd5737eb67bfbc7c12c89dc2Darin Petkov  ExpectSend("password \"Auth\" \"foo\\\"bar\"\n");
498daaa553671f46e46dd5737eb67bfbc7c12c89dc2Darin Petkov  server_.SendPassword("Auth", "foo\"bar");
499683942b7e07f1c27a0d89267d5344c2bde7b2b86Darin Petkov}
500683942b7e07f1c27a0d89267d5344c2bde7b2b86Darin Petkov
5010440b9b420d3a532af111b86c5c7c6cb87bc269aDarin PetkovTEST_F(OpenVPNManagementServerTest, ProcessFailedPasswordMessage) {
5020440b9b420d3a532af111b86c5c7c6cb87bc269aDarin Petkov  EXPECT_FALSE(server_.ProcessFailedPasswordMessage("foo"));
5031c049c794175356e5b6c2b6bbb5ef4a12fbfe9a3Darin Petkov  EXPECT_CALL(driver_, FailService(Service::kFailureConnect,
5041c049c794175356e5b6c2b6bbb5ef4a12fbfe9a3Darin Petkov                                   Service::kErrorDetailsNone)).Times(3);
5051c049c794175356e5b6c2b6bbb5ef4a12fbfe9a3Darin Petkov  EXPECT_CALL(driver_, FailService(Service::kFailureConnect, "Revoked."));
5060440b9b420d3a532af111b86c5c7c6cb87bc269aDarin Petkov  EXPECT_TRUE(
5070440b9b420d3a532af111b86c5c7c6cb87bc269aDarin Petkov      server_.ProcessFailedPasswordMessage(">PASSWORD:Verification Failed: ."));
508aba893217c9cf1dd0d39c4dee89a23d3b1a3f4c1Darin Petkov  EXPECT_TRUE(
509aba893217c9cf1dd0d39c4dee89a23d3b1a3f4c1Darin Petkov      server_.ProcessFailedPasswordMessage(
510aba893217c9cf1dd0d39c4dee89a23d3b1a3f4c1Darin Petkov          ">PASSWORD:Verification Failed: 'Private Key' ['Reason']"));
511aba893217c9cf1dd0d39c4dee89a23d3b1a3f4c1Darin Petkov  EXPECT_TRUE(
512aba893217c9cf1dd0d39c4dee89a23d3b1a3f4c1Darin Petkov      server_.ProcessFailedPasswordMessage(
513aba893217c9cf1dd0d39c4dee89a23d3b1a3f4c1Darin Petkov          ">PASSWORD:Verification Failed: 'Auth'"));
514aba893217c9cf1dd0d39c4dee89a23d3b1a3f4c1Darin Petkov  EXPECT_TRUE(
515aba893217c9cf1dd0d39c4dee89a23d3b1a3f4c1Darin Petkov      server_.ProcessFailedPasswordMessage(
516aba893217c9cf1dd0d39c4dee89a23d3b1a3f4c1Darin Petkov          ">PASSWORD:Verification Failed: 'Auth' ['Revoked.']"));
5170440b9b420d3a532af111b86c5c7c6cb87bc269aDarin Petkov}
5180440b9b420d3a532af111b86c5c7c6cb87bc269aDarin Petkov
51916e70320bf24928d787de97bfb999de8dac9915aDarin PetkovTEST_F(OpenVPNManagementServerTest, ProcessAuthTokenMessage) {
52016e70320bf24928d787de97bfb999de8dac9915aDarin Petkov  EXPECT_FALSE(ProcessAuthTokenMessage("foo"));
52116e70320bf24928d787de97bfb999de8dac9915aDarin Petkov  EXPECT_TRUE(ProcessAuthTokenMessage(">PASSWORD:Auth-Token:ToKeN=="));
52216e70320bf24928d787de97bfb999de8dac9915aDarin Petkov}
52316e70320bf24928d787de97bfb999de8dac9915aDarin Petkov
524a42afe3a1621b8262d5404ecfaf200d3d76bd454Darin PetkovTEST_F(OpenVPNManagementServerTest, SendSignal) {
525a42afe3a1621b8262d5404ecfaf200d3d76bd454Darin Petkov  SetConnectedSocket();
526a42afe3a1621b8262d5404ecfaf200d3d76bd454Darin Petkov  ExpectSend("signal SIGUSR2\n");
527a42afe3a1621b8262d5404ecfaf200d3d76bd454Darin Petkov  SendSignal("SIGUSR2");
528a42afe3a1621b8262d5404ecfaf200d3d76bd454Darin Petkov}
529a42afe3a1621b8262d5404ecfaf200d3d76bd454Darin Petkov
530a42afe3a1621b8262d5404ecfaf200d3d76bd454Darin PetkovTEST_F(OpenVPNManagementServerTest, Restart) {
531a42afe3a1621b8262d5404ecfaf200d3d76bd454Darin Petkov  ExpectRestart();
532a42afe3a1621b8262d5404ecfaf200d3d76bd454Darin Petkov  server_.Restart();
533a42afe3a1621b8262d5404ecfaf200d3d76bd454Darin Petkov}
534a42afe3a1621b8262d5404ecfaf200d3d76bd454Darin Petkov
535a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin PetkovTEST_F(OpenVPNManagementServerTest, SendHoldRelease) {
536a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin Petkov  ExpectHoldRelease();
537a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin Petkov  server_.SendHoldRelease();
538a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin Petkov}
539a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin Petkov
540a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin PetkovTEST_F(OpenVPNManagementServerTest, Hold) {
541a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin Petkov  EXPECT_FALSE(server_.hold_release_);
542a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin Petkov  EXPECT_FALSE(server_.hold_waiting_);
543a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin Petkov
544a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin Petkov  server_.ReleaseHold();
545a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin Petkov  EXPECT_TRUE(server_.hold_release_);
546a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin Petkov  EXPECT_FALSE(server_.hold_waiting_);
547a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin Petkov
548a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin Petkov  server_.Hold();
549a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin Petkov  EXPECT_FALSE(server_.hold_release_);
550a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin Petkov  EXPECT_FALSE(server_.hold_waiting_);
551a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin Petkov
552a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin Petkov  server_.hold_waiting_ = true;
553a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin Petkov  ExpectHoldRelease();
554a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin Petkov  server_.ReleaseHold();
555a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin Petkov  EXPECT_TRUE(server_.hold_release_);
556a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin Petkov  EXPECT_FALSE(server_.hold_waiting_);
557a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin Petkov}
558a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin Petkov
559daaa553671f46e46dd5737eb67bfbc7c12c89dc2Darin PetkovTEST_F(OpenVPNManagementServerTest, EscapeToQuote) {
560daaa553671f46e46dd5737eb67bfbc7c12c89dc2Darin Petkov  EXPECT_EQ("", OpenVPNManagementServer::EscapeToQuote(""));
561daaa553671f46e46dd5737eb67bfbc7c12c89dc2Darin Petkov  EXPECT_EQ("foo './", OpenVPNManagementServer::EscapeToQuote("foo './"));
562daaa553671f46e46dd5737eb67bfbc7c12c89dc2Darin Petkov  EXPECT_EQ("\\\\", OpenVPNManagementServer::EscapeToQuote("\\"));
563daaa553671f46e46dd5737eb67bfbc7c12c89dc2Darin Petkov  EXPECT_EQ("\\\"", OpenVPNManagementServer::EscapeToQuote("\""));
564daaa553671f46e46dd5737eb67bfbc7c12c89dc2Darin Petkov  EXPECT_EQ("\\\\\\\"foo\\\\bar\\\"",
565daaa553671f46e46dd5737eb67bfbc7c12c89dc2Darin Petkov            OpenVPNManagementServer::EscapeToQuote("\\\"foo\\bar\""));
566daaa553671f46e46dd5737eb67bfbc7c12c89dc2Darin Petkov}
567daaa553671f46e46dd5737eb67bfbc7c12c89dc2Darin Petkov
5681c1152030c1bab9f91450b508777feac8c162e60Darin Petkov}  // namespace shill
569