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

Side by Side Diff: chrome/browser/chromeos/web_socket_proxy.cc

Issue 6683060: Private API for extensions like ssh-client that need access to TCP. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: removed changes to rand_util_unittest Created 9 years, 7 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
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 "web_socket_proxy.h" 5 #include "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 12 matching lines...) Expand all
23 #include <sys/types.h> 23 #include <sys/types.h>
24 #include <sys/wait.h> 24 #include <sys/wait.h>
25 25
26 #include "base/base64.h" 26 #include "base/base64.h"
27 #include "base/basictypes.h" 27 #include "base/basictypes.h"
28 #include "base/logging.h" 28 #include "base/logging.h"
29 #include "base/md5.h" 29 #include "base/md5.h"
30 #include "base/memory/scoped_ptr.h" 30 #include "base/memory/scoped_ptr.h"
31 #include "base/string_number_conversions.h" 31 #include "base/string_number_conversions.h"
32 #include "base/string_util.h" 32 #include "base/string_util.h"
33 #include "chrome/browser/internal_auth.h"
33 #include "content/browser/browser_thread.h" 34 #include "content/browser/browser_thread.h"
34 #include "content/common/notification_service.h" 35 #include "content/common/notification_service.h"
35 #include "content/common/notification_type.h" 36 #include "content/common/notification_type.h"
36 // TODO(dilmah): enable this once webSocketProxyPrivate.getToken is wired. 37 #include "content/common/url_constants.h"
37 #if 0 38 #include "googleurl/src/gurl.h"
38 #include "chrome/browser/internal_auth.h"
39 #endif
40 #include "third_party/libevent/evdns.h" 39 #include "third_party/libevent/evdns.h"
41 #include "third_party/libevent/event.h" 40 #include "third_party/libevent/event.h"
42 41
43 namespace chromeos { 42 namespace chromeos {
44 43
45 namespace { 44 namespace {
46 45
47 const uint8 kCRLF[] = "\r\n"; 46 const uint8 kCRLF[] = "\r\n";
48 const uint8 kCRLFCRLF[] = "\r\n\r\n"; 47 const uint8 kCRLFCRLF[] = "\r\n\r\n";
49 48
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
98 *result *= 10; 97 *result *= 10;
99 int digit = s[i] - '0'; 98 int digit = s[i] - '0';
100 if (*result > std::numeric_limits<uint32>::max() - digit) 99 if (*result > std::numeric_limits<uint32>::max() - digit)
101 return false; 100 return false;
102 *result += digit; 101 *result += digit;
103 } 102 }
104 } 103 }
105 return got_something; 104 return got_something;
106 } 105 }
107 106
108 // Parses "token:hostname:port:" string. Returns true on success. 107 // Parses "passport:hostname:port:" string. Returns true on success.
109 bool FetchTokenNamePort( 108 bool FetchPassportNamePort(
110 uint8* begin, uint8* end, 109 uint8* begin, uint8* end,
111 std::string* token, std::string* name, uint32* port) { 110 std::string* passport, std::string* name, uint32* port) {
112 std::string input(begin, end); 111 std::string input(begin, end);
113 if (input[input.size() - 1] != ':') 112 if (input[input.size() - 1] != ':')
114 return false; 113 return false;
115 input.resize(input.size() - 1); 114 input.resize(input.size() - 1);
116 115
117 size_t pos = input.find_last_of(':'); 116 size_t pos = input.find_last_of(':');
118 if (pos == std::string::npos) 117 if (pos == std::string::npos)
119 return false; 118 return false;
120 std::string port_str(input, pos + 1); 119 std::string port_str(input, pos + 1);
121 if (port_str.empty()) 120 if (port_str.empty())
122 return false; 121 return false;
123 const char kAsciiDigits[] = "0123456789"; 122 const char kAsciiDigits[] = "0123456789";
124 COMPILE_ASSERT(sizeof(kAsciiDigits) == 10 + 1, mess_with_digits); 123 COMPILE_ASSERT(sizeof(kAsciiDigits) == 10 + 1, mess_with_digits);
125 if (port_str.find_first_not_of(kAsciiDigits) != std::string::npos) 124 if (port_str.find_first_not_of(kAsciiDigits) != std::string::npos)
126 return false; 125 return false;
127 if (!FetchDecimalDigits(port_str, port) || 126 if (!FetchDecimalDigits(port_str, port) ||
128 *port <= 0 || 127 *port <= 0 ||
129 *port >= (1 << 16)) { 128 *port >= (1 << 16)) {
130 return false; 129 return false;
131 } 130 }
132 input.resize(pos); 131 input.resize(pos);
133 132
134 pos = input.find_first_of(':'); 133 pos = input.find_first_of(':');
135 if (pos == std::string::npos) 134 if (pos == std::string::npos)
136 return false; 135 return false;
137 token->assign(input, 0, pos); 136 passport->assign(input, 0, pos);
138 name->assign(input, pos + 1, std::string::npos); 137 name->assign(input, pos + 1, std::string::npos);
139 return !name->empty(); 138 return !name->empty();
140 } 139 }
141 140
142 std::string FetchExtensionIdFromOrigin(const std::string origin) { 141 std::string FetchExtensionIdFromOrigin(const std::string &origin) {
143 // Origin of extension looks like "chrome-extension://EXTENSION_ID". 142 GURL url(origin);
144 return origin.substr(origin.find_last_of('/')); 143 if (url.SchemeIs(chrome::kExtensionScheme))
144 return url.host();
145 else
146 return std::string();
145 } 147 }
146 148
147 inline size_t strlen(const uint8* s) { 149 inline size_t strlen(const uint8* s) {
148 return ::strlen(reinterpret_cast<const char*>(s)); 150 return ::strlen(reinterpret_cast<const char*>(s));
149 } 151 }
150 152
151 void SendNotification() { 153 void SendNotification() {
152 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 154 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
153 NotificationService::current()->Notify( 155 NotificationService::current()->Notify(
154 NotificationType::WEB_SOCKET_PROXY_STARTED, 156 NotificationType::WEB_SOCKET_PROXY_STARTED,
(...skipping 571 matching lines...) Expand 10 before | Expand all | Expand 10 after
726 if (!key.empty()) 728 if (!key.empty())
727 header_fields_[key] = FetchLowerCasedASCIISnippet(npos, pos); 729 header_fields_[key] = FetchLowerCasedASCIISnippet(npos, pos);
728 } 730 }
729 731
730 // Values of Upgrade and Connection fields are hardcoded in the protocol. 732 // Values of Upgrade and Connection fields are hardcoded in the protocol.
731 if (header_fields_["upgrade"] != "websocket" || 733 if (header_fields_["upgrade"] != "websocket" ||
732 header_fields_["connection"] != "upgrade") { 734 header_fields_["connection"] != "upgrade") {
733 return STATUS_ABORT; 735 return STATUS_ABORT;
734 } 736 }
735 737
736 if (!master_->IsOriginAllowed(header_fields_["origin"])) 738 // Normalize origin (e.g. leading slash).
739 GURL origin = GURL(header_fields_["origin"]).GetOrigin();
740 if (!origin.is_valid())
741 return STATUS_ABORT;
742 // Here we check origin. This check may seem redundant because we verify
743 // passport token later. However the earlier we can reject connection the
744 // better. We receive origin field in websocket header way before receiving
745 // passport string.
746 if (!master_->IsOriginAllowed(origin.spec()))
737 return STATUS_ABORT; 747 return STATUS_ABORT;
738 748
739 static const std::string kSecKey1 = "sec-websocket-key1"; 749 static const std::string kSecKey1 = "sec-websocket-key1";
740 static const std::string kSecKey2 = "sec-websocket-key2"; 750 static const std::string kSecKey2 = "sec-websocket-key2";
741 uint32 key_number1, key_number2; 751 uint32 key_number1, key_number2;
742 if (!FetchDecimalDigits(header_fields_[kSecKey1], 752 if (!FetchDecimalDigits(header_fields_[kSecKey1], &key_number1) ||
743 &key_number1) || 753 !FetchDecimalDigits(header_fields_[kSecKey2], &key_number2)) {
744 !FetchDecimalDigits(header_fields_[kSecKey2],
745 &key_number2)) {
746 return STATUS_ABORT; 754 return STATUS_ABORT;
747 } 755 }
748 756
749 // We limit incoming header size so following numbers shall not be too high. 757 // We limit incoming header size so following numbers shall not be too high.
750 int spaces1 = CountSpaces(header_fields_[kSecKey1]); 758 int spaces1 = CountSpaces(header_fields_[kSecKey1]);
751 int spaces2 = CountSpaces(header_fields_[kSecKey2]); 759 int spaces2 = CountSpaces(header_fields_[kSecKey2]);
752 if (spaces1 == 0 || 760 if (spaces1 == 0 ||
753 spaces2 == 0 || 761 spaces2 == 0 ||
754 key_number1 % spaces1 != 0 || 762 key_number1 % spaces1 != 0 ||
755 key_number2 % spaces2 != 0) { 763 key_number2 % spaces2 != 0) {
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
821 uint8* buf_end = buf + buf_size; 829 uint8* buf_end = buf + buf_size;
822 uint8* term_pos = std::find(buf + 1, buf_end, 0xff); 830 uint8* term_pos = std::find(buf + 1, buf_end, 0xff);
823 if (term_pos == buf_end) { 831 if (term_pos == buf_end) {
824 if (buf_size >= WebSocketProxy::kHeaderLimit) { 832 if (buf_size >= WebSocketProxy::kHeaderLimit) {
825 // So big and still worth nothing. 833 // So big and still worth nothing.
826 return STATUS_ABORT; 834 return STATUS_ABORT;
827 } 835 }
828 return STATUS_INCOMPLETE; 836 return STATUS_INCOMPLETE;
829 } 837 }
830 838
831 std::string token; 839 std::string passport;
832 if (!FetchTokenNamePort(buf + 1, term_pos, &token, &destname_, &destport_)) 840 if (!FetchPassportNamePort(
841 buf + 1, term_pos, &passport, &destname_, &destport_)) {
833 return STATUS_ABORT; 842 return STATUS_ABORT;
834 // TODO(dilmah): enable this once webSocketProxyPrivate.getToken is wired. 843 }
835 #if 0
836 std::map<std::string, std::string> map; 844 std::map<std::string, std::string> map;
837 map["hostname"] = destname_; 845 map["hostname"] = destname_;
838 map["port"] = base::IntToString(destport_); 846 map["port"] = base::IntToString(destport_);
839 map["extension_id"] = FetchExtensionIdFromOrigin(header_fields_["origin"]); 847 map["extension_id"] = FetchExtensionIdFromOrigin(header_fields_["origin"]);
840 if (!browser::InternalAuthVerification::VerifyToken( 848 if (!browser::InternalAuthVerification::VerifyPassport(
841 "web_socket_proxy", token, map)) { 849 passport, "web_socket_proxy", map)) {
842 return STATUS_ABORT; 850 return STATUS_ABORT;
843 } 851 }
844 #endif
845 852
846 evbuffer_drain(evb, term_pos - buf + 1); 853 evbuffer_drain(evb, term_pos - buf + 1);
847 return STATUS_OK; 854 return STATUS_OK;
848 } 855 }
849 856
850 Conn::Status Conn::ConsumeFrameHeader(struct evbuffer* evb) { 857 Conn::Status Conn::ConsumeFrameHeader(struct evbuffer* evb) {
851 uint8* buf = EVBUFFER_DATA(evb); 858 uint8* buf = EVBUFFER_DATA(evb);
852 size_t buf_size = EVBUFFER_LENGTH(evb); 859 size_t buf_size = EVBUFFER_LENGTH(evb);
853 860
854 if (buf_size < 1) 861 if (buf_size < 1)
(...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after
1281 void WebSocketProxy::Run() { 1288 void WebSocketProxy::Run() {
1282 static_cast<Serv*>(impl_)->Run(); 1289 static_cast<Serv*>(impl_)->Run();
1283 } 1290 }
1284 1291
1285 void WebSocketProxy::Shutdown() { 1292 void WebSocketProxy::Shutdown() {
1286 static_cast<Serv*>(impl_)->Shutdown(); 1293 static_cast<Serv*>(impl_)->Shutdown();
1287 } 1294 }
1288 1295
1289 } // namespace chromeos 1296 } // namespace chromeos
1290 1297
OLDNEW
« no previous file with comments | « chrome/browser/chromeos/web_socket_proxy.h ('k') | chrome/browser/chromeos/web_socket_proxy_controller.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698