// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "shill/openvpn_management_server.h"

#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"
#include "shill/net/mock_sockets.h"

using base::Bind;
using base::Unretained;
using std::string;
using std::vector;
using testing::_;
using testing::Assign;
using testing::InSequence;
using testing::Return;
using testing::ReturnNew;

namespace shill {

namespace {
MATCHER_P(VoidStringEq, value, "") {
  return value == reinterpret_cast<const char *>(arg);
}
}  // namespace

class OpenVPNManagementServerTest : public testing::Test {
 public:
  OpenVPNManagementServerTest()
      : server_(&driver_, &glib_) {}

  virtual ~OpenVPNManagementServerTest() {}

 protected:
  static const int kConnectedSocket;

  void SetSockets() { server_.sockets_ = &sockets_; }
  void SetDispatcher() { server_.dispatcher_ = &dispatcher_; }
  void ExpectNotStarted() { EXPECT_FALSE(server_.IsStarted()); }

  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 ExpectOTPStaticChallengeResponse() {
    driver_.args()->SetString(kOpenVPNUserProperty, "jojo");
    driver_.args()->SetString(kOpenVPNPasswordProperty, "yoyo");
    driver_.args()->SetString(kOpenVPNOTPProperty, "123456");
    SetConnectedSocket();
    ExpectSend("username \"Auth\" jojo\n");
    ExpectSend("password \"Auth\" \"SCRV1:eW95bw==:MTIzNDU2\"\n");
  }

  void ExpectTokenStaticChallengeResponse() {
    driver_.args()->SetString(kOpenVPNUserProperty, "jojo");
    driver_.args()->SetString(kOpenVPNTokenProperty, "toto");
    SetConnectedSocket();
    ExpectSend("username \"Auth\" jojo\n");
    ExpectSend("password \"Auth\" \"toto\"\n");
  }

  void ExpectAuthenticationResponse() {
    driver_.args()->SetString(kOpenVPNUserProperty, "jojo");
    driver_.args()->SetString(kOpenVPNPasswordProperty, "yoyo");
    SetConnectedSocket();
    ExpectSend("username \"Auth\" jojo\n");
    ExpectSend("password \"Auth\" \"yoyo\"\n");
  }

  void ExpectPINResponse() {
    driver_.args()->SetString(kOpenVPNPinProperty, "987654");
    SetConnectedSocket();
    ExpectSend("password \"User-Specific TPM Token FOO\" \"987654\"\n");
  }

  void ExpectHoldRelease() {
    SetConnectedSocket();
    ExpectSend("hold release\n");
  }

  void ExpectRestart() {
    SetConnectedSocket();
    ExpectSend("signal SIGUSR1\n");
  }

  InputData CreateInputDataFromString(const string &str) {
    InputData data(
        reinterpret_cast<unsigned char *>(const_cast<char *>(str.data())),
        str.size());
    return data;
  }

  void SendSignal(const string &signal) {
    server_.SendSignal(signal);
  }

  void OnInput(InputData *data) {
    server_.OnInput(data);
  }

  void ProcessMessage(const string &message) {
    server_.ProcessMessage(message);
  }

  bool ProcessSuccessMessage(const string &message) {
    return server_.ProcessSuccessMessage(message);
  }

  bool ProcessStateMessage(const string &message) {
    return server_.ProcessStateMessage(message);
  }

  bool ProcessAuthTokenMessage(const string &message) {
    return server_.ProcessAuthTokenMessage(message);
  }

  bool GetHoldWaiting() { return server_.hold_waiting_; }

  static string ParseSubstring(
      const string &message, const string &start, const string &end) {
    return OpenVPNManagementServer::ParseSubstring(message, start, end);
  }

  static string ParsePasswordTag(const string &message) {
    return OpenVPNManagementServer::ParsePasswordTag(message);
  }

  static string ParsePasswordFailedReason(const string &message) {
    return OpenVPNManagementServer::ParsePasswordFailedReason(message);
  }

  void SetClientState(const string &state) {
    server_.state_ = state;
  }

