Darin Petkov | 1c11520 | 2012-03-22 15:35:47 +0100 | [diff] [blame] | 1 | // 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 | |
Darin Petkov | a42afe3 | 2013-02-05 16:53:52 +0100 | [diff] [blame] | 5 | #ifndef SHILL_OPENVPN_MANAGEMENT_SERVER_H_ |
| 6 | #define SHILL_OPENVPN_MANAGEMENT_SERVER_H_ |
Darin Petkov | 1c11520 | 2012-03-22 15:35:47 +0100 | [diff] [blame] | 7 | |
Darin Petkov | 4646302 | 2012-03-29 14:57:32 +0200 | [diff] [blame] | 8 | #include <string> |
| 9 | #include <vector> |
| 10 | |
Darin Petkov | 1c11520 | 2012-03-22 15:35:47 +0100 | [diff] [blame] | 11 | #include <base/basictypes.h> |
Darin Petkov | 3273da7 | 2013-02-13 11:50:25 +0100 | [diff] [blame] | 12 | #include <base/memory/scoped_ptr.h> |
Darin Petkov | 271fe52 | 2012-03-27 13:47:29 +0200 | [diff] [blame] | 13 | #include <gtest/gtest_prod.h> // for FRIEND_TEST |
Darin Petkov | 1c11520 | 2012-03-22 15:35:47 +0100 | [diff] [blame] | 14 | |
| 15 | namespace shill { |
| 16 | |
Darin Petkov | 3273da7 | 2013-02-13 11:50:25 +0100 | [diff] [blame] | 17 | class Error; |
Darin Petkov | 78f6326 | 2012-03-26 01:30:24 +0200 | [diff] [blame] | 18 | class EventDispatcher; |
Darin Petkov | 683942b | 2012-03-27 18:00:04 +0200 | [diff] [blame] | 19 | class GLib; |
Liam McLoughlin | f4baef2 | 2012-08-01 19:08:25 -0700 | [diff] [blame] | 20 | struct InputData; |
Darin Petkov | 78f6326 | 2012-03-26 01:30:24 +0200 | [diff] [blame] | 21 | class IOHandler; |
Darin Petkov | 1c11520 | 2012-03-22 15:35:47 +0100 | [diff] [blame] | 22 | class OpenVPNDriver; |
Darin Petkov | 78f6326 | 2012-03-26 01:30:24 +0200 | [diff] [blame] | 23 | class Sockets; |
Darin Petkov | 1c11520 | 2012-03-22 15:35:47 +0100 | [diff] [blame] | 24 | |
| 25 | class OpenVPNManagementServer { |
| 26 | public: |
Darin Petkov | 1c049c7 | 2013-03-21 13:15:45 +0100 | [diff] [blame] | 27 | static const char kStateReconnecting[]; |
| 28 | static const char kStateResolve[]; |
| 29 | |
Darin Petkov | 683942b | 2012-03-27 18:00:04 +0200 | [diff] [blame] | 30 | OpenVPNManagementServer(OpenVPNDriver *driver, GLib *glib); |
Darin Petkov | 1c11520 | 2012-03-22 15:35:47 +0100 | [diff] [blame] | 31 | virtual ~OpenVPNManagementServer(); |
| 32 | |
Darin Petkov | 4646302 | 2012-03-29 14:57:32 +0200 | [diff] [blame] | 33 | // Returns false on failure. On success, returns true and appends management |
| 34 | // interface openvpn options to |options|. |
| 35 | virtual bool Start(EventDispatcher *dispatcher, |
| 36 | Sockets *sockets, |
| 37 | std::vector<std::string> *options); |
Darin Petkov | 78f6326 | 2012-03-26 01:30:24 +0200 | [diff] [blame] | 38 | |
Darin Petkov | 4646302 | 2012-03-29 14:57:32 +0200 | [diff] [blame] | 39 | virtual void Stop(); |
Darin Petkov | 1c11520 | 2012-03-22 15:35:47 +0100 | [diff] [blame] | 40 | |
Darin Petkov | a5e07ef | 2012-07-09 14:27:57 +0200 | [diff] [blame] | 41 | // Releases openvpn's hold if it's waiting for a hold release (i.e., if |
| 42 | // |hold_waiting_| is true). Otherwise, sets |hold_release_| to true |
| 43 | // indicating that the hold can be released as soon as openvpn requests. |
| 44 | virtual void ReleaseHold(); |
| 45 | |
| 46 | // Holds openvpn so that it doesn't connect or reconnect automatically (i.e., |
| 47 | // sets |hold_release_| to false). Note that this method neither drops an |
| 48 | // existing connection, nor sends any commands to the openvpn client. |
| 49 | virtual void Hold(); |
| 50 | |
Darin Petkov | a42afe3 | 2013-02-05 16:53:52 +0100 | [diff] [blame] | 51 | // Restarts openvpn causing a disconnect followed by a reconnect attempt. |
| 52 | virtual void Restart(); |
| 53 | |
Darin Petkov | 1c049c7 | 2013-03-21 13:15:45 +0100 | [diff] [blame] | 54 | // OpenVPN client state. |
| 55 | const std::string &state() const { return state_; } |
| 56 | |
Darin Petkov | 1c11520 | 2012-03-22 15:35:47 +0100 | [diff] [blame] | 57 | private: |
Darin Petkov | 1c049c7 | 2013-03-21 13:15:45 +0100 | [diff] [blame] | 58 | friend class OpenVPNDriverTest; |
Darin Petkov | 271fe52 | 2012-03-27 13:47:29 +0200 | [diff] [blame] | 59 | friend class OpenVPNManagementServerTest; |
Darin Petkov | daaa553 | 2012-07-24 15:37:55 +0200 | [diff] [blame] | 60 | FRIEND_TEST(OpenVPNManagementServerTest, EscapeToQuote); |
Darin Petkov | a5e07ef | 2012-07-09 14:27:57 +0200 | [diff] [blame] | 61 | FRIEND_TEST(OpenVPNManagementServerTest, Hold); |
Darin Petkov | e08084d | 2012-06-11 13:19:35 +0200 | [diff] [blame] | 62 | FRIEND_TEST(OpenVPNManagementServerTest, OnInputStop); |
Darin Petkov | 271fe52 | 2012-03-27 13:47:29 +0200 | [diff] [blame] | 63 | FRIEND_TEST(OpenVPNManagementServerTest, OnReady); |
| 64 | FRIEND_TEST(OpenVPNManagementServerTest, OnReadyAcceptFail); |
Darin Petkov | daaa553 | 2012-07-24 15:37:55 +0200 | [diff] [blame] | 65 | FRIEND_TEST(OpenVPNManagementServerTest, PerformAuthentication); |
| 66 | FRIEND_TEST(OpenVPNManagementServerTest, PerformAuthenticationNoCreds); |
Darin Petkov | 683942b | 2012-03-27 18:00:04 +0200 | [diff] [blame] | 67 | FRIEND_TEST(OpenVPNManagementServerTest, PerformStaticChallenge); |
| 68 | FRIEND_TEST(OpenVPNManagementServerTest, PerformStaticChallengeNoCreds); |
Darin Petkov | 0440b9b | 2012-04-17 16:11:56 +0200 | [diff] [blame] | 69 | FRIEND_TEST(OpenVPNManagementServerTest, ProcessFailedPasswordMessage); |
Darin Petkov | a5e07ef | 2012-07-09 14:27:57 +0200 | [diff] [blame] | 70 | FRIEND_TEST(OpenVPNManagementServerTest, ProcessHoldMessage); |
Darin Petkov | 271fe52 | 2012-03-27 13:47:29 +0200 | [diff] [blame] | 71 | FRIEND_TEST(OpenVPNManagementServerTest, ProcessInfoMessage); |
Darin Petkov | daaa553 | 2012-07-24 15:37:55 +0200 | [diff] [blame] | 72 | FRIEND_TEST(OpenVPNManagementServerTest, ProcessNeedPasswordMessageAuth); |
Darin Petkov | 683942b | 2012-03-27 18:00:04 +0200 | [diff] [blame] | 73 | FRIEND_TEST(OpenVPNManagementServerTest, ProcessNeedPasswordMessageAuthSC); |
Darin Petkov | e0d5dd1 | 2012-04-04 16:10:48 +0200 | [diff] [blame] | 74 | FRIEND_TEST(OpenVPNManagementServerTest, ProcessNeedPasswordMessageTPMToken); |
| 75 | FRIEND_TEST(OpenVPNManagementServerTest, ProcessNeedPasswordMessageUnknown); |
Darin Petkov | 271fe52 | 2012-03-27 13:47:29 +0200 | [diff] [blame] | 76 | FRIEND_TEST(OpenVPNManagementServerTest, Send); |
Darin Petkov | a5e07ef | 2012-07-09 14:27:57 +0200 | [diff] [blame] | 77 | FRIEND_TEST(OpenVPNManagementServerTest, SendHoldRelease); |
Darin Petkov | 683942b | 2012-03-27 18:00:04 +0200 | [diff] [blame] | 78 | FRIEND_TEST(OpenVPNManagementServerTest, SendPassword); |
Darin Petkov | 271fe52 | 2012-03-27 13:47:29 +0200 | [diff] [blame] | 79 | FRIEND_TEST(OpenVPNManagementServerTest, SendState); |
Darin Petkov | 683942b | 2012-03-27 18:00:04 +0200 | [diff] [blame] | 80 | FRIEND_TEST(OpenVPNManagementServerTest, SendUsername); |
Darin Petkov | 271fe52 | 2012-03-27 13:47:29 +0200 | [diff] [blame] | 81 | FRIEND_TEST(OpenVPNManagementServerTest, Start); |
| 82 | FRIEND_TEST(OpenVPNManagementServerTest, Stop); |
Darin Petkov | e0d5dd1 | 2012-04-04 16:10:48 +0200 | [diff] [blame] | 83 | FRIEND_TEST(OpenVPNManagementServerTest, SupplyTPMToken); |
| 84 | FRIEND_TEST(OpenVPNManagementServerTest, SupplyTPMTokenNoPIN); |
Darin Petkov | 271fe52 | 2012-03-27 13:47:29 +0200 | [diff] [blame] | 85 | |
Darin Petkov | 78f6326 | 2012-03-26 01:30:24 +0200 | [diff] [blame] | 86 | // IO handler callbacks. |
| 87 | void OnReady(int fd); |
| 88 | void OnInput(InputData *data); |
Darin Petkov | 3273da7 | 2013-02-13 11:50:25 +0100 | [diff] [blame] | 89 | void OnInputError(const Error &error); |
Darin Petkov | 78f6326 | 2012-03-26 01:30:24 +0200 | [diff] [blame] | 90 | |
| 91 | void Send(const std::string &data); |
| 92 | void SendState(const std::string &state); |
Darin Petkov | 683942b | 2012-03-27 18:00:04 +0200 | [diff] [blame] | 93 | void SendUsername(const std::string &tag, const std::string &username); |
| 94 | void SendPassword(const std::string &tag, const std::string &password); |
Darin Petkov | a5e07ef | 2012-07-09 14:27:57 +0200 | [diff] [blame] | 95 | void SendHoldRelease(); |
Darin Petkov | a42afe3 | 2013-02-05 16:53:52 +0100 | [diff] [blame] | 96 | void SendSignal(const std::string &signal); |
Darin Petkov | 78f6326 | 2012-03-26 01:30:24 +0200 | [diff] [blame] | 97 | |
| 98 | void ProcessMessage(const std::string &message); |
Darin Petkov | 271fe52 | 2012-03-27 13:47:29 +0200 | [diff] [blame] | 99 | bool ProcessInfoMessage(const std::string &message); |
| 100 | bool ProcessNeedPasswordMessage(const std::string &message); |
| 101 | bool ProcessFailedPasswordMessage(const std::string &message); |
Darin Petkov | 16e7032 | 2013-03-07 15:54:23 +0100 | [diff] [blame] | 102 | bool ProcessAuthTokenMessage(const std::string &message); |
Darin Petkov | 271fe52 | 2012-03-27 13:47:29 +0200 | [diff] [blame] | 103 | bool ProcessStateMessage(const std::string &message); |
Darin Petkov | a5e07ef | 2012-07-09 14:27:57 +0200 | [diff] [blame] | 104 | bool ProcessHoldMessage(const std::string &message); |
Darin Petkov | a42afe3 | 2013-02-05 16:53:52 +0100 | [diff] [blame] | 105 | bool ProcessSuccessMessage(const std::string &message); |
Darin Petkov | 78f6326 | 2012-03-26 01:30:24 +0200 | [diff] [blame] | 106 | |
Darin Petkov | e0d5dd1 | 2012-04-04 16:10:48 +0200 | [diff] [blame] | 107 | void PerformStaticChallenge(const std::string &tag); |
Darin Petkov | daaa553 | 2012-07-24 15:37:55 +0200 | [diff] [blame] | 108 | void PerformAuthentication(const std::string &tag); |
Darin Petkov | e0d5dd1 | 2012-04-04 16:10:48 +0200 | [diff] [blame] | 109 | void SupplyTPMToken(const std::string &tag); |
| 110 | |
Darin Petkov | aba8932 | 2013-03-11 14:48:22 +0100 | [diff] [blame] | 111 | // Returns the first substring in |message| enclosed by the |start| and |end| |
| 112 | // substrings. Note that the first |end| substring after the position of |
| 113 | // |start| is matched. |
| 114 | static std::string ParseSubstring(const std::string &message, |
| 115 | const std::string &start, |
| 116 | const std::string &end); |
| 117 | |
| 118 | // Password messages come in two forms: |
| 119 | // |
| 120 | // >PASSWORD:Need 'AUTH_TYPE' ... |
| 121 | // >PASSWORD:Verification Failed: 'AUTH_TYPE' ['REASON_STRING'] |
| 122 | // |
| 123 | // ParsePasswordTag parses AUTH_TYPE out of a password |message| and returns |
| 124 | // it. ParsePasswordFailedReason parses REASON_STRING, if any, out of a |
| 125 | // password |message| and returns it. |
| 126 | static std::string ParsePasswordTag(const std::string &message); |
| 127 | static std::string ParsePasswordFailedReason(const std::string &message); |
Darin Petkov | 683942b | 2012-03-27 18:00:04 +0200 | [diff] [blame] | 128 | |
Darin Petkov | daaa553 | 2012-07-24 15:37:55 +0200 | [diff] [blame] | 129 | // Escapes |str| per OpenVPN's command parsing rules assuming |str| will be |
| 130 | // sent over the management interface quoted (i.e., whitespace is not |
| 131 | // escaped). |
| 132 | static std::string EscapeToQuote(const std::string &str); |
| 133 | |
Darin Petkov | e08084d | 2012-06-11 13:19:35 +0200 | [diff] [blame] | 134 | bool IsStarted() const { return sockets_; } |
| 135 | |
Darin Petkov | 1c11520 | 2012-03-22 15:35:47 +0100 | [diff] [blame] | 136 | OpenVPNDriver *driver_; |
Darin Petkov | 683942b | 2012-03-27 18:00:04 +0200 | [diff] [blame] | 137 | GLib *glib_; |
Darin Petkov | 78f6326 | 2012-03-26 01:30:24 +0200 | [diff] [blame] | 138 | |
| 139 | Sockets *sockets_; |
| 140 | int socket_; |
| 141 | scoped_ptr<IOHandler> ready_handler_; |
| 142 | EventDispatcher *dispatcher_; |
| 143 | int connected_socket_; |
| 144 | scoped_ptr<IOHandler> input_handler_; |
Darin Petkov | 1c11520 | 2012-03-22 15:35:47 +0100 | [diff] [blame] | 145 | |
Darin Petkov | 1c049c7 | 2013-03-21 13:15:45 +0100 | [diff] [blame] | 146 | std::string state_; |
| 147 | |
Darin Petkov | a5e07ef | 2012-07-09 14:27:57 +0200 | [diff] [blame] | 148 | bool hold_waiting_; |
| 149 | bool hold_release_; |
| 150 | |
Darin Petkov | 1c11520 | 2012-03-22 15:35:47 +0100 | [diff] [blame] | 151 | DISALLOW_COPY_AND_ASSIGN(OpenVPNManagementServer); |
| 152 | }; |
| 153 | |
| 154 | } // namespace shill |
| 155 | |
Darin Petkov | a42afe3 | 2013-02-05 16:53:52 +0100 | [diff] [blame] | 156 | #endif // SHILL_OPENVPN_MANAGEMENT_SERVER_H_ |