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

Side by Side Diff: blimp/client/session/assignment_source.cc

Issue 1696563002: Blimp: add support for SSL connections. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 10 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
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "blimp/client/session/assignment_source.h" 5 #include "blimp/client/session/assignment_source.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/callback.h"
8 #include "base/command_line.h" 9 #include "base/command_line.h"
10 #include "base/files/file_util.h"
9 #include "base/location.h" 11 #include "base/location.h"
10 #include "base/numerics/safe_conversions.h" 12 #include "base/numerics/safe_conversions.h"
11 #include "base/strings/string_number_conversions.h" 13 #include "base/strings/string_number_conversions.h"
12 #include "blimp/client/app/blimp_client_switches.h" 14 #include "blimp/client/app/blimp_client_switches.h"
15 #include "net/base/hash_value.h"
13 #include "net/base/ip_address.h" 16 #include "net/base/ip_address.h"
14 #include "net/base/ip_endpoint.h" 17 #include "net/base/ip_endpoint.h"
18 #include "net/cert/pem_tokenizer.h"
15 19
16 namespace blimp { 20 namespace blimp {
17 namespace { 21 namespace {
18 22
19 // TODO(kmarshall): Take values from configuration data. 23 // TODO(kmarshall): Take values from configuration data.
20 const char kDummyClientToken[] = "MyVoiceIsMyPassport"; 24 const char kDummyClientToken[] = "MyVoiceIsMyPassport";
21 const std::string kDefaultBlimpletIPAddress = "127.0.0.1"; 25 const std::string kDefaultBlimpletIPAddress = "127.0.0.1";
22 const uint16_t kDefaultBlimpletTCPPort = 25467; 26 const uint16_t kNoPort = 0;
Wez 2016/02/12 02:31:13 nit: kPortNotSet or kInvalidPort?
Kevin M 2016/02/13 00:44:17 Done.
23 27
24 net::IPAddress GetBlimpletIPAddress() { 28 net::IPAddress GetBlimpletIPAddress() {
25 std::string host; 29 std::string host;
26 if (base::CommandLine::ForCurrentProcess()->HasSwitch( 30 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
27 switches::kBlimpletHost)) { 31 switches::kBlimpletHost)) {
28 host = base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( 32 host = base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
29 switches::kBlimpletHost); 33 switches::kBlimpletHost);
30 } else { 34 } else {
31 host = kDefaultBlimpletIPAddress; 35 host = kDefaultBlimpletIPAddress;
32 } 36 }
33 net::IPAddress ip_address; 37 net::IPAddress ip_address;
34 if (!ip_address.AssignFromIPLiteral(host)) 38 if (!ip_address.AssignFromIPLiteral(host))
35 CHECK(false) << "Invalid BlimpletAssignment host " << host; 39 CHECK(false) << "Invalid BlimpletAssignment host " << host;
36 return ip_address; 40 return ip_address;
37 } 41 }
38 42
39 uint16_t GetBlimpletTCPPort() { 43 uint16_t GetBlimpletTCPPort() {
40 if (base::CommandLine::ForCurrentProcess()->HasSwitch( 44 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
41 switches::kBlimpletTCPPort)) { 45 switches::kBlimpletTCPPort)) {
42 std::string port_str = 46 std::string port_str =
43 base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( 47 base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
44 switches::kBlimpletTCPPort); 48 switches::kBlimpletTCPPort);
45 uint port_64t; 49 uint port_64t;
Wez 2016/02/12 02:31:13 nit: This needs to be explicitly initialized.
Kevin M 2016/02/13 00:44:17 Done.
46 if (!base::StringToUint(port_str, &port_64t) || 50 if (!base::StringToUint(port_str, &port_64t) ||
47 !base::IsValueInRangeForNumericType<uint16_t>(port_64t)) { 51 !base::IsValueInRangeForNumericType<uint16_t>(port_64t)) {
48 CHECK(false) << "Invalid BlimpletAssignment port " << port_str; 52 CHECK(false) << "Invalid BlimpletAssignment port " << port_str;
49 } 53 }
50 return base::checked_cast<uint16_t>(port_64t); 54 return base::checked_cast<uint16_t>(port_64t);
51 } else { 55 } else {
52 return kDefaultBlimpletTCPPort; 56 return kNoPort;
53 } 57 }
54 } 58 }
55 59
60 uint16_t GetBlimpletSSLPort() {
Wez 2016/02/12 02:31:13 This is basically identical to the TCP port one ab
Kevin M 2016/02/13 00:44:17 Done.
61 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
62 switches::kBlimpletSSLPort)) {
Wez 2016/02/12 02:31:13 GetSwitchValueASCII returns an empty string if the
Kevin M 2016/02/13 00:44:18 Done.
63 std::string port_str =
64 base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
65 switches::kBlimpletSSLPort);
66 uint port_64t;
Wez 2016/02/12 02:31:13 nit: This needs to be explicitly initialized.
Kevin M 2016/02/13 00:44:17 Done.
67 if (!base::StringToUint(port_str, &port_64t) ||
68 !base::IsValueInRangeForNumericType<uint16_t>(port_64t)) {
69 CHECK(false) << "Invalid SSL port " << port_str;
Wez 2016/02/12 02:31:13 nit: Save the result of StringToUint || IsValue..
Kevin M 2016/02/13 00:44:17 Done.
70 }
71 return base::checked_cast<uint16_t>(port_64t);
72 } else {
73 return kNoPort;
74 }
75 }
76
77 base::FilePath GetBlimpletCertPath() {
Wez 2016/02/12 02:31:13 This function is redundant; GetSwitchValuePath() a
Kevin M 2016/02/13 00:44:18 Done.
78 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
79 switches::kBlimpletCertPath)) {
80 return base::CommandLine::ForCurrentProcess()->GetSwitchValuePath(
81 switches::kBlimpletCertPath);
82 }
83 return base::FilePath();
84 }
85
56 } // namespace 86 } // namespace
57 87
58 namespace client { 88 namespace client {
59 89
90 Assignment::Assignment() {}
Wez 2016/02/12 02:31:13 See above re inline init; you need to make sure to
Kevin M 2016/02/13 00:44:17 Done.
91
92 Assignment::~Assignment() {}
93
60 AssignmentSource::AssignmentSource( 94 AssignmentSource::AssignmentSource(
61 const scoped_refptr<base::SingleThreadTaskRunner>& main_task_runner) 95 const scoped_refptr<base::SingleThreadTaskRunner>& main_task_runner)
62 : main_task_runner_(main_task_runner) {} 96 : main_task_runner_(main_task_runner), io_thread_("CertFileThread") {
97 base::Thread::Options options;
98 options.message_loop_type = base::MessageLoop::TYPE_IO;
99 io_thread_.StartWithOptions(options);
Wez 2016/02/12 02:31:13 Cleaner to avoid creating this thread until you ac
Kevin M 2016/02/13 00:44:17 Done.
100 }
63 101
64 AssignmentSource::~AssignmentSource() {} 102 AssignmentSource::~AssignmentSource() {}
65 103
104 void AssignmentSource::ReadFromDisk(
Wez 2016/02/12 02:31:13 As noted elsewhere, this function can be a static
Kevin M 2016/02/13 00:44:17 Done.
105 base::FilePath path,
106 const base::Callback<void(const std::string&)>& callback) {
107 if (!io_thread_.task_runner()->RunsTasksOnCurrentThread()) {
108 // Execute file reads on the I/O thread.
109 io_thread_.task_runner()->PostTask(
110 FROM_HERE, base::Bind(&AssignmentSource::ReadFromDisk,
111 base::Unretained(this), path, callback));
112 return;
Wez 2016/02/12 02:31:13 ICK! This sort of trampolining is safe while the
Kevin M 2016/02/13 00:44:18 Done.
113 }
114
115 std::string output;
116 if (!base::ReadFileToString(path, &output)) {
117 LOG(ERROR) << "Couldn't read cert from file: " << path.LossyDisplayName();
Wez 2016/02/12 02:31:13 Why LOG(ERROR) when we CHECK for everything else?
Kevin M 2016/02/13 00:44:18 Done.
118 }
119
120 main_task_runner_->PostTask(FROM_HERE, base::Bind(callback, output));
Wez 2016/02/12 02:31:13 This doesn't match the API comment.
Kevin M 2016/02/13 00:44:17 Acknowledged.
121 }
122
123 void AssignmentSource::ParseCertForAssignment(
124 Assignment assignment,
125 const AssignmentCallback& callback,
126 const std::string& cert_str) {
127 if (!cert_str.empty()) {
Wez 2016/02/12 02:31:13 Surely you can't reach here if it's empty, so this
Kevin M 2016/02/13 00:44:17 Done.
128 scoped_refptr<net::X509Certificate> cert;
Wez 2016/02/12 02:31:13 Doesn't look like you use this?
Kevin M 2016/02/13 00:44:17 Done.
129 net::PEMTokenizer pem_tokenizer(cert_str, {"CERTIFICATE"});
130 int num_certs = 0;
Wez 2016/02/12 02:31:13 Rather than counting the certs, you can surely jus
Kevin M 2016/02/13 00:44:17 Done.
131 for (; pem_tokenizer.GetNext(); ++num_certs) {
132 assignment.cert = net::X509Certificate::CreateFromBytes(
133 pem_tokenizer.data().data(), pem_tokenizer.data().length());
134 if (!assignment.cert) {
135 LOG(ERROR) << "Couldn't parse cert!";
136 } else {
137 DVLOG(1) << "Parsed X509 cert.";
138 }
139 }
140 if (num_certs != 1) {
141 LOG(ERROR) << "Expected exactly 1 CERTIFICATE block, but found "
142 << num_certs << " blocks instead.";
143 assignment.cert = nullptr;
144 }
145 }
146
147 main_task_runner_->PostTask(FROM_HERE, base::Bind(callback, assignment));
Wez 2016/02/12 02:31:13 You're already on the main task runner, with a cle
Kevin M 2016/02/13 00:44:18 This line is from Tommy's initial impl, I was thin
148 }
149
66 void AssignmentSource::GetAssignment(const AssignmentCallback& callback) { 150 void AssignmentSource::GetAssignment(const AssignmentCallback& callback) {
67 DCHECK(main_task_runner_->BelongsToCurrentThread()); 151 DCHECK(main_task_runner_->BelongsToCurrentThread());
68 Assignment assignment; 152 Assignment assignment;
69 assignment.ip_endpoint = 153 assignment.ip_addresses.push_back(GetBlimpletIPAddress());
70 net::IPEndPoint(GetBlimpletIPAddress(), GetBlimpletTCPPort()); 154 if (GetBlimpletTCPPort() > 0) {
Wez 2016/02/12 02:31:13 This if() is always true, since the Get*Port() met
Kevin M 2016/02/13 00:44:17 Done.
155 assignment.tcp_port = GetBlimpletTCPPort();
156 }
157 if (GetBlimpletSSLPort() > 0) {
158 assignment.ssl_port = GetBlimpletSSLPort();
159 }
71 assignment.client_token = kDummyClientToken; 160 assignment.client_token = kDummyClientToken;
72 main_task_runner_->PostTask(FROM_HERE, base::Bind(callback, assignment)); 161
162 base::FilePath cert_path = GetBlimpletCertPath();
163 if (!cert_path.empty()) {
164 ReadFromDisk(cert_path,
165 base::Bind(&AssignmentSource::ParseCertForAssignment,
166 base::Unretained(this), assignment, callback));
Wez 2016/02/12 02:31:13 See notes above re combining file-read and cert-pa
Kevin M 2016/02/13 00:44:18 Done.
167 } else {
168 main_task_runner_->PostTask(FROM_HERE, base::Bind(callback, assignment));
Wez 2016/02/12 02:31:13 Assert that the SSL port is kNoPort in this case?
Kevin M 2016/02/13 00:44:17 Done.
169 }
73 } 170 }
74 171
75 } // namespace client 172 } // namespace client
76 } // namespace blimp 173 } // namespace blimp
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698