1 // 2 // Copyright (C) 2012 The Android Open Source Project 3 // 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 // 16 17 #ifndef SHILL_VPN_OPENVPN_MANAGEMENT_SERVER_H_ 18 #define SHILL_VPN_OPENVPN_MANAGEMENT_SERVER_H_ 19 20 #include <memory> 21 #include <string> 22 #include <vector> 23 24 #include <base/macros.h> 25 #include <gtest/gtest_prod.h> // for FRIEND_TEST 26 27 namespace shill { 28 29 class Error; 30 class EventDispatcher; 31 struct InputData; 32 class IOHandler; 33 class OpenVPNDriver; 34 class Sockets; 35 36 class OpenVPNManagementServer { 37 public: 38 static const char kStateReconnecting[]; 39 static const char kStateResolve[]; 40 41 explicit OpenVPNManagementServer(OpenVPNDriver* driver); 42 virtual ~OpenVPNManagementServer(); 43 44 // Returns false on failure. On success, returns true and appends management 45 // interface openvpn options to |options|. 46 virtual bool Start(EventDispatcher* dispatcher, 47 Sockets* sockets, 48 std::vector<std::vector<std::string>>* options); 49 50 virtual void Stop(); 51 52 // Releases openvpn's hold if it's waiting for a hold release (i.e., if 53 // |hold_waiting_| is true). Otherwise, sets |hold_release_| to true 54 // indicating that the hold can be released as soon as openvpn requests. 55 virtual void ReleaseHold(); 56 57 // Holds openvpn so that it doesn't connect or reconnect automatically (i.e., 58 // sets |hold_release_| to false). Note that this method neither drops an 59 // existing connection, nor sends any commands to the openvpn client. 60 virtual void Hold(); 61 62 // Restarts openvpn causing a disconnect followed by a reconnect attempt. 63 virtual void Restart(); 64 65 // OpenVPN client state. state()66 const std::string& state() const { return state_; } 67 68 // Method to get service identifier for logging. 69 virtual std::string GetServiceRpcIdentifier(); 70 71 private: 72 friend class OpenVPNDriverTest; 73 friend class OpenVPNManagementServerTest; 74 FRIEND_TEST(OpenVPNManagementServerTest, EscapeToQuote); 75 FRIEND_TEST(OpenVPNManagementServerTest, Hold); 76 FRIEND_TEST(OpenVPNManagementServerTest, OnInputStop); 77 FRIEND_TEST(OpenVPNManagementServerTest, OnReady); 78 FRIEND_TEST(OpenVPNManagementServerTest, OnReadyAcceptFail); 79 FRIEND_TEST(OpenVPNManagementServerTest, PerformAuthentication); 80 FRIEND_TEST(OpenVPNManagementServerTest, PerformAuthenticationNoCreds); 81 FRIEND_TEST(OpenVPNManagementServerTest, PerformStaticChallengeNoCreds); 82 FRIEND_TEST(OpenVPNManagementServerTest, PerformStaticChallengeOTP); 83 FRIEND_TEST(OpenVPNManagementServerTest, PerformStaticChallengeToken); 84 FRIEND_TEST(OpenVPNManagementServerTest, ProcessFailedPasswordMessage); 85 FRIEND_TEST(OpenVPNManagementServerTest, ProcessHoldMessage); 86 FRIEND_TEST(OpenVPNManagementServerTest, ProcessInfoMessage); 87 FRIEND_TEST(OpenVPNManagementServerTest, ProcessNeedPasswordMessageAuth); 88 FRIEND_TEST(OpenVPNManagementServerTest, ProcessNeedPasswordMessageAuthSC); 89 FRIEND_TEST(OpenVPNManagementServerTest, ProcessNeedPasswordMessageTPMToken); 90 FRIEND_TEST(OpenVPNManagementServerTest, ProcessNeedPasswordMessageUnknown); 91 FRIEND_TEST(OpenVPNManagementServerTest, Send); 92 FRIEND_TEST(OpenVPNManagementServerTest, SendHoldRelease); 93 FRIEND_TEST(OpenVPNManagementServerTest, SendPassword); 94 FRIEND_TEST(OpenVPNManagementServerTest, SendState); 95 FRIEND_TEST(OpenVPNManagementServerTest, SendUsername); 96 FRIEND_TEST(OpenVPNManagementServerTest, Start); 97 FRIEND_TEST(OpenVPNManagementServerTest, Stop); 98 FRIEND_TEST(OpenVPNManagementServerTest, SupplyTPMToken); 99 FRIEND_TEST(OpenVPNManagementServerTest, SupplyTPMTokenNoPIN); 100 101 // IO handler callbacks. 102 void OnReady(int fd); 103 void OnInput(InputData* data); 104 void OnInputError(const std::string& error_msg); 105 106 void Send(const std::string& data); 107 void SendState(const std::string& state); 108 void SendUsername(const std::string& tag, const std::string& username); 109 void SendPassword(const std::string& tag, const std::string& password); 110 void SendHoldRelease(); 111 void SendSignal(const std::string& signal); 112 113 void ProcessMessage(const std::string& message); 114 bool ProcessInfoMessage(const std::string& message); 115 bool ProcessNeedPasswordMessage(const std::string& message); 116 bool ProcessFailedPasswordMessage(const std::string& message); 117 bool ProcessAuthTokenMessage(const std::string& message); 118 bool ProcessStateMessage(const std::string& message); 119 bool ProcessHoldMessage(const std::string& message); 120 bool ProcessSuccessMessage(const std::string& message); 121 122 void PerformStaticChallenge(const std::string& tag); 123 void PerformAuthentication(const std::string& tag); 124 void SupplyTPMToken(const std::string& tag); 125 126 // Returns the first substring in |message| enclosed by the |start| and |end| 127 // substrings. Note that the first |end| substring after the position of 128 // |start| is matched. 129 static std::string ParseSubstring(const std::string& message, 130 const std::string& start, 131 const std::string& end); 132 133 // Password messages come in two forms: 134 // 135 // >PASSWORD:Need 'AUTH_TYPE' ... 136 // >PASSWORD:Verification Failed: 'AUTH_TYPE' ['REASON_STRING'] 137 // 138 // ParsePasswordTag parses AUTH_TYPE out of a password |message| and returns 139 // it. ParsePasswordFailedReason parses REASON_STRING, if any, out of a 140 // password |message| and returns it. 141 static std::string ParsePasswordTag(const std::string& message); 142 static std::string ParsePasswordFailedReason(const std::string& message); 143 144 // Escapes |str| per OpenVPN's command parsing rules assuming |str| will be 145 // sent over the management interface quoted (i.e., whitespace is not 146 // escaped). 147 static std::string EscapeToQuote(const std::string& str); 148 IsStarted()149 bool IsStarted() const { return sockets_; } 150 151 OpenVPNDriver* driver_; 152 153 Sockets* sockets_; 154 int socket_; 155 std::unique_ptr<IOHandler> ready_handler_; 156 EventDispatcher* dispatcher_; 157 int connected_socket_; 158 std::unique_ptr<IOHandler> input_handler_; 159 160 std::string state_; 161 162 bool hold_waiting_; 163 bool hold_release_; 164 165 DISALLOW_COPY_AND_ASSIGN(OpenVPNManagementServer); 166 }; 167 168 } // namespace shill 169 170 #endif // SHILL_VPN_OPENVPN_MANAGEMENT_SERVER_H_ 171