File: session_authz_authenticator.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (162 lines) | stat: -rw-r--r-- 6,681 bytes parent folder | download | duplicates (5)
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
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef REMOTING_PROTOCOL_SESSION_AUTHZ_AUTHENTICATOR_H_
#define REMOTING_PROTOCOL_SESSION_AUTHZ_AUTHENTICATOR_H_

#include <memory>
#include <optional>
#include <string>
#include <string_view>

#include "base/functional/callback.h"
#include "base/time/time.h"
#include "remoting/base/constants.h"
#include "remoting/base/http_status.h"
#include "remoting/base/session_authz_service_client.h"
#include "remoting/base/session_policies.h"
#include "remoting/proto/session_authz_service.h"
#include "remoting/protocol/authenticator.h"
#include "remoting/protocol/channel_authenticator.h"
#include "remoting/protocol/credentials_type.h"
#include "remoting/protocol/session_authz_reauthorizer.h"
#include "third_party/libjingle_xmpp/xmllite/xmlelement.h"

namespace remoting::protocol {

// Class that implements the host leg of the SessionAuthz mechanism. Note that
// this class only handles the initial authorization process. Inter-session
// reauthorization will be handled by a different class.
// See go/crd-sessionauthz-integration for internal details.
class SessionAuthzAuthenticator : public Authenticator {
 public:
  static constexpr jingle_xmpp::StaticQName kHostTokenTag = {
      remoting::kChromotingXmlNamespace, "host-token"};
  static constexpr jingle_xmpp::StaticQName kSessionTokenTag = {
      remoting::kChromotingXmlNamespace, "session-token"};

  SessionAuthzAuthenticator(
      CredentialsType credentials_type,
      std::unique_ptr<SessionAuthzServiceClient> service_client,
      const CreateBaseAuthenticatorCallback&
          create_base_authenticator_callback);
  ~SessionAuthzAuthenticator() override;

  SessionAuthzAuthenticator(const SessionAuthzAuthenticator&) = delete;
  SessionAuthzAuthenticator& operator=(const SessionAuthzAuthenticator&) =
      delete;

  // Start the authenticator. The authenticator won't be in the `MESSAGE_READY`
  // state until |resume_callback| is called.
  void Start(base::OnceClosure resume_callback);

  const SessionAuthzReauthorizer* reauthorizer() const {
    return reauthorizer_.get();
  }

  // The session ID generated by the SessionAuthz server. This is only set if
  // the GenerateHostToken API call has completed and succeeded. Otherwise, this
  // will be an empty string.
  const std::string& session_id() const { return session_id_; }

  // The host token returned by the SessionAuthz server. This is only set if
  // the GenerateHostToken API call has completed and succeeded. Otherwise, this
  // will be an empty string.
  const std::string& host_token() const { return host_token_; }

  // Authenticator implementation.
  CredentialsType credentials_type() const override;
  const Authenticator& implementing_authenticator() const override;
  State state() const override;
  bool started() const override;
  RejectionReason rejection_reason() const override;
  RejectionDetails rejection_details() const override;
  void ProcessMessage(const jingle_xmpp::XmlElement* message,
                      base::OnceClosure resume_callback) override;
  std::unique_ptr<jingle_xmpp::XmlElement> GetNextMessage() override;
  const std::string& GetAuthKey() const override;
  const SessionPolicies* GetSessionPolicies() const override;
  std::unique_ptr<ChannelAuthenticator> CreateChannelAuthenticator()
      const override;

  void SetReauthorizerForTesting(
      std::unique_ptr<SessionAuthzReauthorizer> reauthorizer);
  void SetSessionIdForTesting(std::string_view session_id);
  void SetHostTokenForTesting(std::string_view host_token);

 private:
  enum class SessionAuthzState {
    NOT_STARTED,

    // A request was made to call GenerateHostToken on SessionAuthz, and the
    // response is pending.
    GENERATING_HOST_TOKEN,

    // The response for GenerateHostToken has been received, and is ready to be
    // sent to the client.
    READY_TO_SEND_HOST_TOKEN,

    // Waiting for the client to send the session token.
    WAITING_FOR_SESSION_TOKEN,

    // A request was made to call VerifySessionToken on SessionAuthz, with the
    // session token sent by the client, and the response is pending.
    VERIFYING_SESSION_TOKEN,

    // The shared secret has been returned by the VerifySessionToken call. The
    // rest of the authentication process is now handed over to the underlying
    // authenticator.
    SHARED_SECRET_FETCHED,

    // An error has occurred when trying to fetch the shared secret. Note that
    // an error might occur in the underlying authenticator, in which case the
    // SessionAuthz state will be `SHARED_SECRET_FETCHED` and
    // `underlying_->state()` will be `REJECTED`.
    FAILED,
  };

  void GenerateHostToken(base::OnceClosure resume_callback);
  void OnHostTokenGenerated(
      base::OnceClosure resume_callback,
      const HttpStatus& status,
      std::unique_ptr<internal::GenerateHostTokenResponseStruct> response);
  void AddHostTokenElement(jingle_xmpp::XmlElement* message);
  void VerifySessionToken(const jingle_xmpp::XmlElement& message,
                          base::OnceClosure resume_callback);
  void OnVerifiedSessionToken(
      const jingle_xmpp::XmlElement& message,
      base::OnceClosure resume_callback,
      const HttpStatus& status,
      std::unique_ptr<internal::VerifySessionTokenResponseStruct> response);
  void HandleSessionAuthzError(const std::string_view& action_name,
                               const HttpStatus& status);
  void StartReauthorizerIfNecessary();
  void OnReauthorizationFailed(HttpStatus::Code error_code,
                               const Authenticator::RejectionDetails& details);

  CredentialsType credentials_type_;
  std::unique_ptr<SessionAuthzServiceClient> service_client_;
  CreateBaseAuthenticatorCallback create_base_authenticator_callback_;
  std::unique_ptr<Authenticator> underlying_;
  std::unique_ptr<internal::VerifySessionTokenResponseStruct>
      verify_token_response_;
  std::optional<SessionPolicies> session_policies_;
  std::unique_ptr<SessionAuthzReauthorizer> reauthorizer_;

  SessionAuthzState session_authz_state_ = SessionAuthzState::NOT_STARTED;

  // The rejection reason specific to fetching the shared secret from
  // SessionAuthz. If |session_authz_state_| is NOT `ERROR`, the actual
  // rejection reason is delegated to `underlying_->rejection_reason()`.
  RejectionReason session_authz_rejection_reason_;

  RejectionDetails rejection_details_;

  std::string session_id_;
  std::string host_token_;
};

}  // namespace remoting::protocol

#endif  // REMOTING_PROTOCOL_SESSION_AUTHZ_AUTHENTICATOR_H_