  GLib glib_;
  MockOpenVPNDriver driver_;
  MockSockets sockets_;
  MockEventDispatcher dispatcher_;
  OpenVPNManagementServer server_;  // Destroy before anything it references.
};

// static
const int OpenVPNManagementServerTest::kConnectedSocket = 555;

TEST_F(OpenVPNManagementServerTest, StartStarted) {
  SetSockets();
  EXPECT_TRUE(server_.Start(nullptr, nullptr, nullptr));
}

TEST_F(OpenVPNManagementServerTest, StartSocketFail) {
  EXPECT_CALL(sockets_, Socket(AF_INET, SOCK_STREAM, IPPROTO_TCP))
      .WillOnce(Return(-1));
  EXPECT_FALSE(server_.Start(nullptr, &sockets_, nullptr));
  ExpectNotStarted();
}

TEST_F(OpenVPNManagementServerTest, StartGetSockNameFail) {
  const int kSocket = 123;
  EXPECT_CALL(sockets_, Socket(AF_INET, SOCK_STREAM, IPPROTO_TCP))
      .WillOnce(Return(kSocket));
  EXPECT_CALL(sockets_, Bind(kSocket, _, _)).WillOnce(Return(0));
  EXPECT_CALL(sockets_, Listen(kSocket, 1)).WillOnce(Return(0));
  EXPECT_CALL(sockets_, GetSockName(kSocket, _, _)).WillOnce(Return(-1));
  EXPECT_CALL(sockets_, Close(kSocket)).WillOnce(Return(0));
  EXPECT_FALSE(server_.Start(nullptr, &sockets_, nullptr));
  ExpectNotStarted();
}

TEST_F(OpenVPNManagementServerTest, Start) {
  const string kStaticChallenge = "static-challenge";
  driver_.args()->SetString(kOpenVPNStaticChallengeProperty, kStaticChallenge);
  const int kSocket = 123;
  EXPECT_CALL(sockets_, Socket(AF_INET, SOCK_STREAM, IPPROTO_TCP))
      .WillOnce(Return(kSocket));
  EXPECT_CALL(sockets_, Bind(kSocket, _, _)).WillOnce(Return(0));
  EXPECT_CALL(sockets_, Listen(kSocket, 1)).WillOnce(Return(0));
  EXPECT_CALL(sockets_, GetSockName(kSocket, _, _)).WillOnce(Return(0));
  EXPECT_CALL(dispatcher_,
              CreateReadyHandler(kSocket, IOHandler::kModeInput, _))
      .WillOnce(ReturnNew<IOHandler>());
  vector<vector<string>> options;
  EXPECT_TRUE(server_.Start(&dispatcher_, &sockets_, &options));
  EXPECT_EQ(&sockets_, server_.sockets_);
  EXPECT_EQ(kSocket, server_.socket_);
  EXPECT_TRUE(server_.ready_handler_.get());
  EXPECT_EQ(&dispatcher_, server_.dispatcher_);
  vector<vector<string>> expected_options {
      { "management", "127.0.0.1", "0" },
      { "management-client" },
      { "management-hold" },
      { "management-query-passwords" },
      { "static-challenge", kStaticChallenge, "1" }
  };
  EXPECT_EQ(expected_options, options);
}

TEST_F(OpenVPNManagementServerTest, Stop) {
  EXPECT_TRUE(server_.state().empty());
  SetSockets();
  server_.input_handler_.reset(new IOHandler());
  const int kConnectedSocket = 234;
  server_.connected_socket_ = kConnectedSocket;
  EXPECT_CALL(sockets_, Close(kConnectedSocket)).WillOnce(Return(0));
  SetDispatcher();
  server_.ready_handler_.reset(new IOHandler());
  const int kSocket = 345;
  server_.socket_ = kSocket;
  SetClientState(OpenVPNManagementServer::kStateReconnecting);
  EXPECT_CALL(sockets_, Close(kSocket)).WillOnce(Return(0));
  server_.Stop();
  EXPECT_FALSE(server_.input_handler_.get());
  EXPECT_EQ(-1, server_.connected_socket_);
  EXPECT_FALSE(server_.dispatcher_);
  EXPECT_FALSE(server_.ready_handler_.get());
  EXPECT_EQ(-1, server_.socket_);
  EXPECT_TRUE(server_.state().empty());
  ExpectNotStarted();
}

TEST_F(OpenVPNManagementServerTest, OnReadyAcceptFail) {
  const int kSocket = 333;
  SetSockets();
  EXPECT_CALL(sockets_, Accept(kSocket, nullptr, nullptr)).WillOnce(Return(-1));
  server_.OnReady(kSocket);
  EXPECT_EQ(-1, server_.connected_socket_);
}

TEST_F(OpenVPNManagementServerTest, OnReady) {
  const int kSocket = 111;
  SetConnectedSocket();
  SetDispatcher();
  EXPECT_CALL(sockets_, Accept(kSocket, nullptr, nullptr))
      .WillOnce(Return(kConnectedSocket));
  server_.ready_handler_.reset(new IOHandler());
  EXPECT_CALL(dispatcher_, CreateInputHandler(kConnectedSocket, _, _))
      .WillOnce(ReturnNew<IOHandler>());
  ExpectSend("state on\n");
  server_.OnReady(kSocket);
  EXPECT_EQ(kConnectedSocket, server_.connected_socket_);
  EXPECT_FALSE(server_.ready_handler_.get());
  EXPECT_TRUE(server_.input_handler_.get());
}

TEST_F(OpenVPNManagementServerTest, OnInput) {
  {
    string s;
    InputData data = CreateInputDataFromString(s);
    OnInput(&data);
  }
  {
    string s = "foo\n"
        ">INFO:...\n"
        ">PASSWORD:Need 'Auth' SC:user/password/otp\n"
        ">PASSWORD:Need 'User-Specific TPM Token FOO' ...\n"
        ">PASSWORD:Verification Failed: .\n"
        ">PASSWORD:Auth-Token:ToKeN==\n"
        ">STATE:123,RECONNECTING,detail,...,...\n"
        ">HOLD:Waiting for hold release\n"
        "SUCCESS: Hold released.";
    InputData data = CreateInputDataFromString(s);
    ExpectOTPStaticChallengeResponse();
    ExpectPINResponse();
    EXPECT_CALL(driver_, FailService(Service::kFailureConnect,
                                     Service::kErrorDetailsNone));
    EXPECT_CALL(driver_, OnReconnecting(_));
    EXPECT_FALSE(GetHoldWaiting());
    OnInput(&data);
    EXPECT_TRUE(GetHoldWaiting());
  }
}

TEST_F(OpenVPNManagementServerTest, OnInputStop) {
  string s =
      ">PASSWORD:Verification Failed: .\n"
      ">STATE:123,RECONNECTING,detail,...,...";
  InputData data = CreateInputDataFromString(s);
  SetSockets();
  // Stops the server after the first message is processed.
  EXPECT_CALL(driver_, FailService(Service::kFailureConnect,
                                   Service::kErrorDetailsNone))
      .WillOnce(Assign(&server_.sockets_, nullptr));
  // The second message should not be processed.
  EXPECT_CALL(driver_, OnReconnecting(_)).Times(0);
  OnInput(&data);
}

TEST_F(OpenVPNManagementServerTest, ProcessMessage) {
  ProcessMessage("foo");
  ProcessMessage(">INFO:");

  EXPECT_CALL(driver_, OnReconnecting(_));
  ProcessMessage(">STATE:123,RECONNECTING,detail,...,...");
}

TEST_F(OpenVPNManagementServerTest, ProcessSuccessMessage) {
  EXPECT_FALSE(ProcessSuccessMessage("foo"));
  EXPECT_TRUE(ProcessSuccessMessage("SUCCESS: foo"));
}

TEST_F(OpenVPNManagementServerTest, ProcessInfoMessage) {
  EXPECT_FALSE(server_.ProcessInfoMessage("foo"));
  EXPECT_TRUE(server_.ProcessInfoMessage(">INFO:foo"));
}

TEST_F(OpenVPNManagementServerTest, ProcessStateMessage) {
  EXPECT_TRUE(server_.state().empty());
  EXPECT_FALSE(ProcessStateMessage("foo"));
  EXPECT_TRUE(server_.state().empty());
  EXPECT_TRUE(ProcessStateMessage(">STATE:123,WAIT,detail,...,..."));
  EXPECT_EQ("WAIT", server_.state());
  {
    InSequence seq;
    EXPECT_CALL(driver_,
                OnReconnecting(OpenVPNDriver::kReconnectReasonUnknown));
    EXPECT_CALL(driver_,
                OnReconnecting(OpenVPNDriver::kReconnectReasonTLSError));
  }
  EXPECT_TRUE(ProcessStateMessage(">STATE:123,RECONNECTING,detail,...,..."));
  EXPECT_EQ(OpenVPNManagementServer::kStateReconnecting, server_.state());
  EXPECT_TRUE(ProcessStateMessage(">STATE:123,RECONNECTING,tls-error,...,..."));
}

TEST_F(OpenVPNManagementServerTest, ProcessNeedPasswordMessageAuthSC) {
  ExpectOTPStaticChallengeResponse();
  EXPECT_TRUE(
      server_.ProcessNeedPasswordMessage(
          ">PASSWORD:Need 'Auth' SC:user/password/otp"));
  EXPECT_FALSE(driver_.args()->ContainsString(kOpenVPNOTPProperty));
}

TEST_F(OpenVPNManagementServerTest, ProcessNeedPasswordMessageAuth) {
  ExpectAuthenticationResponse();
  EXPECT_TRUE(
      server_.ProcessNeedPasswordMessage(
          ">PASSWORD:Need 'Auth' username/password"));
}

TEST_F(OpenVPNManagementServerTest, ProcessNeedPasswordMessageTPMToken) {
  ExpectPINResponse();
  EXPECT_TRUE(
      server_.ProcessNeedPasswordMessage(
          ">PASSWORD:Need 'User-Specific TPM Token FOO' ..."));
}

TEST_F(OpenVPNManagementServerTest, ProcessNeedPasswordMessageUnknown) {
  EXPECT_FALSE(server_.ProcessNeedPasswordMessage("foo"));
}

TEST_F(OpenVPNManagementServerTest, ParseSubstring) {
  EXPECT_EQ("", ParseSubstring("", "'", "'"));
  EXPECT_EQ("", ParseSubstring(" ", "'", "'"));
  EXPECT_EQ("", ParseSubstring("'", "'", "'"));
  EXPECT_EQ("", ParseSubstring("''", "'", "'"));
  EXPECT_EQ("", ParseSubstring("] [", "[", "]"));
  EXPECT_EQ("", ParseSubstring("[]", "[", "]"));
  EXPECT_EQ("bar", ParseSubstring("foo['bar']zoo", "['", "']"));
  EXPECT_EQ("bar", ParseSubstring("foo['bar']", "['", "']"));
  EXPECT_EQ("bar", ParseSubstring("['bar']zoo", "['", "']"));
  EXPECT_EQ("bar", ParseSubstring("['bar']['zoo']", "['", "']"));
}

TEST_F(OpenVPNManagementServerTest, ParsePasswordTag) {
  EXPECT_EQ("", ParsePasswordTag(""));
  EXPECT_EQ("Auth",
            ParsePasswordTag(
                ">PASSWORD:Verification Failed: 'Auth' "
                "['REVOKED: client certificate has been revoked']"));
}

TEST_F(OpenVPNManagementServerTest, ParsePasswordFailedReason) {
  EXPECT_EQ("", ParsePasswordFailedReason(""));
  EXPECT_EQ("REVOKED: client certificate has been revoked",
            ParsePasswordFailedReason(
                ">PASSWORD:Verification Failed: 'Auth' "
                "['REVOKED: client certificate has been revoked']"));
}

TEST_F(OpenVPNManagementServerTest, PerformStaticChallengeNoCreds) {
  EXPECT_CALL(driver_, FailService(Service::kFailureInternal,
                                   Service::kErrorDetailsNone)).Times(4);
  server_.PerformStaticChallenge("Auth");
  driver_.args()->SetString(kOpenVPNUserProperty, "jojo");
  server_.PerformStaticChallenge("Auth");
  driver_.args()->SetString(kOpenVPNPasswordProperty, "yoyo");
  server_.PerformStaticChallenge("Auth");
  driver_.args()->Clear();
  driver_.args()->SetString(kOpenVPNTokenProperty, "toto");
  server_.PerformStaticChallenge("Auth");
}

TEST_F(OpenVPNManagementServerTest, PerformStaticChallengeOTP) {
  ExpectOTPStaticChallengeResponse();
  server_.PerformStaticChallenge("Auth");
  EXPECT_FALSE(driver_.args()->ContainsString(kOpenVPNOTPProperty));
}

TEST_F(OpenVPNManagementServerTest, PerformStaticChallengeToken) {
  ExpectTokenStaticChallengeResponse();
  server_.PerformStaticChallenge("Auth");
  EXPECT_FALSE(driver_.args()->ContainsString(kOpenVPNTokenProperty));
}

TEST_F(OpenVPNManagementServerTest, PerformAuthenticationNoCreds) {
  EXPECT_CALL(driver_, FailService(Service::kFailureInternal,
                                   Service::kErrorDetailsNone)).Times(2);
  server_.PerformAuthentication("Auth");
  driver_.args()->SetString(kOpenVPNUserProperty, "jojo");
  server_.PerformAuthentication("Auth");
}

TEST_F(OpenVPNManagementServerTest, PerformAuthentication) {
  ExpectAuthenticationResponse();
  server_.PerformAuthentication("Auth");
}

TEST_F(OpenVPNManagementServerTest, ProcessHoldMessage) {
  EXPECT_FALSE(server_.hold_release_);
  EXPECT_FALSE(server_.hold_waiting_);

  EXPECT_FALSE(server_.ProcessHoldMessage("foo"));

  EXPECT_TRUE(server_.ProcessHoldMessage(">HOLD:Waiting for hold release"));
  EXPECT_FALSE(server_.hold_release_);
  EXPECT_TRUE(server_.hold_waiting_);

  ExpectHoldRelease();
  server_.hold_release_ = true;
  server_.hold_waiting_ = false;
  EXPECT_TRUE(server_.ProcessHoldMessage(">HOLD:Waiting for hold release"));
  EXPECT_TRUE(server_.hold_release_);
  EXPECT_FALSE(server_.hold_waiting_);
}

TEST_F(OpenVPNManagementServerTest, SupplyTPMTokenNoPIN) {
  EXPECT_CALL(driver_, FailService(Service::kFailureInternal,
                                   Service::kErrorDetailsNone));
  server_.SupplyTPMToken("User-Specific TPM Token FOO");
}

TEST_F(OpenVPNManagementServerTest, SupplyTPMToken) {
  ExpectPINResponse();
  server_.SupplyTPMToken("User-Specific TPM Token FOO");
}

TEST_F(OpenVPNManagementServerTest, Send) {
  const char kMessage[] = "foo\n";
  SetConnectedSocket();
  ExpectSend(kMessage);
  server_.Send(kMessage);
}

TEST_F(OpenVPNManagementServerTest, SendState) {
  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\" \"foo\\\"bar\"\n");
  server_.SendPassword("Auth", "foo\"bar");
}

