Commit 7bde8d9e authored by Lutz Justen's avatar Lutz Justen Committed by Commit Bot

Kerberos: Implement ticket expiry notification

Adds a notification triggered by a signal from the Kerberos credentials
manager when the active Kerberos ticket expires. Upon clicking the
ticket, the reauthentication flow is started. In practice, this should
happen every few weeks if the Kerberos ticket lifetime and renewal
lifetime are set properly on the KDC, e.g. 24 h lifetime + 14 days
renewal lifetime.

BUG=chromium:952245
TEST=None

Change-Id: I0bb9965a0598571208f20c9ab53750ded2f6769a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1667304Reviewed-by: default avatarSteven Bennetts <stevenjb@chromium.org>
Reviewed-by: default avatarMichael Giuffrida <michaelpg@chromium.org>
Reviewed-by: default avatarRyo Hashimoto <hashimoto@chromium.org>
Commit-Queue: Lutz Justen <ljusten@chromium.org>
Auto-Submit: Lutz Justen <ljusten@chromium.org>
Cr-Commit-Position: refs/heads/master@{#673353}
parent c96de10f
......@@ -1089,6 +1089,8 @@ source_set("chromeos") {
"input_method/input_method_syncer.h",
"kerberos/kerberos_credentials_manager.cc",
"kerberos/kerberos_credentials_manager.h",
"kerberos/kerberos_ticket_expiry_notification.cc",
"kerberos/kerberos_ticket_expiry_notification.h",
"kiosk_next/kiosk_next_browser_factory.cc",
"kiosk_next/kiosk_next_browser_factory.h",
"language_preferences.cc",
......@@ -2477,6 +2479,7 @@ source_set("unit_tests") {
"input_method/input_method_engine_unittest.cc",
"input_method/input_method_manager_impl_unittest.cc",
"input_method/input_method_persistence_unittest.cc",
"kerberos/kerberos_ticket_expiry_notification_test.cc",
"locale_change_guard_unittest.cc",
"lock_screen_apps/app_manager_impl_unittest.cc",
"lock_screen_apps/lock_screen_profile_creator_impl_unittest.cc",
......
......@@ -10,11 +10,15 @@
#include "base/strings/stringprintf.h"
#include "base/threading/thread_task_runner_handle.h"
#include "chrome/browser/chromeos/authpolicy/data_pipe_utils.h"
#include "chrome/browser/chromeos/kerberos/kerberos_ticket_expiry_notification.h"
#include "chrome/browser/chromeos/login/session/user_session_manager.h"
#include "chrome/browser/chromeos/profiles/profile_helper.h"
#include "chrome/browser/policy/profile_policy_connector.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/chrome_pages.h"
#include "chrome/browser/ui/settings_window_manager_chromeos.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/webui_url_constants.h"
#include "chromeos/dbus/kerberos/kerberos_client.h"
#include "chromeos/dbus/kerberos/kerberos_service.pb.h"
#include "chromeos/network/onc/variable_expander.h"
......@@ -23,6 +27,7 @@
#include "components/prefs/pref_service.h"
#include "components/user_manager/user.h"
#include "dbus/message.h"
#include "net/base/escape.h"
#include "third_party/cros_system_api/dbus/kerberos/dbus-constants.h"
namespace chromeos {
......@@ -296,6 +301,12 @@ KerberosCredentialsManager::KerberosCredentialsManager(PrefService* local_state,
base::BindRepeating(&KerberosCredentialsManager::OnKerberosFilesChanged,
weak_factory_.GetWeakPtr()));
// Connect to a signal that indicates when a Kerberos ticket is about to
// expire.
KerberosClient::Get()->ConnectToKerberosTicketExpiringSignal(
base::BindRepeating(&KerberosCredentialsManager::OnKerberosTicketExpiring,
weak_factory_.GetWeakPtr()));
// Listen to pref changes.
pref_change_registrar_ = std::make_unique<PrefChangeRegistrar>();
pref_change_registrar_->Init(local_state);
......@@ -635,10 +646,24 @@ void KerberosCredentialsManager::OnGetKerberosFiles(
void KerberosCredentialsManager::OnKerberosFilesChanged(
const std::string& principal_name) {
// Only listen to the active account.
VLOG(1) << "Got KerberosFilesChanged for " << principal_name;
if (principal_name == GetActivePrincipalName())
GetKerberosFiles();
}
void KerberosCredentialsManager::OnKerberosTicketExpiring(
const std::string& principal_name) {
// Only listen to the active account.
VLOG(1) << "Got KerberosTicketExpiring for " << principal_name;
if (principal_name == GetActivePrincipalName()) {
kerberos_ticket_expiry_notification::Show(
primary_profile_, GetActivePrincipalName(),
base::BindRepeating(
&KerberosCredentialsManager::OnTicketExpiryNotificationClick,
weak_factory_.GetWeakPtr()));
}
}
void KerberosCredentialsManager::NotifyAccountsChanged() {
for (auto& observer : observers_)
observer.OnAccountsChanged();
......@@ -775,4 +800,15 @@ void KerberosCredentialsManager::NotifyRequiresLoginPassword(
requires_login_password);
}
void KerberosCredentialsManager::OnTicketExpiryNotificationClick(
const std::string& principal_name) {
// TODO(https://crbug.com/952245): Right now, the reauth dialog is tied to the
// settings. Consider creating a standalone reauth dialog.
kerberos_ticket_expiry_notification::Close(primary_profile_);
chrome::SettingsWindowManager::GetInstance()->ShowOSSettings(
primary_profile_,
chrome::kKerberosAccountsSubPage + std::string("?kerberos_reauth=") +
net::EscapeQueryParamValue(principal_name, false /* use_plus */));
}
} // namespace chromeos
......@@ -177,6 +177,9 @@ class KerberosCredentialsManager : public policy::PolicyService::Observer {
// Callback for 'KerberosFilesChanged' D-Bus signal sent by kerberosd.
void OnKerberosFilesChanged(const std::string& principal_name);
// Callback for 'KerberosTicketExpiring' D-Bus signal sent by kerberosd.
void OnKerberosTicketExpiring(const std::string& principal_name);
// Calls OnAccountsChanged() on all observers.
void NotifyAccountsChanged();
......@@ -191,6 +194,9 @@ class KerberosCredentialsManager : public policy::PolicyService::Observer {
// the active principal should ever break for whatever reason.
void ValidateActivePrincipal(const kerberos::ListAccountsResponse& response);
// Notification shown when the Kerberos ticket is about to expire.
void ShowTicketExpiryNotification();
// Pref change handlers.
void UpdateEnabledFromPref();
void UpdateRememberPasswordEnabledFromPref();
......@@ -203,6 +209,9 @@ class KerberosCredentialsManager : public policy::PolicyService::Observer {
// password.
void NotifyRequiresLoginPassword(bool requires_login_password);
// Called when the user clicks on the ticket expiry notification.
void OnTicketExpiryNotificationClick(const std::string& principal_name);
// Local state prefs, not owned.
PrefService* local_state_ = nullptr;
......
// Copyright 2019 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/chromeos/kerberos/kerberos_ticket_expiry_notification.h"
#include "ash/public/cpp/notification_utils.h"
#include "base/bind.h"
#include "base/memory/ref_counted.h"
#include "base/strings/string16.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/notifications/notification_display_service.h"
#include "chrome/browser/notifications/notification_display_service_factory.h"
#include "chromeos/strings/grit/chromeos_strings.h"
#include "components/vector_icons/vector_icons.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/message_center/public/cpp/notification.h"
#include "ui/message_center/public/cpp/notification_delegate.h"
#include "ui/message_center/public/cpp/notification_types.h"
#include "url/gurl.h"
using message_center::ButtonInfo;
using message_center::HandleNotificationClickDelegate;
using message_center::Notification;
using message_center::NotificationType;
using message_center::NotifierId;
using message_center::NotifierType;
using message_center::RichNotificationData;
using message_center::SystemNotificationWarningLevel;
namespace chromeos {
namespace kerberos_ticket_expiry_notification {
namespace {
// Unique ID for this notification.
constexpr char kNotificationId[] = "kerberos.ticket-expiry-notification";
// Simplest type of notification UI - no progress bars, images etc.
constexpr NotificationType kNotificationType =
message_center::NOTIFICATION_TYPE_SIMPLE;
// Generic type for notifications that are not from web pages etc.
const NotificationHandler::Type kNotificationHandlerType =
NotificationHandler::Type::TRANSIENT;
// This notification is a regular warning. It's not critical as users can still
// authenticate in most cases using username/password.
constexpr SystemNotificationWarningLevel kWarningLevel =
SystemNotificationWarningLevel::WARNING;
void OnClick(ClickCallback click_callback,
const std::string& passed_principal_name,
base::Optional<int> /* button_idx */) {
click_callback.Run(passed_principal_name);
}
} // namespace
void Show(Profile* profile,
const std::string& principal_name,
ClickCallback click_callback) {
const base::string16 kDisplaySource =
l10n_util::GetStringUTF16(IDS_KERBEROS_TICKET_EXPIRY_DISPLAY_SOURCE);
const base::string16 kTitle =
l10n_util::GetStringUTF16(IDS_KERBEROS_TICKET_EXPIRY_TITLE);
const base::string16 kBody = l10n_util::GetStringFUTF16(
IDS_KERBEROS_TICKET_EXPIRY_BODY, base::UTF8ToUTF16(principal_name));
const base::string16 kButton =
l10n_util::GetStringUTF16(IDS_KERBEROS_TICKET_EXPIRY_BUTTON);
// For histogram reporting.
const NotifierId kNotifierId(NotifierType::SYSTEM_COMPONENT, kNotificationId);
// No origin URL is needed since the notification comes from the system.
const GURL kEmptyOriginUrl;
// Office building.
const gfx::VectorIcon& kIcon = vector_icons::kBusinessIcon;
// Show button with proper text.
RichNotificationData notification_data;
notification_data.buttons = std::vector<ButtonInfo>{ButtonInfo(kButton)};
// Wrapper to call the |click_callback| with the |principal_name|.
HandleNotificationClickDelegate::ButtonClickCallback callback_wrapper =
base::BindRepeating(&OnClick, click_callback, principal_name);
std::unique_ptr<Notification> notification = ash::CreateSystemNotification(
kNotificationType, kNotificationId, kTitle, kBody, kDisplaySource,
kEmptyOriginUrl, kNotifierId, notification_data,
base::MakeRefCounted<HandleNotificationClickDelegate>(callback_wrapper),
kIcon, kWarningLevel);
NotificationDisplayService* nds =
NotificationDisplayServiceFactory::GetForProfile(profile);
// Calling close before display ensures that the notification pops up again
// even if it is already shown.
nds->Close(kNotificationHandlerType, kNotificationId);
nds->Display(kNotificationHandlerType, *notification, nullptr /* metadata */);
}
void Close(Profile* profile) {
NotificationDisplayServiceFactory::GetForProfile(profile)->Close(
kNotificationHandlerType, kNotificationId);
}
} // namespace kerberos_ticket_expiry_notification
} // namespace chromeos
// Copyright 2019 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.
#ifndef CHROME_BROWSER_CHROMEOS_KERBEROS_KERBEROS_TICKET_EXPIRY_NOTIFICATION_H_
#define CHROME_BROWSER_CHROMEOS_KERBEROS_KERBEROS_TICKET_EXPIRY_NOTIFICATION_H_
#include <string>
#include "base/memory/weak_ptr.h"
#include "ui/message_center/public/cpp/notification_delegate.h"
class Profile;
namespace chromeos {
namespace kerberos_ticket_expiry_notification {
using ClickCallback =
base::RepeatingCallback<void(const std::string& principal_name)>;
// Shows the ticket expiry notification for the given |principal_name|.
// |click_callback| is called when the user clicks on the notification.
void Show(Profile* profile,
const std::string& principal_name,
ClickCallback click_callback);
// Closes the ticket expiry notification.
void Close(Profile* profile);
} // namespace kerberos_ticket_expiry_notification
} // namespace chromeos
#endif // CHROME_BROWSER_CHROMEOS_KERBEROS_KERBEROS_TICKET_EXPIRY_NOTIFICATION_H_
// Copyright 2019 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/chromeos/kerberos/kerberos_ticket_expiry_notification.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/chromeos/profiles/profile_helper.h"
#include "chrome/browser/notifications/notification_display_service_impl.h"
#include "chrome/browser/notifications/notification_display_service_tester.h"
#include "chrome/test/base/testing_browser_process.h"
#include "chrome/test/base/testing_profile.h"
#include "chrome/test/base/testing_profile_manager.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/message_center/public/cpp/notification.h"
using message_center::Notification;
namespace chromeos {
namespace {
constexpr char kUser[] = "user@EXAMPLE.COM";
constexpr char kNotificationId[] = "kerberos.ticket-expiry-notification";
class KerberosTicketExpiryNotificationTest : public testing::Test {
public:
void SetUp() override {
ASSERT_TRUE(profile_manager_.SetUp());
profile_ = profile_manager_.CreateTestingProfile("test");
display_service_tester_ =
std::make_unique<NotificationDisplayServiceTester>(profile_);
}
void TearDown() override { display_service_tester_.reset(); }
void OnNotificationClick(const std::string& principal_name) {
notification_click_count_[principal_name]++;
}
protected:
base::Optional<Notification> Notification() {
return display_service_tester_->GetNotification(kNotificationId);
}
void Show() {
kerberos_ticket_expiry_notification::Show(
profile_, kUser,
base::BindRepeating(
&KerberosTicketExpiryNotificationTest::OnNotificationClick,
base::Unretained(this)));
}
content::TestBrowserThreadBundle test_environment_{
base::test::ScopedTaskEnvironment::MainThreadType::UI};
TestingProfileManager profile_manager_{TestingBrowserProcess::GetGlobal()};
TestingProfile* profile_ = nullptr;
std::unique_ptr<NotificationDisplayServiceTester> display_service_tester_;
// Counts how many times a notification for a given user was clicked.
std::map<std::string, int> notification_click_count_;
};
} // namespace
TEST_F(KerberosTicketExpiryNotificationTest, ShowClose) {
Show();
ASSERT_TRUE(Notification().has_value());
// Don't check the exact text here, just check if the username is there.
EXPECT_NE(std::string::npos,
Notification()->message().find(base::ASCIIToUTF16(kUser)));
kerberos_ticket_expiry_notification::Close(profile_);
EXPECT_FALSE(Notification().has_value());
}
TEST_F(KerberosTicketExpiryNotificationTest, Click) {
Show();
EXPECT_EQ(0, notification_click_count_[kUser]);
display_service_tester_->SimulateClick(
NotificationHandler::Type::TRANSIENT, kNotificationId,
base::nullopt /* action_index */, base::nullopt /* reply */);
EXPECT_EQ(1, notification_click_count_[kUser]);
}
} // namespace chromeos
......@@ -53,7 +53,20 @@ Polymer({
ready: function() {
this.browserProxy_ =
settings.KerberosAccountsBrowserProxyImpl.getInstance();
this.refreshAccounts_();
// Grab account list and - when done - pop up the reauthentication dialog if
// there is a kerberos_reauth param.
this.refreshAccounts_().then(() => {
const queryParams = settings.getQueryParameters();
const reauthPrincipal = queryParams.get('kerberos_reauth');
const reauthAccount = this.accounts_.find(account => {
return account.principalName == reauthPrincipal;
});
if (reauthAccount) {
this.selectedAccount_ = reauthAccount;
this.showAddAccountDialog_ = true;
}
});
},
/**
......@@ -90,9 +103,12 @@ Polymer({
this.closeActionMenu_();
},
/** @private */
/**
* @return {!Promise}
* @private
*/
refreshAccounts_: function() {
this.browserProxy_.getAccounts().then(accounts => {
return this.browserProxy_.getAccounts().then(accounts => {
this.accounts_ = accounts;
});
},
......
......@@ -14,8 +14,8 @@ namespace chrome {
// Please keep this file in the same order as the header.
// Note: Add hosts to |kChromeHostURLs| at the bottom of this file to be listed by
// chrome://chrome-urls (about:about) and the built-in AutocompleteProvider.
// Note: Add hosts to |kChromeHostURLs| at the bottom of this file to be listed
// by chrome://chrome-urls (about:about) and the built-in AutocompleteProvider.
const char kChromeUIAboutHost[] = "about";
const char kChromeUIAboutURL[] = "chrome://about/";
......@@ -367,14 +367,15 @@ const char kAccountManagerSubPage[] = "accountManager";
const char kAndroidAppsDetailsSubPage[] = "androidApps/details";
const char kAssistantSubPage[] = "googleAssistant";
const char kBluetoothSubPage[] = "bluetoothDevices";
// 'multidevice/features' is a child of the 'multidevice' route
const char kConnectedDevicesSubPage[] = "multidevice/features";
const char kCrostiniSharedUsbDevicesSubPage[] = "crostini/sharedUsbDevices";
const char kDateTimeSubPage[] = "dateTime";
const char kDisplaySubPage[] = "display";
const char kHelpSubPage[] = "help";
const char kInternetSubPage[] = "internet";
// 'multidevice/features' is a child of the 'multidevice' route
const char kConnectedDevicesSubPage[] = "multidevice/features";
const char kLockScreenSubPage[] = "lockScreen";
const char kKerberosAccountsSubPage[] = "kerberosAccounts";
const char kNativePrintingSettingsSubPage[] = "cupsPrinters";
const char kNetworkDetailSubPage[] = "networkDetail";
const char kNetworksSubPage[] = "networks";
......@@ -394,12 +395,13 @@ bool IsOSSettingsSubPage(const std::string& sub_page) {
kAndroidAppsDetailsSubPage,
kAssistantSubPage,
kBluetoothSubPage,
kConnectedDevicesSubPage,
kCrostiniSharedUsbDevicesSubPage,
kDateTimeSubPage,
kDisplaySubPage,
kHelpSubPage,
kInternetSubPage,
kConnectedDevicesSubPage,
kKerberosAccountsSubPage,
kLockScreenSubPage,
kNetworkDetailSubPage,
kNetworksSubPage,
......
......@@ -327,12 +327,13 @@ extern const char kAccountManagerSubPage[];
extern const char kAndroidAppsDetailsSubPage[];
extern const char kAssistantSubPage[];
extern const char kBluetoothSubPage[];
extern const char kConnectedDevicesSubPage[];
extern const char kCrostiniSharedUsbDevicesSubPage[];
extern const char kDateTimeSubPage[];
extern const char kDisplaySubPage[];
extern const char kHelpSubPage[];
extern const char kInternetSubPage[];
extern const char kConnectedDevicesSubPage[];
extern const char kKerberosAccountsSubPage[];
extern const char kLockScreenSubPage[];
extern const char kNativePrintingSettingsSubPage[];
extern const char kNetworkDetailSubPage[];
......
......@@ -155,6 +155,27 @@ cr.define('settings_people_page_kerberos_accounts', function() {
});
});
// Appending '?kerberos_reauth=<principal>' to the URL opens the reauth
// dialog for that account.
test('HandleReauthQueryParameter', function(done) {
const principal_name = testAccounts[Account.FIRST].principalName;
const params = new URLSearchParams;
params.append('kerberos_reauth', principal_name);
settings.navigateTo(settings.routes.KERBEROS_ACCOUNTS, params);
// The setTimeout is necessary since the kerberos_reauth param would
// otherwise be handled AFTER the callback below is executed.
browserProxy.whenCalled('getAccounts').then(() => {
setTimeout(() => {
Polymer.dom.flush();
const addDialog = kerberosAccounts.$$('kerberos-add-account-dialog');
assertTrue(!!addDialog);
assertEquals(principal_name, addDialog.$.username.value);
done();
});
});
});
test('RefreshNow', function() {
return browserProxy.whenCalled('getAccounts').then(() => {
Polymer.dom.flush();
......
......@@ -231,6 +231,20 @@ Try tapping the mic to ask me anything.
Passwords do not match
</message>
<!-- Kerberos ticket expiry notifications -->
<message name="IDS_KERBEROS_TICKET_EXPIRY_DISPLAY_SOURCE" desc="Display source of the notification shown when a Kerberos ticket is about to expire (shown on the top of the notification).">
Kerberos ticket expiring
</message>
<message name="IDS_KERBEROS_TICKET_EXPIRY_TITLE" desc="Title of the notification shown when a Kerberos ticket is about to expire (shown below the display source and above the body).">
Your Kerberos ticket is expiring
</message>
<message name="IDS_KERBEROS_TICKET_EXPIRY_BODY" desc="Body of the notification shown when a Kerberos ticket is about to expire (shown below the title).">
Please refresh the ticket for <ph name="PRINCIPAL_NAME">$1<ex>user@EXAMPLE.COM</ex></ph> soon
</message>
<message name="IDS_KERBEROS_TICKET_EXPIRY_BUTTON" desc="Button label of the notification shown when a Kerberos ticket is about to expire.">
REFRESH TICKET
</message>
<message name="IDS_IME_SERVICE_DISPLAY_NAME" desc="The display name (in the system task manager, etc) of the service process providing the input methods.">
Chrome OS Input Method Service
</message>
......
6ff127c0b94aac76132b5568a95d10c34390e130
\ No newline at end of file
6ff127c0b94aac76132b5568a95d10c34390e130
\ No newline at end of file
6ff127c0b94aac76132b5568a95d10c34390e130
\ No newline at end of file
6ff127c0b94aac76132b5568a95d10c34390e130
\ No newline at end of file
......@@ -192,6 +192,12 @@ void FakeKerberosClient::ConnectToKerberosFileChangedSignal(
kerberos_files_changed_callback_ = callback;
}
void FakeKerberosClient::ConnectToKerberosTicketExpiringSignal(
KerberosTicketExpiringCallback callback) {
DCHECK(!kerberos_ticket_expiring_callback_);
kerberos_ticket_expiring_callback_ = callback;
}
FakeKerberosClient::AccountData* FakeKerberosClient::GetAccountData(
const std::string& principal_name) {
auto it = accounts_.find(principal_name);
......
......@@ -39,6 +39,8 @@ class COMPONENT_EXPORT(CHROMEOS_DBUS) FakeKerberosClient
GetKerberosFilesCallback callback) override;
void ConnectToKerberosFileChangedSignal(
KerberosFilesChangedCallback callback) override;
void ConnectToKerberosTicketExpiringSignal(
KerberosTicketExpiringCallback callback) override;
private:
struct AccountData {
......@@ -64,6 +66,7 @@ class COMPONENT_EXPORT(CHROMEOS_DBUS) FakeKerberosClient
AccountsMap accounts_;
KerberosFilesChangedCallback kerberos_files_changed_callback_;
KerberosTicketExpiringCallback kerberos_ticket_expiring_callback_;
DISALLOW_COPY_AND_ASSIGN(FakeKerberosClient);
};
......
......@@ -19,6 +19,8 @@
namespace chromeos {
namespace {
KerberosClient* g_instance = nullptr;
// Tries to parse a proto message from |response| into |proto|.
// Returns false if |response| is nullptr or the message cannot be parsed.
bool ParseProto(dbus::Response* response,
......@@ -37,7 +39,12 @@ bool ParseProto(dbus::Response* response,
return true;
}
KerberosClient* g_instance = nullptr;
void OnSignalConnected(const std::string& interface_name,
const std::string& signal_name,
bool success) {
DCHECK_EQ(interface_name, kerberos::kKerberosInterface);
DCHECK(success);
}
// "Real" implementation of KerberosClient taking to the Kerberos daemon on the
// Chrome OS side.
......@@ -103,8 +110,19 @@ class KerberosClientImpl : public KerberosClient {
kerberos::kKerberosInterface, kerberos::kKerberosFilesChangedSignal,
base::BindRepeating(&KerberosClientImpl::OnKerberosFilesChanged,
weak_factory_.GetWeakPtr()),
base::BindOnce(&KerberosClientImpl::OnKerberosFilesChangedConnected,
weak_factory_.GetWeakPtr()));
base::BindOnce(&OnSignalConnected));
}
void ConnectToKerberosTicketExpiringSignal(
KerberosTicketExpiringCallback callback) override {
DCHECK(callback);
kerberos_ticket_expiring_callback_ = callback;
proxy_->ConnectToSignal(
kerberos::kKerberosInterface, kerberos::kKerberosTicketExpiringSignal,
base::BindRepeating(&KerberosClientImpl::OnKerberosTicketExpiring,
weak_factory_.GetWeakPtr()),
base::BindOnce(&OnSignalConnected));
}
void OnKerberosFilesChanged(dbus::Signal* signal) {
......@@ -123,12 +141,20 @@ class KerberosClientImpl : public KerberosClient {
kerberos_files_changed_callback_.Run(principal_name);
}
void OnKerberosFilesChangedConnected(const std::string& interface_name,
const std::string& signal_name,
bool success) {
DCHECK_EQ(interface_name, kerberos::kKerberosInterface);
DCHECK_EQ(signal_name, kerberos::kKerberosFilesChangedSignal);
DCHECK(success);
void OnKerberosTicketExpiring(dbus::Signal* signal) {
DCHECK_EQ(signal->GetInterface(), kerberos::kKerberosInterface);
DCHECK_EQ(signal->GetMember(), kerberos::kKerberosTicketExpiringSignal);
dbus::MessageReader signal_reader(signal);
std::string principal_name;
if (!signal_reader.PopString(&principal_name)) {
LOG(ERROR)
<< "Failed to read principal name for KerberosTicketExpiring signal";
return;
}
DCHECK(kerberos_ticket_expiring_callback_);
kerberos_ticket_expiring_callback_.Run(principal_name);
}
void Init(dbus::Bus* bus) {
......@@ -188,8 +214,9 @@ class KerberosClientImpl : public KerberosClient {
// D-Bus proxy for the Kerberos daemon, not owned.
dbus::ObjectProxy* proxy_ = nullptr;
// Callback for the KerberosFilesChanged signal.
// Signal callbacks.
KerberosFilesChangedCallback kerberos_files_changed_callback_;
KerberosTicketExpiringCallback kerberos_ticket_expiring_callback_;
base::WeakPtrFactory<KerberosClientImpl> weak_factory_{this};
DISALLOW_COPY_AND_ASSIGN(KerberosClientImpl);
......
......@@ -38,16 +38,8 @@ class COMPONENT_EXPORT(KERBEROS) KerberosClient {
const kerberos::GetKerberosFilesResponse& response)>;
using KerberosFilesChangedCallback =
base::RepeatingCallback<void(const std::string& principal_name)>;
// Interface for testing. Only implemented in the fake implementation.
class TestInterface {
public:
// Sets whether the (fake) daemon has been started by Upstart.
virtual void set_started(bool started) = 0;
// Whether the (fake) daemon has been started and is in a running state.
virtual bool started() const = 0;
};
using KerberosTicketExpiringCallback =
base::RepeatingCallback<void(const std::string& principal_name)>;
// Creates and initializes the global instance. |bus| must not be null.
static void Initialize(dbus::Bus* bus);
......@@ -91,6 +83,9 @@ class COMPONENT_EXPORT(KERBEROS) KerberosClient {
virtual void ConnectToKerberosFileChangedSignal(
KerberosFilesChangedCallback callback) = 0;
virtual void ConnectToKerberosTicketExpiringSignal(
KerberosTicketExpiringCallback callback) = 0;
protected:
// Initialize/Shutdown should be used instead.
KerberosClient();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment