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

Side by Side Diff: chrome/common/extensions/permissions/socket_permission_data.cc

Issue 10993078: Use extensions socket permission for TCP/UDP socket APIs in Pepper (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fixed Android build Created 8 years, 1 month 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) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/common/extensions/permissions/socket_permission_data.h" 5 #include "chrome/common/extensions/permissions/socket_permission_data.h"
6 6
7 #include <cstdlib> 7 #include <cstdlib>
8 #include <sstream> 8 #include <sstream>
9 #include <vector> 9 #include <vector>
10 10
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/string_number_conversions.h" 12 #include "base/string_number_conversions.h"
13 #include "base/string_split.h" 13 #include "base/string_split.h"
14 #include "base/string_util.h" 14 #include "base/string_util.h"
15 #include "googleurl/src/url_canon.h" 15 #include "googleurl/src/url_canon.h"
16 16
17 namespace { 17 namespace {
18 18
19 using content::SocketPermissionRequest;
19 using extensions::SocketPermissionData; 20 using extensions::SocketPermissionData;
20 21
21 const char kColon = ':'; 22 const char kColon = ':';
22 const char kDot = '.'; 23 const char kDot = '.';
23 const char kWildcard[] = "*"; 24 const char kWildcard[] = "*";
24 const char kInvalid[] = "invalid"; 25 const char kInvalid[] = "invalid";
25 const char kTCPConnect[] = "tcp-connect"; 26 const char kTCPConnect[] = "tcp-connect";
26 const char kTCPListen[] = "tcp-listen"; 27 const char kTCPListen[] = "tcp-listen";
27 const char kUDPBind[] = "udp-bind"; 28 const char kUDPBind[] = "udp-bind";
28 const char kUDPSendTo[] = "udp-send-to"; 29 const char kUDPSendTo[] = "udp-send-to";
29 const int kAnyPort = 0; 30 const int kAnyPort = 0;
30 const int kInvalidPort = -1; 31 const int kInvalidPort = -1;
31 32
32 SocketPermissionData::OperationType StringToType(const std::string& s) { 33 SocketPermissionRequest::OperationType StringToType(const std::string& s) {
33 if (s == kTCPConnect) 34 if (s == kTCPConnect)
34 return SocketPermissionData::TCP_CONNECT; 35 return SocketPermissionRequest::TCP_CONNECT;
35 if (s == kTCPListen) 36 if (s == kTCPListen)
36 return SocketPermissionData::TCP_LISTEN; 37 return SocketPermissionRequest::TCP_LISTEN;
37 if (s == kUDPBind) 38 if (s == kUDPBind)
38 return SocketPermissionData::UDP_BIND; 39 return SocketPermissionRequest::UDP_BIND;
39 if (s == kUDPSendTo) 40 if (s == kUDPSendTo)
40 return SocketPermissionData::UDP_SEND_TO; 41 return SocketPermissionRequest::UDP_SEND_TO;
41 return SocketPermissionData::NONE; 42 return SocketPermissionRequest::NONE;
42 } 43 }
43 44
44 const char* TypeToString(SocketPermissionData::OperationType type) { 45 const char* TypeToString(SocketPermissionRequest::OperationType type) {
45 switch (type) { 46 switch (type) {
46 case SocketPermissionData::TCP_CONNECT: 47 case SocketPermissionRequest::TCP_CONNECT:
47 return kTCPConnect; 48 return kTCPConnect;
48 case SocketPermissionData::TCP_LISTEN: 49 case SocketPermissionRequest::TCP_LISTEN:
49 return kTCPListen; 50 return kTCPListen;
50 case SocketPermissionData::UDP_BIND: 51 case SocketPermissionRequest::UDP_BIND:
51 return kUDPBind; 52 return kUDPBind;
52 case SocketPermissionData::UDP_SEND_TO: 53 case SocketPermissionRequest::UDP_SEND_TO:
53 return kUDPSendTo; 54 return kUDPSendTo;
54 default: 55 default:
55 return kInvalid; 56 return kInvalid;
56 } 57 }
57 } 58 }
58 59
59 bool StartsOrEndsWithWhitespace(const std::string& str) { 60 bool StartsOrEndsWithWhitespace(const std::string& str) {
60 if (str.find_first_not_of(kWhitespaceASCII) != 0) 61 if (str.find_first_not_of(kWhitespaceASCII) != 0)
61 return true; 62 return true;
62 if (str.find_last_not_of(kWhitespaceASCII) != str.length() - 1) 63 if (str.find_last_not_of(kWhitespaceASCII) != str.length() - 1)
63 return true; 64 return true;
64 return false; 65 return false;
65 } 66 }
66 67
67 } // namespace 68 } // namespace
68 69
69 namespace extensions { 70 namespace extensions {
70 71
71 SocketPermissionData::SocketPermissionData() { 72 SocketPermissionData::SocketPermissionData()
73 : pattern_(SocketPermissionRequest::NONE, std::string(), kInvalidPort) {
72 Reset(); 74 Reset();
73 } 75 }
74 76
75 SocketPermissionData::~SocketPermissionData() { 77 SocketPermissionData::~SocketPermissionData() {
76 } 78 }
77 79
78 bool SocketPermissionData::operator<(const SocketPermissionData& rhs) const { 80 bool SocketPermissionData::operator<(const SocketPermissionData& rhs) const {
79 if (type_ < rhs.type_) 81 if (pattern_.type < rhs.pattern_.type)
80 return true; 82 return true;
81 if (type_ > rhs.type_) 83 if (pattern_.type > rhs.pattern_.type)
82 return false; 84 return false;
83 85
84 if (host_ < rhs.host_) 86 if (pattern_.host < rhs.pattern_.host)
85 return true; 87 return true;
86 if (host_ > rhs.host_) 88 if (pattern_.host > rhs.pattern_.host)
87 return false; 89 return false;
88 90
89 if (match_subdomains_ < rhs.match_subdomains_) 91 if (match_subdomains_ < rhs.match_subdomains_)
90 return true; 92 return true;
91 if (match_subdomains_ > rhs.match_subdomains_) 93 if (match_subdomains_ > rhs.match_subdomains_)
92 return false; 94 return false;
93 95
94 if (port_ < rhs.port_) 96 if (pattern_.port < rhs.pattern_.port)
95 return true; 97 return true;
96 return false; 98 return false;
97 } 99 }
98 100
99 bool SocketPermissionData::operator==(const SocketPermissionData& rhs) const { 101 bool SocketPermissionData::operator==(const SocketPermissionData& rhs) const {
100 return (type_ == rhs.type_) && (host_ == rhs.host_) && 102 return (pattern_.type == rhs.pattern_.type) &&
101 (match_subdomains_ == rhs.match_subdomains_) && 103 (pattern_.host == rhs.pattern_.host) &&
102 (port_ == rhs.port_); 104 (match_subdomains_ == rhs.match_subdomains_) &&
105 (pattern_.port == rhs.pattern_.port);
103 } 106 }
104 107
105 bool SocketPermissionData::Match( 108 bool SocketPermissionData::Match(SocketPermissionRequest request) const {
106 OperationType type, const std::string& host, int port) const { 109 if (pattern_.type != request.type)
107 if (type_ != type)
108 return false; 110 return false;
109 111
110 std::string lhost = StringToLowerASCII(host); 112 std::string lhost = StringToLowerASCII(request.host);
111 if (host_ != lhost) { 113 if (pattern_.host != lhost) {
112 if (!match_subdomains_) 114 if (!match_subdomains_)
113 return false; 115 return false;
114 116
115 if (!host_.empty()) { 117 if (!pattern_.host.empty()) {
116 // Do not wildcard part of IP address. 118 // Do not wildcard part of IP address.
117 url_parse::Component component(0, lhost.length()); 119 url_parse::Component component(0, lhost.length());
118 url_canon::RawCanonOutputT<char, 128> ignored_output; 120 url_canon::RawCanonOutputT<char, 128> ignored_output;
119 url_canon::CanonHostInfo host_info; 121 url_canon::CanonHostInfo host_info;
120 url_canon::CanonicalizeIPAddress(lhost.c_str(), component, 122 url_canon::CanonicalizeIPAddress(lhost.c_str(), component,
121 &ignored_output, &host_info); 123 &ignored_output, &host_info);
122 if (host_info.IsIPAddress()) 124 if (host_info.IsIPAddress())
123 return false; 125 return false;
124 126
125 // host should equal one or more chars + "." + host_. 127 // host should equal one or more chars + "." + host_.
126 int i = lhost.length() - host_.length(); 128 int i = lhost.length() - pattern_.host.length();
127 if (i < 2) 129 if (i < 2)
128 return false; 130 return false;
129 131
130 if (lhost.compare(i, host_.length(), host_) != 0) 132 if (lhost.compare(i, pattern_.host.length(), pattern_.host) != 0)
131 return false; 133 return false;
132 134
133 if (lhost[i - 1] != kDot) 135 if (lhost[i - 1] != kDot)
134 return false; 136 return false;
135 } 137 }
136 } 138 }
137 139
138 if (port_ != port && port_ != kAnyPort) 140 if (pattern_.port != request.port && pattern_.port != kAnyPort)
139 return false; 141 return false;
140 142
141 return true; 143 return true;
142 } 144 }
143 145
144 bool SocketPermissionData::Parse(const std::string& permission) { 146 bool SocketPermissionData::Parse(const std::string& permission) {
145 do { 147 do {
146 host_.clear(); 148 pattern_.host.clear();
147 match_subdomains_ = true; 149 match_subdomains_ = true;
148 port_ = kAnyPort; 150 pattern_.port = kAnyPort;
149 spec_.clear(); 151 spec_.clear();
150 152
151 std::vector<std::string> tokens; 153 std::vector<std::string> tokens;
152 base::SplitStringDontTrim(permission, kColon, &tokens); 154 base::SplitStringDontTrim(permission, kColon, &tokens);
153 155
154 if (tokens.empty() || tokens.size() > 3) 156 if (tokens.empty() || tokens.size() > 3)
155 break; 157 break;
156 158
157 type_ = StringToType(tokens[0]); 159 pattern_.type = StringToType(tokens[0]);
158 if (type_ == NONE) 160 if (pattern_.type == SocketPermissionRequest::NONE)
159 break; 161 break;
160 162
161 if (tokens.size() == 1) 163 if (tokens.size() == 1)
162 return true; 164 return true;
163 165
164 host_ = tokens[1]; 166 pattern_.host = tokens[1];
165 if (!host_.empty()) { 167 if (!pattern_.host.empty()) {
166 if (StartsOrEndsWithWhitespace(host_)) 168 if (StartsOrEndsWithWhitespace(pattern_.host))
167 break; 169 break;
168 host_ = StringToLowerASCII(host_); 170 pattern_.host = StringToLowerASCII(pattern_.host);
169 171
170 // The first component can optionally be '*' to match all subdomains. 172 // The first component can optionally be '*' to match all subdomains.
171 std::vector<std::string> host_components; 173 std::vector<std::string> host_components;
172 base::SplitString(host_, kDot, &host_components); 174 base::SplitString(pattern_.host, kDot, &host_components);
173 DCHECK(!host_components.empty()); 175 DCHECK(!host_components.empty());
174 176
175 if (host_components[0] == kWildcard || host_components[0].empty()) { 177 if (host_components[0] == kWildcard || host_components[0].empty()) {
176 host_components.erase(host_components.begin(), 178 host_components.erase(host_components.begin(),
177 host_components.begin() + 1); 179 host_components.begin() + 1);
178 } else { 180 } else {
179 match_subdomains_ = false; 181 match_subdomains_ = false;
180 } 182 }
181 host_ = JoinString(host_components, kDot); 183 pattern_.host = JoinString(host_components, kDot);
182 } 184 }
183 185
184 if (tokens.size() == 2 || tokens[2].empty() || tokens[2] == kWildcard) 186 if (tokens.size() == 2 || tokens[2].empty() || tokens[2] == kWildcard)
185 return true; 187 return true;
186 188
187 if (StartsOrEndsWithWhitespace(tokens[2])) 189 if (StartsOrEndsWithWhitespace(tokens[2]))
188 break; 190 break;
189 191
190 if (!base::StringToInt(tokens[2], &port_) || 192 if (!base::StringToInt(tokens[2], &pattern_.port) ||
191 port_ < 1 || port_ > 65535) 193 pattern_.port < 1 || pattern_.port > 65535)
192 break; 194 break;
193 return true; 195 return true;
194 } while (false); 196 } while (false);
195 197
196 Reset(); 198 Reset();
197 return false; 199 return false;
198 } 200 }
199 201
200 SocketPermissionData::HostType SocketPermissionData::GetHostType() const { 202 SocketPermissionData::HostType SocketPermissionData::GetHostType() const {
201 return host_.empty() ? SocketPermissionData::ANY_HOST : 203 return pattern_.host.empty() ? SocketPermissionData::ANY_HOST :
202 match_subdomains_ ? SocketPermissionData::HOSTS_IN_DOMAINS : 204 match_subdomains_ ? SocketPermissionData::HOSTS_IN_DOMAINS :
203 SocketPermissionData::SPECIFIC_HOSTS; 205 SocketPermissionData::SPECIFIC_HOSTS;
204 } 206 }
205 207
206 const std::string SocketPermissionData::GetHost() const { 208 const std::string SocketPermissionData::GetHost() const {
207 return host_; 209 return pattern_.host;
208 } 210 }
209 211
210 const std::string& SocketPermissionData::GetAsString() const { 212 const std::string& SocketPermissionData::GetAsString() const {
211 if (!spec_.empty()) 213 if (!spec_.empty())
212 return spec_; 214 return spec_;
213 215
214 spec_.reserve(64); 216 spec_.reserve(64);
215 spec_.append(TypeToString(type_)); 217 spec_.append(TypeToString(pattern_.type));
216 218
217 if (match_subdomains_) { 219 if (match_subdomains_) {
218 spec_.append(1, kColon).append(kWildcard); 220 spec_.append(1, kColon).append(kWildcard);
219 if (!host_.empty()) 221 if (!pattern_.host.empty())
220 spec_.append(1, kDot).append(host_); 222 spec_.append(1, kDot).append(pattern_.host);
221 } else { 223 } else {
222 spec_.append(1, kColon).append(host_); 224 spec_.append(1, kColon).append(pattern_.host);
223 } 225 }
224 226
225 if (port_ == kAnyPort) 227 if (pattern_.port == kAnyPort)
226 spec_.append(1, kColon).append(kWildcard); 228 spec_.append(1, kColon).append(kWildcard);
227 else 229 else
228 spec_.append(1, kColon).append(base::IntToString(port_)); 230 spec_.append(1, kColon).append(base::IntToString(pattern_.port));
229 231
230 return spec_; 232 return spec_;
231 } 233 }
232 234
233 void SocketPermissionData::Reset() { 235 void SocketPermissionData::Reset() {
234 type_ = NONE; 236 pattern_.type = SocketPermissionRequest::NONE;
235 host_.clear(); 237 pattern_.host.clear();
236 match_subdomains_ = false; 238 match_subdomains_ = false;
237 port_ = kInvalidPort; 239 pattern_.port = kInvalidPort;
238 spec_.clear(); 240 spec_.clear();
239 } 241 }
240 242
241 } // namespace extensions 243 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698