| 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))) {
|
|
|