Home | History | Annotate | Download | only in sockets
      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