TEST_F(OpenVPNManagementServerTest, ProcessFailedPasswordMessage) {
  EXPECT_FALSE(server_.ProcessFailedPasswordMessage("foo"));
  EXPECT_CALL(driver_, FailService(Service::kFailureConnect,
                                   Service::kErrorDetailsNone)).Times(3);
  EXPECT_CALL(driver_, FailService(Service::kFailureConnect, "Revoked."));
  EXPECT_TRUE(
      server_.ProcessFailedPasswordMessage(">PASSWORD:Verification Failed: ."));
  EXPECT_TRUE(
      server_.ProcessFailedPasswordMessage(
          ">PASSWORD:Verification Failed: 'Private Key' ['Reason']"));
  EXPECT_TRUE(
      server_.ProcessFailedPasswordMessage(
          ">PASSWORD:Verification Failed: 'Auth'"));
  EXPECT_TRUE(
      server_.ProcessFailedPasswordMessage(
          ">PASSWORD:Verification Failed: 'Auth' ['Revoked.']"));
}

TEST_F(OpenVPNManagementServerTest, ProcessAuthTokenMessage) {
  EXPECT_FALSE(ProcessAuthTokenMessage("foo"));
  EXPECT_TRUE(ProcessAuthTokenMessage(">PASSWORD:Auth-Token:ToKeN=="));
}

