blob: f959c9f2bd0c2f0a8e7c384f88b396fb7791c724 [file] [log] [blame]
Darin Petkov1c115202012-03-22 15:35:47 +01001// 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 Petkov46463022012-03-29 14:57:32 +02008#include <string>
9#include <vector>
10
Darin Petkov1c115202012-03-22 15:35:47 +010011#include <base/basictypes.h>
Darin Petkov78f63262012-03-26 01:30:24 +020012#include <base/cancelable_callback.h>
13#include <base/memory/weak_ptr.h>
Darin Petkov271fe522012-03-27 13:47:29 +020014#include <gtest/gtest_prod.h> // for FRIEND_TEST
Darin Petkov1c115202012-03-22 15:35:47 +010015
16namespace shill {
17
Darin Petkov78f63262012-03-26 01:30:24 +020018class EventDispatcher;
Darin Petkov683942b2012-03-27 18:00:04 +020019class GLib;
Darin Petkov78f63262012-03-26 01:30:24 +020020class InputData;
21class IOHandler;
Darin Petkov1c115202012-03-22 15:35:47 +010022class OpenVPNDriver;
Darin Petkov78f63262012-03-26 01:30:24 +020023class Sockets;
Darin Petkov1c115202012-03-22 15:35:47 +010024
25class OpenVPNManagementServer {
26 public:
Darin Petkov683942b2012-03-27 18:00:04 +020027 OpenVPNManagementServer(OpenVPNDriver *driver, GLib *glib);
Darin Petkov1c115202012-03-22 15:35:47 +010028 virtual ~OpenVPNManagementServer();
29
Darin Petkov46463022012-03-29 14:57:32 +020030 // 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 Petkov78f63262012-03-26 01:30:24 +020035
Darin Petkov46463022012-03-29 14:57:32 +020036 virtual void Stop();
Darin Petkov1c115202012-03-22 15:35:47 +010037
Darin Petkova5e07ef2012-07-09 14:27:57 +020038 // 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 Petkov1c115202012-03-22 15:35:47 +010048 private:
Darin Petkov271fe522012-03-27 13:47:29 +020049 friend class OpenVPNManagementServerTest;
Darin Petkovdaaa5532012-07-24 15:37:55 +020050 FRIEND_TEST(OpenVPNManagementServerTest, EscapeToQuote);
Darin Petkova5e07ef2012-07-09 14:27:57 +020051 FRIEND_TEST(OpenVPNManagementServerTest, Hold);
Darin Petkov271fe522012-03-27 13:47:29 +020052 FRIEND_TEST(OpenVPNManagementServerTest, OnInput);
Darin Petkove08084d2012-06-11 13:19:35 +020053 FRIEND_TEST(OpenVPNManagementServerTest, OnInputStop);
Darin Petkov271fe522012-03-27 13:47:29 +020054 FRIEND_TEST(OpenVPNManagementServerTest, OnReady);
55 FRIEND_TEST(OpenVPNManagementServerTest, OnReadyAcceptFail);
Darin Petkove0d5dd12012-04-04 16:10:48 +020056 FRIEND_TEST(OpenVPNManagementServerTest, ParseNeedPasswordTag);
Darin Petkovdaaa5532012-07-24 15:37:55 +020057 FRIEND_TEST(OpenVPNManagementServerTest, PerformAuthentication);
58 FRIEND_TEST(OpenVPNManagementServerTest, PerformAuthenticationNoCreds);
Darin Petkov683942b2012-03-27 18:00:04 +020059 FRIEND_TEST(OpenVPNManagementServerTest, PerformStaticChallenge);
60 FRIEND_TEST(OpenVPNManagementServerTest, PerformStaticChallengeNoCreds);
Darin Petkov0440b9b2012-04-17 16:11:56 +020061 FRIEND_TEST(OpenVPNManagementServerTest, ProcessFailedPasswordMessage);
Darin Petkova5e07ef2012-07-09 14:27:57 +020062 FRIEND_TEST(OpenVPNManagementServerTest, ProcessHoldMessage);
Darin Petkov271fe522012-03-27 13:47:29 +020063 FRIEND_TEST(OpenVPNManagementServerTest, ProcessInfoMessage);
64 FRIEND_TEST(OpenVPNManagementServerTest, ProcessMessage);
Darin Petkovdaaa5532012-07-24 15:37:55 +020065 FRIEND_TEST(OpenVPNManagementServerTest, ProcessNeedPasswordMessageAuth);
Darin Petkov683942b2012-03-27 18:00:04 +020066 FRIEND_TEST(OpenVPNManagementServerTest, ProcessNeedPasswordMessageAuthSC);
Darin Petkove0d5dd12012-04-04 16:10:48 +020067 FRIEND_TEST(OpenVPNManagementServerTest, ProcessNeedPasswordMessageTPMToken);
68 FRIEND_TEST(OpenVPNManagementServerTest, ProcessNeedPasswordMessageUnknown);
Darin Petkov271fe522012-03-27 13:47:29 +020069 FRIEND_TEST(OpenVPNManagementServerTest, ProcessStateMessage);
70 FRIEND_TEST(OpenVPNManagementServerTest, Send);
Darin Petkova5e07ef2012-07-09 14:27:57 +020071 FRIEND_TEST(OpenVPNManagementServerTest, SendHoldRelease);
Darin Petkov683942b2012-03-27 18:00:04 +020072 FRIEND_TEST(OpenVPNManagementServerTest, SendPassword);
Darin Petkov271fe522012-03-27 13:47:29 +020073 FRIEND_TEST(OpenVPNManagementServerTest, SendState);
Darin Petkov683942b2012-03-27 18:00:04 +020074 FRIEND_TEST(OpenVPNManagementServerTest, SendUsername);
Darin Petkov271fe522012-03-27 13:47:29 +020075 FRIEND_TEST(OpenVPNManagementServerTest, Start);
76 FRIEND_TEST(OpenVPNManagementServerTest, Stop);
Darin Petkove0d5dd12012-04-04 16:10:48 +020077 FRIEND_TEST(OpenVPNManagementServerTest, SupplyTPMToken);
78 FRIEND_TEST(OpenVPNManagementServerTest, SupplyTPMTokenNoPIN);
Darin Petkov271fe522012-03-27 13:47:29 +020079
Darin Petkov78f63262012-03-26 01:30:24 +020080 // 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 Petkov683942b2012-03-27 18:00:04 +020086 void SendUsername(const std::string &tag, const std::string &username);
87 void SendPassword(const std::string &tag, const std::string &password);
Darin Petkova5e07ef2012-07-09 14:27:57 +020088 void SendHoldRelease();
Darin Petkov78f63262012-03-26 01:30:24 +020089
90 void ProcessMessage(const std::string &message);
Darin Petkov271fe522012-03-27 13:47:29 +020091 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 Petkova5e07ef2012-07-09 14:27:57 +020095 bool ProcessHoldMessage(const std::string &message);
Darin Petkov78f63262012-03-26 01:30:24 +020096
Darin Petkove0d5dd12012-04-04 16:10:48 +020097 void PerformStaticChallenge(const std::string &tag);
Darin Petkovdaaa5532012-07-24 15:37:55 +020098 void PerformAuthentication(const std::string &tag);
Darin Petkove0d5dd12012-04-04 16:10:48 +020099 void SupplyTPMToken(const std::string &tag);
100
101 static std::string ParseNeedPasswordTag(const std::string &message);
Darin Petkov683942b2012-03-27 18:00:04 +0200102
Darin Petkovdaaa5532012-07-24 15:37:55 +0200103 // 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 Petkove08084d2012-06-11 13:19:35 +0200108 bool IsStarted() const { return sockets_; }
109
Darin Petkov1c115202012-03-22 15:35:47 +0100110 OpenVPNDriver *driver_;
Darin Petkov683942b2012-03-27 18:00:04 +0200111 GLib *glib_;
Darin Petkov78f63262012-03-26 01:30:24 +0200112 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 Petkov1c115202012-03-22 15:35:47 +0100122
Darin Petkova5e07ef2012-07-09 14:27:57 +0200123 bool hold_waiting_;
124 bool hold_release_;
125
Darin Petkov1c115202012-03-22 15:35:47 +0100126 DISALLOW_COPY_AND_ASSIGN(OpenVPNManagementServer);
127};
128
129} // namespace shill
130
131#endif // SHILL_OPENVPN_MANAGEMENT_SERVER_