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