Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(581)

Side by Side Diff: l2tp_manager.cc

Issue 6508016: vpn-manager: Add l2tp/ipsec vpn manager (Closed) Base URL: ssh://git@gitrw.chromium.org:9222/vpn-manager.git@master
Patch Set: tweak Created 9 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2011 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 #include "vpn-manager/l2tp_manager.h"
6
7 #include "base/file_util.h"
8 #include "base/logging.h"
9 #include "base/string_util.h"
10 #include "chromeos/process.h"
11 #include "gflags/gflags.h"
12
13 #pragma GCC diagnostic ignored "-Wstrict-aliasing"
14 DEFINE_bool(require_chap, true, "require chap");
15 DEFINE_bool(refuse_pap, true, "refuse chap");
16 DEFINE_bool(require_authentication, true, "require authentication");
17 DEFINE_bool(ppp_debug, true, "ppp debug");
18 DEFINE_bool(length_bit, true, "length bit");
19 DEFINE_int32(authentication_timeout, 10, "timeout to authenticate (seconds)");
20 DEFINE_string(pppd_plugin, "", "pppd plugin");
21 DEFINE_string(user, "", "user name");
22 DEFINE_string(password, "", "password");
23 #pragma GCC diagnostic error "-Wstrict-aliasing"
24
25 const char kL2tpConnectionName[] = "managed";
26 const char kPppInterfacePath[] = "/sys/class/net/ppp0";
27
28 using ::chromeos::ProcessImpl;
29
30 // TODO: enable PPPoL2TP or at least measure efficiency gap.
petkov 2011/03/04 18:42:56 TODO(kmixter)
kmixter1 2011/03/05 02:48:59 Removed here and added crosbug.com/12769
31
32 L2tpManager::L2tpManager() : ServiceManager("l2tp"), output_fd_(-1),
petkov 2011/03/04 18:42:56 initializers on separate lines?
kmixter1 2011/03/05 02:48:59 Done.
33 l2tpd_(new ProcessImpl) {
34 }
35
36 bool L2tpManager::Initialize(const std::string& remote) {
37 remote_ = remote;
38 if (FLAGS_user.empty()) {
39 LOG(ERROR) << "l2tp layer requires user name";
40 return false;
41 }
42 if (!FLAGS_pppd_plugin.empty() &&
43 !file_util::PathExists(FilePath(FLAGS_pppd_plugin))) {
44 LOG(WARNING) << "pppd_plugin (" << FLAGS_pppd_plugin << ") does not exist.";
45 }
46 return true;
47 }
48
49 static void AddString(std::string* config, const char* key,
50 const std::string& value) {
51 config->append(StringPrintf("%s = %s\n", key, value.c_str()));
52 }
53
54 static void AddBool(std::string* config, const char* key, bool value) {
55 config->append(StringPrintf("%s = %s\n", key, value ? "yes" : "no"));
56 }
57
58 std::string L2tpManager::FormatL2tpdConfiguration(
59 const std::string& ppp_config_path) {
60 std::string l2tpd_config;
61 l2tpd_config.append(StringPrintf("[lac %s]\n", kL2tpConnectionName));
62 AddString(&l2tpd_config, "lns", remote_);
63 AddBool(&l2tpd_config, "require chap", FLAGS_require_chap);
64 AddBool(&l2tpd_config, "refuse pap", FLAGS_refuse_pap);
65 AddBool(&l2tpd_config, "require authentication",
66 FLAGS_require_authentication);
67 AddString(&l2tpd_config, "name", FLAGS_user);
68 AddBool(&l2tpd_config, "ppp debug", FLAGS_ppp_debug);
69 AddString(&l2tpd_config, "pppoptfile", ppp_config_path);
70 AddBool(&l2tpd_config, "length bit", FLAGS_length_bit);
71 return l2tpd_config;
72 }
73
74 std::string L2tpManager::FormatPppdConfiguration() {
75 std::string pppd_config = StringPrintf(
76 "ipcp-accept-local\n"
77 "ipcp-accept-remote\n"
78 "refuse-eap\n"
79 "noccp\n"
80 "noauth\n"
81 "crtscts\n"
82 "idle 1800\n"
83 "mtu 1410\n"
84 "mru 1410\n"
85 "nodefaultroute\n"
86 "debug\n"
87 "lock\n"
88 "connect-delay 5000\n");
89 if (!FLAGS_pppd_plugin.empty()) {
90 DLOG(INFO) << "Using pppd plugin " << FLAGS_pppd_plugin;
91 pppd_config.append(StringPrintf("plugin %s\n", FLAGS_pppd_plugin.c_str()));
92 }
93 return pppd_config;
94 }
95
96 bool L2tpManager::Initiate() {
97 std::string control_string;
98 control_string = StringPrintf("c %s", kL2tpConnectionName);
99 if (FLAGS_pppd_plugin.empty()) {
100 control_string.append(StringPrintf(" %s %s\n",
101 FLAGS_user.c_str(),
102 FLAGS_password.c_str()));
103 } else {
104 // otherwise the plugin must specify username and password.
105 control_string.append("\n");
106 }
107 if (!file_util::WriteFile(l2tpd_control_path_, control_string.c_str(),
108 control_string.size())) {
109 return false;
110 }
111 return true;
112 }
113
114 bool L2tpManager::Terminate() {
115 std::string control_string = StringPrintf("d %s\n",
116 kL2tpConnectionName);
117 if (!file_util::WriteFile(l2tpd_control_path_, control_string.c_str(),
118 control_string.size())) {
119 return false;
120 }
121 return true;
122 }
123
124 bool L2tpManager::Start() {
125 FilePath pppd_config_path = temp_path_.Append("pppd.conf");
126 std::string l2tpd_config = FormatL2tpdConfiguration(pppd_config_path.value());
127 FilePath l2tpd_config_path = temp_path_.Append("l2tpd.conf");
128 if (!file_util::WriteFile(l2tpd_config_path, l2tpd_config.c_str(),
129 l2tpd_config.size())) {
130 LOG(ERROR) << "Unable to write l2tpd config to "
131 << l2tpd_config_path.value();
132 return false;
133 }
134 std::string pppd_config = FormatPppdConfiguration();
135 if (!file_util::WriteFile(pppd_config_path, pppd_config.c_str(),
136 pppd_config.size())) {
137 LOG(ERROR) << "Unable to write pppd config to " << pppd_config_path.value();
138 return false;
139 }
140 l2tpd_control_path_ = temp_path_.Append("l2tpd.control");
141 file_util::Delete(l2tpd_control_path_, false);
142 l2tpd_->Reset(0);
143 l2tpd_->AddArg(L2TPD);
144 l2tpd_->AddStringOption("-c", l2tpd_config_path.value());
145 l2tpd_->AddStringOption("-C", l2tpd_control_path_.value());
146 l2tpd_->AddArg("-D");
147 l2tpd_->RedirectUsingPipe(STDERR_FILENO, false);
148 l2tpd_->Start();
149 output_fd_ = l2tpd_->GetPipe(STDERR_FILENO);
150 // TODO: better synchronization - maybe wait for file to appear.
petkov 2011/03/04 18:42:56 TODO(kmixter)
kmixter1 2011/03/05 02:48:59 Done.
151 sleep(1);
152 bool result = Initiate();
153 start_ticks_ = base::TimeTicks::Now();
154 return result;
155 }
156
157 // TODO: unit test this
158 int L2tpManager::Poll() {
159 if (is_running()) return -1;
160 if (start_ticks_.is_null()) return -1;
161 if (!file_util::PathExists(FilePath(kPppInterfacePath))) {
162 if ((base::TimeTicks::Now() - start_ticks_).InSecondsF() >
petkov 2011/03/04 18:42:56 why InSecondsF rather than InSeconds? also, I've u
kmixter1 2011/03/05 02:48:59 Not entirely sure why that form is better, but cha
163 FLAGS_authentication_timeout) {
164 LOG(ERROR) << "PPP authentication timed out.";
165 Terminate();
166 OnStopped(false);
167 // Return 1 in order to get check exit conditions.
petkov 2011/03/04 18:42:56 return 1000?
kmixter1 2011/03/05 02:48:59 Done.
168 }
169 return 1000;
170 }
171 LOG(INFO) << "L2TP connection now up";
172 OnStarted();
173 return -1;
174 }
175
176 void L2tpManager::HandleChild(pid_t pid, int signal) {
177 if (pid != l2tpd_->pid()) return;
178
179 LOG(INFO) << "L2TP layer stopped";
180 OnStopped(true);
181 }
182
183 void L2tpManager::Stop() {
184 if (l2tpd_->pid()) {
185 LOG(INFO) << "Shutting down L2TP";
186 Terminate();
187 }
188 OnStopped(false);
189 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698