| // 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. |
| |
| #ifndef SHILL_OPENVPN_MANAGEMENT_SERVER_H_ |
| #define SHILL_OPENVPN_MANAGEMENT_SERVER_H_ |
| |
| #include <string> |
| #include <vector> |
| |
| #include <base/basictypes.h> |
| #include <base/memory/scoped_ptr.h> |
| #include <gtest/gtest_prod.h> // for FRIEND_TEST |
| |
| namespace shill { |
| |
| class Error; |
| class EventDispatcher; |
| class GLib; |
| struct InputData; |
| class IOHandler; |
| class OpenVPNDriver; |
| class Sockets; |
| |
| class OpenVPNManagementServer { |
| public: |
| static const char kStateReconnecting[]; |
| static const char kStateResolve[]; |
| |
| OpenVPNManagementServer(OpenVPNDriver *driver, GLib *glib); |
| virtual ~OpenVPNManagementServer(); |
| |
| // Returns false on failure. On success, returns true and appends management |
| // interface openvpn options to |options|. |
| virtual bool Start(EventDispatcher *dispatcher, |
| Sockets *sockets, |
| std::vector<std::string> *options); |
| |
| virtual void Stop(); |
| |
| // Releases openvpn's hold if it's waiting for a hold release (i.e., if |
| // |hold_waiting_| is true). Otherwise, sets |hold_release_| to true |
| // indicating that the hold can be released as soon as openvpn requests. |
| virtual void ReleaseHold(); |
| |
| // Holds openvpn so that it doesn't connect or reconnect automatically (i.e., |
| // sets |hold_release_| to false). Note that this method neither drops an |
| // existing connection, nor sends any commands to the openvpn client. |
| virtual void Hold(); |
| |
| // Restarts openvpn causing a disconnect followed by a reconnect attempt. |
| virtual void Restart(); |
| |
| // OpenVPN client state. |
| const std::string &state() const { return state_; } |
| |
| private: |
| friend class OpenVPNDriverTest; |
| friend class OpenVPNManagementServerTest; |
| FRIEND_TEST(OpenVPNManagementServerTest, EscapeToQuote); |
| FRIEND_TEST(OpenVPNManagementServerTest, Hold); |
| FRIEND_TEST(OpenVPNManagementServerTest, OnInputStop); |
| FRIEND_TEST(OpenVPNManagementServerTest, OnReady); |
| FRIEND_TEST(OpenVPNManagementServerTest, OnReadyAcceptFail); |
| FRIEND_TEST(OpenVPNManagementServerTest, PerformAuthentication); |
| FRIEND_TEST(OpenVPNManagementServerTest, PerformAuthenticationNoCreds); |
| FRIEND_TEST(OpenVPNManagementServerTest, PerformStaticChallenge); |
| FRIEND_TEST(OpenVPNManagementServerTest, PerformStaticChallengeNoCreds); |
| FRIEND_TEST(OpenVPNManagementServerTest, ProcessFailedPasswordMessage); |
| FRIEND_TEST(OpenVPNManagementServerTest, ProcessHoldMessage); |
| FRIEND_TEST(OpenVPNManagementServerTest, ProcessInfoMessage); |
| FRIEND_TEST(OpenVPNManagementServerTest, ProcessNeedPasswordMessageAuth); |
| FRIEND_TEST(OpenVPNManagementServerTest, ProcessNeedPasswordMessageAuthSC); |
| FRIEND_TEST(OpenVPNManagementServerTest, ProcessNeedPasswordMessageTPMToken); |
| FRIEND_TEST(OpenVPNManagementServerTest, ProcessNeedPasswordMessageUnknown); |
| FRIEND_TEST(OpenVPNManagementServerTest, Send); |
| FRIEND_TEST(OpenVPNManagementServerTest, SendHoldRelease); |
| FRIEND_TEST(OpenVPNManagementServerTest, SendPassword); |
| FRIEND_TEST(OpenVPNManagementServerTest, SendState); |
| FRIEND_TEST(OpenVPNManagementServerTest, SendUsername); |
| FRIEND_TEST(OpenVPNManagementServerTest, Start); |
| FRIEND_TEST(OpenVPNManagementServerTest, Stop); |
| FRIEND_TEST(OpenVPNManagementServerTest, SupplyTPMToken); |
| FRIEND_TEST(OpenVPNManagementServerTest, SupplyTPMTokenNoPIN); |
| |
| // IO handler callbacks. |
| void OnReady(int fd); |
| void OnInput(InputData *data); |
| void OnInputError(const Error &error); |
| |
| void Send(const std::string &data); |
| void SendState(const std::string &state); |
| void SendUsername(const std::string &tag, const std::string &username); |
| void SendPassword(const std::string &tag, const std::string &password); |
| void SendHoldRelease(); |
| void SendSignal(const std::string &signal); |
| |
| void ProcessMessage(const std::string &message); |
| bool ProcessInfoMessage(const std::string &message); |
| bool ProcessNeedPasswordMessage(const std::string &message); |
| bool ProcessFailedPasswordMessage(const std::string &message); |
| bool ProcessAuthTokenMessage(const std::string &message); |
| bool ProcessStateMessage(const std::string &message); |
| bool ProcessHoldMessage(const std::string &message); |
| bool ProcessSuccessMessage(const std::string &message); |
| |
| void PerformStaticChallenge(const std::string &tag); |
| void PerformAuthentication(const std::string &tag); |
| void SupplyTPMToken(const std::string &tag); |
| |
| // Returns the first substring in |message| enclosed by the |start| and |end| |
| // substrings. Note that the first |end| substring after the position of |
| // |start| is matched. |
| static std::string ParseSubstring(const std::string &message, |
| const std::string &start, |
| const std::string &end); |
| |
| // Password messages come in two forms: |
| // |
| // >PASSWORD:Need 'AUTH_TYPE' ... |
| // >PASSWORD:Verification Failed: 'AUTH_TYPE' ['REASON_STRING'] |
| // |
| // ParsePasswordTag parses AUTH_TYPE out of a password |message| and returns |
| // it. ParsePasswordFailedReason parses REASON_STRING, if any, out of a |
| // password |message| and returns it. |
| static std::string ParsePasswordTag(const std::string &message); |
| static std::string ParsePasswordFailedReason(const std::string &message); |
| |
| // Escapes |str| per OpenVPN's command parsing rules assuming |str| will be |
| // sent over the management interface quoted (i.e., whitespace is not |
| // escaped). |
| static std::string EscapeToQuote(const std::string &str); |
| |
| bool IsStarted() const { return sockets_; } |
| |
| OpenVPNDriver *driver_; |
| GLib *glib_; |
| |
| Sockets *sockets_; |
| int socket_; |
| scoped_ptr<IOHandler> ready_handler_; |
| EventDispatcher *dispatcher_; |
| int connected_socket_; |
| scoped_ptr<IOHandler> input_handler_; |
| |
| std::string state_; |
| |
| bool hold_waiting_; |
| bool hold_release_; |
| |
| DISALLOW_COPY_AND_ASSIGN(OpenVPNManagementServer); |
| }; |
| |
| } // namespace shill |
| |
| #endif // SHILL_OPENVPN_MANAGEMENT_SERVER_H_ |