blob: b8064a1c12a1d8144ee4f8bf9c956a1d92e332cc [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;
19using testing::_;
20using testing::Return;
21using testing::ReturnNew;
Darin Petkov1c115202012-03-22 15:35:47 +010022
23namespace shill {
24
Darin Petkov271fe522012-03-27 13:47:29 +020025namespace {
26MATCHER_P(CallbackEq, callback, "") {
27 return arg.Equals(callback);
28}
29
30MATCHER_P(VoidStringEq, value, "") {
31 return value == reinterpret_cast<const char *>(arg);
32}
33} // namespace {}
34
Darin Petkov1c115202012-03-22 15:35:47 +010035class OpenVPNManagementServerTest : public testing::Test {
36 public:
37 OpenVPNManagementServerTest()
38 : driver_(args_),
Darin Petkov683942b2012-03-27 18:00:04 +020039 server_(&driver_, &glib_) {}
Darin Petkov1c115202012-03-22 15:35:47 +010040
41 virtual ~OpenVPNManagementServerTest() {}
42
Darin Petkov271fe522012-03-27 13:47:29 +020043 void SetSockets() { server_.sockets_ = &sockets_; }
44 void SetDispatcher() { server_.dispatcher_ = &dispatcher_; }
45 void ExpectNotStarted() { EXPECT_TRUE(server_.sockets_ == NULL); }
46
Darin Petkov683942b2012-03-27 18:00:04 +020047 void SetConnectedSocket() {
48 server_.connected_socket_ = kConnectedSocket;
49 SetSockets();
50 }
51
52 void ExpectSend(const string &value) {
53 EXPECT_CALL(sockets_,
54 Send(kConnectedSocket, VoidStringEq(value), value.size(), 0))
Darin Petkov271fe522012-03-27 13:47:29 +020055 .WillOnce(Return(value.size()));
56 }
57
Darin Petkov683942b2012-03-27 18:00:04 +020058 void ExpectStaticChallengeResponse() {
59 driver_.args()->SetString(flimflam::kOpenVPNUserProperty, "jojo");
60 driver_.args()->SetString(flimflam::kOpenVPNPasswordProperty, "yoyo");
61 driver_.args()->SetString(flimflam::kOpenVPNOTPProperty, "123456");
62 SetConnectedSocket();
63 ExpectSend("username \"Auth\" jojo\n");
64 ExpectSend("password \"Auth\" \"SCRV1:eW95bw==:MTIzNDU2\"\n");
65 }
66
Darin Petkov271fe522012-03-27 13:47:29 +020067 InputData CreateInputDataFromString(const string &str) {
68 InputData data(
69 reinterpret_cast<unsigned char *>(const_cast<char *>(str.data())),
70 str.size());
71 return data;
72 }
73
Darin Petkov1c115202012-03-22 15:35:47 +010074 protected:
Darin Petkov683942b2012-03-27 18:00:04 +020075 static const int kConnectedSocket;
76
77 GLib glib_;
Darin Petkov1c115202012-03-22 15:35:47 +010078 KeyValueStore args_;
79 MockOpenVPNDriver driver_;
80 OpenVPNManagementServer server_;
Darin Petkov271fe522012-03-27 13:47:29 +020081 MockSockets sockets_;
82 MockEventDispatcher dispatcher_;
Darin Petkov1c115202012-03-22 15:35:47 +010083};
84
Darin Petkov683942b2012-03-27 18:00:04 +020085// static
86const int OpenVPNManagementServerTest::kConnectedSocket = 555;
87
Darin Petkov271fe522012-03-27 13:47:29 +020088TEST_F(OpenVPNManagementServerTest, StartStarted) {
89 SetSockets();
90 EXPECT_TRUE(server_.Start(NULL, NULL));
91}
92
93TEST_F(OpenVPNManagementServerTest, StartSocketFail) {
94 EXPECT_CALL(sockets_, Socket(AF_INET, SOCK_STREAM, IPPROTO_TCP))
95 .WillOnce(Return(-1));
96 EXPECT_FALSE(server_.Start(NULL, &sockets_));
97 ExpectNotStarted();
98}
99
100TEST_F(OpenVPNManagementServerTest, StartGetSockNameFail) {
101 const int kSocket = 123;
102 EXPECT_CALL(sockets_, Socket(AF_INET, SOCK_STREAM, IPPROTO_TCP))
103 .WillOnce(Return(kSocket));
104 EXPECT_CALL(sockets_, Bind(kSocket, _, _)).WillOnce(Return(0));
105 EXPECT_CALL(sockets_, Listen(kSocket, 1)).WillOnce(Return(0));
106 EXPECT_CALL(sockets_, GetSockName(kSocket, _, _)).WillOnce(Return(-1));
107 EXPECT_CALL(sockets_, Close(kSocket)).WillOnce(Return(0));
108 EXPECT_FALSE(server_.Start(NULL, &sockets_));
109 ExpectNotStarted();
110}
111
Darin Petkov78f63262012-03-26 01:30:24 +0200112TEST_F(OpenVPNManagementServerTest, Start) {
Darin Petkov271fe522012-03-27 13:47:29 +0200113 const int kSocket = 123;
114 EXPECT_CALL(sockets_, Socket(AF_INET, SOCK_STREAM, IPPROTO_TCP))
115 .WillOnce(Return(kSocket));
116 EXPECT_CALL(sockets_, Bind(kSocket, _, _)).WillOnce(Return(0));
117 EXPECT_CALL(sockets_, Listen(kSocket, 1)).WillOnce(Return(0));
118 EXPECT_CALL(sockets_, GetSockName(kSocket, _, _)).WillOnce(Return(0));
119 EXPECT_CALL(dispatcher_,
120 CreateReadyHandler(kSocket, IOHandler::kModeInput,
121 CallbackEq(server_.ready_callback_)))
122 .WillOnce(ReturnNew<IOHandler>());
123 EXPECT_TRUE(server_.Start(&dispatcher_, &sockets_));
124 EXPECT_EQ(&sockets_, server_.sockets_);
125 EXPECT_EQ(kSocket, server_.socket_);
126 EXPECT_TRUE(server_.ready_handler_.get());
127 EXPECT_EQ(&dispatcher_, server_.dispatcher_);
128}
129
130TEST_F(OpenVPNManagementServerTest, Stop) {
131 SetSockets();
132 server_.input_handler_.reset(new IOHandler());
133 const int kConnectedSocket = 234;
134 server_.connected_socket_ = kConnectedSocket;
135 EXPECT_CALL(sockets_, Close(kConnectedSocket)).WillOnce(Return(0));
136 SetDispatcher();
137 server_.ready_handler_.reset(new IOHandler());
138 const int kSocket = 345;
139 server_.socket_ = kSocket;
140 EXPECT_CALL(sockets_, Close(kSocket)).WillOnce(Return(0));
141 server_.Stop();
142 EXPECT_FALSE(server_.input_handler_.get());
143 EXPECT_EQ(-1, server_.connected_socket_);
144 EXPECT_FALSE(server_.dispatcher_);
145 EXPECT_FALSE(server_.ready_handler_.get());
146 EXPECT_EQ(-1, server_.socket_);
147 ExpectNotStarted();
148}
149
150TEST_F(OpenVPNManagementServerTest, OnReadyAcceptFail) {
151 const int kSocket = 333;
152 SetSockets();
153 EXPECT_CALL(sockets_, Accept(kSocket, NULL, NULL)).WillOnce(Return(-1));
154 server_.OnReady(kSocket);
155 EXPECT_EQ(-1, server_.connected_socket_);
156}
157
158TEST_F(OpenVPNManagementServerTest, OnReady) {
159 const int kSocket = 111;
Darin Petkov683942b2012-03-27 18:00:04 +0200160 SetConnectedSocket();
Darin Petkov271fe522012-03-27 13:47:29 +0200161 SetDispatcher();
162 EXPECT_CALL(sockets_, Accept(kSocket, NULL, NULL))
163 .WillOnce(Return(kConnectedSocket));
164 server_.ready_handler_.reset(new IOHandler());
165 EXPECT_CALL(dispatcher_,
166 CreateInputHandler(kConnectedSocket,
167 CallbackEq(server_.input_callback_)))
168 .WillOnce(ReturnNew<IOHandler>());
Darin Petkov683942b2012-03-27 18:00:04 +0200169 ExpectSend("state on\n");
Darin Petkov271fe522012-03-27 13:47:29 +0200170 server_.OnReady(kSocket);
171 EXPECT_EQ(kConnectedSocket, server_.connected_socket_);
172 EXPECT_FALSE(server_.ready_handler_.get());
173 EXPECT_TRUE(server_.input_handler_.get());
174}
175
176TEST_F(OpenVPNManagementServerTest, OnInput) {
177 {
178 string s;
179 InputData data = CreateInputDataFromString(s);
180 server_.OnInput(&data);
181 }
182 {
183 string s = "foo\n"
184 ">INFO:...\n"
Darin Petkov683942b2012-03-27 18:00:04 +0200185 ">PASSWORD:Need 'Auth' SC:user/password/otp\n"
Darin Petkov271fe522012-03-27 13:47:29 +0200186 ">STATE:123,RECONNECTING,detail,...,...";
187 InputData data = CreateInputDataFromString(s);
Darin Petkov683942b2012-03-27 18:00:04 +0200188 ExpectStaticChallengeResponse();
Darin Petkov271fe522012-03-27 13:47:29 +0200189 EXPECT_CALL(driver_, OnReconnecting());
190 server_.OnInput(&data);
191 }
192}
193
194TEST_F(OpenVPNManagementServerTest, ProcessMessage) {
195 server_.ProcessMessage("foo");
196 server_.ProcessMessage(">INFO:");
197
198 EXPECT_CALL(driver_, OnReconnecting());
199 server_.ProcessMessage(">STATE:123,RECONNECTING,detail,...,...");
200}
201
202TEST_F(OpenVPNManagementServerTest, ProcessInfoMessage) {
203 EXPECT_FALSE(server_.ProcessInfoMessage("foo"));
204 EXPECT_TRUE(server_.ProcessInfoMessage(">INFO:"));
205}
206
207TEST_F(OpenVPNManagementServerTest, ProcessStateMessage) {
208 EXPECT_FALSE(server_.ProcessStateMessage("foo"));
209 EXPECT_TRUE(server_.ProcessStateMessage(">STATE:123,WAIT,detail,...,..."));
210 EXPECT_CALL(driver_, OnReconnecting());
211 EXPECT_TRUE(
212 server_.ProcessStateMessage(">STATE:123,RECONNECTING,detail,...,..."));
213}
214
Darin Petkov683942b2012-03-27 18:00:04 +0200215TEST_F(OpenVPNManagementServerTest, ProcessNeedPasswordMessageAuthSC) {
216 EXPECT_FALSE(server_.ProcessNeedPasswordMessage("foo"));
217 ExpectStaticChallengeResponse();
218 EXPECT_TRUE(
219 server_.ProcessNeedPasswordMessage(
220 ">PASSWORD:Need 'Auth' SC:user/password/otp"));
221 EXPECT_FALSE(driver_.args()->ContainsString(flimflam::kOpenVPNOTPProperty));
222}
223
224TEST_F(OpenVPNManagementServerTest, PerformStaticChallengeNoCreds) {
225 // Expect no crash due to null sockets_.
226 server_.PerformStaticChallenge();
227 driver_.args()->SetString(flimflam::kOpenVPNUserProperty, "jojo");
228 server_.PerformStaticChallenge();
229 driver_.args()->SetString(flimflam::kOpenVPNPasswordProperty, "yoyo");
230 server_.PerformStaticChallenge();
231}
232
233TEST_F(OpenVPNManagementServerTest, PerformStaticChallenge) {
234 ExpectStaticChallengeResponse();
235 server_.PerformStaticChallenge();
236 EXPECT_FALSE(driver_.args()->ContainsString(flimflam::kOpenVPNOTPProperty));
237}
238
Darin Petkov271fe522012-03-27 13:47:29 +0200239TEST_F(OpenVPNManagementServerTest, Send) {
Darin Petkov271fe522012-03-27 13:47:29 +0200240 const char kMessage[] = "foo\n";
Darin Petkov683942b2012-03-27 18:00:04 +0200241 SetConnectedSocket();
242 ExpectSend(kMessage);
Darin Petkov271fe522012-03-27 13:47:29 +0200243 server_.Send(kMessage);
244}
245
246TEST_F(OpenVPNManagementServerTest, SendState) {
Darin Petkov683942b2012-03-27 18:00:04 +0200247 SetConnectedSocket();
248 ExpectSend("state off\n");
Darin Petkov271fe522012-03-27 13:47:29 +0200249 server_.SendState("off");
Darin Petkov1c115202012-03-22 15:35:47 +0100250}
251
Darin Petkov683942b2012-03-27 18:00:04 +0200252TEST_F(OpenVPNManagementServerTest, SendUsername) {
253 SetConnectedSocket();
254 ExpectSend("username \"Auth\" joesmith\n");
255 server_.SendUsername("Auth", "joesmith");
256}
257
258TEST_F(OpenVPNManagementServerTest, SendPassword) {
259 SetConnectedSocket();
260 ExpectSend("password \"Auth\" \"foobar\"\n");
261 server_.SendPassword("Auth", "foobar");
262}
263
Darin Petkov1c115202012-03-22 15:35:47 +0100264} // namespace shill