1 // Copyright 2014 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 <set> 6 7 #include "base/json/json_reader.h" 8 #include "base/pickle.h" 9 #include "base/values.h" 10 #include "extensions/common/api/sockets/sockets_manifest_permission.h" 11 #include "extensions/common/manifest_constants.h" 12 #include "ipc/ipc_message.h" 13 #include "testing/gtest/include/gtest/gtest.h" 14 15 using content::SocketPermissionRequest; 16 17 namespace extensions { 18 19 namespace { 20 21 const char kUdpBindPermission[] = 22 "{ \"udp\": { \"bind\": [\"127.0.0.1:3007\", \"a.com:80\"] } }"; 23 24 const char kUdpSendPermission[] = 25 "{ \"udp\": { \"send\": [\"\", \"a.com:80\"] } }"; 26 27 const char kTcpConnectPermission[] = 28 "{ \"tcp\": { \"connect\": [\"127.0.0.1:80\", \"a.com:80\"] } }"; 29 30 const char kTcpServerListenPermission[] = 31 "{ \"tcpServer\": { \"listen\": [\"127.0.0.1:80\", \"a.com:80\"] } }"; 32 33 static void AssertEmptyPermission(const SocketsManifestPermission* permission) { 34 EXPECT_TRUE(permission); 35 EXPECT_EQ(std::string(extensions::manifest_keys::kSockets), permission->id()); 36 EXPECT_EQ(permission->id(), permission->name()); 37 EXPECT_FALSE(permission->HasMessages()); 38 EXPECT_EQ(0u, permission->entries().size()); 39 } 40 41 static scoped_ptr<base::Value> ParsePermissionJSON(const std::string& json) { 42 scoped_ptr<base::Value> result(base::JSONReader::Read(json)); 43 EXPECT_TRUE(result) << "Invalid JSON string: " << json; 44 return result.Pass(); 45 } 46 47 static scoped_ptr<SocketsManifestPermission> PermissionFromValue( 48 const base::Value& value) { 49 base::string16 error16; 50 scoped_ptr<SocketsManifestPermission> permission( 51 SocketsManifestPermission::FromValue(value, &error16)); 52 EXPECT_TRUE(permission) << "Error parsing Value into permission: " << error16; 53 return permission.Pass(); 54 } 55 56 static scoped_ptr<SocketsManifestPermission> PermissionFromJSON( 57 const std::string& json) { 58 scoped_ptr<base::Value> value(ParsePermissionJSON(json)); 59 return PermissionFromValue(*value); 60 } 61 62 struct CheckFormatEntry { 63 CheckFormatEntry(SocketPermissionRequest::OperationType operation_type, 64 std::string host_pattern) 65 : operation_type(operation_type), host_pattern(host_pattern) {} 66 67 // operators <, == are needed by container std::set and algorithms 68 // std::set_includes and std::set_differences. 69 bool operator<(const CheckFormatEntry& rhs) const { 70 if (operation_type == rhs.operation_type) 71 return host_pattern < rhs.host_pattern; 72 73 return operation_type < rhs.operation_type; 74 } 75 76 bool operator==(const CheckFormatEntry& rhs) const { 77 return operation_type == rhs.operation_type && 78 host_pattern == rhs.host_pattern; 79 } 80 81 SocketPermissionRequest::OperationType operation_type; 82 std::string host_pattern; 83 }; 84 85 static testing::AssertionResult CheckFormat( 86 std::multiset<CheckFormatEntry> permissions, 87 const std::string& json) { 88 scoped_ptr<SocketsManifestPermission> permission(PermissionFromJSON(json)); 89 if (!permission) 90 return testing::AssertionFailure() << "Invalid permission " << json; 91 92 if (permissions.size() != permission->entries().size()) { 93 return testing::AssertionFailure() 94 << "Incorrect # of entries in json: " << json; 95 } 96 97 // Note: We use multiset because SocketsManifestPermission does not have to 98 // store entries in the order found in the json message. 99 std::multiset<CheckFormatEntry> parsed_permissions; 100 for (SocketsManifestPermission::SocketPermissionEntrySet::const_iterator it = 101 permission->entries().begin(); 102 it != permission->entries().end(); 103 ++it) { 104 parsed_permissions.insert( 105 CheckFormatEntry(it->pattern().type, it->GetHostPatternAsString())); 106 } 107 108 if (!std::equal( 109 permissions.begin(), permissions.end(), parsed_permissions.begin())) { 110 return testing::AssertionFailure() << "Incorrect socket operations."; 111 } 112 return testing::AssertionSuccess(); 113 } 114 115 static testing::AssertionResult CheckFormat(const std::string& json) { 116 return CheckFormat(std::multiset<CheckFormatEntry>(), json); 117 } 118 119 static testing::AssertionResult CheckFormat(const std::string& json, 120 const CheckFormatEntry& op1) { 121 CheckFormatEntry entries[] = {op1}; 122 return CheckFormat( 123 std::multiset<CheckFormatEntry>(entries, entries + arraysize(entries)), 124 json); 125 } 126 127 static testing::AssertionResult CheckFormat(const std::string& json, 128 const CheckFormatEntry& op1, 129 const CheckFormatEntry& op2) { 130 CheckFormatEntry entries[] = {op1, op2}; 131 return CheckFormat( 132 std::multiset<CheckFormatEntry>(entries, entries + arraysize(entries)), 133 json); 134 } 135 136 static testing::AssertionResult CheckFormat(const std::string& json, 137 const CheckFormatEntry& op1, 138 const CheckFormatEntry& op2, 139 const CheckFormatEntry& op3, 140 const CheckFormatEntry& op4, 141 const CheckFormatEntry& op5, 142 const CheckFormatEntry& op6, 143 const CheckFormatEntry& op7, 144 const CheckFormatEntry& op8, 145 const CheckFormatEntry& op9) { 146 CheckFormatEntry entries[] = {op1, op2, op3, op4, op5, op6, op7, op8, op9}; 147 return CheckFormat( 148 std::multiset<CheckFormatEntry>(entries, entries + arraysize(entries)), 149 json); 150 } 151 152 } // namespace 153 154 TEST(SocketsManifestPermissionTest, Empty) { 155 // Construction 156 scoped_ptr<SocketsManifestPermission> permission( 157 new SocketsManifestPermission()); 158 AssertEmptyPermission(permission.get()); 159 160 // Clone()/Equal() 161 scoped_ptr<SocketsManifestPermission> clone( 162 static_cast<SocketsManifestPermission*>(permission->Clone())); 163 AssertEmptyPermission(clone.get()); 164 165 EXPECT_TRUE(permission->Equal(clone.get())); 166 167 // ToValue()/FromValue() 168 scoped_ptr<const base::Value> value(permission->ToValue()); 169 EXPECT_TRUE(value.get()); 170 171 scoped_ptr<SocketsManifestPermission> permission2( 172 new SocketsManifestPermission()); 173 EXPECT_TRUE(permission2->FromValue(value.get())); 174 AssertEmptyPermission(permission2.get()); 175 176 // Union/Diff/Intersection 177 scoped_ptr<SocketsManifestPermission> diff_perm( 178 static_cast<SocketsManifestPermission*>(permission->Diff(clone.get()))); 179 AssertEmptyPermission(diff_perm.get()); 180 181 scoped_ptr<SocketsManifestPermission> union_perm( 182 static_cast<SocketsManifestPermission*>(permission->Union(clone.get()))); 183 AssertEmptyPermission(union_perm.get()); 184 185 scoped_ptr<SocketsManifestPermission> intersect_perm( 186 static_cast<SocketsManifestPermission*>( 187 permission->Intersect(clone.get()))); 188 AssertEmptyPermission(intersect_perm.get()); 189 190 // IPC 191 scoped_ptr<SocketsManifestPermission> ipc_perm( 192 new SocketsManifestPermission()); 193 scoped_ptr<SocketsManifestPermission> ipc_perm2( 194 new SocketsManifestPermission()); 195 196 IPC::Message m; 197 ipc_perm->Write(&m); 198 PickleIterator iter(m); 199 EXPECT_TRUE(ipc_perm2->Read(&m, &iter)); 200 AssertEmptyPermission(ipc_perm2.get()); 201 } 202 203 TEST(SocketsManifestPermissionTest, JSONFormats) { 204 EXPECT_TRUE(CheckFormat( 205 "{\"udp\":{\"send\":\"\"}}", 206 CheckFormatEntry(SocketPermissionRequest::UDP_SEND_TO, "*:*"))); 207 EXPECT_TRUE(CheckFormat("{\"udp\":{\"send\":[]}}")); 208 EXPECT_TRUE(CheckFormat( 209 "{\"udp\":{\"send\":[\"\"]}}", 210 CheckFormatEntry(SocketPermissionRequest::UDP_SEND_TO, "*:*"))); 211 EXPECT_TRUE(CheckFormat( 212 "{\"udp\":{\"send\":[\"a:80\", \"b:10\"]}}", 213 CheckFormatEntry(SocketPermissionRequest::UDP_SEND_TO, "a:80"), 214 CheckFormatEntry(SocketPermissionRequest::UDP_SEND_TO, "b:10"))); 215 216 EXPECT_TRUE( 217 CheckFormat("{\"udp\":{\"bind\":\"\"}}", 218 CheckFormatEntry(SocketPermissionRequest::UDP_BIND, "*:*"))); 219 EXPECT_TRUE(CheckFormat("{\"udp\":{\"bind\":[]}}")); 220 EXPECT_TRUE( 221 CheckFormat("{\"udp\":{\"bind\":[\"\"]}}", 222 CheckFormatEntry(SocketPermissionRequest::UDP_BIND, "*:*"))); 223 EXPECT_TRUE( 224 CheckFormat("{\"udp\":{\"bind\":[\"a:80\", \"b:10\"]}}", 225 CheckFormatEntry(SocketPermissionRequest::UDP_BIND, "a:80"), 226 CheckFormatEntry(SocketPermissionRequest::UDP_BIND, "b:10"))); 227 228 EXPECT_TRUE(CheckFormat( 229 "{\"udp\":{\"multicastMembership\":\"\"}}", 230 CheckFormatEntry(SocketPermissionRequest::UDP_MULTICAST_MEMBERSHIP, ""))); 231 EXPECT_TRUE(CheckFormat("{\"udp\":{\"multicastMembership\":[]}}")); 232 EXPECT_TRUE(CheckFormat( 233 "{\"udp\":{\"multicastMembership\":[\"\"]}}", 234 CheckFormatEntry(SocketPermissionRequest::UDP_MULTICAST_MEMBERSHIP, ""))); 235 EXPECT_TRUE(CheckFormat( 236 "{\"udp\":{\"multicastMembership\":[\"\", \"\"]}}", 237 CheckFormatEntry(SocketPermissionRequest::UDP_MULTICAST_MEMBERSHIP, ""))); 238 239 EXPECT_TRUE(CheckFormat( 240 "{\"tcp\":{\"connect\":\"\"}}", 241 CheckFormatEntry(SocketPermissionRequest::TCP_CONNECT, "*:*"))); 242 EXPECT_TRUE(CheckFormat("{\"tcp\":{\"connect\":[]}}")); 243 EXPECT_TRUE(CheckFormat( 244 "{\"tcp\":{\"connect\":[\"\"]}}", 245 CheckFormatEntry(SocketPermissionRequest::TCP_CONNECT, "*:*"))); 246 EXPECT_TRUE(CheckFormat( 247 "{\"tcp\":{\"connect\":[\"a:80\", \"b:10\"]}}", 248 CheckFormatEntry(SocketPermissionRequest::TCP_CONNECT, "a:80"), 249 CheckFormatEntry(SocketPermissionRequest::TCP_CONNECT, "b:10"))); 250 251 EXPECT_TRUE(CheckFormat( 252 "{\"tcpServer\":{\"listen\":\"\"}}", 253 CheckFormatEntry(SocketPermissionRequest::TCP_LISTEN, "*:*"))); 254 EXPECT_TRUE(CheckFormat("{\"tcpServer\":{\"listen\":[]}}")); 255 EXPECT_TRUE(CheckFormat( 256 "{\"tcpServer\":{\"listen\":[\"\"]}}", 257 CheckFormatEntry(SocketPermissionRequest::TCP_LISTEN, "*:*"))); 258 EXPECT_TRUE(CheckFormat( 259 "{\"tcpServer\":{\"listen\":[\"a:80\", \"b:10\"]}}", 260 CheckFormatEntry(SocketPermissionRequest::TCP_LISTEN, "a:80"), 261 CheckFormatEntry(SocketPermissionRequest::TCP_LISTEN, "b:10"))); 262 263 EXPECT_TRUE(CheckFormat( 264 "{" 265 "\"udp\":{" 266 "\"send\":[\"a:80\", \"b:10\"]," 267 "\"bind\":[\"a:80\", \"b:10\"]," 268 "\"multicastMembership\":\"\"" 269 "}," 270 "\"tcp\":{\"connect\":[\"a:80\", \"b:10\"]}," 271 "\"tcpServer\":{\"listen\":[\"a:80\", \"b:10\"]}" 272 "}", 273 CheckFormatEntry(SocketPermissionRequest::UDP_SEND_TO, "a:80"), 274 CheckFormatEntry(SocketPermissionRequest::UDP_SEND_TO, "b:10"), 275 CheckFormatEntry(SocketPermissionRequest::UDP_BIND, "a:80"), 276 CheckFormatEntry(SocketPermissionRequest::UDP_BIND, "b:10"), 277 CheckFormatEntry(SocketPermissionRequest::UDP_MULTICAST_MEMBERSHIP, ""), 278 CheckFormatEntry(SocketPermissionRequest::TCP_CONNECT, "a:80"), 279 CheckFormatEntry(SocketPermissionRequest::TCP_CONNECT, "b:10"), 280 CheckFormatEntry(SocketPermissionRequest::TCP_LISTEN, "a:80"), 281 CheckFormatEntry(SocketPermissionRequest::TCP_LISTEN, "b:10"))); 282 } 283 284 TEST(SocketsManifestPermissionTest, FromToValue) { 285 scoped_ptr<base::Value> udp_send(ParsePermissionJSON(kUdpBindPermission)); 286 scoped_ptr<base::Value> udp_bind(ParsePermissionJSON(kUdpSendPermission)); 287 scoped_ptr<base::Value> tcp_connect( 288 ParsePermissionJSON(kTcpConnectPermission)); 289 scoped_ptr<base::Value> tcp_server_listen( 290 ParsePermissionJSON(kTcpServerListenPermission)); 291 292 // FromValue() 293 scoped_ptr<SocketsManifestPermission> permission1( 294 new SocketsManifestPermission()); 295 EXPECT_TRUE(permission1->FromValue(udp_send.get())); 296 EXPECT_EQ(2u, permission1->entries().size()); 297 298 scoped_ptr<SocketsManifestPermission> permission2( 299 new SocketsManifestPermission()); 300 EXPECT_TRUE(permission2->FromValue(udp_bind.get())); 301 EXPECT_EQ(2u, permission2->entries().size()); 302 303 scoped_ptr<SocketsManifestPermission> permission3( 304 new SocketsManifestPermission()); 305 EXPECT_TRUE(permission3->FromValue(tcp_connect.get())); 306 EXPECT_EQ(2u, permission3->entries().size()); 307 308 scoped_ptr<SocketsManifestPermission> permission4( 309 new SocketsManifestPermission()); 310 EXPECT_TRUE(permission4->FromValue(tcp_server_listen.get())); 311 EXPECT_EQ(2u, permission4->entries().size()); 312 313 // ToValue() 314 scoped_ptr<base::Value> value1 = permission1->ToValue(); 315 EXPECT_TRUE(value1); 316 scoped_ptr<SocketsManifestPermission> permission1_1( 317 new SocketsManifestPermission()); 318 EXPECT_TRUE(permission1_1->FromValue(value1.get())); 319 EXPECT_TRUE(permission1->Equal(permission1_1.get())); 320 321 scoped_ptr<base::Value> value2 = permission2->ToValue(); 322 EXPECT_TRUE(value2); 323 scoped_ptr<SocketsManifestPermission> permission2_1( 324 new SocketsManifestPermission()); 325 EXPECT_TRUE(permission2_1->FromValue(value2.get())); 326 EXPECT_TRUE(permission2->Equal(permission2_1.get())); 327 328 scoped_ptr<base::Value> value3 = permission3->ToValue(); 329 EXPECT_TRUE(value3); 330 scoped_ptr<SocketsManifestPermission> permission3_1( 331 new SocketsManifestPermission()); 332 EXPECT_TRUE(permission3_1->FromValue(value3.get())); 333 EXPECT_TRUE(permission3->Equal(permission3_1.get())); 334 335 scoped_ptr<base::Value> value4 = permission4->ToValue(); 336 EXPECT_TRUE(value4); 337 scoped_ptr<SocketsManifestPermission> permission4_1( 338 new SocketsManifestPermission()); 339 EXPECT_TRUE(permission4_1->FromValue(value4.get())); 340 EXPECT_TRUE(permission4->Equal(permission4_1.get())); 341 } 342 343 TEST(SocketsManifestPermissionTest, SetOperations) { 344 scoped_ptr<SocketsManifestPermission> permission1( 345 PermissionFromJSON(kUdpBindPermission)); 346 scoped_ptr<SocketsManifestPermission> permission2( 347 PermissionFromJSON(kUdpSendPermission)); 348 scoped_ptr<SocketsManifestPermission> permission3( 349 PermissionFromJSON(kTcpConnectPermission)); 350 scoped_ptr<SocketsManifestPermission> permission4( 351 PermissionFromJSON(kTcpServerListenPermission)); 352 353 // Union 354 scoped_ptr<SocketsManifestPermission> union_perm( 355 static_cast<SocketsManifestPermission*>( 356 permission1->Union(permission2.get()))); 357 EXPECT_TRUE(union_perm); 358 EXPECT_EQ(4u, union_perm->entries().size()); 359 360 EXPECT_TRUE(union_perm->Contains(permission1.get())); 361 EXPECT_TRUE(union_perm->Contains(permission2.get())); 362 EXPECT_FALSE(union_perm->Contains(permission3.get())); 363 EXPECT_FALSE(union_perm->Contains(permission4.get())); 364 365 // Diff 366 scoped_ptr<SocketsManifestPermission> diff_perm1( 367 static_cast<SocketsManifestPermission*>( 368 permission1->Diff(permission2.get()))); 369 EXPECT_TRUE(diff_perm1); 370 EXPECT_EQ(2u, diff_perm1->entries().size()); 371 372 EXPECT_TRUE(permission1->Equal(diff_perm1.get())); 373 EXPECT_TRUE(diff_perm1->Equal(permission1.get())); 374 375 scoped_ptr<SocketsManifestPermission> diff_perm2( 376 static_cast<SocketsManifestPermission*>( 377 permission1->Diff(union_perm.get()))); 378 EXPECT_TRUE(diff_perm2); 379 AssertEmptyPermission(diff_perm2.get()); 380 381 // Intersection 382 scoped_ptr<SocketsManifestPermission> intersect_perm1( 383 static_cast<SocketsManifestPermission*>( 384 union_perm->Intersect(permission1.get()))); 385 EXPECT_TRUE(intersect_perm1); 386 EXPECT_EQ(2u, intersect_perm1->entries().size()); 387 388 EXPECT_TRUE(permission1->Equal(intersect_perm1.get())); 389 EXPECT_TRUE(intersect_perm1->Equal(permission1.get())); 390 } 391 392 TEST(SocketsManifestPermissionTest, IPC) { 393 scoped_ptr<SocketsManifestPermission> permission( 394 PermissionFromJSON(kUdpBindPermission)); 395 396 scoped_ptr<SocketsManifestPermission> ipc_perm( 397 static_cast<SocketsManifestPermission*>(permission->Clone())); 398 scoped_ptr<SocketsManifestPermission> ipc_perm2( 399 new SocketsManifestPermission()); 400 401 IPC::Message m; 402 ipc_perm->Write(&m); 403 PickleIterator iter(m); 404 EXPECT_TRUE(ipc_perm2->Read(&m, &iter)); 405 EXPECT_TRUE(permission->Equal(ipc_perm2.get())); 406 } 407 408 } // namespace extensions 409