Index: chrome/browser/chromeos/web_socket_proxy.cc |
diff --git a/chrome/browser/chromeos/web_socket_proxy.cc b/chrome/browser/chromeos/web_socket_proxy.cc |
index c2f29baaf72f88ec0f255b1f2df6c3845bfd610d..0e062c9ffe72b29bb9aa3d729893a941fb9dc20c 100644 |
--- a/chrome/browser/chromeos/web_socket_proxy.cc |
+++ b/chrome/browser/chromeos/web_socket_proxy.cc |
@@ -27,6 +27,7 @@ |
#include "base/basictypes.h" |
#include "base/bind.h" |
#include "base/logging.h" |
+#include "base/string_split.h" |
#include "base/memory/ref_counted.h" |
#include "base/memory/scoped_ptr.h" |
#include "base/sha1.h" |
@@ -147,38 +148,39 @@ std::string FetchAsciiSnippet(uint8* begin, uint8* end, AsciiFilter filter) { |
return rv; |
} |
-// Parses "passport:hostname:port:" string. Returns true on success. |
-bool FetchPassportNamePort( |
+// Parses "passport:addr:hostname:port:" string. Returns true on success. |
+bool FetchPassportAddrNamePort( |
uint8* begin, uint8* end, |
- std::string* passport, std::string* name, int* port) { |
+ std::string* passport, std::string* addr, |
+ std::string* hostname, int* port) { |
+ |
std::string input(begin, end); |
- if (input[input.size() - 1] != ':') |
- return false; |
- input.resize(input.size() - 1); |
- size_t pos = input.find_last_of(':'); |
- if (pos == std::string::npos) |
- return false; |
- std::string port_str(input, pos + 1); |
- if (port_str.empty()) |
- return false; |
- const char kAsciiDigits[] = "0123456789"; |
- COMPILE_ASSERT(sizeof(kAsciiDigits) == 10 + 1, mess_with_digits); |
- if (port_str.find_first_not_of(kAsciiDigits) != std::string::npos) |
+ std::vector<std::string> parts; |
+ base::SplitString(input, ':', &parts); |
+ |
+ if (parts.size() != 5 || !parts.back().empty()) { |
+ LOG(ERROR) << "Wrong format, input" << input; |
return false; |
- if (!base::StringToInt(port_str, port) || |
- *port < 0 || |
- *port >= (1 << 16)) { |
+ } |
+ |
+ // Get passport |
+ *passport = parts[0]; |
+ // Get IP address. |
+ *addr = parts[1]; |
+ // Get hostname. |
+ *hostname = parts[2]; |
+ // Get port. |
+ if (!base::StringToInt(parts[3], port) || *port < 0 || *port >= (1<<16)) { |
+ LOG(ERROR) << "Not a port: " << port << ", input=" << input; |
return false; |
} |
- input.resize(pos); |
- pos = input.find_first_of(':'); |
- if (pos == std::string::npos) |
+ if (passport->empty() || hostname->empty()) { |
+ LOG(ERROR) << "Password or hostname is empty, input=" << input; |
return false; |
- passport->assign(input, 0, pos); |
- name->assign(input, pos + 1, std::string::npos); |
- return !name->empty(); |
+ } |
+ return true; |
} |
std::string FetchExtensionIdFromOrigin(const std::string &origin) { |
@@ -450,6 +452,9 @@ class Conn { |
std::string destname_; |
int destport_; |
+ // Preresolved |destname_| (empty if not pre-resolved). |
+ std::string destaddr_; |
+ |
// Whether TLS over TCP requested. |
bool do_tls_; |
@@ -1302,6 +1307,7 @@ Conn::Status Conn::ConsumeHeader(struct evbuffer* evb) { |
return STATUS_ABORT; |
} |
destport_ = port; |
+ destaddr_ = requested_parameters_["addr"]; |
do_tls_ = (requested_parameters_["tls"] == "true"); |
requested_parameters_["extension_id"] = |
@@ -1389,14 +1395,16 @@ Conn::Status Conn::ConsumeDestframe(struct evbuffer* evb) { |
frame_mask_index_ = (frame_mask_index_ + 1) % 4; |
} |
std::string passport; |
- if (!FetchPassportNamePort(buf, buf + frame_bytes_remaining_, |
- &passport, &destname_, &destport_)) { |
+ if (!FetchPassportAddrNamePort(buf, buf + frame_bytes_remaining_, |
+ &passport, &destaddr_, &destname_, &destport_)) { |
return STATUS_ABORT; |
} |
std::map<std::string, std::string> map; |
map["hostname"] = destname_; |
map["port"] = base::IntToString(destport_); |
map["extension_id"] = FetchExtensionIdFromOrigin(GetOrigin()); |
+ if (!destaddr_.empty()) |
+ map["addr"] = destaddr_; |
if (!browser::InternalAuthVerification::VerifyPassport( |
passport, "web_socket_proxy", map)) { |
return STATUS_ABORT; |
@@ -1605,12 +1613,14 @@ void Conn::OnPrimchanRead(struct bufferevent* bev, EventKey evkey) { |
if (cs->destname_ == "localhost") |
cs->destname_ = "127.0.0.1"; |
} |
+ if (cs->destaddr_.empty()) |
+ cs->destaddr_ = cs->destname_; |
{ |
struct sockaddr_in sa; |
memset(&sa, 0, sizeof(sa)); |
sa.sin_port = htons(cs->destport_); |
if (inet_pton(sa.sin_family = AF_INET, |
- cs->destname_.c_str(), |
+ cs->destaddr_.c_str(), |
&sa.sin_addr) == 1) { |
// valid IPv4 address supplied. |
if (cs->TryConnectDest((struct sockaddr*)&sa, sizeof(sa))) { |
@@ -1620,18 +1630,18 @@ void Conn::OnPrimchanRead(struct bufferevent* bev, EventKey evkey) { |
} |
} |
{ |
- if (cs->destname_.size() >= 2 && |
- cs->destname_[0] == '[' && |
- cs->destname_[cs->destname_.size() - 1] == ']') { |
+ if (cs->destaddr_.size() >= 2 && |
+ cs->destaddr_[0] == '[' && |
+ cs->destaddr_[cs->destaddr_.size() - 1] == ']') { |
// Literal IPv6 address in brackets. |
- cs->destname_ = |
- cs->destname_.substr(1, cs->destname_.size() - 2); |
+ cs->destaddr_ = |
+ cs->destaddr_.substr(1, cs->destaddr_.size() - 2); |
} |
struct sockaddr_in6 sa; |
memset(&sa, 0, sizeof(sa)); |
sa.sin6_port = htons(cs->destport_); |
if (inet_pton(sa.sin6_family = AF_INET6, |
- cs->destname_.c_str(), |
+ cs->destaddr_.c_str(), |
&sa.sin6_addr) == 1) { |
// valid IPv6 address supplied. |
if (cs->TryConnectDest((struct sockaddr*)&sa, sizeof(sa))) { |