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

Unified 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, 10 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/extensions/api/messaging/native_messaging_host_manifest.cc
diff --git a/chrome/browser/extensions/api/messaging/native_messaging_host_manifest.cc b/chrome/browser/extensions/api/messaging/native_messaging_host_manifest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..a93b8637e088e1f10f0a1eb53491ed06abb35a46
--- /dev/null
+++ b/chrome/browser/extensions/api/messaging/native_messaging_host_manifest.cc
@@ -0,0 +1,138 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/extensions/api/messaging/native_messaging_host_manifest.h"
+
+#include "base/json/json_file_value_serializer.h"
+#include "base/logging.h"
+#include "base/values.h"
+
+namespace extensions {
+
+NativeMessagingHostManifest::~NativeMessagingHostManifest() {}
+
+// static
+bool NativeMessagingHostManifest::IsValidName(const std::string& name) {
+ if (name.empty()) {
+ return false;
+ }
+
+ for (size_t i = 0; i < name.size(); ++i) {
+ char c = name[i];
+
+ // Verify that only the following characters are used: [a-z0-9._].
+ if (!((c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') ||
+ c == '.' || c == '_')) {
+ return false;
+ }
+
+ // Verify that dots are separated by other characters and that string
+ // doesn't begin or end with a dot.
+ if (c == '.' && (i == 0 || name[i - 1] == '.' || i == name.size() - 1)) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+// static
+scoped_ptr<NativeMessagingHostManifest> NativeMessagingHostManifest::Load(
+ const base::FilePath& file_path,
+ std::string* error_message) {
+ DCHECK(error_message);
+
+ JSONFileValueSerializer serializer(file_path);
+ scoped_ptr<base::Value> parsed(serializer.Deserialize(NULL, error_message));
+ if (!parsed) {
+ return scoped_ptr<NativeMessagingHostManifest>();
+ }
+
+ base::DictionaryValue* dictionary;
+ if (!parsed->GetAsDictionary(&dictionary)) {
+ *error_message = "Invalid manifest file.";
+ return scoped_ptr<NativeMessagingHostManifest>();
+ }
+
+ scoped_ptr<NativeMessagingHostManifest> result(
+ new NativeMessagingHostManifest());
+ if (!result->Parse(dictionary, error_message)) {
+ return scoped_ptr<NativeMessagingHostManifest>();
+ }
+
+ return result.Pass();
+}
+
+NativeMessagingHostManifest::NativeMessagingHostManifest() {
+}
+
+bool NativeMessagingHostManifest::Parse(base::DictionaryValue* dictionary,
+ std::string* error_message) {
+ if (!dictionary->GetString("name", &name_) ||
+ !IsValidName(name_)) {
+ *error_message = "Invalid value for name.";
+ return false;
+ }
+
+ if (!dictionary->GetString("description", &description_) ||
+ description_.empty()) {
+ *error_message = "Invalid value for description.";
+ return false;
+ }
+
+ std::string type;
+ // stdio is the only host type that's currently supported.
+ if (!dictionary->GetString("type", &type) ||
+ type != "stdio") {
+ *error_message = "Invalid value for type.";
+ return false;
+ }
+ interface_ = HOST_INTERFACE_STDIO;
+
+ std::string path;
+ // JSON parsed checks that all strings are valid UTF8.
+ if (!dictionary->GetString("path", &path) ||
+ (path_ = base::FilePath::FromUTF8Unsafe(path)).empty() ||
+ !path_.IsAbsolute()) {
+ *error_message = "Invalid value for path.";
+ return false;
+ }
+
+ const base::ListValue* allowed_origins_list;
+ if (!dictionary->GetList("allowed_origins", &allowed_origins_list)) {
+ *error_message =
+ "Invalid value for allowed_origins. Expected a list of strings.";
+ return false;
+ }
+ allowed_origins_.ClearPatterns();
+ for (base::ListValue::const_iterator it = allowed_origins_list->begin();
+ it != allowed_origins_list->end(); ++it) {
+ std::string pattern_string;
+ if (!(*it)->GetAsString(&pattern_string)) {
+ *error_message = "allowed_origins must be list of strings.";
+ return false;
+ }
+
+ URLPattern pattern(URLPattern::SCHEME_EXTENSION);
+ URLPattern::ParseResult result = pattern.Parse(pattern_string);
+ if (result != URLPattern::PARSE_SUCCESS) {
+ *error_message = "Failed to parse pattern \"" + pattern_string +
+ "\": " + URLPattern::GetParseResultString(result);
+ return false;
+ }
+
+ // Disallow patterns that are too broad. Set of allowed origins must be a
+ // fixed list of extensions.
+ if (pattern.match_all_urls() || pattern.match_subdomains()) {
+ *error_message = "Pattern \"" + pattern_string + "\" is not allowed.";
+ return false;
+ }
+
+ allowed_origins_.AddPattern(pattern);
+ }
+
+ return true;
+}
+
+} // namespace extensions

Powered by Google App Engine
This is Rietveld 408576698