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 | |
| 5 | #ifndef SHILL_OPENVPN_MANAGEMENT_SERVER_ |
| 6 | #define SHILL_OPENVPN_MANAGEMENT_SERVER_ |
| 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 | 78f6326 | 2012-03-26 01:30:24 +0200 | [diff] [blame] | 12 | #include <base/cancelable_callback.h> |
| 13 | #include <base/memory/weak_ptr.h> |
Darin Petkov | 271fe52 | 2012-03-27 13:47:29 +0200 | [diff] [blame] | 14 | #include <gtest/gtest_prod.h> // for FRIEND_TEST |
Darin Petkov | 1c11520 | 2012-03-22 15:35:47 +0100 | [diff] [blame] | 15 | |
| 16 | namespace shill { |
| 17 | |
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; |
Darin Petkov | 78f6326 | 2012-03-26 01:30:24 +0200 | [diff] [blame] | 20 | class InputData; |
| 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 | 683942b | 2012-03-27 18:00:04 +0200 | [diff] [blame] | 27 | OpenVPNManagementServer(OpenVPNDriver *driver, GLib *glib); |
Darin Petkov | 1c11520 | 2012-03-22 15:35:47 +0100 | [diff] [blame] | 28 | virtual ~OpenVPNManagementServer(); |
| 29 | |
Darin Petkov | 4646302 | 2012-03-29 14:57:32 +0200 | [diff] [blame] | 30 | // Returns false on failure. On success, returns true and appends management |
| 31 | // interface openvpn options to |options|. |
| 32 | virtual bool Start(EventDispatcher *dispatcher, |
| 33 | Sockets *sockets, |
| 34 | std::vector<std::string> *options); |
Darin Petkov | 78f6326 | 2012-03-26 01:30:24 +0200 | [diff] [blame] | 35 | |
Darin Petkov | 4646302 | 2012-03-29 14:57:32 +0200 | [diff] [blame] | 36 | virtual void Stop(); |
Darin Petkov | 1c11520 | 2012-03-22 15:35:47 +0100 | [diff] [blame] | 37 | |
Darin Petkov | a5e07ef | 2012-07-09 14:27:57 +0200 | [diff] [blame] | 38 | // Releases openvpn's hold if it's waiting for a hold release (i.e., if |
| 39 | // |hold_waiting_| is true). Otherwise, sets |hold_release_| to true |
| 40 | // indicating that the hold can be released as soon as openvpn requests. |
| 41 | virtual void ReleaseHold(); |
| 42 | |
| 43 | // Holds openvpn so that it doesn't connect or reconnect automatically (i.e., |
| 44 | // sets |hold_release_| to false). Note that this method neither drops an |
| 45 | // existing connection, nor sends any commands to the openvpn client. |
| 46 | virtual void Hold(); |
| 47 | |
Darin Petkov | 1c11520 | 2012-03-22 15:35:47 +0100 | [diff] [blame] | 48 | private: |
Darin Petkov | 271fe52 | 2012-03-27 13:47:29 +0200 | [diff] [blame] | 49 | friend class OpenVPNManagementServerTest; |
Darin Petkov | daaa553 | 2012-07-24 15:37:55 +0200 | [diff] [blame] | 50 | FRIEND_TEST(OpenVPNManagementServerTest, EscapeToQuote); |
Darin Petkov | a5e07ef | 2012-07-09 14:27:57 +0200 | [diff] [blame] | 51 | FRIEND_TEST(OpenVPNManagementServerTest, Hold); |
Darin Petkov | 271fe52 | 2012-03-27 13:47:29 +0200 | [diff] [blame] | 52 | FRIEND_TEST(OpenVPNManagementServerTest, OnInput); |
Darin Petkov | e08084d | 2012-06-11 13:19:35 +0200 | [diff] [blame] | 53 | FRIEND_TEST(OpenVPNManagementServerTest, OnInputStop); |
Darin Petkov | 271fe52 | 2012-03-27 13:47:29 +0200 | [diff] [blame] | 54 | FRIEND_TEST(OpenVPNManagementServerTest, OnReady); |
| 55 | FRIEND_TEST(OpenVPNManagementServerTest, OnReadyAcceptFail); |
Darin Petkov | e0d5dd1 | 2012-04-04 16:10:48 +0200 | [diff] [blame] | 56 | FRIEND_TEST(OpenVPNManagementServerTest, ParseNeedPasswordTag); |
Darin Petkov | daaa553 | 2012-07-24 15:37:55 +0200 | [diff] [blame] | 57 | FRIEND_TEST(OpenVPNManagementServerTest, PerformAuthentication); |
| 58 | FRIEND_TEST(OpenVPNManagementServerTest, PerformAuthenticationNoCreds); |
Darin Petkov | 683942b | 2012-03-27 18:00:04 +0200 | [diff] [blame] | 59 | FRIEND_TEST(OpenVPNManagementServerTest, PerformStaticChallenge); |
| 60 | FRIEND_TEST(OpenVPNManagementServerTest, PerformStaticChallengeNoCreds); |
Darin Petkov | 0440b9b | 2012-04-17 16:11:56 +0200 | [diff] [blame] | 61 | FRIEND_TEST(OpenVPNManagementServerTest, ProcessFailedPasswordMessage); |
Darin Petkov | a5e07ef | 2012-07-09 14:27:57 +0200 | [diff] [blame] | 62 | FRIEND_TEST(OpenVPNManagementServerTest, ProcessHoldMessage); |
Darin Petkov | 271fe52 | 2012-03-27 13:47:29 +0200 | [diff] [blame] | 63 | FRIEND_TEST(OpenVPNManagementServerTest, ProcessInfoMessage); |
| 64 | FRIEND_TEST(OpenVPNManagementServerTest, ProcessMessage); |
Darin Petkov | daaa553 | 2012-07-24 15:37:55 +0200 | [diff] [blame] | 65 | FRIEND_TEST(OpenVPNManagementServerTest, ProcessNeedPasswordMessageAuth); |
Darin Petkov | 683942b | 2012-03-27 18:00:04 +0200 | [diff] [blame] | 66 | FRIEND_TEST(OpenVPNManagementServerTest, ProcessNeedPasswordMessageAuthSC); |
Darin Petkov | e0d5dd1 | 2012-04-04 16:10:48 +0200 | [diff] [blame] | 67 | FRIEND_TEST(OpenVPNManagementServerTest, ProcessNeedPasswordMessageTPMToken); |
| 68 | FRIEND_TEST(OpenVPNManagementServerTest, ProcessNeedPasswordMessageUnknown); |
Darin Petkov | 271fe52 | 2012-03-27 13:47:29 +0200 | [diff] [blame] | 69 | FRIEND_TEST(OpenVPNManagementServerTest, ProcessStateMessage); |
| 70 | FRIEND_TEST(OpenVPNManagementServerTest, Send); |
Darin Petkov | a5e07ef | 2012-07-09 14:27:57 +0200 | [diff] [blame] | 71 | FRIEND_TEST(OpenVPNManagementServerTest, SendHoldRelease); |
Darin Petkov | 683942b | 2012-03-27 18:00:04 +0200 | [diff] [blame] | 72 | FRIEND_TEST(OpenVPNManagementServerTest, SendPassword); |
Darin Petkov | 271fe52 | 2012-03-27 13:47:29 +0200 | [diff] [blame] | 73 | FRIEND_TEST(OpenVPNManagementServerTest, SendState); |
Darin Petkov | 683942b | 2012-03-27 18:00:04 +0200 | [diff] [blame] | 74 | FRIEND_TEST(OpenVPNManagementServerTest, SendUsername); |
Darin Petkov | 271fe52 | 2012-03-27 13:47:29 +0200 | [diff] [blame] | 75 | FRIEND_TEST(OpenVPNManagementServerTest, Start); |
| 76 | FRIEND_TEST(OpenVPNManagementServerTest, Stop); |
Darin Petkov | e0d5dd1 | 2012-04-04 16:10:48 +0200 | [diff] [blame] | 77 | FRIEND_TEST(OpenVPNManagementServerTest, SupplyTPMToken); |
| 78 | FRIEND_TEST(OpenVPNManagementServerTest, SupplyTPMTokenNoPIN); |
Darin Petkov | 271fe52 | 2012-03-27 13:47:29 +0200 | [diff] [blame] | 79 | |
Darin Petkov | 78f6326 | 2012-03-26 01:30:24 +0200 | [diff] [blame] | 80 | // IO handler callbacks. |
| 81 | void OnReady(int fd); |
| 82 | void OnInput(InputData *data); |
| 83 | |
| 84 | void Send(const std::string &data); |
| 85 | void SendState(const std::string &state); |
Darin Petkov | 683942b | 2012-03-27 18:00:04 +0200 | [diff] [blame] | 86 | void SendUsername(const std::string &tag, const std::string &username); |
| 87 | void SendPassword(const std::string &tag, const std::string &password); |
Darin Petkov | a5e07ef | 2012-07-09 14:27:57 +0200 | [diff] [blame] | 88 | void SendHoldRelease(); |
Darin Petkov | 78f6326 | 2012-03-26 01:30:24 +0200 | [diff] [blame] | 89 | |
| 90 | void ProcessMessage(const std::string &message); |
Darin Petkov | 271fe52 | 2012-03-27 13:47:29 +0200 | [diff] [blame] | 91 | bool ProcessInfoMessage(const std::string &message); |
| 92 | bool ProcessNeedPasswordMessage(const std::string &message); |
| 93 | bool ProcessFailedPasswordMessage(const std::string &message); |
| 94 | bool ProcessStateMessage(const std::string &message); |
Darin Petkov | a5e07ef | 2012-07-09 14:27:57 +0200 | [diff] [blame] | 95 | bool ProcessHoldMessage(const std::string &message); |
Darin Petkov | 78f6326 | 2012-03-26 01:30:24 +0200 | [diff] [blame] | 96 | |
Darin Petkov | e0d5dd1 | 2012-04-04 16:10:48 +0200 | [diff] [blame] | 97 | void PerformStaticChallenge(const std::string &tag); |
Darin Petkov | daaa553 | 2012-07-24 15:37:55 +0200 | [diff] [blame] | 98 | void PerformAuthentication(const std::string &tag); |
Darin Petkov | e0d5dd1 | 2012-04-04 16:10:48 +0200 | [diff] [blame] | 99 | void SupplyTPMToken(const std::string &tag); |
| 100 | |
| 101 | static std::string ParseNeedPasswordTag(const std::string &message); |
Darin Petkov | 683942b | 2012-03-27 18:00:04 +0200 | [diff] [blame] | 102 | |
Darin Petkov | daaa553 | 2012-07-24 15:37:55 +0200 | [diff] [blame] | 103 | // Escapes |str| per OpenVPN's command parsing rules assuming |str| will be |
| 104 | // sent over the management interface quoted (i.e., whitespace is not |
| 105 | // escaped). |
| 106 | static std::string EscapeToQuote(const std::string &str); |
| 107 | |
Darin Petkov | e08084d | 2012-06-11 13:19:35 +0200 | [diff] [blame] | 108 | bool IsStarted() const { return sockets_; } |
| 109 | |
Darin Petkov | 1c11520 | 2012-03-22 15:35:47 +0100 | [diff] [blame] | 110 | OpenVPNDriver *driver_; |
Darin Petkov | 683942b | 2012-03-27 18:00:04 +0200 | [diff] [blame] | 111 | GLib *glib_; |
Darin Petkov | 78f6326 | 2012-03-26 01:30:24 +0200 | [diff] [blame] | 112 | base::WeakPtrFactory<OpenVPNManagementServer> weak_ptr_factory_; |
| 113 | base::Callback<void(int)> ready_callback_; |
| 114 | base::Callback<void(InputData *)> input_callback_; |
| 115 | |
| 116 | Sockets *sockets_; |
| 117 | int socket_; |
| 118 | scoped_ptr<IOHandler> ready_handler_; |
| 119 | EventDispatcher *dispatcher_; |
| 120 | int connected_socket_; |
| 121 | scoped_ptr<IOHandler> input_handler_; |
Darin Petkov | 1c11520 | 2012-03-22 15:35:47 +0100 | [diff] [blame] | 122 | |
Darin Petkov | a5e07ef | 2012-07-09 14:27:57 +0200 | [diff] [blame] | 123 | bool hold_waiting_; |
| 124 | bool hold_release_; |
| 125 | |
Darin Petkov | 1c11520 | 2012-03-22 15:35:47 +0100 | [diff] [blame] | 126 | DISALLOW_COPY_AND_ASSIGN(OpenVPNManagementServer); |
| 127 | }; |
| 128 | |
| 129 | } // namespace shill |
| 130 | |
| 131 | #endif // SHILL_OPENVPN_MANAGEMENT_SERVER_ |