blob: 9852cbe35e8caa138e0a5d5454612693bb3c387d [file] [log] [blame]
Darin Petkov1c115202012-03-22 15:35:47 +01001// 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
Darin Petkov271fe522012-03-27 13:47:29 +02007#include <netinet/in.h>
8
Darin Petkov683942b2012-03-27 18:00:04 +02009#include <chromeos/dbus/service_constants.h>
Darin Petkov1c115202012-03-22 15:35:47 +010010#include <gtest/gtest.h>
11
Darin Petkov683942b2012-03-27 18:00:04 +020012#include "shill/glib.h"
Darin Petkov1c115202012-03-22 15:35:47 +010013#include "shill/key_value_store.h"
Darin Petkov271fe522012-03-27 13:47:29 +020014#include "shill/mock_event_dispatcher.h"
Darin Petkov1c115202012-03-22 15:35:47 +010015#include "shill/mock_openvpn_driver.h"
Darin Petkov271fe522012-03-27 13:47:29 +020016#include "shill/mock_sockets.h"
17
18using std::string;
Darin Petkov46463022012-03-29 14:57:32 +020019using std::vector;
Darin Petkov271fe522012-03-27 13:47:29 +020020using testing::_;
Darin Petkove08084d2012-06-11 13:19:35 +020021using testing::Assign;
Darin Petkov271fe522012-03-27 13:47:29 +020022using testing::Return;
23using testing::ReturnNew;
Darin Petkov1c115202012-03-22 15:35:47 +010024
25namespace shill {
26
Darin Petkov271fe522012-03-27 13:47:29 +020027namespace {
28MATCHER_P(CallbackEq, callback, "") {
29 return arg.Equals(callback);
30}
31
32MATCHER_P(VoidStringEq, value, "") {
33 return value == reinterpret_cast<const char *>(arg);
34}
35} // namespace {}
36
Darin Petkov1c115202012-03-22 15:35:47 +010037class OpenVPNManagementServerTest : public testing::Test {
38 public:
39 OpenVPNManagementServerTest()
Paul Stewart451aa7f2012-04-11 19:07:58 -070040 : server_(&driver_, &glib_) {}
Darin Petkov1c115202012-03-22 15:35:47 +010041
42 virtual ~OpenVPNManagementServerTest() {}
43
Darin Petkov271fe522012-03-27 13:47:29 +020044 void SetSockets() { server_.sockets_ = &sockets_; }
45 void SetDispatcher() { server_.dispatcher_ = &dispatcher_; }
Darin Petkovffd33062012-06-11 19:23:42 +020046 void ExpectNotStarted() { EXPECT_FALSE(server_.IsStarted()); }
Darin Petkov271fe522012-03-27 13:47:29 +020047
Darin Petkov683942b2012-03-27 18:00:04 +020048 void SetConnectedSocket() {
49 server_.connected_socket_ = kConnectedSocket;
50 SetSockets();
51 }
52
53 void ExpectSend(const string &value) {
54 EXPECT_CALL(sockets_,
55 Send(kConnectedSocket, VoidStringEq(value), value.size(), 0))
Darin Petkov271fe522012-03-27 13:47:29 +020056 .WillOnce(Return(value.size()));
57 }
58
Darin Petkov683942b2012-03-27 18:00:04 +020059 void ExpectStaticChallengeResponse() {
60 driver_.args()->SetString(flimflam::kOpenVPNUserProperty, "jojo");
61 driver_.args()->SetString(flimflam::kOpenVPNPasswordProperty, "yoyo");
62 driver_.args()->SetString(flimflam::kOpenVPNOTPProperty, "123456");
63 SetConnectedSocket();
64 ExpectSend("username \"Auth\" jojo\n");
65 ExpectSend("password \"Auth\" \"SCRV1:eW95bw==:MTIzNDU2\"\n");
66 }
67
Darin Petkovdaaa5532012-07-24 15:37:55 +020068 void ExpectAuthenticationResponse() {
69 driver_.args()->SetString(flimflam::kOpenVPNUserProperty, "jojo");
70 driver_.args()->SetString(flimflam::kOpenVPNPasswordProperty, "yoyo");
71 SetConnectedSocket();
72 ExpectSend("username \"Auth\" jojo\n");
73 ExpectSend("password \"Auth\" \"yoyo\"\n");
74 }
75
Darin Petkove0d5dd12012-04-04 16:10:48 +020076 void ExpectPINResponse() {
77 driver_.args()->SetString(flimflam::kOpenVPNPinProperty, "987654");
78 SetConnectedSocket();
79 ExpectSend("password \"User-Specific TPM Token FOO\" \"987654\"\n");
80 }
81
Darin Petkova5e07ef2012-07-09 14:27:57 +020082 void ExpectHoldRelease() {
83 SetConnectedSocket();
84 ExpectSend("hold release\n");
85 }
86
Darin Petkov271fe522012-03-27 13:47:29 +020087 InputData CreateInputDataFromString(const string &str) {
88 InputData data(
89 reinterpret_cast<unsigned char *>(const_cast<char *>(str.data())),
90 str.size());
91 return data;
92 }
93
Darin Petkov1c115202012-03-22 15:35:47 +010094 protected:
Darin Petkov683942b2012-03-27 18:00:04 +020095 static const int kConnectedSocket;
96
97 GLib glib_;
Darin Petkov1c115202012-03-22 15:35:47 +010098 MockOpenVPNDriver driver_;
99 OpenVPNManagementServer server_;
Darin Petkov271fe522012-03-27 13:47:29 +0200100 MockSockets sockets_;
101 MockEventDispatcher dispatcher_;
Darin Petkov1c115202012-03-22 15:35:47 +0100102};
103
Darin Petkov683942b2012-03-27 18:00:04 +0200104// static
105const int OpenVPNManagementServerTest::kConnectedSocket = 555;
106
Darin Petkov271fe522012-03-27 13:47:29 +0200107TEST_F(OpenVPNManagementServerTest, StartStarted) {
108 SetSockets();
Darin Petkov46463022012-03-29 14:57:32 +0200109 EXPECT_TRUE(server_.Start(NULL, NULL, NULL));
Darin Petkov271fe522012-03-27 13:47:29 +0200110}
111
112TEST_F(OpenVPNManagementServerTest, StartSocketFail) {
113 EXPECT_CALL(sockets_, Socket(AF_INET, SOCK_STREAM, IPPROTO_TCP))
114 .WillOnce(Return(-1));
Darin Petkov46463022012-03-29 14:57:32 +0200115 EXPECT_FALSE(server_.Start(NULL, &sockets_, NULL));
Darin Petkov271fe522012-03-27 13:47:29 +0200116 ExpectNotStarted();
117}
118
119TEST_F(OpenVPNManagementServerTest, StartGetSockNameFail) {
120 const int kSocket = 123;
121 EXPECT_CALL(sockets_, Socket(AF_INET, SOCK_STREAM, IPPROTO_TCP))
122 .WillOnce(Return(kSocket));
123 EXPECT_CALL(sockets_, Bind(kSocket, _, _)).WillOnce(Return(0));
124 EXPECT_CALL(sockets_, Listen(kSocket, 1)).WillOnce(Return(0));
125 EXPECT_CALL(sockets_, GetSockName(kSocket, _, _)).WillOnce(Return(-1));
126 EXPECT_CALL(sockets_, Close(kSocket)).WillOnce(Return(0));
Darin Petkov46463022012-03-29 14:57:32 +0200127 EXPECT_FALSE(server_.Start(NULL, &sockets_, NULL));
Darin Petkov271fe522012-03-27 13:47:29 +0200128 ExpectNotStarted();
129}
130
Darin Petkov78f63262012-03-26 01:30:24 +0200131TEST_F(OpenVPNManagementServerTest, Start) {
Darin Petkov271fe522012-03-27 13:47:29 +0200132 const int kSocket = 123;
133 EXPECT_CALL(sockets_, Socket(AF_INET, SOCK_STREAM, IPPROTO_TCP))
134 .WillOnce(Return(kSocket));
135 EXPECT_CALL(sockets_, Bind(kSocket, _, _)).WillOnce(Return(0));
136 EXPECT_CALL(sockets_, Listen(kSocket, 1)).WillOnce(Return(0));
137 EXPECT_CALL(sockets_, GetSockName(kSocket, _, _)).WillOnce(Return(0));
138 EXPECT_CALL(dispatcher_,
139 CreateReadyHandler(kSocket, IOHandler::kModeInput,
140 CallbackEq(server_.ready_callback_)))
141 .WillOnce(ReturnNew<IOHandler>());
Darin Petkov46463022012-03-29 14:57:32 +0200142 vector<string> options;
143 EXPECT_TRUE(server_.Start(&dispatcher_, &sockets_, &options));
Darin Petkov271fe522012-03-27 13:47:29 +0200144 EXPECT_EQ(&sockets_, server_.sockets_);
145 EXPECT_EQ(kSocket, server_.socket_);
146 EXPECT_TRUE(server_.ready_handler_.get());
147 EXPECT_EQ(&dispatcher_, server_.dispatcher_);
Darin Petkov46463022012-03-29 14:57:32 +0200148 EXPECT_FALSE(options.empty());
Darin Petkov271fe522012-03-27 13:47:29 +0200149}
150
151TEST_F(OpenVPNManagementServerTest, Stop) {
152 SetSockets();
153 server_.input_handler_.reset(new IOHandler());
154 const int kConnectedSocket = 234;
155 server_.connected_socket_ = kConnectedSocket;
156 EXPECT_CALL(sockets_, Close(kConnectedSocket)).WillOnce(Return(0));
157 SetDispatcher();
158 server_.ready_handler_.reset(new IOHandler());
159 const int kSocket = 345;
160 server_.socket_ = kSocket;
161 EXPECT_CALL(sockets_, Close(kSocket)).WillOnce(Return(0));
162 server_.Stop();
163 EXPECT_FALSE(server_.input_handler_.get());
164 EXPECT_EQ(-1, server_.connected_socket_);
165 EXPECT_FALSE(server_.dispatcher_);
166 EXPECT_FALSE(server_.ready_handler_.get());
167 EXPECT_EQ(-1, server_.socket_);
168 ExpectNotStarted();
169}
170
171TEST_F(OpenVPNManagementServerTest, OnReadyAcceptFail) {
172 const int kSocket = 333;
173 SetSockets();
174 EXPECT_CALL(sockets_, Accept(kSocket, NULL, NULL)).WillOnce(Return(-1));
175 server_.OnReady(kSocket);
176 EXPECT_EQ(-1, server_.connected_socket_);
177}
178
179TEST_F(OpenVPNManagementServerTest, OnReady) {
180 const int kSocket = 111;
Darin Petkov683942b2012-03-27 18:00:04 +0200181 SetConnectedSocket();
Darin Petkov271fe522012-03-27 13:47:29 +0200182 SetDispatcher();
183 EXPECT_CALL(sockets_, Accept(kSocket, NULL, NULL))
184 .WillOnce(Return(kConnectedSocket));
185 server_.ready_handler_.reset(new IOHandler());
186 EXPECT_CALL(dispatcher_,
187 CreateInputHandler(kConnectedSocket,
188 CallbackEq(server_.input_callback_)))
189 .WillOnce(ReturnNew<IOHandler>());
Darin Petkov683942b2012-03-27 18:00:04 +0200190 ExpectSend("state on\n");
Darin Petkov271fe522012-03-27 13:47:29 +0200191 server_.OnReady(kSocket);
192 EXPECT_EQ(kConnectedSocket, server_.connected_socket_);
193 EXPECT_FALSE(server_.ready_handler_.get());
194 EXPECT_TRUE(server_.input_handler_.get());
195}
196
197TEST_F(OpenVPNManagementServerTest, OnInput) {
198 {
199 string s;
200 InputData data = CreateInputDataFromString(s);
201 server_.OnInput(&data);
202 }
203 {
204 string s = "foo\n"
205 ">INFO:...\n"
Darin Petkov683942b2012-03-27 18:00:04 +0200206 ">PASSWORD:Need 'Auth' SC:user/password/otp\n"
Darin Petkove0d5dd12012-04-04 16:10:48 +0200207 ">PASSWORD:Need 'User-Specific TPM Token FOO' ...\n"
Darin Petkov0440b9b2012-04-17 16:11:56 +0200208 ">PASSWORD:Verification Failed: .\n"
Darin Petkova5e07ef2012-07-09 14:27:57 +0200209 ">STATE:123,RECONNECTING,detail,...,...\n"
210 ">HOLD:Waiting for hold release";
Darin Petkov271fe522012-03-27 13:47:29 +0200211 InputData data = CreateInputDataFromString(s);
Darin Petkov683942b2012-03-27 18:00:04 +0200212 ExpectStaticChallengeResponse();
Darin Petkove0d5dd12012-04-04 16:10:48 +0200213 ExpectPINResponse();
Darin Petkov0440b9b2012-04-17 16:11:56 +0200214 EXPECT_CALL(driver_, Cleanup(Service::kStateFailure));
Darin Petkov271fe522012-03-27 13:47:29 +0200215 EXPECT_CALL(driver_, OnReconnecting());
Darin Petkova5e07ef2012-07-09 14:27:57 +0200216 EXPECT_FALSE(server_.hold_waiting_);
Darin Petkov271fe522012-03-27 13:47:29 +0200217 server_.OnInput(&data);
Darin Petkova5e07ef2012-07-09 14:27:57 +0200218 EXPECT_TRUE(server_.hold_waiting_);
Darin Petkov271fe522012-03-27 13:47:29 +0200219 }
220}
221
Darin Petkove08084d2012-06-11 13:19:35 +0200222TEST_F(OpenVPNManagementServerTest, OnInputStop) {
223 string s =
224 ">PASSWORD:Verification Failed: .\n"
225 ">STATE:123,RECONNECTING,detail,...,...";
226 InputData data = CreateInputDataFromString(s);
227 SetSockets();
228 // Stops the server after the first message is processed.
229 EXPECT_CALL(driver_, Cleanup(Service::kStateFailure))
230 .WillOnce(Assign(&server_.sockets_, reinterpret_cast<Sockets *>(NULL)));
231 // The second message should not be processed.
232 EXPECT_CALL(driver_, OnReconnecting()).Times(0);
233 server_.OnInput(&data);
234}
235
Darin Petkov271fe522012-03-27 13:47:29 +0200236TEST_F(OpenVPNManagementServerTest, ProcessMessage) {
237 server_.ProcessMessage("foo");
238 server_.ProcessMessage(">INFO:");
239
240 EXPECT_CALL(driver_, OnReconnecting());
241 server_.ProcessMessage(">STATE:123,RECONNECTING,detail,...,...");
242}
243
244TEST_F(OpenVPNManagementServerTest, ProcessInfoMessage) {
245 EXPECT_FALSE(server_.ProcessInfoMessage("foo"));
246 EXPECT_TRUE(server_.ProcessInfoMessage(">INFO:"));
247}
248
249TEST_F(OpenVPNManagementServerTest, ProcessStateMessage) {
250 EXPECT_FALSE(server_.ProcessStateMessage("foo"));
251 EXPECT_TRUE(server_.ProcessStateMessage(">STATE:123,WAIT,detail,...,..."));
252 EXPECT_CALL(driver_, OnReconnecting());
253 EXPECT_TRUE(
254 server_.ProcessStateMessage(">STATE:123,RECONNECTING,detail,...,..."));
255}
256
Darin Petkov683942b2012-03-27 18:00:04 +0200257TEST_F(OpenVPNManagementServerTest, ProcessNeedPasswordMessageAuthSC) {
Darin Petkov683942b2012-03-27 18:00:04 +0200258 ExpectStaticChallengeResponse();
259 EXPECT_TRUE(
260 server_.ProcessNeedPasswordMessage(
261 ">PASSWORD:Need 'Auth' SC:user/password/otp"));
262 EXPECT_FALSE(driver_.args()->ContainsString(flimflam::kOpenVPNOTPProperty));
263}
264
Darin Petkovdaaa5532012-07-24 15:37:55 +0200265TEST_F(OpenVPNManagementServerTest, ProcessNeedPasswordMessageAuth) {
266 ExpectAuthenticationResponse();
267 EXPECT_TRUE(
268 server_.ProcessNeedPasswordMessage(
269 ">PASSWORD:Need 'Auth' username/password"));
270}
271
Darin Petkove0d5dd12012-04-04 16:10:48 +0200272TEST_F(OpenVPNManagementServerTest, ProcessNeedPasswordMessageTPMToken) {
273 ExpectPINResponse();
274 EXPECT_TRUE(
275 server_.ProcessNeedPasswordMessage(
276 ">PASSWORD:Need 'User-Specific TPM Token FOO' ..."));
277}
278
279TEST_F(OpenVPNManagementServerTest, ProcessNeedPasswordMessageUnknown) {
280 EXPECT_FALSE(server_.ProcessNeedPasswordMessage("foo"));
281}
282
283TEST_F(OpenVPNManagementServerTest, ParseNeedPasswordTag) {
284 EXPECT_EQ("", OpenVPNManagementServer::ParseNeedPasswordTag(""));
285 EXPECT_EQ("", OpenVPNManagementServer::ParseNeedPasswordTag(" "));
286 EXPECT_EQ("", OpenVPNManagementServer::ParseNeedPasswordTag("'"));
287 EXPECT_EQ("", OpenVPNManagementServer::ParseNeedPasswordTag("''"));
288 EXPECT_EQ("bar",
289 OpenVPNManagementServer::ParseNeedPasswordTag("foo'bar'zoo"));
290 EXPECT_EQ("bar", OpenVPNManagementServer::ParseNeedPasswordTag("foo'bar'"));
291 EXPECT_EQ("bar", OpenVPNManagementServer::ParseNeedPasswordTag("'bar'zoo"));
292 EXPECT_EQ("bar",
293 OpenVPNManagementServer::ParseNeedPasswordTag("foo'bar'zoo'moo"));
294}
295
Darin Petkov683942b2012-03-27 18:00:04 +0200296TEST_F(OpenVPNManagementServerTest, PerformStaticChallengeNoCreds) {
Darin Petkov0440b9b2012-04-17 16:11:56 +0200297 EXPECT_CALL(driver_, Cleanup(Service::kStateFailure)).Times(3);
Darin Petkove0d5dd12012-04-04 16:10:48 +0200298 server_.PerformStaticChallenge("Auth");
Darin Petkov683942b2012-03-27 18:00:04 +0200299 driver_.args()->SetString(flimflam::kOpenVPNUserProperty, "jojo");
Darin Petkove0d5dd12012-04-04 16:10:48 +0200300 server_.PerformStaticChallenge("Auth");
Darin Petkov683942b2012-03-27 18:00:04 +0200301 driver_.args()->SetString(flimflam::kOpenVPNPasswordProperty, "yoyo");
Darin Petkove0d5dd12012-04-04 16:10:48 +0200302 server_.PerformStaticChallenge("Auth");
Darin Petkov683942b2012-03-27 18:00:04 +0200303}
304
305TEST_F(OpenVPNManagementServerTest, PerformStaticChallenge) {
306 ExpectStaticChallengeResponse();
Darin Petkove0d5dd12012-04-04 16:10:48 +0200307 server_.PerformStaticChallenge("Auth");
Darin Petkov683942b2012-03-27 18:00:04 +0200308 EXPECT_FALSE(driver_.args()->ContainsString(flimflam::kOpenVPNOTPProperty));
309}
310
Darin Petkovdaaa5532012-07-24 15:37:55 +0200311TEST_F(OpenVPNManagementServerTest, PerformAuthenticationNoCreds) {
312 EXPECT_CALL(driver_, Cleanup(Service::kStateFailure)).Times(2);
313 server_.PerformAuthentication("Auth");
314 driver_.args()->SetString(flimflam::kOpenVPNUserProperty, "jojo");
315 server_.PerformAuthentication("Auth");
316}
317
318TEST_F(OpenVPNManagementServerTest, PerformAuthentication) {
319 ExpectAuthenticationResponse();
320 server_.PerformAuthentication("Auth");
321}
322
Darin Petkova5e07ef2012-07-09 14:27:57 +0200323TEST_F(OpenVPNManagementServerTest, ProcessHoldMessage) {
324 EXPECT_FALSE(server_.hold_release_);
325 EXPECT_FALSE(server_.hold_waiting_);
326
327 EXPECT_FALSE(server_.ProcessHoldMessage("foo"));
328
329 EXPECT_TRUE(server_.ProcessHoldMessage(">HOLD:Waiting for hold release"));
330 EXPECT_FALSE(server_.hold_release_);
331 EXPECT_TRUE(server_.hold_waiting_);
332
333 ExpectHoldRelease();
334 server_.hold_release_ = true;
335 server_.hold_waiting_ = false;
336 EXPECT_TRUE(server_.ProcessHoldMessage(">HOLD:Waiting for hold release"));
337 EXPECT_TRUE(server_.hold_release_);
338 EXPECT_FALSE(server_.hold_waiting_);
339}
340
Darin Petkove0d5dd12012-04-04 16:10:48 +0200341TEST_F(OpenVPNManagementServerTest, SupplyTPMTokenNoPIN) {
Darin Petkov0440b9b2012-04-17 16:11:56 +0200342 EXPECT_CALL(driver_, Cleanup(Service::kStateFailure));
Darin Petkove0d5dd12012-04-04 16:10:48 +0200343 server_.SupplyTPMToken("User-Specific TPM Token FOO");
344}
345
346TEST_F(OpenVPNManagementServerTest, SupplyTPMToken) {
347 ExpectPINResponse();
348 server_.SupplyTPMToken("User-Specific TPM Token FOO");
349}
350
Darin Petkov271fe522012-03-27 13:47:29 +0200351TEST_F(OpenVPNManagementServerTest, Send) {
Darin Petkov271fe522012-03-27 13:47:29 +0200352 const char kMessage[] = "foo\n";
Darin Petkov683942b2012-03-27 18:00:04 +0200353 SetConnectedSocket();
354 ExpectSend(kMessage);
Darin Petkov271fe522012-03-27 13:47:29 +0200355 server_.Send(kMessage);
356}
357
358TEST_F(OpenVPNManagementServerTest, SendState) {
Darin Petkov683942b2012-03-27 18:00:04 +0200359 SetConnectedSocket();
360 ExpectSend("state off\n");
Darin Petkov271fe522012-03-27 13:47:29 +0200361 server_.SendState("off");
Darin Petkov1c115202012-03-22 15:35:47 +0100362}
363
Darin Petkov683942b2012-03-27 18:00:04 +0200364TEST_F(OpenVPNManagementServerTest, SendUsername) {
365 SetConnectedSocket();
366 ExpectSend("username \"Auth\" joesmith\n");
367 server_.SendUsername("Auth", "joesmith");
368}
369
370TEST_F(OpenVPNManagementServerTest, SendPassword) {
371 SetConnectedSocket();
Darin Petkovdaaa5532012-07-24 15:37:55 +0200372 ExpectSend("password \"Auth\" \"foo\\\"bar\"\n");
373 server_.SendPassword("Auth", "foo\"bar");
Darin Petkov683942b2012-03-27 18:00:04 +0200374}
375
Darin Petkov0440b9b2012-04-17 16:11:56 +0200376TEST_F(OpenVPNManagementServerTest, ProcessFailedPasswordMessage) {
377 EXPECT_FALSE(server_.ProcessFailedPasswordMessage("foo"));
378 EXPECT_CALL(driver_, Cleanup(Service::kStateFailure));
379 EXPECT_TRUE(
380 server_.ProcessFailedPasswordMessage(">PASSWORD:Verification Failed: ."));
381}
382
Darin Petkova5e07ef2012-07-09 14:27:57 +0200383TEST_F(OpenVPNManagementServerTest, SendHoldRelease) {
384 ExpectHoldRelease();
385 server_.SendHoldRelease();
386}
387
388TEST_F(OpenVPNManagementServerTest, Hold) {
389 EXPECT_FALSE(server_.hold_release_);
390 EXPECT_FALSE(server_.hold_waiting_);
391
392 server_.ReleaseHold();
393 EXPECT_TRUE(server_.hold_release_);
394 EXPECT_FALSE(server_.hold_waiting_);
395
396 server_.Hold();
397 EXPECT_FALSE(server_.hold_release_);
398 EXPECT_FALSE(server_.hold_waiting_);
399
400 server_.hold_waiting_ = true;
401 ExpectHoldRelease();
402 server_.ReleaseHold();
403 EXPECT_TRUE(server_.hold_release_);
404 EXPECT_FALSE(server_.hold_waiting_);
405}
406
Darin Petkovdaaa5532012-07-24 15:37:55 +0200407TEST_F(OpenVPNManagementServerTest, EscapeToQuote) {
408 EXPECT_EQ("", OpenVPNManagementServer::EscapeToQuote(""));
409 EXPECT_EQ("foo './", OpenVPNManagementServer::EscapeToQuote("foo './"));
410 EXPECT_EQ("\\\\", OpenVPNManagementServer::EscapeToQuote("\\"));
411 EXPECT_EQ("\\\"", OpenVPNManagementServer::EscapeToQuote("\""));
412 EXPECT_EQ("\\\\\\\"foo\\\\bar\\\"",
413 OpenVPNManagementServer::EscapeToQuote("\\\"foo\\bar\""));
414}
415
Darin Petkov1c115202012-03-22 15:35:47 +0100416} // namespace shill