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

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

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

Powered by Google App Engine
This is Rietveld 408576698