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

Side by Side Diff: chrome/browser/extensions/api/messaging/native_messaging_host_manifest.cc

Issue 12285015: Require manifests for native messaging hosts. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 9 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 | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2013 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/browser/extensions/api/messaging/native_messaging_host_manifest .h"
6
7 #include "base/json/json_file_value_serializer.h"
8 #include "base/logging.h"
9 #include "base/values.h"
10
11 namespace extensions {
12
13 NativeMessagingHostManifest::~NativeMessagingHostManifest() {}
14
15 // static
16 bool NativeMessagingHostManifest::IsValidName(const std::string& name) {
17 if (name.empty()) {
18 return false;
19 }
20
21 for (size_t i = 0; i < name.size(); ++i) {
22 char c = name[i];
23
24 // Verify that only the following characters are used: [a-z0-9._].
25 if (!((c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') ||
26 c == '.' || c == '_')) {
27 return false;
28 }
29
30 // Verify that dots are separated by other characters and that string
31 // doesn't begin or end with a dot.
32 if (c == '.' && (i == 0 || name[i - 1] == '.' || i == name.size() - 1)) {
33 return false;
34 }
35 }
36
37 return true;
38 }
39
40 // static
41 scoped_ptr<NativeMessagingHostManifest> NativeMessagingHostManifest::Load(
42 const base::FilePath& file_path,
43 std::string* error_message) {
44 DCHECK(error_message);
45
46 JSONFileValueSerializer serializer(file_path);
47 scoped_ptr<base::Value> parsed(serializer.Deserialize(NULL, error_message));
48 if (!parsed) {
49 return scoped_ptr<NativeMessagingHostManifest>();
50 }
51
52 base::DictionaryValue* dictionary;
53 if (!parsed->GetAsDictionary(&dictionary)) {
54 *error_message = "Invalid manifest file.";
55 return scoped_ptr<NativeMessagingHostManifest>();
56 }
57
58 scoped_ptr<NativeMessagingHostManifest> result(
59 new NativeMessagingHostManifest());
60 if (!result->Parse(dictionary, error_message)) {
61 return scoped_ptr<NativeMessagingHostManifest>();
62 }
63
64 return result.Pass();
65 }
66
67 NativeMessagingHostManifest::NativeMessagingHostManifest() {
68 }
69
70 bool NativeMessagingHostManifest::Parse(base::DictionaryValue* dictionary,
71 std::string* error_message) {
72 if (!dictionary->GetString("name", &name_) ||
73 !IsValidName(name_)) {
74 *error_message = "Invalid value for name.";
75 return false;
76 }
77
78 if (!dictionary->GetString("description", &description_) ||
79 description_.empty()) {
80 *error_message = "Invalid value for description.";
81 return false;
82 }
83
84 std::string type;
85 // stdio is the only host type that's currently supported.
86 if (!dictionary->GetString("type", &type) ||
87 type != "stdio") {
88 *error_message = "Invalid value for type.";
89 return false;
90 }
91 interface_ = HOST_INTERFACE_STDIO;
92
93 std::string path;
94 // JSON parsed checks that all strings are valid UTF8.
95 if (!dictionary->GetString("path", &path) ||
96 (path_ = base::FilePath::FromUTF8Unsafe(path)).empty() ||
97 !path_.IsAbsolute()) {
98 *error_message = "Invalid value for path.";
99 return false;
100 }
101
102 const base::ListValue* allowed_origins_list;
103 if (!dictionary->GetList("allowed_origins", &allowed_origins_list)) {
104 *error_message =
105 "Invalid value for allowed_origins. Expected a list of strings.";
106 return false;
107 }
108 allowed_origins_.ClearPatterns();
109 for (base::ListValue::const_iterator it = allowed_origins_list->begin();
110 it != allowed_origins_list->end(); ++it) {
111 std::string pattern_string;
112 if (!(*it)->GetAsString(&pattern_string)) {
113 *error_message = "allowed_origins must be list of strings.";
114 return false;
115 }
116
117 URLPattern pattern(URLPattern::SCHEME_EXTENSION);
118 URLPattern::ParseResult result = pattern.Parse(pattern_string);
119 if (result != URLPattern::PARSE_SUCCESS) {
120 *error_message = "Failed to parse pattern \"" + pattern_string +
121 "\": " + URLPattern::GetParseResultString(result);
122 return false;
123 }
124
125 // Disallow patterns that are too broad. Set of allowed origins must be a
126 // fixed list of extensions.
127 if (pattern.match_all_urls() || pattern.match_subdomains()) {
128 *error_message = "Pattern \"" + pattern_string + "\" is not allowed.";
129 return false;
130 }
131
132 allowed_origins_.AddPattern(pattern);
133 }
134
135 return true;
136 }
137
138 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698