shill: vpn: Implement OpenVPN static challenge authentication.
BUG=chromium-os:26994
TEST=unit tests
Change-Id: I80a0c51afdcfe435f32c94679d993ccd85910a7b
Reviewed-on: https://gerrit.chromium.org/gerrit/19161
Tested-by: Darin Petkov <petkov@chromium.org>
Reviewed-by: Paul Stewart <pstew@chromium.org>
Commit-Ready: Darin Petkov <petkov@chromium.org>
diff --git a/openvpn_management_server_unittest.cc b/openvpn_management_server_unittest.cc
index 2e8b037..b8064a1 100644
--- a/openvpn_management_server_unittest.cc
+++ b/openvpn_management_server_unittest.cc
@@ -6,8 +6,10 @@
#include <netinet/in.h>
+#include <chromeos/dbus/service_constants.h>
#include <gtest/gtest.h>
+#include "shill/glib.h"
#include "shill/key_value_store.h"
#include "shill/mock_event_dispatcher.h"
#include "shill/mock_openvpn_driver.h"
@@ -34,7 +36,7 @@
public:
OpenVPNManagementServerTest()
: driver_(args_),
- server_(&driver_) {}
+ server_(&driver_, &glib_) {}
virtual ~OpenVPNManagementServerTest() {}
@@ -42,11 +44,26 @@
void SetDispatcher() { server_.dispatcher_ = &dispatcher_; }
void ExpectNotStarted() { EXPECT_TRUE(server_.sockets_ == NULL); }
- void ExpectSend(int socket, const string &value) {
- EXPECT_CALL(sockets_, Send(socket, VoidStringEq(value), value.size(), 0))
+ void SetConnectedSocket() {
+ server_.connected_socket_ = kConnectedSocket;
+ SetSockets();
+ }
+
+ void ExpectSend(const string &value) {
+ EXPECT_CALL(sockets_,
+ Send(kConnectedSocket, VoidStringEq(value), value.size(), 0))
.WillOnce(Return(value.size()));
}
+ void ExpectStaticChallengeResponse() {
+ driver_.args()->SetString(flimflam::kOpenVPNUserProperty, "jojo");
+ driver_.args()->SetString(flimflam::kOpenVPNPasswordProperty, "yoyo");
+ driver_.args()->SetString(flimflam::kOpenVPNOTPProperty, "123456");
+ SetConnectedSocket();
+ ExpectSend("username \"Auth\" jojo\n");
+ ExpectSend("password \"Auth\" \"SCRV1:eW95bw==:MTIzNDU2\"\n");
+ }
+
InputData CreateInputDataFromString(const string &str) {
InputData data(
reinterpret_cast<unsigned char *>(const_cast<char *>(str.data())),
@@ -55,6 +72,9 @@
}
protected:
+ static const int kConnectedSocket;
+
+ GLib glib_;
KeyValueStore args_;
MockOpenVPNDriver driver_;
OpenVPNManagementServer server_;
@@ -62,6 +82,9 @@
MockEventDispatcher dispatcher_;
};
+// static
+const int OpenVPNManagementServerTest::kConnectedSocket = 555;
+
TEST_F(OpenVPNManagementServerTest, StartStarted) {
SetSockets();
EXPECT_TRUE(server_.Start(NULL, NULL));
@@ -134,8 +157,7 @@
TEST_F(OpenVPNManagementServerTest, OnReady) {
const int kSocket = 111;
- const int kConnectedSocket = 112;
- SetSockets();
+ SetConnectedSocket();
SetDispatcher();
EXPECT_CALL(sockets_, Accept(kSocket, NULL, NULL))
.WillOnce(Return(kConnectedSocket));
@@ -144,7 +166,7 @@
CreateInputHandler(kConnectedSocket,
CallbackEq(server_.input_callback_)))
.WillOnce(ReturnNew<IOHandler>());
- ExpectSend(kConnectedSocket, "state on\n");
+ ExpectSend("state on\n");
server_.OnReady(kSocket);
EXPECT_EQ(kConnectedSocket, server_.connected_socket_);
EXPECT_FALSE(server_.ready_handler_.get());
@@ -160,8 +182,10 @@
{
string s = "foo\n"
">INFO:...\n"
+ ">PASSWORD:Need 'Auth' SC:user/password/otp\n"
">STATE:123,RECONNECTING,detail,...,...";
InputData data = CreateInputDataFromString(s);
+ ExpectStaticChallengeResponse();
EXPECT_CALL(driver_, OnReconnecting());
server_.OnInput(&data);
}
@@ -188,21 +212,53 @@
server_.ProcessStateMessage(">STATE:123,RECONNECTING,detail,...,..."));
}
+TEST_F(OpenVPNManagementServerTest, ProcessNeedPasswordMessageAuthSC) {
+ EXPECT_FALSE(server_.ProcessNeedPasswordMessage("foo"));
+ ExpectStaticChallengeResponse();
+ EXPECT_TRUE(
+ server_.ProcessNeedPasswordMessage(
+ ">PASSWORD:Need 'Auth' SC:user/password/otp"));
+ EXPECT_FALSE(driver_.args()->ContainsString(flimflam::kOpenVPNOTPProperty));
+}
+
+TEST_F(OpenVPNManagementServerTest, PerformStaticChallengeNoCreds) {
+ // Expect no crash due to null sockets_.
+ server_.PerformStaticChallenge();
+ driver_.args()->SetString(flimflam::kOpenVPNUserProperty, "jojo");
+ server_.PerformStaticChallenge();
+ driver_.args()->SetString(flimflam::kOpenVPNPasswordProperty, "yoyo");
+ server_.PerformStaticChallenge();
+}
+
+TEST_F(OpenVPNManagementServerTest, PerformStaticChallenge) {
+ ExpectStaticChallengeResponse();
+ server_.PerformStaticChallenge();
+ EXPECT_FALSE(driver_.args()->ContainsString(flimflam::kOpenVPNOTPProperty));
+}
+
TEST_F(OpenVPNManagementServerTest, Send) {
- const int kSocket = 555;
const char kMessage[] = "foo\n";
- server_.connected_socket_ = kSocket;
- SetSockets();
- ExpectSend(kSocket, kMessage);
+ SetConnectedSocket();
+ ExpectSend(kMessage);
server_.Send(kMessage);
}
TEST_F(OpenVPNManagementServerTest, SendState) {
- const int kSocket = 555;
- server_.connected_socket_ = kSocket;
- SetSockets();
- ExpectSend(kSocket, "state off\n");
+ SetConnectedSocket();
+ ExpectSend("state off\n");
server_.SendState("off");
}
+TEST_F(OpenVPNManagementServerTest, SendUsername) {
+ SetConnectedSocket();
+ ExpectSend("username \"Auth\" joesmith\n");
+ server_.SendUsername("Auth", "joesmith");
+}
+
+TEST_F(OpenVPNManagementServerTest, SendPassword) {
+ SetConnectedSocket();
+ ExpectSend("password \"Auth\" \"foobar\"\n");
+ server_.SendPassword("Auth", "foobar");
+}
+
} // namespace shill