Home | History | Annotate | Download | only in messaging
      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