| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "chrome/browser/chromeos/web_socket_proxy.h" | 5 #include "chrome/browser/chromeos/web_socket_proxy.h" |
| 6 | 6 |
| 7 #include <stdio.h> | 7 #include <stdio.h> |
| 8 #include <stdlib.h> | 8 #include <stdlib.h> |
| 9 #include <string.h> | 9 #include <string.h> |
| 10 | 10 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 27 #include "base/basictypes.h" | 27 #include "base/basictypes.h" |
| 28 #include "base/bind.h" | 28 #include "base/bind.h" |
| 29 #include "base/lazy_instance.h" | 29 #include "base/lazy_instance.h" |
| 30 #include "base/logging.h" | 30 #include "base/logging.h" |
| 31 #include "base/memory/ref_counted.h" | 31 #include "base/memory/ref_counted.h" |
| 32 #include "base/memory/scoped_ptr.h" | 32 #include "base/memory/scoped_ptr.h" |
| 33 #include "base/sha1.h" | 33 #include "base/sha1.h" |
| 34 #include "base/stl_util.h" | 34 #include "base/stl_util.h" |
| 35 #include "base/string_number_conversions.h" | 35 #include "base/string_number_conversions.h" |
| 36 #include "base/string_util.h" | 36 #include "base/string_util.h" |
| 37 #include "chrome/browser/chromeos/web_socket_proxy_helper.h" |
| 37 #include "chrome/browser/internal_auth.h" | 38 #include "chrome/browser/internal_auth.h" |
| 38 #include "chrome/common/chrome_notification_types.h" | 39 #include "chrome/common/chrome_notification_types.h" |
| 39 #include "chrome/common/url_constants.h" | 40 #include "chrome/common/url_constants.h" |
| 40 #include "content/public/browser/browser_thread.h" | 41 #include "content/public/browser/browser_thread.h" |
| 41 #include "content/public/browser/notification_details.h" | 42 #include "content/public/browser/notification_details.h" |
| 42 #include "content/public/browser/notification_service.h" | 43 #include "content/public/browser/notification_service.h" |
| 43 #include "content/public/browser/notification_types.h" | 44 #include "content/public/browser/notification_types.h" |
| 44 #include "content/public/common/url_constants.h" | 45 #include "content/public/common/url_constants.h" |
| 45 #include "googleurl/src/gurl.h" | 46 #include "googleurl/src/gurl.h" |
| 46 #include "googleurl/src/url_parse.h" | 47 #include "googleurl/src/url_parse.h" |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 141 std::string FetchAsciiSnippet(uint8* begin, uint8* end, AsciiFilter filter) { | 142 std::string FetchAsciiSnippet(uint8* begin, uint8* end, AsciiFilter filter) { |
| 142 std::string rv; | 143 std::string rv; |
| 143 for (; begin < end; ++begin) { | 144 for (; begin < end; ++begin) { |
| 144 if (!isascii(*begin)) | 145 if (!isascii(*begin)) |
| 145 return rv; | 146 return rv; |
| 146 rv += filter(*begin); | 147 rv += filter(*begin); |
| 147 } | 148 } |
| 148 return rv; | 149 return rv; |
| 149 } | 150 } |
| 150 | 151 |
| 151 // Parses "passport:hostname:port:" string. Returns true on success. | |
| 152 bool FetchPassportNamePort( | |
| 153 uint8* begin, uint8* end, | |
| 154 std::string* passport, std::string* name, int* port) { | |
| 155 std::string input(begin, end); | |
| 156 if (input[input.size() - 1] != ':') | |
| 157 return false; | |
| 158 input.resize(input.size() - 1); | |
| 159 | |
| 160 size_t pos = input.find_last_of(':'); | |
| 161 if (pos == std::string::npos) | |
| 162 return false; | |
| 163 std::string port_str(input, pos + 1); | |
| 164 if (port_str.empty()) | |
| 165 return false; | |
| 166 const char kAsciiDigits[] = "0123456789"; | |
| 167 COMPILE_ASSERT(sizeof(kAsciiDigits) == 10 + 1, mess_with_digits); | |
| 168 if (port_str.find_first_not_of(kAsciiDigits) != std::string::npos) | |
| 169 return false; | |
| 170 if (!base::StringToInt(port_str, port) || | |
| 171 *port < 0 || | |
| 172 *port >= (1 << 16)) { | |
| 173 return false; | |
| 174 } | |
| 175 input.resize(pos); | |
| 176 | |
| 177 pos = input.find_first_of(':'); | |
| 178 if (pos == std::string::npos) | |
| 179 return false; | |
| 180 passport->assign(input, 0, pos); | |
| 181 name->assign(input, pos + 1, std::string::npos); | |
| 182 return !name->empty(); | |
| 183 } | |
| 184 | |
| 185 std::string FetchExtensionIdFromOrigin(const std::string &origin) { | 152 std::string FetchExtensionIdFromOrigin(const std::string &origin) { |
| 186 GURL url(origin); | 153 GURL url(origin); |
| 187 if (url.SchemeIs(chrome::kExtensionScheme)) | 154 if (url.SchemeIs(chrome::kExtensionScheme)) |
| 188 return url.host(); | 155 return url.host(); |
| 189 else | 156 else |
| 190 return std::string(); | 157 return std::string(); |
| 191 } | 158 } |
| 192 | 159 |
| 193 inline size_t strlen(const void* s) { | 160 inline size_t strlen(const void* s) { |
| 194 return ::strlen(static_cast<const char*>(s)); | 161 return ::strlen(static_cast<const char*>(s)); |
| (...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 444 std::map<std::string, std::string> header_fields_; | 411 std::map<std::string, std::string> header_fields_; |
| 445 | 412 |
| 446 // Parameters requested via query component of GET resource. | 413 // Parameters requested via query component of GET resource. |
| 447 std::map<std::string, std::string> requested_parameters_; | 414 std::map<std::string, std::string> requested_parameters_; |
| 448 | 415 |
| 449 // Hostname and port of destination socket. | 416 // Hostname and port of destination socket. |
| 450 // Websocket client supplies them in first data frame (destframe). | 417 // Websocket client supplies them in first data frame (destframe). |
| 451 std::string destname_; | 418 std::string destname_; |
| 452 int destport_; | 419 int destport_; |
| 453 | 420 |
| 421 // Preresolved |destname_| (empty if not pre-resolved). |
| 422 std::string destaddr_; |
| 423 |
| 454 // Whether TLS over TCP requested. | 424 // Whether TLS over TCP requested. |
| 455 bool do_tls_; | 425 bool do_tls_; |
| 456 | 426 |
| 457 // We try to DNS resolve hostname in both IPv4 and IPv6 domains. | 427 // We try to DNS resolve hostname in both IPv4 and IPv6 domains. |
| 458 // Track resolution failures here. | 428 // Track resolution failures here. |
| 459 bool destresolution_ipv4_failed_; | 429 bool destresolution_ipv4_failed_; |
| 460 bool destresolution_ipv6_failed_; | 430 bool destresolution_ipv6_failed_; |
| 461 | 431 |
| 462 // Used to schedule a timeout for initial phase of connection. | 432 // Used to schedule a timeout for initial phase of connection. |
| 463 scoped_ptr<struct event> destconnect_timeout_event_; | 433 scoped_ptr<struct event> destconnect_timeout_event_; |
| (...skipping 834 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1298 return STATUS_ABORT; | 1268 return STATUS_ABORT; |
| 1299 | 1269 |
| 1300 if (!requested_parameters_.empty()) { | 1270 if (!requested_parameters_.empty()) { |
| 1301 destname_ = requested_parameters_["hostname"]; | 1271 destname_ = requested_parameters_["hostname"]; |
| 1302 int port; | 1272 int port; |
| 1303 if (!base::StringToInt(requested_parameters_["port"], &port) || | 1273 if (!base::StringToInt(requested_parameters_["port"], &port) || |
| 1304 port < 0 || port >= 1 << 16) { | 1274 port < 0 || port >= 1 << 16) { |
| 1305 return STATUS_ABORT; | 1275 return STATUS_ABORT; |
| 1306 } | 1276 } |
| 1307 destport_ = port; | 1277 destport_ = port; |
| 1278 destaddr_ = requested_parameters_["addr"]; |
| 1308 do_tls_ = (requested_parameters_["tls"] == "true"); | 1279 do_tls_ = (requested_parameters_["tls"] == "true"); |
| 1309 | 1280 |
| 1310 requested_parameters_["extension_id"] = | 1281 requested_parameters_["extension_id"] = |
| 1311 FetchExtensionIdFromOrigin(GetOrigin()); | 1282 FetchExtensionIdFromOrigin(GetOrigin()); |
| 1312 std::string passport(requested_parameters_["passport"]); | 1283 std::string passport(requested_parameters_["passport"]); |
| 1313 requested_parameters_.erase("passport"); | 1284 requested_parameters_.erase("passport"); |
| 1314 if (!browser::InternalAuthVerification::VerifyPassport( | 1285 if (!browser::InternalAuthVerification::VerifyPassport( |
| 1315 passport, "web_socket_proxy", requested_parameters_)) { | 1286 passport, "web_socket_proxy", requested_parameters_)) { |
| 1316 return STATUS_ABORT; | 1287 return STATUS_ABORT; |
| 1317 } | 1288 } |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1385 | 1356 |
| 1386 uint8* buf = EVBUFFER_DATA(evb); | 1357 uint8* buf = EVBUFFER_DATA(evb); |
| 1387 size_t buf_size = EVBUFFER_LENGTH(evb); | 1358 size_t buf_size = EVBUFFER_LENGTH(evb); |
| 1388 if (buf_size < frame_bytes_remaining_) | 1359 if (buf_size < frame_bytes_remaining_) |
| 1389 return STATUS_INCOMPLETE; | 1360 return STATUS_INCOMPLETE; |
| 1390 for (size_t i = 0; i < buf_size; ++i) { | 1361 for (size_t i = 0; i < buf_size; ++i) { |
| 1391 buf[i] ^= frame_mask_[frame_mask_index_]; | 1362 buf[i] ^= frame_mask_[frame_mask_index_]; |
| 1392 frame_mask_index_ = (frame_mask_index_ + 1) % 4; | 1363 frame_mask_index_ = (frame_mask_index_ + 1) % 4; |
| 1393 } | 1364 } |
| 1394 std::string passport; | 1365 std::string passport; |
| 1395 if (!FetchPassportNamePort(buf, buf + frame_bytes_remaining_, | 1366 if (!WebSocketProxyHelper::FetchPassportAddrNamePort( |
| 1396 &passport, &destname_, &destport_)) { | 1367 buf, buf + frame_bytes_remaining_, |
| 1368 &passport, &destaddr_, &destname_, &destport_)) { |
| 1397 return STATUS_ABORT; | 1369 return STATUS_ABORT; |
| 1398 } | 1370 } |
| 1399 std::map<std::string, std::string> map; | 1371 std::map<std::string, std::string> map; |
| 1400 map["hostname"] = destname_; | 1372 map["hostname"] = destname_; |
| 1401 map["port"] = base::IntToString(destport_); | 1373 map["port"] = base::IntToString(destport_); |
| 1402 map["extension_id"] = FetchExtensionIdFromOrigin(GetOrigin()); | 1374 map["extension_id"] = FetchExtensionIdFromOrigin(GetOrigin()); |
| 1375 if (!destaddr_.empty()) |
| 1376 map["addr"] = destaddr_; |
| 1403 if (!browser::InternalAuthVerification::VerifyPassport( | 1377 if (!browser::InternalAuthVerification::VerifyPassport( |
| 1404 passport, "web_socket_proxy", map)) { | 1378 passport, "web_socket_proxy", map)) { |
| 1405 return STATUS_ABORT; | 1379 return STATUS_ABORT; |
| 1406 } | 1380 } |
| 1407 | 1381 |
| 1408 evbuffer_drain(evb, frame_bytes_remaining_); | 1382 evbuffer_drain(evb, frame_bytes_remaining_); |
| 1409 frame_bytes_remaining_ = 0; | 1383 frame_bytes_remaining_ = 0; |
| 1410 return STATUS_OK; | 1384 return STATUS_OK; |
| 1411 } | 1385 } |
| 1412 | 1386 |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1601 case PHASE_WAIT_DESTFRAME: { | 1575 case PHASE_WAIT_DESTFRAME: { |
| 1602 switch (cs->ConsumeDestframe(EVBUFFER_INPUT(bev))) { | 1576 switch (cs->ConsumeDestframe(EVBUFFER_INPUT(bev))) { |
| 1603 case STATUS_OK: { | 1577 case STATUS_OK: { |
| 1604 { | 1578 { |
| 1605 // Unfortunately libevent as of 1.4 does not look into /etc/hosts. | 1579 // Unfortunately libevent as of 1.4 does not look into /etc/hosts. |
| 1606 // There seems to be no easy API to perform only "local" part of | 1580 // There seems to be no easy API to perform only "local" part of |
| 1607 // getaddrinfo resolution. Hence this hack for "localhost". | 1581 // getaddrinfo resolution. Hence this hack for "localhost". |
| 1608 if (cs->destname_ == "localhost") | 1582 if (cs->destname_ == "localhost") |
| 1609 cs->destname_ = "127.0.0.1"; | 1583 cs->destname_ = "127.0.0.1"; |
| 1610 } | 1584 } |
| 1585 if (cs->destaddr_.empty()) |
| 1586 cs->destaddr_ = cs->destname_; |
| 1611 { | 1587 { |
| 1612 struct sockaddr_in sa; | 1588 struct sockaddr_in sa; |
| 1613 memset(&sa, 0, sizeof(sa)); | 1589 memset(&sa, 0, sizeof(sa)); |
| 1614 sa.sin_port = htons(cs->destport_); | 1590 sa.sin_port = htons(cs->destport_); |
| 1615 if (inet_pton(sa.sin_family = AF_INET, | 1591 if (inet_pton(sa.sin_family = AF_INET, |
| 1616 cs->destname_.c_str(), | 1592 cs->destaddr_.c_str(), |
| 1617 &sa.sin_addr) == 1) { | 1593 &sa.sin_addr) == 1) { |
| 1618 // valid IPv4 address supplied. | 1594 // valid IPv4 address supplied. |
| 1619 if (cs->TryConnectDest((struct sockaddr*)&sa, sizeof(sa))) { | 1595 if (cs->TryConnectDest((struct sockaddr*)&sa, sizeof(sa))) { |
| 1620 cs->phase_ = PHASE_WAIT_DESTCONNECT; | 1596 cs->phase_ = PHASE_WAIT_DESTCONNECT; |
| 1621 return; | 1597 return; |
| 1622 } | 1598 } |
| 1623 } | 1599 } |
| 1624 } | 1600 } |
| 1625 { | 1601 { |
| 1626 if (cs->destname_.size() >= 2 && | 1602 if (cs->destaddr_.size() >= 2 && |
| 1627 cs->destname_[0] == '[' && | 1603 cs->destaddr_[0] == '[' && |
| 1628 cs->destname_[cs->destname_.size() - 1] == ']') { | 1604 cs->destaddr_[cs->destaddr_.size() - 1] == ']') { |
| 1629 // Literal IPv6 address in brackets. | 1605 // Literal IPv6 address in brackets. |
| 1630 cs->destname_ = | 1606 cs->destaddr_ = |
| 1631 cs->destname_.substr(1, cs->destname_.size() - 2); | 1607 cs->destaddr_.substr(1, cs->destaddr_.size() - 2); |
| 1632 } | 1608 } |
| 1633 struct sockaddr_in6 sa; | 1609 struct sockaddr_in6 sa; |
| 1634 memset(&sa, 0, sizeof(sa)); | 1610 memset(&sa, 0, sizeof(sa)); |
| 1635 sa.sin6_port = htons(cs->destport_); | 1611 sa.sin6_port = htons(cs->destport_); |
| 1636 if (inet_pton(sa.sin6_family = AF_INET6, | 1612 if (inet_pton(sa.sin6_family = AF_INET6, |
| 1637 cs->destname_.c_str(), | 1613 cs->destaddr_.c_str(), |
| 1638 &sa.sin6_addr) == 1) { | 1614 &sa.sin6_addr) == 1) { |
| 1639 // valid IPv6 address supplied. | 1615 // valid IPv6 address supplied. |
| 1640 if (cs->TryConnectDest((struct sockaddr*)&sa, sizeof(sa))) { | 1616 if (cs->TryConnectDest((struct sockaddr*)&sa, sizeof(sa))) { |
| 1641 cs->phase_ = PHASE_WAIT_DESTCONNECT; | 1617 cs->phase_ = PHASE_WAIT_DESTCONNECT; |
| 1642 return; | 1618 return; |
| 1643 } | 1619 } |
| 1644 } | 1620 } |
| 1645 } | 1621 } |
| 1646 // Asynchronous DNS resolution. | 1622 // Asynchronous DNS resolution. |
| 1647 if (evdns_count_nameservers() < 1) { | 1623 if (evdns_count_nameservers() < 1) { |
| (...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1937 | 1913 |
| 1938 void WebSocketProxy::Shutdown() { | 1914 void WebSocketProxy::Shutdown() { |
| 1939 static_cast<Serv*>(impl_)->Shutdown(); | 1915 static_cast<Serv*>(impl_)->Shutdown(); |
| 1940 } | 1916 } |
| 1941 | 1917 |
| 1942 void WebSocketProxy::OnNetworkChange() { | 1918 void WebSocketProxy::OnNetworkChange() { |
| 1943 static_cast<Serv*>(impl_)->OnNetworkChange(); | 1919 static_cast<Serv*>(impl_)->OnNetworkChange(); |
| 1944 } | 1920 } |
| 1945 | 1921 |
| 1946 } // namespace chromeos | 1922 } // namespace chromeos |
| OLD | NEW |