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/file_util.h" 8 #include "base/files/file_path.h" 9 #include "base/files/scoped_temp_dir.h" 10 #include "base/json/string_escape.h" 11 #include "extensions/common/url_pattern_set.h" 12 #include "testing/gtest/include/gtest/gtest.h" 13 #include "url/gurl.h" 14 15 namespace extensions { 16 17 const char kTestHostName[] = "com.chrome.test.native_host"; 18 #if defined(OS_WIN) 19 const char kTestHostPath[] = "C:\\ProgramFiles\\host.exe"; 20 #else 21 const char kTestHostPath[] = "/usr/bin/host"; 22 #endif 23 const char kTestOrigin[] = 24 "chrome-extension://knldjmfmopnpolahpmmgbagdohdnhkik/"; 25 26 class NativeMessagingHostManifestTest : public ::testing::Test { 27 public: 28 virtual void SetUp() OVERRIDE { 29 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); 30 manifest_path_ = temp_dir_.path().AppendASCII("test.json"); 31 } 32 33 protected: 34 bool WriteManifest(const std::string& name, 35 const std::string& path, 36 const std::string& origin) { 37 std::string escaped_path; 38 base::JsonDoubleQuote(path, false, &escaped_path); 39 return WriteManifest("{" 40 " \"name\": \"" + name + "\"," 41 " \"description\": \"Native Messaging Test\"," 42 " \"path\": \"" + escaped_path + "\"," 43 " \"type\": \"stdio\"," 44 " \"allowed_origins\": [" 45 " \"" + origin + "\"" 46 " ]" 47 "}"); 48 } 49 50 bool WriteManifest(const std::string& manifest_content) { 51 return file_util::WriteFile( 52 manifest_path_, manifest_content.data(), manifest_content.size()); 53 } 54 55 base::ScopedTempDir temp_dir_; 56 base::FilePath manifest_path_; 57 }; 58 59 TEST_F(NativeMessagingHostManifestTest, HostNameValidation) { 60 EXPECT_TRUE(NativeMessagingHostManifest::IsValidName("a")); 61 EXPECT_TRUE(NativeMessagingHostManifest::IsValidName("foo")); 62 EXPECT_TRUE(NativeMessagingHostManifest::IsValidName("foo132")); 63 EXPECT_TRUE(NativeMessagingHostManifest::IsValidName("foo.bar")); 64 EXPECT_TRUE(NativeMessagingHostManifest::IsValidName("foo.bar2")); 65 EXPECT_TRUE(NativeMessagingHostManifest::IsValidName("a._.c")); 66 EXPECT_TRUE(NativeMessagingHostManifest::IsValidName("a._.c")); 67 EXPECT_FALSE(NativeMessagingHostManifest::IsValidName("A.b")); 68 EXPECT_FALSE(NativeMessagingHostManifest::IsValidName("a..b")); 69 EXPECT_FALSE(NativeMessagingHostManifest::IsValidName(".a")); 70 EXPECT_FALSE(NativeMessagingHostManifest::IsValidName("b.")); 71 EXPECT_FALSE(NativeMessagingHostManifest::IsValidName("a*")); 72 } 73 74 TEST_F(NativeMessagingHostManifestTest, LoadValid) { 75 ASSERT_TRUE(WriteManifest(kTestHostName, kTestHostPath, kTestOrigin)); 76 77 std::string error_message; 78 scoped_ptr<NativeMessagingHostManifest> manifest = 79 NativeMessagingHostManifest::Load(manifest_path_, &error_message); 80 ASSERT_TRUE(manifest) << "Failed to load manifest: " << error_message; 81 EXPECT_TRUE(error_message.empty()); 82 83 EXPECT_EQ(manifest->name(), "com.chrome.test.native_host"); 84 EXPECT_EQ(manifest->description(), "Native Messaging Test"); 85 EXPECT_EQ(manifest->interface(), 86 NativeMessagingHostManifest::HOST_INTERFACE_STDIO); 87 EXPECT_EQ(manifest->path(), base::FilePath::FromUTF8Unsafe(kTestHostPath)); 88 EXPECT_TRUE(manifest->allowed_origins().MatchesSecurityOrigin( 89 GURL("chrome-extension://knldjmfmopnpolahpmmgbagdohdnhkik/"))); 90 EXPECT_FALSE(manifest->allowed_origins().MatchesSecurityOrigin( 91 GURL("chrome-extension://jnldjmfmopnpolahpmmgbagdohdnhkik/"))); 92 } 93 94 TEST_F(NativeMessagingHostManifestTest, InvalidName) { 95 ASSERT_TRUE(WriteManifest(".com.chrome.test.native_host", 96 kTestHostPath, kTestOrigin)); 97 98 std::string error_message; 99 scoped_ptr<NativeMessagingHostManifest> manifest = 100 NativeMessagingHostManifest::Load(manifest_path_, &error_message); 101 ASSERT_FALSE(manifest); 102 EXPECT_FALSE(error_message.empty()); 103 } 104 105 // Verify that match-all origins are rejected. 106 TEST_F(NativeMessagingHostManifestTest, MatchAllOrigin) { 107 ASSERT_TRUE(WriteManifest(kTestHostName, kTestHostPath, 108 "chrome-extension://*/")); 109 110 std::string error_message; 111 scoped_ptr<NativeMessagingHostManifest> manifest = 112 NativeMessagingHostManifest::Load(manifest_path_, &error_message); 113 ASSERT_FALSE(manifest); 114 EXPECT_FALSE(error_message.empty()); 115 } 116 117 } // namespace extensions 118