1 /*
2 This file is part of Telegram Desktop,
3 the official desktop application for the Telegram messaging service.
4 
5 For license and copyright information please follow this link:
6 https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
7 */
8 #include "mtproto/details/mtproto_bound_key_creator.h"
9 
10 #include "mtproto/details/mtproto_serialized_request.h"
11 
12 namespace MTP::details {
13 
BoundKeyCreator(DcKeyRequest request,Delegate delegate)14 BoundKeyCreator::BoundKeyCreator(DcKeyRequest request, Delegate delegate)
15 : _request(request)
16 , _delegate(std::move(delegate)) {
17 }
18 
start(DcId dcId,int16 protocolDcId,not_null<AbstractConnection * > connection,not_null<DcOptions * > dcOptions)19 void BoundKeyCreator::start(
20 		DcId dcId,
21 		int16 protocolDcId,
22 		not_null<AbstractConnection*> connection,
23 		not_null<DcOptions*> dcOptions) {
24 	Expects(!_creator.has_value());
25 
26 	auto delegate = DcKeyCreator::Delegate();
27 	delegate.done = _delegate.unboundReady;
28 	delegate.sentSome = _delegate.sentSome;
29 	delegate.receivedSome = _delegate.receivedSome;
30 
31 	_creator.emplace(
32 		dcId,
33 		protocolDcId,
34 		connection,
35 		dcOptions,
36 		std::move(delegate),
37 		_request);
38 }
39 
stop()40 void BoundKeyCreator::stop() {
41 	_creator = std::nullopt;
42 }
43 
bind(AuthKeyPtr && persistentKey)44 void BoundKeyCreator::bind(AuthKeyPtr &&persistentKey) {
45 	stop();
46 	_binder.emplace(std::move(persistentKey));
47 }
48 
restartBinder()49 void BoundKeyCreator::restartBinder() {
50 	if (_binder) {
51 		_binder.emplace(_binder->persistentKey());
52 	}
53 }
54 
readyToBind() const55 bool BoundKeyCreator::readyToBind() const {
56 	return _binder.has_value();
57 }
58 
prepareBindRequest(const AuthKeyPtr & temporaryKey,uint64 sessionId)59 SerializedRequest BoundKeyCreator::prepareBindRequest(
60 		const AuthKeyPtr &temporaryKey,
61 		uint64 sessionId) {
62 	Expects(_binder.has_value());
63 
64 	return _binder->prepareRequest(temporaryKey, sessionId);
65 }
66 
handleBindResponse(const mtpBuffer & response)67 DcKeyBindState BoundKeyCreator::handleBindResponse(
68 		const mtpBuffer &response) {
69 	Expects(_binder.has_value());
70 
71 	return _binder->handleResponse(response);
72 }
73 
bindPersistentKey() const74 AuthKeyPtr BoundKeyCreator::bindPersistentKey() const {
75 	Expects(_binder.has_value());
76 
77 	return _binder->persistentKey();
78 }
79 
IsDestroyedTemporaryKeyError(const mtpBuffer & buffer)80 bool IsDestroyedTemporaryKeyError(const mtpBuffer &buffer) {
81 	auto from = buffer.data();
82 	auto error = MTPRpcError();
83 	if (!error.read(from, from + buffer.size())) {
84 		return false;
85 	}
86 	return error.match([&](const MTPDrpc_error &data) {
87 		return (data.verror_code().v == 401)
88 			&& (data.verror_message().v == "AUTH_KEY_PERM_EMPTY");
89 	});
90 }
91 
92 } // namespace MTP::details
93