TEST_F(OpenVPNManagementServerTest, SendSignal) {
  SetConnectedSocket();
  ExpectSend("signal SIGUSR2\n");
  SendSignal("SIGUSR2");
}

TEST_F(OpenVPNManagementServerTest, Restart) {
  ExpectRestart();
  server_.Restart();
}

TEST_F(OpenVPNManagementServerTest, SendHoldRelease) {
  ExpectHoldRelease();
  server_.SendHoldRelease();
}

TEST_F(OpenVPNManagementServerTest, Hold) {
  EXPECT_FALSE(server_.hold_release_);
  EXPECT_FALSE(server_.hold_waiting_);

  server_.ReleaseHold();
  EXPECT_TRUE(server_.hold_release_);
  EXPECT_FALSE(server_.hold_waiting_);

  server_.Hold();
  EXPECT_FALSE(server_.hold_release_);
  EXPECT_FALSE(server_.hold_waiting_);

  server_.hold_waiting_ = true;
  ExpectHoldRelease();
  server_.ReleaseHold();
  EXPECT_TRUE(server_.hold_release_);
  EXPECT_FALSE(server_.hold_waiting_);
}

TEST_F(OpenVPNManagementServerTest, EscapeToQuote) {
  EXPECT_EQ("", OpenVPNManagementServer::EscapeToQuote(""));
  EXPECT_EQ("foo './", OpenVPNManagementServer::EscapeToQuote("foo './"));
  EXPECT_EQ("\\\\", OpenVPNManagementServer::EscapeToQuote("\\"));
  EXPECT_EQ("\\\"", OpenVPNManagementServer::EscapeToQuote("\""));
  EXPECT_EQ("\\\\\\\"foo\\\\bar\\\"",
            OpenVPNManagementServer::EscapeToQuote("\\\"foo\\bar\""));
}

}  // namespace shill
