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 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290
|
// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_ASH_NET_SYSTEM_PROXY_MANAGER_H_
#define CHROME_BROWSER_ASH_NET_SYSTEM_PROXY_MANAGER_H_
#include <memory>
#include <optional>
#include <string>
#include <vector>
#include "base/functional/callback_forward.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/scoped_observation.h"
#include "chrome/browser/extensions/api/settings_private/prefs_util.h"
#include "chromeos/ash/components/dbus/system_proxy/system_proxy_service.pb.h"
#include "chromeos/ash/components/network/network_state_handler_observer.h"
#include "content/public/browser/content_browser_client.h"
#include "net/base/auth.h"
#include "third_party/cros_system_api/dbus/service_constants.h"
namespace content {
class LoginDelegate;
} // namespace content
namespace system_proxy {
class SetAuthenticationDetailsResponse;
class ShutDownResponse;
} // namespace system_proxy
namespace views {
class Widget;
} // namespace views
class PrefRegistrySimple;
class PrefService;
class PrefChangeRegistrar;
class Profile;
namespace ash {
class NetworkStateHandler;
class RequestSystemProxyCredentialsView;
class SystemProxyNotification;
// Starts and stops the system-proxy service and handles the authentication
// requests coming from system-proxy. Authentication requests are resolved by
// requesting proxy credentials from the NetworkService or, if the
// NetworkService doesn't have credentials for the specified proxy, it will
// prompt a dialog asking the user for credentials.
// It also listens for the `WorkerActive` dbus signal sent by the System-proxy
// daemon and stores connection information regarding the active worker
// processes.
// TODO(acostinas, https://crbug.com/1145174): Move the logic that tracks
// managed network changes to another class.
class SystemProxyManager : public NetworkStateHandlerObserver {
public:
enum class SystemProxyState {
// System-proxy is not enabled by feature nor policy.
kDisabled = 0,
// System proxy is enabled via feature flag; only available to system
// services which explicitly opt to use system-proxy.
kEnabledForSystemServices,
// System proxy is enabled via policy for all system services and the
// PlayStore.
kEnabledForAll
};
explicit SystemProxyManager(PrefService* local_state);
SystemProxyManager(const SystemProxyManager&) = delete;
SystemProxyManager& operator=(const SystemProxyManager&) = delete;
~SystemProxyManager() override;
// Called by `ChromeBrowserMainPartsAsh` in order to bootstrap the
// SystemProxyManager instance after the required global data is
// available (local state, and CrosSettings).
static void Initialize(PrefService* local_state);
// Returns the instance of the SystemProxyManager singleton. May return
// nullptr during browser startup and shutdown. When calling Get(), either
// make sure that your code executes after browser startup and before shutdown
// or be careful to call Get() every time (instead of holding a pointer) and
// check for nullptr to handle cases where you might access
// SystemProxyManager during startup or shutdown.
static SystemProxyManager* Get();
// Called by `ChromeBrowserMainPartsAsh` in order to shutdown the
// SystemProxyManager instance before the required global data is destroyed
// (local state and CrosSettings).
static void Shutdown();
// If System-proxy is enabled, it returns the URL of the local proxy instance
// that authenticates system services, in PAC format, e.g.
// PROXY localhost:3128
// otherwise it returns an empty string.
std::string SystemServicesProxyPacString(
chromeos::SystemProxyOverride system_proxy_override) const;
void StartObservingPrimaryProfilePrefs(Profile* profile);
void StopObservingPrimaryProfilePrefs();
// If System-proxy is enabled, it will send a request via D-Bus to clear the
// user's proxy credentials cached by the local proxy workers. System-proxy
// requests proxy credentials from the browser by sending an
// |AuthenticationRequired| D-Bus signal.
void ClearUserCredentials();
// Enables/disables system-proxy and sets credentials to be used by ChromeOS
// system services when connecting to a remote web proxy via system-proxy. The
// credentials are only forwarded to system-proxy if the network proxy
// configuration is managed via policy. `auth_schemes` allows restricting the
// credentials to certain HTTP auth schemes.
void SetPolicySettings(bool system_proxy_enabled,
const std::string& system_services_username,
const std::string& system_services_password,
const std::vector<std::string>& auth_schemes);
void SetSystemProxyEnabledForTest(bool enabled);
void SetSystemServicesProxyUrlForTest(const std::string& local_proxy_url);
void SetSendAuthDetailsClosureForTest(base::RepeatingClosure closure);
RequestSystemProxyCredentialsView* GetActiveAuthDialogForTest();
void CloseAuthDialogForTest();
// Registers prefs stored in user profiles.
static void RegisterProfilePrefs(PrefRegistrySimple* registry);
// Indicates whether the credentials set via the device policy
// SystemProxySettings can be used for proxy authentication in Chrome. The
// following conditions must be true:
// - the current session must be Managed Guest Session (MGS) or Kiosk app;
// - the proxy is set via policy;
// - System-proxy is enabled and credentials are set via policy;
// - `first_auth_attempt` is true;
// - `auth_info.scheme` must be allowed by the SystemProxySettings policy.
bool CanUsePolicyCredentials(const net::AuthChallengeInfo& auth_info,
bool first_auth_attempt);
// Returns a login delegate that posts `auth_required_callback` with the
// credentials provided by the policy SystemProxySettings. Callers must verify
// that `CanUsePolicyCredentials` is true before calling this method.
std::unique_ptr<content::LoginDelegate> CreateLoginDelegate(
content::LoginDelegate::LoginAuthRequiredCallback auth_required_callback);
private:
// NetworkStateHandlerObserver implementation
void DefaultNetworkChanged(const NetworkState* network) override;
// Called when the proxy configurations may have changed either by updates to
// the kProxy policy or updates to the default network.
void OnProxyConfigChanged();
// Returns true if there's a policy configured proxy on the default network
// (via device or user ONC policy, user policy or force installed extension).
bool IsManagedProxyConfigured();
// Returns true if the `kProxy` preference set by an extension can be changed
// by the user.
bool IsProxyConfiguredByUserViaExtension();
void OnSetAuthenticationDetails(
const system_proxy::SetAuthenticationDetailsResponse& response);
void OnShutDownProcess(const system_proxy::ShutDownResponse& response);
void OnClearUserCredentials(
const system_proxy::ClearUserCredentialsResponse& response);
void OnKerberosEnabledChanged();
void OnKerberosAccountChanged();
void OnArcEnabledChanged();
// Sets the value of the pref |kSystemProxyUserTrafficHostAndPort|.
void SetUserTrafficProxyPref(const std::string& user_traffic_address);
bool IsArcEnabled() const;
// Returns true if system-proxy is enabled by policy or flag.
bool IsEnabled() const;
// Sends the authentication details for |protection_space| to System-proxy via
// D-Bus.
void SendUserAuthenticationCredentials(
const system_proxy::ProtectionSpace& protection_space,
const std::string& username,
const std::string& password);
// Sends policy set credentials to System-proxy via D-Bus. Credentials are
// sent only if `username` and `password` are different than
// `last_sent_username_` and `last_sent_password_` or if `force_send` is true.
void SendPolicyAuthenticationCredentials(const std::string& username,
const std::string& password,
bool force_send);
// Send the Kerberos enabled state and active principal name to System-proxy
// via D-Bus.
void SendKerberosAuthenticationDetails();
// Sends empty credentials for |protection_space| to System-proxy via D-Bus.
// This can mean that a user is not signed into Chrome OS or they didn't
// provide proxy authentication credentials. In this case, System-proxy will
// forward the authentication failure (HTTP 407 status code) to the Chrome OS
// client.
void SendEmptyCredentials(
const system_proxy::ProtectionSpace& protection_space);
// Sends a shut-down command to the system-proxy daemon. Since system-proxy is
// started via dbus activation, if the daemon is inactive, this command will
// start the daemon and tell it to exit.
// TODO(crbug.com/1055245,acostinas): Do not send shut-down command if
// System-proxy is inactive.
void SendShutDownRequest(system_proxy::TrafficOrigin traffic);
// This function is called when the |WorkerActive| dbus signal is received.
void OnWorkerActive(const system_proxy::WorkerActiveSignalDetails& details);
// Requests from the NetworkService the user credentials associated with the
// protection space specified in |details|. This function is called when the
// |AuthenticationRequired| dbus signal is received.
void OnAuthenticationRequired(
const system_proxy::AuthenticationRequiredDetails& details);
// Forwards the user credentials to System-proxy. |credentials| may be empty
// indicating the credentials for the specified |protection_space| are not
// available.
void LookupProxyAuthCredentialsCallback(
const system_proxy::ProtectionSpace& protection_space,
const std::optional<net::AuthCredentials>& credentials);
void ShowAuthenticationNotification(
const system_proxy::ProtectionSpace& protection_space,
bool show_error);
// Shows a dialog which prompts the user to introduce proxy authentication
// credentials for OS level traffic. If |show_error_label| is true, the
// dialog will show a label that indicates the previous attempt to
// authenticate has failed due to invalid credentials.
void ShowAuthenticationDialog(
const system_proxy::ProtectionSpace& protection_space,
bool show_error_label);
void OnDialogAccepted(const system_proxy::ProtectionSpace& protection_space);
void OnDialogCanceled(const system_proxy::ProtectionSpace& protection_space);
void OnDialogClosed(const system_proxy::ProtectionSpace& protection_space);
// Closes the authentication notification or dialog if shown.
void CloseAuthenticationUI();
SystemProxyState system_proxy_state_ = SystemProxyState::kDisabled;
// The authority URI in the format host:port of the local proxy worker for
// system services.
std::string system_services_address_;
std::string system_services_username_;
std::string system_services_password_;
// List of proxy authentication schemes for which the policy set credentials
// can be used.
std::vector<std::string> policy_credentials_auth_schemes_;
// The credentials which were last sent to System-proxy. They can differ from
// `system_services_username_` and `system_services_username_` if the proxy
// configuration is not managed; in this case `last_sent_username_` and
// `last_sent_password_` are both empty even if credentials were specified by
// policy.
std::string last_sent_username_;
std::string last_sent_password_;
// Local state prefs, not owned.
raw_ptr<PrefService> local_state_ = nullptr;
// Notification which informs the user that System-proxy requires credentials
// for authentication to the remote proxy.
std::unique_ptr<SystemProxyNotification> notification_handler_;
// Owned by |auth_widget_|.
raw_ptr<RequestSystemProxyCredentialsView> active_auth_dialog_ = nullptr;
// Owned by the UI code (NativeWidget).
raw_ptr<views::Widget> auth_widget_ = nullptr;
// Primary profile, not owned.
raw_ptr<Profile> primary_profile_ = nullptr;
std::unique_ptr<extensions::PrefsUtil> extension_prefs_util_;
// Observer for Kerberos-related prefs.
std::unique_ptr<PrefChangeRegistrar> local_state_pref_change_registrar_;
std::unique_ptr<PrefChangeRegistrar> profile_pref_change_registrar_;
base::ScopedObservation<NetworkStateHandler, NetworkStateHandlerObserver>
network_state_handler_observer_{this};
base::RepeatingClosure send_auth_details_closure_for_test_;
base::WeakPtrFactory<SystemProxyManager> weak_factory_{this};
};
} // namespace ash
#endif // CHROME_BROWSER_ASH_NET_SYSTEM_PROXY_MANAGER_H_
|