summaryrefslogtreecommitdiffstats
path: root/blimp/net/engine_authentication_handler.cc
blob: 753438e71cb037a5bd6cda2fb8a928f183248e60 (plain)
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
// Copyright 2015 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 "blimp/net/engine_authentication_handler.h"

#include <string>

#include "base/callback_helpers.h"
#include "base/logging.h"
#include "base/timer/timer.h"
#include "blimp/common/logging.h"
#include "blimp/common/proto/blimp_message.pb.h"
#include "blimp/net/blimp_connection.h"
#include "blimp/net/blimp_message_processor.h"
#include "blimp/net/blimp_transport.h"
#include "blimp/net/common.h"
#include "blimp/net/connection_error_observer.h"
#include "net/base/completion_callback.h"
#include "net/base/net_errors.h"

namespace blimp {

namespace {
// Expect Client to send the StartConnection within ten seconds of becoming
// connected.
const int kAuthTimeoutDurationInSeconds = 10;

// Authenticates one connection. It deletes itself when
//   * the connection is authenticated and passed to |connection_handler|.
//   * the connection gets into an error state.
//   * the auth message does not arrive within a reasonable time.
class Authenticator : public ConnectionErrorObserver,
                      public BlimpMessageProcessor {
 public:
  explicit Authenticator(scoped_ptr<BlimpConnection> connection,
                         base::WeakPtr<ConnectionHandler> connection_handler,
                         const std::string& client_token);
  ~Authenticator() override;

 private:
  // Processes authentication result and deletes |this|.
  void OnConnectionAuthenticated(bool authenticated);

  // Handles timeout waiting for auth message, and deletes |this|.
  void OnAuthenticationTimeout();

  // ConnectionErrorObserver implementation.
  void OnConnectionError(int error) override;

  // BlimpMessageProcessor implementation.
  void ProcessMessage(scoped_ptr<BlimpMessage> message,
                      const net::CompletionCallback& callback) override;

  // The connection to be authenticated.
  scoped_ptr<BlimpConnection> connection_;

  // Handler to pass successfully authenticated connections to.
  base::WeakPtr<ConnectionHandler> connection_handler_;

  // Used to authenticate incoming connection.
  const std::string client_token_;

  // A timer to fail authentication on timeout.
  base::OneShotTimer timeout_timer_;

  DISALLOW_COPY_AND_ASSIGN(Authenticator);
};

Authenticator::Authenticator(
    scoped_ptr<BlimpConnection> connection,
    base::WeakPtr<ConnectionHandler> connection_handler,
    const std::string& client_token)
    : connection_(std::move(connection)),
      connection_handler_(connection_handler),
      client_token_(client_token) {
  DVLOG(1) << "Authenticator object created.";

  // Observe for errors that might occur during the authentication phase.
  connection_->AddConnectionErrorObserver(this);
  connection_->SetIncomingMessageProcessor(this);
  timeout_timer_.Start(
      FROM_HERE, base::TimeDelta::FromSeconds(kAuthTimeoutDurationInSeconds),
      this, &Authenticator::OnAuthenticationTimeout);
}

Authenticator::~Authenticator() {}

void Authenticator::OnConnectionAuthenticated(bool authenticated) {
  DVLOG(1) << "OnConnectionAuthenticated result=" << authenticated;

  if (authenticated && connection_handler_) {
    // Authentication is successful. Stop observing connection errors.
    connection_->RemoveConnectionErrorObserver(this);
    connection_handler_->HandleConnection(std::move(connection_));
  }

  delete this;
}

void Authenticator::OnAuthenticationTimeout() {
  DVLOG(1) << "Connection authentication timeout";
  OnConnectionAuthenticated(false);
}

void Authenticator::OnConnectionError(int error) {
  DVLOG(1) << "Connection error before authenticated "
           << net::ErrorToString(error);
  OnConnectionAuthenticated(false);
}

void Authenticator::ProcessMessage(scoped_ptr<BlimpMessage> message,
                                   const net::CompletionCallback& callback) {
  if (message->type() == BlimpMessage::PROTOCOL_CONTROL &&
      message->protocol_control().type() ==
          ProtocolControlMessage::START_CONNECTION) {
    bool token_match =
        client_token_ ==
        message->protocol_control().start_connection().client_token();
    DVLOG(1) << "Authentication challenge received: "
             << message->protocol_control().start_connection().client_token()
             << ", and token "
             << (token_match ? " matches" : " does not match");
    OnConnectionAuthenticated(token_match);
  } else {
    DVLOG(1) << "Expected START_CONNECTION message, got " << *message
             << " instead.";
    OnConnectionAuthenticated(false);
  }

  callback.Run(net::OK);
}

}  // namespace

EngineAuthenticationHandler::EngineAuthenticationHandler(
    ConnectionHandler* connection_handler,
    const std::string& client_token)
    : connection_handler_weak_factory_(connection_handler),
      client_token_(client_token) {
  DCHECK(!client_token_.empty());
}

EngineAuthenticationHandler::~EngineAuthenticationHandler() {}

void EngineAuthenticationHandler::HandleConnection(
    scoped_ptr<BlimpConnection> connection) {
  // Authenticator manages its own lifetime.
  new Authenticator(std::move(connection),
                    connection_handler_weak_factory_.GetWeakPtr(),
                    client_token_);
}

}  // namespace blimp