14ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch// Copyright 2014 The Chromium Authors. All rights reserved.
2f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// found in the LICENSE file.
4f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
54ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch#include "extensions/common/api/sockets/sockets_manifest_permission.h"
6f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
7f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/memory/scoped_ptr.h"
85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/stl_util.h"
9f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/strings/utf_string_conversions.h"
10f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/values.h"
114ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch#include "extensions/common/api/extensions_manifest_types.h"
124ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch#include "extensions/common/api/sockets/sockets_manifest_data.h"
13f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/error_utils.h"
14f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/manifest_constants.h"
150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "grit/extensions_strings.h"
16f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ipc/ipc_message.h"
17f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ui/base/l10n/l10n_util.h"
18f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
19f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace extensions {
20f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
21f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace sockets_errors {
22f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)const char kErrorInvalidHostPattern[] = "Invalid host:port pattern '*'";
23f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
24f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
25f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace errors = sockets_errors;
264ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdochusing core_api::extensions_manifest_types::Sockets;
274ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdochusing core_api::extensions_manifest_types::SocketHostPatterns;
28f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using content::SocketPermissionRequest;
29f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
304ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdochnamespace {
31f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
32f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)static bool ParseHostPattern(
33f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    SocketsManifestPermission* permission,
34f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    content::SocketPermissionRequest::OperationType operation_type,
35f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const std::string& host_pattern,
36a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    base::string16* error) {
37f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SocketPermissionEntry entry;
38f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!SocketPermissionEntry::ParseHostPattern(
394ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch          operation_type, host_pattern, &entry)) {
40f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    *error = ErrorUtils::FormatErrorMessageUTF16(
41f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        errors::kErrorInvalidHostPattern, host_pattern);
42f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return false;
43f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
44f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  permission->AddPermission(entry);
45f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return true;
46f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
47f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
48f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)static bool ParseHostPatterns(
49f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    SocketsManifestPermission* permission,
50f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    content::SocketPermissionRequest::OperationType operation_type,
51f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const scoped_ptr<SocketHostPatterns>& host_patterns,
52a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    base::string16* error) {
53f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!host_patterns)
54f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return true;
55f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
56f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (host_patterns->as_string) {
574ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch    return ParseHostPattern(
584ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch        permission, operation_type, *host_patterns->as_string, error);
59f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
60f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
61f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CHECK(host_patterns->as_strings);
62f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  for (std::vector<std::string>::const_iterator it =
634ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch           host_patterns->as_strings->begin();
644ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch       it != host_patterns->as_strings->end();
654ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch       ++it) {
66f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (!ParseHostPattern(permission, operation_type, *it, error)) {
67f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return false;
68f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
69f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
70f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return true;
71f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
72f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
73f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)static void SetHostPatterns(
74f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    scoped_ptr<SocketHostPatterns>& host_patterns,
75f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const SocketsManifestPermission* permission,
76f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    content::SocketPermissionRequest::OperationType operation_type) {
77f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  host_patterns.reset(new SocketHostPatterns());
78f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  host_patterns->as_strings.reset(new std::vector<std::string>());
79f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  for (SocketsManifestPermission::SocketPermissionEntrySet::const_iterator it =
804ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch           permission->entries().begin();
814ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch       it != permission->entries().end();
824ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch       ++it) {
83f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (it->pattern().type == operation_type) {
84f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      host_patterns->as_strings->push_back(it->GetHostPatternAsString());
85f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
86f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
87f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
88f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
89f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}  // namespace
90f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
91f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)SocketsManifestPermission::SocketsManifestPermission() {}
92f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
93f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)SocketsManifestPermission::~SocketsManifestPermission() {}
94f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
95f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// static
96f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)scoped_ptr<SocketsManifestPermission> SocketsManifestPermission::FromValue(
97f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const base::Value& value,
98a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    base::string16* error) {
99f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<Sockets> sockets = Sockets::FromValue(value, error);
100f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!sockets)
101f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return scoped_ptr<SocketsManifestPermission>();
102f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
103f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<SocketsManifestPermission> result(new SocketsManifestPermission());
104f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (sockets->udp) {
105f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (!ParseHostPatterns(result.get(),
106f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                           SocketPermissionRequest::UDP_BIND,
107f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                           sockets->udp->bind,
108f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                           error)) {
109f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return scoped_ptr<SocketsManifestPermission>();
110f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
111f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (!ParseHostPatterns(result.get(),
112f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                           SocketPermissionRequest::UDP_SEND_TO,
113f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                           sockets->udp->send,
114f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                           error)) {
115f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return scoped_ptr<SocketsManifestPermission>();
116f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
117f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (!ParseHostPatterns(result.get(),
118f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                           SocketPermissionRequest::UDP_MULTICAST_MEMBERSHIP,
119f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                           sockets->udp->multicast_membership,
120f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                           error)) {
121f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return scoped_ptr<SocketsManifestPermission>();
122f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
123f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
124f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (sockets->tcp) {
125f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (!ParseHostPatterns(result.get(),
126f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                           SocketPermissionRequest::TCP_CONNECT,
127f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                           sockets->tcp->connect,
128f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                           error)) {
129f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return scoped_ptr<SocketsManifestPermission>();
130f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
131f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
132f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (sockets->tcp_server) {
133f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (!ParseHostPatterns(result.get(),
134f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                           SocketPermissionRequest::TCP_LISTEN,
135f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                           sockets->tcp_server->listen,
136f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                           error)) {
137f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return scoped_ptr<SocketsManifestPermission>();
138f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
139f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
140f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return result.Pass();
141f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
142f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
143f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool SocketsManifestPermission::CheckRequest(
144f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const Extension* extension,
145f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const SocketPermissionRequest& request) const {
146f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  for (SocketPermissionEntrySet::const_iterator it = permissions_.begin();
1474ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch       it != permissions_.end();
1484ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch       ++it) {
149f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (it->Check(request))
150f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return true;
151f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
152f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return false;
153f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
154f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
155f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)std::string SocketsManifestPermission::name() const {
156f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return manifest_keys::kSockets;
157f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
158f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1594ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdochstd::string SocketsManifestPermission::id() const { return name(); }
160f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
161f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool SocketsManifestPermission::HasMessages() const {
162f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bool is_empty = permissions_.empty();
163f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return !is_empty;
164f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
165f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
166f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)PermissionMessages SocketsManifestPermission::GetMessages() const {
167f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // TODO(rpaquay): This function and callees is (almost) a copy/paste
168f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // from extensions::SocketPermissiona.
169f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  PermissionMessages result;
170f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!AddAnyHostMessage(result)) {
171f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    AddSpecificHostMessage(result);
172f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    AddSubdomainHostMessage(result);
173f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
174f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  AddNetworkListMessage(result);
175f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return result;
176f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
177f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
178f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool SocketsManifestPermission::FromValue(const base::Value* value) {
179f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!value)
180f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return false;
181a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::string16 error;
182f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<SocketsManifestPermission> manifest_permission(
183f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      SocketsManifestPermission::FromValue(*value, &error));
184f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
185f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!manifest_permission)
186f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return false;
187f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
188f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  permissions_ = manifest_permission->permissions_;
189f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return true;
190f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
191f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
192f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)scoped_ptr<base::Value> SocketsManifestPermission::ToValue() const {
193f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Sockets sockets;
194f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
195f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  sockets.udp.reset(new Sockets::Udp());
1964ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch  SetHostPatterns(sockets.udp->bind, this, SocketPermissionRequest::UDP_BIND);
1974ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch  SetHostPatterns(
1984ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch      sockets.udp->send, this, SocketPermissionRequest::UDP_SEND_TO);
1994ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch  SetHostPatterns(sockets.udp->multicast_membership,
2004ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch                  this,
201f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                  SocketPermissionRequest::UDP_MULTICAST_MEMBERSHIP);
202f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (sockets.udp->bind->as_strings->size() == 0 &&
203f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      sockets.udp->send->as_strings->size() == 0 &&
204f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      sockets.udp->multicast_membership->as_strings->size() == 0) {
205f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    sockets.udp.reset(NULL);
206f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
207f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
208f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  sockets.tcp.reset(new Sockets::Tcp());
2094ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch  SetHostPatterns(
2104ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch      sockets.tcp->connect, this, SocketPermissionRequest::TCP_CONNECT);
211f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (sockets.tcp->connect->as_strings->size() == 0) {
212f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    sockets.tcp.reset(NULL);
213f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
214f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
215f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  sockets.tcp_server.reset(new Sockets::TcpServer());
2164ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch  SetHostPatterns(
2174ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch      sockets.tcp_server->listen, this, SocketPermissionRequest::TCP_LISTEN);
218f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (sockets.tcp_server->listen->as_strings->size() == 0) {
219f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    sockets.tcp_server.reset(NULL);
220f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
221f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
222f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return scoped_ptr<base::Value>(sockets.ToValue().release()).Pass();
223f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
224f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
225f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)ManifestPermission* SocketsManifestPermission::Diff(
226f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const ManifestPermission* rhs) const {
227f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const SocketsManifestPermission* other =
228f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      static_cast<const SocketsManifestPermission*>(rhs);
229f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
230f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<SocketsManifestPermission> result(new SocketsManifestPermission());
2315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  result->permissions_ = base::STLSetDifference<SocketPermissionEntrySet>(
2325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      permissions_, other->permissions_);
233f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return result.release();
234f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
235f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
236f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)ManifestPermission* SocketsManifestPermission::Union(
237f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const ManifestPermission* rhs) const {
238f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const SocketsManifestPermission* other =
239f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      static_cast<const SocketsManifestPermission*>(rhs);
240f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
241f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<SocketsManifestPermission> result(new SocketsManifestPermission());
2425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  result->permissions_ = base::STLSetUnion<SocketPermissionEntrySet>(
2435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      permissions_, other->permissions_);
244f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return result.release();
245f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
246f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
247f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)ManifestPermission* SocketsManifestPermission::Intersect(
248f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const ManifestPermission* rhs) const {
249f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const SocketsManifestPermission* other =
250f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      static_cast<const SocketsManifestPermission*>(rhs);
251f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
252f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<SocketsManifestPermission> result(new SocketsManifestPermission());
2535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  result->permissions_ = base::STLSetIntersection<SocketPermissionEntrySet>(
2545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      permissions_, other->permissions_);
255f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return result.release();
256f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
257f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
258f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SocketsManifestPermission::AddPermission(
259f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const SocketPermissionEntry& entry) {
260f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  permissions_.insert(entry);
261f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
262f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
263f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool SocketsManifestPermission::AddAnyHostMessage(
264f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    PermissionMessages& messages) const {
265f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  for (SocketPermissionEntrySet::const_iterator it = permissions_.begin();
2664ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch       it != permissions_.end();
2674ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch       ++it) {
268f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (it->IsAddressBoundType() &&
269f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        it->GetHostType() == SocketPermissionEntry::ANY_HOST) {
2704ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch      messages.push_back(
2714ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch          PermissionMessage(PermissionMessage::kSocketAnyHost,
2724ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch                            l10n_util::GetStringUTF16(
2734ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch                                IDS_EXTENSION_PROMPT_WARNING_SOCKET_ANY_HOST)));
274f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return true;
275f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
276f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
277f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return false;
278f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
279f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
280f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SocketsManifestPermission::AddSubdomainHostMessage(
281f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    PermissionMessages& messages) const {
282a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::set<base::string16> domains;
283f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  for (SocketPermissionEntrySet::const_iterator it = permissions_.begin();
2844ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch       it != permissions_.end();
2854ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch       ++it) {
286f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (it->GetHostType() == SocketPermissionEntry::HOSTS_IN_DOMAINS)
2875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      domains.insert(base::UTF8ToUTF16(it->pattern().host));
288f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
289f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!domains.empty()) {
2904ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch    int id = (domains.size() == 1)
2914ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch                 ? IDS_EXTENSION_PROMPT_WARNING_SOCKET_HOSTS_IN_DOMAIN
2924ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch                 : IDS_EXTENSION_PROMPT_WARNING_SOCKET_HOSTS_IN_DOMAINS;
293f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    messages.push_back(PermissionMessage(
294f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        PermissionMessage::kSocketDomainHosts,
295f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        l10n_util::GetStringFUTF16(
296f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            id,
297f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            JoinString(
2984ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch                std::vector<base::string16>(domains.begin(), domains.end()),
2994ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch                ' '))));
300f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
301f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
302f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
303f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SocketsManifestPermission::AddSpecificHostMessage(
304f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    PermissionMessages& messages) const {
305a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::set<base::string16> hostnames;
306f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  for (SocketPermissionEntrySet::const_iterator it = permissions_.begin();
3074ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch       it != permissions_.end();
3084ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch       ++it) {
309f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (it->GetHostType() == SocketPermissionEntry::SPECIFIC_HOSTS)
3105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      hostnames.insert(base::UTF8ToUTF16(it->pattern().host));
311f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
312f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!hostnames.empty()) {
3134ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch    int id = (hostnames.size() == 1)
3144ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch                 ? IDS_EXTENSION_PROMPT_WARNING_SOCKET_SPECIFIC_HOST
3154ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch                 : IDS_EXTENSION_PROMPT_WARNING_SOCKET_SPECIFIC_HOSTS;
316f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    messages.push_back(PermissionMessage(
317f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        PermissionMessage::kSocketSpecificHosts,
318f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        l10n_util::GetStringFUTF16(
319f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            id,
320f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            JoinString(
3214ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch                std::vector<base::string16>(hostnames.begin(), hostnames.end()),
3224ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch                ' '))));
323f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
324f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
325f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
326f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SocketsManifestPermission::AddNetworkListMessage(
327f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    PermissionMessages& messages) const {
328f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  for (SocketPermissionEntrySet::const_iterator it = permissions_.begin();
3294ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch       it != permissions_.end();
3304ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch       ++it) {
331f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (it->pattern().type == SocketPermissionRequest::NETWORK_STATE) {
3324ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch      messages.push_back(
3334ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch          PermissionMessage(PermissionMessage::kNetworkState,
3344ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch                            l10n_util::GetStringUTF16(
3354ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch                                IDS_EXTENSION_PROMPT_WARNING_NETWORK_STATE)));
336f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
337f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
338f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
339f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
340f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}  // namespace extensions
341