blob: 7f470d95ff6619574866254bb38610561b359dad [file] [log] [blame]
Andreea Costinas922fbaf2020-05-28 11:55:22 +02001// Copyright 2020 The Chromium OS 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 "system-proxy/kerberos_client.h"
6
7#include <gmock/gmock.h>
8#include <gtest/gtest.h>
9#include <utility>
10
11#include <base/bind.h>
Andreea Costinas922fbaf2020-05-28 11:55:22 +020012#include <base/callback_helpers.h>
13#include <base/files/file_util.h>
14#include <base/files/scoped_file.h>
15#include <base/memory/weak_ptr.h>
Andreea Costinas922fbaf2020-05-28 11:55:22 +020016#include <base/strings/stringprintf.h>
Qijiang Fan34014672020-07-20 16:05:38 +090017#include <base/task/single_thread_task_executor.h>
Andreea Costinas922fbaf2020-05-28 11:55:22 +020018#include <brillo/dbus/async_event_sequencer.h>
19#include <brillo/dbus/dbus_object.h>
20#include <brillo/message_loops/base_message_loop.h>
21#include <dbus/kerberos/dbus-constants.h>
22#include <dbus/object_path.h>
23#include <dbus/message.h>
24#include <dbus/mock_bus.h>
25#include <dbus/mock_object_proxy.h>
26#include <kerberos/proto_bindings/kerberos_service.pb.h>
27
28using testing::_;
29using testing::Return;
30
31namespace system_proxy {
32namespace {
33constexpr char kKrb5ConfFile[] = "/tmp/krb5.conf";
34constexpr char kCCacheFile[] = "/tmp/ccache";
35constexpr char kPrincipalName[] = "user@TEST-REALM";
36
37const char kKrb5Settings[] =
38 "[libdefaults]\n"
39 "\tdns_canonicalize_hostname = false\n"
40 "\trdns = false\n"
41 "\tdefault_realm = TEST-REALM\n";
42
43std::string GetUpdatedConfig(const std::string& updated_config) {
44 return base::StringPrintf("%s%s", kKrb5Settings, updated_config.c_str());
45}
46
47} // namespace
48
49// Implementation of KerberosClient that fakes dbus calls to kerberosd.
50class FakeKerberosClient : public KerberosClient {
51 public:
52 explicit FakeKerberosClient(scoped_refptr<dbus::Bus> bus)
53 : KerberosClient(bus) {}
54 FakeKerberosClient(const FakeKerberosClient&) = delete;
55 FakeKerberosClient& operator=(const FakeKerberosClient&) = delete;
56 ~FakeKerberosClient() override = default;
57
58 void SetFakeGetFilesResponse(const std::string& krb5_conf_data,
59 const std::string& ccache_data) {
60 krb5_conf_data_ = krb5_conf_data;
61 ccache_file_data_ = ccache_data;
62 }
63
64 protected:
65 void GetFiles() override {
66 auto dbus_response = dbus::Response::CreateEmpty();
67 dbus::MessageWriter writer(dbus_response.get());
68
69 kerberos::GetKerberosFilesResponse response;
70 kerberos::KerberosFiles files;
71 files.set_krb5conf(krb5_conf_data_);
72 files.set_krb5cc(ccache_file_data_);
73 *response.mutable_files() = files;
74
75 writer.AppendProtoAsArrayOfBytes(response);
76
77 OnGetFilesResponse(dbus_response.get());
78 }
79
80 private:
81 // Values returned by the kerberosd service.
82 std::string krb5_conf_data_;
83 std::string ccache_file_data_;
84};
85
86class KerberosClientTest : public ::testing::Test {
87 public:
88 KerberosClientTest() {
89 mock_kerberos_proxy_ = base::MakeRefCounted<dbus::MockObjectProxy>(
90 bus_.get(), kerberos::kKerberosServiceName,
91 dbus::ObjectPath(kerberos::kKerberosServicePath));
92 EXPECT_CALL(*bus_, GetObjectProxy(kerberos::kKerberosServiceName, _))
93 .WillRepeatedly(Return(mock_kerberos_proxy_.get()));
94 kerberos_client_.reset(new FakeKerberosClient(bus_));
95
96 krb5_conf_file_path_ = base::FilePath(kKrb5ConfFile);
97 ccache_file_path_ = base::FilePath(kCCacheFile);
98
99 brillo_loop_.SetAsCurrent();
100 }
101 KerberosClientTest(const KerberosClientTest&) = delete;
102 KerberosClientTest& operator=(const KerberosClientTest&) = delete;
103 ~KerberosClientTest() override {
104 // Clean-up
105 kerberos_client_->DeleteFiles();
106 }
107
108 protected:
109 std::unique_ptr<FakeKerberosClient> kerberos_client_;
110 base::FilePath krb5_conf_file_path_;
111 base::FilePath ccache_file_path_;
112
113 scoped_refptr<dbus::MockBus> bus_ = new dbus::MockBus(dbus::Bus::Options());
114 scoped_refptr<dbus::MockObjectProxy> mock_kerberos_proxy_;
115
Qijiang Fan34014672020-07-20 16:05:38 +0900116 base::SingleThreadTaskExecutor task_executor_{base::MessagePumpType::IO};
117 brillo::BaseMessageLoop brillo_loop_{task_executor_.task_runner()};
Andreea Costinas922fbaf2020-05-28 11:55:22 +0200118};
119
120// Test that the kerberos files are written and deleted correctly.
121TEST_F(KerberosClientTest, KerberosEnabled) {
hscham53cf73a2020-11-30 15:58:42 +0900122 base::DeleteFile(base::FilePath(kKrb5ConfFile));
123 base::DeleteFile(base::FilePath(kCCacheFile));
Andreea Costinas922fbaf2020-05-28 11:55:22 +0200124 std::string actual_krb5config;
125 std::string actual_ccache;
126
127 EXPECT_FALSE(
128 base::ReadFileToString(krb5_conf_file_path_, &actual_krb5config));
129 EXPECT_FALSE(base::ReadFileToString(ccache_file_path_, &actual_ccache));
130
131 kerberos_client_->SetFakeGetFilesResponse("fake conf", "fake ccache");
132 kerberos_client_->SetKerberosEnabled(true);
133 kerberos_client_->SetPrincipalName(kPrincipalName);
134
135 ASSERT_TRUE(base::ReadFileToString(krb5_conf_file_path_, &actual_krb5config));
136 ASSERT_TRUE(base::ReadFileToString(ccache_file_path_, &actual_ccache));
137 EXPECT_EQ(GetUpdatedConfig("fake conf"), actual_krb5config);
138 EXPECT_EQ("fake ccache", actual_ccache);
139
140 kerberos_client_->SetKerberosEnabled(false);
141 EXPECT_FALSE(
142 base::ReadFileToString(krb5_conf_file_path_, &actual_krb5config));
143 EXPECT_FALSE(base::ReadFileToString(ccache_file_path_, &actual_ccache));
144}
145
146// Test that the kerberos files are requested again when the
147TEST_F(KerberosClientTest, SignalHandling) {
148 std::string actual_krb5config;
149 std::string actual_ccache;
150
151 kerberos_client_->SetFakeGetFilesResponse("fake conf 1", "fake ccache 1");
152 kerberos_client_->SetKerberosEnabled(true);
153 kerberos_client_->SetPrincipalName(kPrincipalName);
154
155 ASSERT_TRUE(base::ReadFileToString(krb5_conf_file_path_, &actual_krb5config));
156 ASSERT_TRUE(base::ReadFileToString(ccache_file_path_, &actual_ccache));
157 EXPECT_EQ(GetUpdatedConfig("fake conf 1"), actual_krb5config);
158 EXPECT_EQ("fake ccache 1", actual_ccache);
159
160 kerberos_client_->SetFakeGetFilesResponse("fake conf 2", "fake ccache 2");
161 dbus::Signal signal_to_send(kerberos::kKerberosInterface,
162 kerberos::kKerberosFilesChangedSignal);
163 kerberos_client_->OnKerberosFilesChanged(&signal_to_send);
164 ASSERT_TRUE(base::ReadFileToString(krb5_conf_file_path_, &actual_krb5config));
165 ASSERT_TRUE(base::ReadFileToString(ccache_file_path_, &actual_ccache));
166 EXPECT_EQ(GetUpdatedConfig("fake conf 2"), actual_krb5config);
167 EXPECT_EQ("fake ccache 2", actual_ccache);
168}
169
170} // namespace system_proxy