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 <string>
6
7#include "base/pickle.h"
8#include "base/values.h"
9#include "chrome/common/extensions/permissions/permissions_info.h"
10#include "chrome/common/extensions/permissions/socket_permission.h"
11#include "chrome/common/extensions/permissions/socket_permission_data.h"
12#include "ipc/ipc_message.h"
13#include "testing/gtest/include/gtest/gtest.h"
14
15namespace extensions {
16
17namespace {
18
19using content::SocketPermissionRequest;
20
21void ParseTest(const std::string& permission,
22               const std::string& expected_result) {
23  SocketPermissionData data;
24  ASSERT_TRUE(data.ParseForTest(permission)) << "Parse permission \""
25                                             << permission << "\" failed.";
26  EXPECT_EQ(expected_result, data.GetAsStringForTest());
27}
28
29TEST(SocketPermissionTest, General) {
30  SocketPermissionData data1, data2;
31
32  CHECK(data1.ParseForTest("tcp-connect"));
33  CHECK(data2.ParseForTest("tcp-connect"));
34
35  EXPECT_TRUE(data1 == data2);
36  EXPECT_FALSE(data1 < data2);
37
38  CHECK(data1.ParseForTest("tcp-connect"));
39  CHECK(data2.ParseForTest("tcp-connect:www.example.com"));
40
41  EXPECT_FALSE(data1 == data2);
42  EXPECT_TRUE(data1 < data2);
43}
44
45TEST(SocketPermissionTest, Parse) {
46  SocketPermissionData data;
47
48  EXPECT_FALSE(data.ParseForTest(std::string()));
49  EXPECT_FALSE(data.ParseForTest("*"));
50  EXPECT_FALSE(data.ParseForTest("\00\00*"));
51  EXPECT_FALSE(data.ParseForTest("\01*"));
52  EXPECT_FALSE(data.ParseForTest("tcp-connect:www.example.com:-1"));
53  EXPECT_FALSE(data.ParseForTest("tcp-connect:www.example.com:65536"));
54  EXPECT_FALSE(data.ParseForTest("tcp-connect:::"));
55  EXPECT_FALSE(data.ParseForTest("tcp-connect::0"));
56  EXPECT_FALSE(data.ParseForTest("tcp-connect:  www.exmaple.com:  99  "));
57  EXPECT_FALSE(data.ParseForTest("tcp-connect:*.exmaple.com :99"));
58  EXPECT_FALSE(data.ParseForTest("tcp-connect:*.exmaple.com: 99"));
59  EXPECT_FALSE(data.ParseForTest("tcp-connect:*.exmaple.com:99 "));
60  EXPECT_FALSE(data.ParseForTest("tcp-connect:\t*.exmaple.com:99"));
61  EXPECT_FALSE(data.ParseForTest("tcp-connect:\n*.exmaple.com:99"));
62  EXPECT_FALSE(data.ParseForTest("resolve-host:exmaple.com:99"));
63  EXPECT_FALSE(data.ParseForTest("resolve-host:127.0.0.1"));
64  EXPECT_FALSE(data.ParseForTest("resolve-host:"));
65  EXPECT_FALSE(data.ParseForTest("resolve-proxy:exmaple.com:99"));
66  EXPECT_FALSE(data.ParseForTest("resolve-proxy:exmaple.com"));
67
68  ParseTest("tcp-connect", "tcp-connect:*:*");
69  ParseTest("tcp-listen", "tcp-listen:*:*");
70  ParseTest("udp-bind", "udp-bind:*:*");
71  ParseTest("udp-send-to", "udp-send-to:*:*");
72  ParseTest("resolve-host", "resolve-host");
73  ParseTest("resolve-proxy", "resolve-proxy");
74
75  ParseTest("tcp-connect:", "tcp-connect:*:*");
76  ParseTest("tcp-listen:", "tcp-listen:*:*");
77  ParseTest("udp-bind:", "udp-bind:*:*");
78  ParseTest("udp-send-to:", "udp-send-to:*:*");
79
80  ParseTest("tcp-connect::", "tcp-connect:*:*");
81  ParseTest("tcp-listen::", "tcp-listen:*:*");
82  ParseTest("udp-bind::", "udp-bind:*:*");
83  ParseTest("udp-send-to::", "udp-send-to:*:*");
84
85  ParseTest("tcp-connect:*", "tcp-connect:*:*");
86  ParseTest("tcp-listen:*", "tcp-listen:*:*");
87  ParseTest("udp-bind:*", "udp-bind:*:*");
88  ParseTest("udp-send-to:*", "udp-send-to:*:*");
89
90  ParseTest("tcp-connect:*:", "tcp-connect:*:*");
91  ParseTest("tcp-listen:*:", "tcp-listen:*:*");
92  ParseTest("udp-bind:*:", "udp-bind:*:*");
93  ParseTest("udp-send-to:*:", "udp-send-to:*:*");
94
95  ParseTest("tcp-connect::*", "tcp-connect:*:*");
96  ParseTest("tcp-listen::*", "tcp-listen:*:*");
97  ParseTest("udp-bind::*", "udp-bind:*:*");
98  ParseTest("udp-send-to::*", "udp-send-to:*:*");
99
100  ParseTest("tcp-connect:www.example.com", "tcp-connect:www.example.com:*");
101  ParseTest("tcp-listen:www.example.com", "tcp-listen:www.example.com:*");
102  ParseTest("udp-bind:www.example.com", "udp-bind:www.example.com:*");
103  ParseTest("udp-send-to:www.example.com", "udp-send-to:www.example.com:*");
104  ParseTest("udp-send-to:wWW.ExAmPlE.cOm", "udp-send-to:www.example.com:*");
105
106  ParseTest("tcp-connect:.example.com", "tcp-connect:*.example.com:*");
107  ParseTest("tcp-listen:.example.com", "tcp-listen:*.example.com:*");
108  ParseTest("udp-bind:.example.com", "udp-bind:*.example.com:*");
109  ParseTest("udp-send-to:.example.com", "udp-send-to:*.example.com:*");
110
111  ParseTest("tcp-connect:*.example.com", "tcp-connect:*.example.com:*");
112  ParseTest("tcp-listen:*.example.com", "tcp-listen:*.example.com:*");
113  ParseTest("udp-bind:*.example.com", "udp-bind:*.example.com:*");
114  ParseTest("udp-send-to:*.example.com", "udp-send-to:*.example.com:*");
115
116  ParseTest("tcp-connect::99", "tcp-connect:*:99");
117  ParseTest("tcp-listen::99", "tcp-listen:*:99");
118  ParseTest("udp-bind::99", "udp-bind:*:99");
119  ParseTest("udp-send-to::99", "udp-send-to:*:99");
120
121  ParseTest("tcp-connect:www.example.com", "tcp-connect:www.example.com:*");
122
123  ParseTest("tcp-connect:*.example.com:99", "tcp-connect:*.example.com:99");
124}
125
126TEST(SocketPermissionTest, Match) {
127  SocketPermissionData data;
128  scoped_ptr<SocketPermission::CheckParam> param;
129
130  CHECK(data.ParseForTest("tcp-connect"));
131  param.reset(new SocketPermission::CheckParam(
132      SocketPermissionRequest::TCP_CONNECT, "www.example.com", 80));
133  EXPECT_TRUE(data.Check(param.get()));
134  param.reset(new SocketPermission::CheckParam(
135      SocketPermissionRequest::UDP_SEND_TO, "www.example.com", 80));
136  EXPECT_FALSE(data.Check(param.get()));
137
138  CHECK(data.ParseForTest("udp-send-to::8800"));
139  param.reset(new SocketPermission::CheckParam(
140      SocketPermissionRequest::UDP_SEND_TO, "www.example.com", 8800));
141  EXPECT_TRUE(data.Check(param.get()));
142  param.reset(new SocketPermission::CheckParam(
143      SocketPermissionRequest::UDP_SEND_TO, "smtp.example.com", 8800));
144  EXPECT_TRUE(data.Check(param.get()));
145  param.reset(new SocketPermission::CheckParam(
146      SocketPermissionRequest::TCP_CONNECT, "www.example.com", 80));
147  EXPECT_FALSE(data.Check(param.get()));
148
149  CHECK(data.ParseForTest("udp-send-to:*.example.com:8800"));
150  param.reset(new SocketPermission::CheckParam(
151      SocketPermissionRequest::UDP_SEND_TO, "www.example.com", 8800));
152  EXPECT_TRUE(data.Check(param.get()));
153  param.reset(new SocketPermission::CheckParam(
154      SocketPermissionRequest::UDP_SEND_TO, "smtp.example.com", 8800));
155  EXPECT_TRUE(data.Check(param.get()));
156  param.reset(new SocketPermission::CheckParam(
157      SocketPermissionRequest::UDP_SEND_TO, "SMTP.example.com", 8800));
158  EXPECT_TRUE(data.Check(param.get()));
159  param.reset(new SocketPermission::CheckParam(
160      SocketPermissionRequest::TCP_CONNECT, "www.example.com", 80));
161  EXPECT_FALSE(data.Check(param.get()));
162  param.reset(new SocketPermission::CheckParam(
163      SocketPermissionRequest::UDP_SEND_TO, "www.google.com", 8800));
164  EXPECT_FALSE(data.Check(param.get()));
165  param.reset(new SocketPermission::CheckParam(
166      SocketPermissionRequest::UDP_SEND_TO, "wwwexample.com", 8800));
167  EXPECT_FALSE(data.Check(param.get()));
168
169  CHECK(data.ParseForTest("udp-send-to:*.ExAmPlE.cOm:8800"));
170  param.reset(new SocketPermission::CheckParam(
171      SocketPermissionRequest::UDP_SEND_TO, "www.example.com", 8800));
172  EXPECT_TRUE(data.Check(param.get()));
173  param.reset(new SocketPermission::CheckParam(
174      SocketPermissionRequest::UDP_SEND_TO, "smtp.example.com", 8800));
175  EXPECT_TRUE(data.Check(param.get()));
176  param.reset(new SocketPermission::CheckParam(
177      SocketPermissionRequest::UDP_SEND_TO, "SMTP.example.com", 8800));
178  EXPECT_TRUE(data.Check(param.get()));
179  param.reset(new SocketPermission::CheckParam(
180      SocketPermissionRequest::TCP_CONNECT, "www.example.com", 80));
181  EXPECT_FALSE(data.Check(param.get()));
182  param.reset(new SocketPermission::CheckParam(
183      SocketPermissionRequest::UDP_SEND_TO, "www.google.com", 8800));
184  EXPECT_FALSE(data.Check(param.get()));
185
186  ASSERT_TRUE(data.ParseForTest("udp-bind::8800"));
187  param.reset(new SocketPermission::CheckParam(
188      SocketPermissionRequest::UDP_BIND, "127.0.0.1", 8800));
189  EXPECT_TRUE(data.Check(param.get()));
190  param.reset(new SocketPermission::CheckParam(
191      SocketPermissionRequest::UDP_BIND, "127.0.0.1", 8888));
192  EXPECT_FALSE(data.Check(param.get()));
193  param.reset(new SocketPermission::CheckParam(
194      SocketPermissionRequest::TCP_CONNECT, "www.example.com", 80));
195  EXPECT_FALSE(data.Check(param.get()));
196  param.reset(new SocketPermission::CheckParam(
197      SocketPermissionRequest::UDP_SEND_TO, "www.google.com", 8800));
198  EXPECT_FALSE(data.Check(param.get()));
199
200  // Do not wildcard part of ip address.
201  ASSERT_TRUE(data.ParseForTest("tcp-connect:*.168.0.1:8800"));
202  param.reset(new SocketPermission::CheckParam(
203      SocketPermissionRequest::TCP_CONNECT, "192.168.0.1", 8800));
204  EXPECT_FALSE(data.Check(param.get()));
205
206  ASSERT_FALSE(data.ParseForTest("udp-multicast-membership:*"));
207  ASSERT_FALSE(data.ParseForTest("udp-multicast-membership:*:*"));
208  ASSERT_TRUE(data.ParseForTest("udp-multicast-membership"));
209  param.reset(new SocketPermission::CheckParam(
210      SocketPermissionRequest::UDP_BIND, "127.0.0.1", 8800));
211  EXPECT_FALSE(data.Check(param.get()));
212  param.reset(new SocketPermission::CheckParam(
213      SocketPermissionRequest::UDP_BIND, "127.0.0.1", 8888));
214  EXPECT_FALSE(data.Check(param.get()));
215  param.reset(new SocketPermission::CheckParam(
216      SocketPermissionRequest::TCP_CONNECT, "www.example.com", 80));
217  EXPECT_FALSE(data.Check(param.get()));
218  param.reset(new SocketPermission::CheckParam(
219      SocketPermissionRequest::UDP_SEND_TO, "www.google.com", 8800));
220  EXPECT_FALSE(data.Check(param.get()));
221  param.reset(new SocketPermission::CheckParam(
222      SocketPermissionRequest::UDP_MULTICAST_MEMBERSHIP, "127.0.0.1", 35));
223  EXPECT_TRUE(data.Check(param.get()));
224
225  ASSERT_TRUE(data.ParseForTest("resolve-host"));
226  param.reset(new SocketPermission::CheckParam(
227      SocketPermissionRequest::RESOLVE_HOST, "www.example.com", 80));
228  EXPECT_TRUE(data.Check(param.get()));
229  param.reset(new SocketPermission::CheckParam(
230      SocketPermissionRequest::RESOLVE_HOST, "www.example.com", 8080));
231  EXPECT_TRUE(data.Check(param.get()));
232  param.reset(new SocketPermission::CheckParam(
233      SocketPermissionRequest::UDP_BIND, "127.0.0.1", 8800));
234  EXPECT_FALSE(data.Check(param.get()));
235  param.reset(new SocketPermission::CheckParam(
236      SocketPermissionRequest::TCP_CONNECT, "127.0.0.1", 8800));
237  EXPECT_FALSE(data.Check(param.get()));
238
239  ASSERT_TRUE(data.ParseForTest("resolve-proxy"));
240  param.reset(new SocketPermission::CheckParam(
241      SocketPermissionRequest::RESOLVE_PROXY, "www.example.com", 80));
242  EXPECT_TRUE(data.Check(param.get()));
243  param.reset(new SocketPermission::CheckParam(
244      SocketPermissionRequest::RESOLVE_PROXY, "www.example.com", 8080));
245  EXPECT_TRUE(data.Check(param.get()));
246  param.reset(new SocketPermission::CheckParam(
247      SocketPermissionRequest::UDP_BIND, "127.0.0.1", 8800));
248  EXPECT_FALSE(data.Check(param.get()));
249  param.reset(new SocketPermission::CheckParam(
250      SocketPermissionRequest::TCP_CONNECT, "127.0.0.1", 8800));
251  EXPECT_FALSE(data.Check(param.get()));
252}
253
254TEST(SocketPermissionTest, IPC) {
255  const APIPermissionInfo* permission_info =
256    PermissionsInfo::GetInstance()->GetByID(APIPermission::kSocket);
257
258  {
259    IPC::Message m;
260
261    scoped_ptr<APIPermission> permission1(
262        permission_info->CreateAPIPermission());
263    scoped_ptr<APIPermission> permission2(
264        permission_info->CreateAPIPermission());
265
266    permission1->Write(&m);
267    PickleIterator iter(m);
268    permission2->Read(&m, &iter);
269
270    EXPECT_TRUE(permission1->Equal(permission2.get()));
271  }
272
273  {
274    IPC::Message m;
275
276    scoped_ptr<APIPermission> permission1(
277        permission_info->CreateAPIPermission());
278    scoped_ptr<APIPermission> permission2(
279        permission_info->CreateAPIPermission());
280
281    scoped_ptr<base::ListValue> value(new base::ListValue());
282    value->AppendString("tcp-connect:*.example.com:80");
283    value->AppendString("udp-bind::8080");
284    value->AppendString("udp-send-to::8888");
285    ASSERT_TRUE(permission1->FromValue(value.get()));
286
287    EXPECT_FALSE(permission1->Equal(permission2.get()));
288
289    permission1->Write(&m);
290    PickleIterator iter(m);
291    permission2->Read(&m, &iter);
292    EXPECT_TRUE(permission1->Equal(permission2.get()));
293  }
294}
295
296TEST(SocketPermissionTest, Value) {
297  const APIPermissionInfo* permission_info =
298    PermissionsInfo::GetInstance()->GetByID(APIPermission::kSocket);
299
300  scoped_ptr<APIPermission> permission1(
301      permission_info->CreateAPIPermission());
302  scoped_ptr<APIPermission> permission2(
303      permission_info->CreateAPIPermission());
304
305  scoped_ptr<base::ListValue> value(new base::ListValue());
306  value->AppendString("tcp-connect:*.example.com:80");
307  value->AppendString("udp-bind::8080");
308  value->AppendString("udp-send-to::8888");
309  ASSERT_TRUE(permission1->FromValue(value.get()));
310
311  EXPECT_FALSE(permission1->Equal(permission2.get()));
312
313  scoped_ptr<base::Value> vtmp(permission1->ToValue());
314  ASSERT_TRUE(vtmp);
315  ASSERT_TRUE(permission2->FromValue(vtmp.get()));
316  EXPECT_TRUE(permission1->Equal(permission2.get()));
317}
318
319}  // namespace
320
321}  // namespace extensions
322
323