aboutsummaryrefslogtreecommitdiff
path: root/src/privet/security_manager.h
blob: 651089a80c5ea8a0857de3f8184e8053fee9e74a (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
// Copyright 2015 The Weave 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 LIBWEAVE_SRC_PRIVET_SECURITY_MANAGER_H_
#define LIBWEAVE_SRC_PRIVET_SECURITY_MANAGER_H_

#include <map>
#include <memory>
#include <set>
#include <string>
#include <vector>

#include <base/callback.h>
#include <base/gtest_prod_util.h>
#include <base/memory/weak_ptr.h>
#include <weave/error.h>

#include "src/config.h"
#include "src/privet/security_delegate.h"

namespace crypto {
class P224EncryptedKeyExchange;
}  // namespace crypto

namespace weave {

namespace provider {
class TaskRunner;
}

namespace privet {

class AuthManager;

class SecurityManager : public SecurityDelegate {
 public:
  using PairingStartListener =
      base::Callback<void(const std::string& session_id,
                          PairingType pairing_type,
                          const std::vector<uint8_t>& code)>;
  using PairingEndListener =
      base::Callback<void(const std::string& session_id)>;

  class KeyExchanger {
   public:
    virtual ~KeyExchanger() {}

    virtual const std::string& GetMessage() = 0;
    virtual bool ProcessMessage(const std::string& message,
                                ErrorPtr* error) = 0;
    virtual const std::string& GetKey() const = 0;
  };

  SecurityManager(const Config* config,
                  AuthManager* auth_manager,
                  // TODO(vitalybuka): Remove task_runner.
                  provider::TaskRunner* task_runner);
  ~SecurityManager() override;

  // SecurityDelegate methods
  bool CreateAccessToken(AuthType auth_type,
                         const std::string& auth_code,
                         AuthScope desired_scope,
                         std::string* access_token,
                         AuthScope* access_token_scope,
                         base::TimeDelta* access_token_ttl,
                         ErrorPtr* error) override;
  bool ParseAccessToken(const std::string& token,
                        UserInfo* user_info,
                        ErrorPtr* error) const override;
  std::set<PairingType> GetPairingTypes() const override;
  std::set<CryptoType> GetCryptoTypes() const override;
  std::set<AuthType> GetAuthTypes() const override;
  std::string ClaimRootClientAuthToken(ErrorPtr* error) override;
  bool ConfirmClientAuthToken(const std::string& token,
                              ErrorPtr* error) override;
  bool StartPairing(PairingType mode,
                    CryptoType crypto,
                    std::string* session_id,
                    std::string* device_commitment,
                    ErrorPtr* error) override;

  bool ConfirmPairing(const std::string& session_id,
                      const std::string& client_commitment,
                      std::string* fingerprint,
                      std::string* signature,
                      ErrorPtr* error) override;
  bool CancelPairing(const std::string& session_id, ErrorPtr* error) override;
  std::string CreateSessionId() override;

  void RegisterPairingListeners(const PairingStartListener& on_start,
                                const PairingEndListener& on_end);

 private:
  const Config::Settings& GetSettings() const;
  bool IsValidPairingCode(const std::vector<uint8_t>& auth_code) const;
  FRIEND_TEST_ALL_PREFIXES(SecurityManagerTest, ThrottlePairing);
  // Allows limited number of new sessions without successful authorization.
  bool CheckIfPairingAllowed(ErrorPtr* error);
  bool ClosePendingSession(const std::string& session_id);
  bool CloseConfirmedSession(const std::string& session_id);
  bool CreateAccessTokenImpl(AuthType auth_type,
                             const std::vector<uint8_t>& auth_code,
                             AuthScope desired_scope,
                             std::vector<uint8_t>* access_token,
                             AuthScope* access_token_scope,
                             base::TimeDelta* access_token_ttl,
                             ErrorPtr* error);
  bool CreateAccessTokenImpl(AuthType auth_type,
                             AuthScope desired_scope,
                             std::vector<uint8_t>* access_token,
                             AuthScope* access_token_scope,
                             base::TimeDelta* access_token_ttl);
  bool IsAnonymousAuthSupported() const;
  bool IsPairingAuthSupported() const;
  bool IsLocalAuthSupported() const;

  const Config* config_{nullptr};
  AuthManager* auth_manager_{nullptr};

  // TODO(vitalybuka): Session cleanup can be done without posting tasks.
  provider::TaskRunner* task_runner_{nullptr};
  std::map<std::string, std::unique_ptr<KeyExchanger>> pending_sessions_;
  std::map<std::string, std::unique_ptr<KeyExchanger>> confirmed_sessions_;
  mutable int pairing_attemts_{0};
  mutable base::Time block_pairing_until_;
  PairingStartListener on_start_;
  PairingEndListener on_end_;
  uint64_t last_user_id_{0};

  base::WeakPtrFactory<SecurityManager> weak_ptr_factory_{this};

  DISALLOW_COPY_AND_ASSIGN(SecurityManager);
};

}  // namespace privet
}  // namespace weave

#endif  // LIBWEAVE_SRC_PRIVET_SECURITY_MANAGER_H_