1 
2 /**
3  *    Copyright (C) 2018-present MongoDB, Inc.
4  *
5  *    This program is free software: you can redistribute it and/or modify
6  *    it under the terms of the Server Side Public License, version 1,
7  *    as published by MongoDB, Inc.
8  *
9  *    This program is distributed in the hope that it will be useful,
10  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *    Server Side Public License for more details.
13  *
14  *    You should have received a copy of the Server Side Public License
15  *    along with this program. If not, see
16  *    <http://www.mongodb.com/licensing/server-side-public-license>.
17  *
18  *    As a special exception, the copyright holders give permission to link the
19  *    code of portions of this program with the OpenSSL library under certain
20  *    conditions as described in each individual source file and distribute
21  *    linked combinations including the program with the OpenSSL library. You
22  *    must comply with the Server Side Public License in all respects for
23  *    all of the code used other than as permitted herein. If you modify file(s)
24  *    with this exception, you may extend this exception to your version of the
25  *    file(s), but you are not obligated to do so. If you do not wish to do so,
26  *    delete this exception statement from your version. If you delete this
27  *    exception statement from all source files in the program, then also delete
28  *    it in the license file.
29  */
30 
31 #pragma once
32 
33 #include <memory>
34 
35 #include "mongo/db/signed_logical_time.h"
36 #include "mongo/db/time_proof_service.h"
37 #include "mongo/stdx/mutex.h"
38 
39 namespace mongo {
40 
41 class OperationContext;
42 class ServiceContext;
43 class KeysCollectionDocument;
44 class KeysCollectionManagerSharding;
45 
46 /**
47  * This is responsible for signing cluster times that can be used to sent to other servers and
48  * verifying signatures of signed cluster times.
49  */
50 class LogicalTimeValidator {
51 public:
52     // Decorate ServiceContext with LogicalTimeValidator instance.
53     static LogicalTimeValidator* get(ServiceContext* service);
54     static LogicalTimeValidator* get(OperationContext* ctx);
55     static void set(ServiceContext* service, std::unique_ptr<LogicalTimeValidator> validator);
56 
57     /**
58      * Constructs a new LogicalTimeValidator that uses the given key manager. The passed-in
59      * key manager must outlive this object.
60      */
61     explicit LogicalTimeValidator(std::shared_ptr<KeysCollectionManagerSharding> keyManager);
62 
63     /**
64      * Tries to sign the newTime with a valid signature. Can return an empty signature and keyId
65      * of 0 if it cannot find valid key for newTime.
66      */
67     SignedLogicalTime trySignLogicalTime(const LogicalTime& newTime);
68 
69     /**
70      * Returns the newTime with a valid signature.
71      */
72     SignedLogicalTime signLogicalTime(OperationContext* opCtx, const LogicalTime& newTime);
73 
74     /**
75      * Returns true if the signature of newTime is valid.
76      */
77     Status validate(OperationContext* opCtx, const SignedLogicalTime& newTime);
78 
79     /**
80      * Initializes this validator. This should be called first before the other methods can be used.
81      */
82     void init(ServiceContext* service);
83 
84     /**
85      * Cleans up this validator. This will no longer be usable after this is called.
86      */
87     void shutDown();
88 
89     /**
90      * Enable writing new keys.
91      */
92     void enableKeyGenerator(OperationContext* opCtx, bool doEnable);
93 
94     /**
95      * Returns true if client has sufficient privilege to advance clock.
96      */
97     static bool isAuthorizedToAdvanceClock(OperationContext* opCtx);
98 
99     /**
100      * Returns true if the server should gossip, sign, and validate cluster times. False until there
101      * are keys in the config server.
102      */
103     bool shouldGossipLogicalTime();
104 
105     /**
106      * Makes the KeysCollectionManager refresh synchronously.
107      */
108     void forceKeyRefreshNow(OperationContext* opCtx);
109 
110     /**
111      * Stops the key manager and resets its state to prevent the former members of standalone
112      * replica set to use old keys with sharded cluster.
113      */
114     void stopKeyManager();
115 
116     /**
117      * Reset the key manager cache of keys.
118      */
119     void resetKeyManagerCache();
120 
121 private:
122     /**
123      *  Returns the copy of the _keyManager to work when its reset by resetKeyManager call.
124      */
125     std::shared_ptr<KeysCollectionManagerSharding> _getKeyManagerCopy();
126 
127 
128     SignedLogicalTime _getProof(const KeysCollectionDocument& keyDoc, LogicalTime newTime);
129 
130     stdx::mutex _mutex;            // protects _lastSeenValidTime
131     stdx::mutex _mutexKeyManager;  // protects _keyManager
132     SignedLogicalTime _lastSeenValidTime;
133     TimeProofService _timeProofService;
134     std::shared_ptr<KeysCollectionManagerSharding> _keyManager;
135 };
136 
137 }  // namespace mongo
138