-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathtgt_manager.h
217 lines (166 loc) · 8.32 KB
/
tgt_manager.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
// Copyright 2017 The Chromium OS 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 AUTHPOLICY_TGT_MANAGER_H_
#define AUTHPOLICY_TGT_MANAGER_H_
#include <string>
#include <base/cancelable_callback.h>
#include <base/macros.h>
#include "authpolicy/path_service.h"
#include "authpolicy/proto_bindings/active_directory_info.pb.h"
namespace authpolicy {
namespace protos {
class DebugFlags;
class TgtLifetime;
class TgtState;
} // namespace protos
class Anonymizer;
class AuthPolicyMetrics;
class JailHelper;
class PathService;
class ProcessExecutor;
// Responsible for acquiring a ticket-tranting-ticket (TGT) from an Active
// Directory key distribution center (KDC) and managing the TGT. The TGT is
// kept in a file, the credentials cache. Supports authentication via a password
// or a keytab file.
class TgtManager {
public:
class Delegate {
public:
virtual ~Delegate() = default;
// Called when the Kerberos ticket has been auto-renewed.
virtual void OnTgtRenewed() = 0;
};
TgtManager(const PathService* path_service,
AuthPolicyMetrics* metrics,
const protos::DebugFlags* flags,
const JailHelper* jail_helper,
Anonymizer* anonymizer,
Delegate* delegate,
Path config_path,
Path credential_cache_path);
TgtManager(const TgtManager&) = delete;
TgtManager& operator=(const TgtManager&) = delete;
~TgtManager();
// Sets the principal (user@REALM or machine$@REALM).
void SetPrincipal(const std::string& principal);
// Sets the Active Directory realm (e.g. ENG.EXAMPLE.COM).
void SetRealm(const std::string& realm) { realm_ = realm; }
// Sets the key distribution center IP.
void SetKdcIp(const std::string& kdc_ip) { kdc_ip_ = kdc_ip; }
// If an account has just been created, it might not have propagated through
// Active Directory yet, so attempts to acquire a TGT might fail. Enabling
// propagation retry causes kinit to be retried a few times if an error occurs
// that indicates a propagation issue. Disables itself after kinit has run.
void SetPropagationRetry(bool enabled) { kinit_retry_ = enabled; }
// Sets the encryption types to use for kinit.
void SetKerberosEncryptionTypes(KerberosEncryptionTypes encryption_types) {
encryption_types_ = encryption_types;
}
// Resets the principal, the realm, the KDC IP, propagation retry and
// encryption types.
void Reset();
// Acquires a TGT using the password given in the file descriptor
// |password_fd|. See AcquiteTgt() for details.
ErrorType AcquireTgtWithPassword(int password_fd) WARN_UNUSED_RESULT;
// Acquires a TGT using the keytab file at |keytab_path|. See AcquiteTgt() for
// details.
ErrorType AcquireTgtWithKeytab(Path keytab_path) WARN_UNUSED_RESULT;
// Returns the Kerberos credentials cache and the configuration file. Returns
// ERROR_NONE if the credentials cache is missing and ERROR_LOCAL_IO if any of
// the files failed to read.
ErrorType GetKerberosFiles(KerberosFiles* files) WARN_UNUSED_RESULT;
// Sets a callback that gets called when either the Kerberos credential cache
// or the configuration file changes on disk. Use in combination with
// GetKerberosFiles() to get the latest files.
void SetKerberosFilesChangedCallback(const base::Closure& callback);
// If enabled, the TGT renews automatically by scheduling RenewTgt()
// periodically on the |task_runner_| (usually the D-Bus thread). Renewal must
// happen within the the TGT's validity lifetime. The scheduling delay is a
// fraction of that lifetime.
void EnableTgtAutoRenewal(bool enabled);
// Renews a TGT. Must happen within its validity lifetime.
ErrorType RenewTgt() WARN_UNUSED_RESULT;
// Returns the lifetime of a TGT.
ErrorType GetTgtLifetime(protos::TgtLifetime* lifetime) WARN_UNUSED_RESULT;
// Use kpasswd to change the password for the current principal.
ErrorType ChangePassword(const std::string& old_password,
const std::string& new_password) WARN_UNUSED_RESULT;
// Returns the file path of the Kerberos configuration file.
Path GetConfigPath() const { return config_path_; }
// Returns the file path of the Kerberos credential cache.
Path GetCredentialCachePath() const { return credential_cache_path_; }
// Saves internal state to the given |state| blob. Fails if the TGT does not
// exist or cannot be read.
bool Backup(protos::TgtState* state);
// Restores internal state from the given |state| blob.
bool Restore(const protos::TgtState& state);
// Disable retry sleep for unit tests.
void DisableRetrySleepForTesting() {
kinit_retry_sleep_disabled_for_testing_ = true;
}
// Returns whether TGT auto renewal is active, see EnableTgtAutoRenewal().
bool IsTgtAutoRenewalEnabledForTesting() { return tgt_autorenewal_enabled_; }
private:
// Acquires a TGT for the current principal. If |password_fd| is not -1, uses
// the password in that file descriptor for authentication. If |keytab_path|
// is not Path::INVALID, uses the keytab for authentication. Should always
// pass one or the other. Must set principal, KDC IP and realm beforehand.
ErrorType AcquireTgt(int password_fd, Path keytab_path) WARN_UNUSED_RESULT;
// Writes the Kerberos configuration and runs |kinit_cmd|. If |password_fd| is
// not -1, the file descriptor is duplicated and set as input pipe.
ErrorType RunKinit(ProcessExecutor* kinit_cmd,
int password_fd) const WARN_UNUSED_RESULT;
// Writes the krb5 configuration file.
ErrorType WriteKrb5Conf() const WARN_UNUSED_RESULT;
// Turns on krb5 trace logging if |flags_->TraceKrb5()| is enabled.
void SetupKrb5Trace(ProcessExecutor* krb5_cmd) const;
// Logs the krb5 trace if |flags_->TraceKrb5()| is enabled.
void OutputKrb5Trace() const;
// Cancels |tgt_renewal_callback_|. If |tgt_autorenewal_enabled_| is true and
// the TGT is valid, schedules RenewTgt() with a delay of a fraction of the
// TGT's validity lifetime.
void UpdateTgtAutoRenewal();
// Callback scheduled to renew the TGT. Calls RenewTgt() internally and prints
// appropriate error messages.
void AutoRenewTgt();
// Runs |kerberos_files_changed_| if |kerberos_files_dirty_| is set.
void MaybeTriggerKerberosFilesChanged();
const PathService* const paths_ = nullptr; // File paths, not owned.
AuthPolicyMetrics* const metrics_ = nullptr; // UMA statistics, not owned.
const protos::DebugFlags* const flags_ = nullptr; // Debug flags, not owned.
const JailHelper* const jail_helper_ = nullptr; // Minijail, not owned.
Anonymizer* const anonymizer_ = nullptr; // Log anonymizer, not owned.
Delegate* delegate_ = nullptr; // Delegate to receive events, not owned.
const Path config_path_ = Path::INVALID;
const Path credential_cache_path_ = Path::INVALID;
base::Closure kerberos_files_changed_;
// Principal for which TGTs are acquired (user@REALM or machine$@REALM).
std::string principal_;
// Realm written to the Kerberos config.
std::string realm_;
// Key distribution center (KDC) IP address written to the Kerberos config. If
// fetching a TGT with prescribed KDC IP fails with an error code that
// indicates that the KDC could not be reached, |kdc_ip_| gets wiped and kinit
// is retried, which lets Samba query the KDC IP.
std::string kdc_ip_;
// Whether the TGT was acquired for a user or machine principal. Determines
// what error code is returned if the principal was bad.
bool is_machine_principal_ = false;
// Callback for automatic TGT renewal.
base::CancelableClosure tgt_renewal_callback_;
bool tgt_autorenewal_enabled_ = false;
// Whether to retry kinit in case an error indicates that the credentials
// haven't propagated yet.
bool kinit_retry_ = false;
// Disables sleeping when retrying kinit (to prevent slowdowns in tests).
bool kinit_retry_sleep_disabled_for_testing_ = false;
// Encryption types to use for kinit.
KerberosEncryptionTypes encryption_types_ = ENC_TYPES_STRONG;
// If true, the Kerberos files changed and |kerberos_files_changed_| needs to
// be called if it exists. Prevents that signals are fired too often, e.g. if
// both krb5cc and config change in the same call.
mutable bool kerberos_files_dirty_ = false;
};
} // namespace authpolicy
#endif // AUTHPOLICY_TGT_MANAGER_H_