Skip to content

Commit 5bc1c3d

Browse files
committed
update to 10.13.1 (4845)
1 parent d494ea8 commit 5bc1c3d

File tree

580 files changed

+23061
-5923
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

580 files changed

+23061
-5923
lines changed

TMessagesProj/build.gradle

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,15 @@ dependencies {
3939
implementation 'com.google.android.gms:play-services-wearable:18.0.0'
4040
implementation 'com.google.android.gms:play-services-location:21.0.1'
4141
implementation 'com.google.android.gms:play-services-wallet:19.1.0'
42-
implementation 'com.google.android.gms:play-services-safetynet:18.0.1'
4342
implementation 'com.googlecode.mp4parser:isoparser:1.0.6'
4443
implementation 'com.stripe:stripe-android:2.0.2'
4544
implementation 'com.google.mlkit:language-id:16.1.1'
4645
implementation 'com.android.billingclient:billing:5.1.0'
4746
implementation 'com.google.code.gson:gson:2.10'
4847
implementation 'com.google.guava:guava:31.1-android'
48+
implementation 'com.airbnb.android:lottie:6.4.0'
49+
implementation 'com.google.android.play:integrity:1.3.0'
50+
implementation 'com.google.android.gms:play-services-safetynet:18.0.1'
4951

5052
implementation 'com.google.android.gms:play-services-mlkit-subject-segmentation:16.0.0-beta1'
5153
implementation 'com.google.android.gms:play-services-mlkit-image-labeling:16.0.8'

TMessagesProj/jni/TgNetWrapper.cpp

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@
66
#include "tgnet/MTProtoScheme.h"
77
#include "tgnet/ConnectionSocket.h"
88
#include "tgnet/FileLog.h"
9+
#include "tgnet/Handshake.h"
10+
#include <openssl/rand.h>
11+
#include <openssl/sha.h>
12+
#include <openssl/bn.h>
13+
#include <openssl/pem.h>
14+
#include <openssl/aes.h>
915

1016
JavaVM *java;
1117

@@ -31,6 +37,7 @@ jmethodID jclass_ConnectionsManager_onProxyError;
3137
jmethodID jclass_ConnectionsManager_getHostByName;
3238
jmethodID jclass_ConnectionsManager_getInitFlags;
3339
jmethodID jclass_ConnectionsManager_onPremiumFloodWait;
40+
jmethodID jclass_ConnectionsManager_onIntegrityCheckClassic;
3441

3542
bool check_utf8(const char *data, size_t len);
3643

@@ -133,6 +140,40 @@ void failNotRunningRequest(JNIEnv *env, jclass c, jint instanceNum, jint token)
133140
return ConnectionsManager::getInstance(instanceNum).failNotRunningRequest(token);
134141
}
135142

143+
void receivedIntegrityCheckClassic(JNIEnv *env, jclass c, jint instanceNum, jint requestToken, jstring nonce, jstring token) {
144+
const char* nonceStr = env->GetStringUTFChars(nonce, 0);
145+
const char* tokenStr = env->GetStringUTFChars(token, 0);
146+
std::string nonceString = nonceStr;
147+
std::string tokenString = tokenStr;
148+
ConnectionsManager::getInstance(instanceNum).receivedIntegrityCheckClassic(requestToken, nonceString, tokenString);
149+
if (nonceStr != nullptr) {
150+
env->ReleaseStringUTFChars(nonce, nonceStr);
151+
}
152+
if (tokenStr != nullptr) {
153+
env->ReleaseStringUTFChars(token, tokenStr);
154+
}
155+
}
156+
157+
jboolean isGoodPrime(JNIEnv *env, jclass c, jbyteArray prime, jint g) {
158+
jsize length = env->GetArrayLength(prime);
159+
jbyte *bytes = env->GetByteArrayElements(prime, NULL);
160+
if (bytes == NULL) {
161+
DEBUG_E("isGoodPrime: failed to get byte array");
162+
return false;
163+
}
164+
unsigned char *unsignedBytes = (unsigned char *)bytes;
165+
BIGNUM *bn = BN_bin2bn(unsignedBytes, length, NULL);
166+
if (bn == NULL) {
167+
env->ReleaseByteArrayElements(prime, bytes, 0);
168+
DEBUG_E("isGoodPrime: failed to convert byte array into BIGNUM");
169+
return false;
170+
}
171+
bool result = Handshake::isGoodPrime(bn, g);
172+
BN_free(bn);
173+
env->ReleaseByteArrayElements(prime, bytes, 0);
174+
return result;
175+
}
176+
136177
void cleanUp(JNIEnv *env, jclass c, jint instanceNum, jboolean resetKeys) {
137178
return ConnectionsManager::getInstance(instanceNum).cleanUp(resetKeys, -1);
138179
}
@@ -324,6 +365,13 @@ class Delegate : public ConnectiosManagerDelegate {
324365
void onPremiumFloodWait(int32_t instanceNum, int32_t requestToken, bool isUpload) {
325366
jniEnv[instanceNum]->CallStaticVoidMethod(jclass_ConnectionsManager, jclass_ConnectionsManager_onPremiumFloodWait, instanceNum, requestToken, isUpload);
326367
}
368+
369+
void onIntegrityCheckClassic(int32_t instanceNum, int32_t requestToken, std::string nonce) {
370+
jstring nonceStr = jniEnv[instanceNum]->NewStringUTF(nonce.c_str());
371+
jniEnv[instanceNum]->CallStaticVoidMethod(jclass_ConnectionsManager, jclass_ConnectionsManager_onIntegrityCheckClassic, instanceNum, requestToken, nonceStr);
372+
jniEnv[instanceNum]->DeleteLocalRef(nonceStr);
373+
}
374+
327375
};
328376

329377
void onHostNameResolved(JNIEnv *env, jclass c, jstring host, jlong address, jstring ip) {
@@ -465,6 +513,8 @@ static JNINativeMethod ConnectionsManagerMethods[] = {
465513
{"native_onHostNameResolved", "(Ljava/lang/String;JLjava/lang/String;)V", (void *) onHostNameResolved},
466514
{"native_discardConnection", "(III)V", (void *) discardConnection},
467515
{"native_failNotRunningRequest", "(II)V", (void *) failNotRunningRequest},
516+
{"native_receivedIntegrityCheckClassic", "(IILjava/lang/String;Ljava/lang/String;)V", (void *) receivedIntegrityCheckClassic},
517+
{"native_isGoodPrime", "([BI)Z", (void *) isGoodPrime},
468518
};
469519

470520
inline int registerNativeMethods(JNIEnv *env, const char *className, JNINativeMethod *methods, int methodsCount) {
@@ -577,6 +627,10 @@ extern "C" int registerNativeTgNetFunctions(JavaVM *vm, JNIEnv *env) {
577627
if (jclass_ConnectionsManager_onPremiumFloodWait == 0) {
578628
return JNI_FALSE;
579629
}
630+
jclass_ConnectionsManager_onIntegrityCheckClassic = env->GetStaticMethodID(jclass_ConnectionsManager, "onIntegrityCheckClassic", "(IILjava/lang/String;)V");
631+
if (jclass_ConnectionsManager_onIntegrityCheckClassic == 0) {
632+
return JNI_FALSE;
633+
}
580634

581635
return JNI_TRUE;
582636
}

TMessagesProj/jni/tgnet/ApiScheme.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -810,6 +810,9 @@ MessageEntity *MessageEntity::TLdeserialize(NativeByteBuffer *stream, uint32_t c
810810
result = new TL_messageEntityStrike();
811811
break;
812812
case 0x20df5d0:
813+
result = new TL_messageEntityBlockquote_layer180();
814+
break;
815+
case 0xf1ccaaac:
813816
result = new TL_messageEntityBlockquote();
814817
break;
815818
case 0x9c4e7e8b:
@@ -1001,11 +1004,24 @@ void TL_messageEntityStrike::serializeToStream(NativeByteBuffer *stream) {
10011004
}
10021005

10031006
void TL_messageEntityBlockquote::readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error) {
1007+
flags = stream->readInt32(&error);
1008+
offset = stream->readInt32(&error);
1009+
length = stream->readInt32(&error);
1010+
}
1011+
1012+
void TL_messageEntityBlockquote_layer180::readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error) {
10041013
offset = stream->readInt32(&error);
10051014
length = stream->readInt32(&error);
10061015
}
10071016

10081017
void TL_messageEntityBlockquote::serializeToStream(NativeByteBuffer *stream) {
1018+
stream->writeInt32(constructor);
1019+
stream->writeInt32(flags);
1020+
stream->writeInt32(offset);
1021+
stream->writeInt32(length);
1022+
}
1023+
1024+
void TL_messageEntityBlockquote_layer180::serializeToStream(NativeByteBuffer *stream) {
10091025
stream->writeInt32(constructor);
10101026
stream->writeInt32(offset);
10111027
stream->writeInt32(length);

TMessagesProj/jni/tgnet/ApiScheme.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -537,6 +537,7 @@ class TL_inputUserFromMessage : public InputUser {
537537
class MessageEntity : public TLObject {
538538

539539
public:
540+
int32_t flags;
540541
int32_t offset;
541542
int32_t length;
542543
std::string url;
@@ -685,6 +686,15 @@ class TL_messageEntityStrike : public MessageEntity {
685686

686687
class TL_messageEntityBlockquote : public MessageEntity {
687688

689+
public:
690+
static const uint32_t constructor = 0xf1ccaaac;
691+
692+
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
693+
void serializeToStream(NativeByteBuffer *stream);
694+
};
695+
696+
class TL_messageEntityBlockquote_layer180 : public MessageEntity {
697+
688698
public:
689699
static const uint32_t constructor = 0x20df5d0;
690700

TMessagesProj/jni/tgnet/Connection.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ void Connection::suspendConnection(bool idle) {
5757
connectionState = idle ? TcpConnectionStageIdle : TcpConnectionStageSuspended;
5858
dropConnection();
5959
ConnectionsManager::getInstance(currentDatacenter->instanceNum).onConnectionClosed(this, 0);
60+
generation++;
6061
firstPacketSent = false;
6162
if (restOfTheData != nullptr) {
6263
restOfTheData->reuse();
@@ -243,7 +244,11 @@ void Connection::onReceivedData(NativeByteBuffer *buffer) {
243244

244245
uint32_t old = buffer->limit();
245246
buffer->limit(buffer->position() + currentPacketLength);
247+
uint32_t current_generation = generation;
246248
ConnectionsManager::getInstance(currentDatacenter->instanceNum).onConnectionDataReceived(this, buffer, currentPacketLength);
249+
if (current_generation != generation) {
250+
break;
251+
}
247252
buffer->position(buffer->limit());
248253
buffer->limit(old);
249254

@@ -350,6 +355,7 @@ void Connection::connect() {
350355
reconnectTimer->stop();
351356

352357
if (LOGS_ENABLED) DEBUG_D("connection(%p, account%u, dc%u, type %d) connecting (%s:%hu)", this, currentDatacenter->instanceNum, currentDatacenter->getDatacenterId(), connectionType, hostAddress.c_str(), hostPort);
358+
generation++;
353359
firstPacketSent = false;
354360
if (restOfTheData != nullptr) {
355361
restOfTheData->reuse();
@@ -657,6 +663,7 @@ void Connection::onDisconnectedInternal(int32_t reason, int32_t error) {
657663
currentTimeout += 2;
658664
}
659665
}
666+
generation++;
660667
firstPacketSent = false;
661668
if (restOfTheData != nullptr) {
662669
restOfTheData->reuse();

TMessagesProj/jni/tgnet/Connection.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ class Connection : public ConnectionSession, public ConnectionSocket {
101101
int64_t usefullDataReceiveTime;
102102
uint32_t currentTimeout = 4;
103103
uint32_t receivedDataAmount = 0;
104+
uint32_t generation = 0;
104105

105106
uint8_t temp[64];
106107

TMessagesProj/jni/tgnet/ConnectionsManager.cpp

Lines changed: 51 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -891,8 +891,11 @@ void ConnectionsManager::onConnectionDataReceived(Connection *connection, Native
891891
TLObject *request;
892892
if (datacenter->isHandshaking(connection->isMediaConnection)) {
893893
request = datacenter->getCurrentHandshakeRequest(connection->isMediaConnection);
894+
if (request == nullptr) {
895+
return;
896+
}
894897
} else {
895-
request = getRequestWithMessageId(messageId);
898+
return;
896899
}
897900

898901
deserializingDatacenter = datacenter;
@@ -1287,6 +1290,7 @@ void ConnectionsManager::processServerResponse(TLObject *message, int64_t messag
12871290
static std::string authRestart = "AUTH_RESTART";
12881291
static std::string authKeyPermEmpty = "AUTH_KEY_PERM_EMPTY";
12891292
static std::string workerBusy = "WORKER_BUSY_TOO_LONG_RETRY";
1293+
static std::string integrityCheckClassic = "INTEGRITY_CHECK_CLASSIC_";
12901294
bool processEvenFailed = error->error_code == 500 && error->error_message.find(authRestart) != std::string::npos;
12911295
bool isWorkerBusy = error->error_code == 500 && error->error_message.find(workerBusy) != std::string::npos;
12921296
if (LOGS_ENABLED) DEBUG_E("request %p rpc error %d: %s", request, error->error_code, error->error_message.c_str());
@@ -1301,8 +1305,19 @@ void ConnectionsManager::processServerResponse(TLObject *message, int64_t messag
13011305
saveConfig();
13021306
datacenter->beginHandshake(connection->isMediaConnection ? HandshakeTypeMediaTemp : HandshakeTypeTemp, false);
13031307
}
1304-
} else if ((request->requestFlags & RequestFlagFailOnServerErrors) == 0 || processEvenFailed) {
1305-
if (error->error_code == 500 || error->error_code < 0) {
1308+
} else if (error->error_code == 403 && error->error_message.find(integrityCheckClassic) != std::string::npos) {
1309+
discardResponse = true;
1310+
std::string nonce = error->error_message.substr(integrityCheckClassic.size(), error->error_message.size() - integrityCheckClassic.size());
1311+
request->awaitingIntegrityCheck = true;
1312+
request->startTime = 0;
1313+
request->startTimeMillis = 0;
1314+
if (delegate != nullptr) {
1315+
delegate->onIntegrityCheckClassic(instanceNum, request->requestToken, nonce);
1316+
}
1317+
} else {
1318+
bool failServerErrors = (request->requestFlags & RequestFlagFailOnServerErrors) == 0 || processEvenFailed;
1319+
bool exceptFloodWait = (request->requestFlags & RequestFlagFailOnServerErrorsExceptFloodWait) != 0;
1320+
if (failServerErrors && (error->error_code == 500 || error->error_code < 0)) {
13061321
static std::string waitFailed = "MSG_WAIT_FAILED";
13071322
static std::string waitTimeout = "MSG_WAIT_TIMEOUT";
13081323
if (error->error_message.find(waitFailed) != std::string::npos) {
@@ -1318,13 +1333,14 @@ void ConnectionsManager::processServerResponse(TLObject *message, int64_t messag
13181333
request->serverFailureCount++;
13191334
}
13201335
discardResponse = true;
1321-
} else if (error->error_code == -504) {
1336+
} else if (failServerErrors && error->error_code == -504) {
13221337
discardResponse = (request->requestFlags & RequestFlagIgnoreFloodWait) == 0;
13231338
request->failedByFloodWait = 2;
13241339
request->startTime = 0;
13251340
request->startTimeMillis = 0;
13261341
request->minStartTime = (int32_t) (getCurrentTimeMonotonicMillis() / 1000 + 2);
13271342
} else if (
1343+
(failServerErrors || exceptFloodWait) &&
13281344
error->error_code == 420 && (request->requestFlags & RequestFlagIgnoreFloodWait) == 0 &&
13291345
error->error_message.find("STORY_SEND_FLOOD") == std::string::npos
13301346
) {
@@ -1363,7 +1379,7 @@ void ConnectionsManager::processServerResponse(TLObject *message, int64_t messag
13631379
if (isPremiumFloodWait && delegate != nullptr) {
13641380
delegate->onPremiumFloodWait(instanceNum, request->requestToken, (request->connectionType & ConnectionTypeUpload) != 0);
13651381
}
1366-
} else if (error->error_code == 400) {
1382+
} else if (failServerErrors && error->error_code == 400) {
13671383
static std::string waitFailed = "MSG_WAIT_FAILED";
13681384
static std::string bindFailed = "ENCRYPTED_MESSAGE_INVALID";
13691385
static std::string waitTimeout = "MSG_WAIT_TIMEOUT";
@@ -2154,6 +2170,32 @@ void ConnectionsManager::failNotRunningRequest(int32_t token) {
21542170
});
21552171
}
21562172

2173+
void ConnectionsManager::receivedIntegrityCheckClassic(int32_t requestToken, std::string nonce, std::string token) {
2174+
scheduleTask([&, requestToken, nonce, token] {
2175+
for (auto iter = runningRequests.begin(); iter != runningRequests.end(); iter++) {
2176+
Request *request = iter->get();
2177+
if (requestToken != 0 && request->requestToken == requestToken) {
2178+
auto invokeIntegrity = new invokeWithGooglePlayIntegrity();
2179+
invokeIntegrity->nonce = nonce;
2180+
invokeIntegrity->token = token;
2181+
invokeIntegrity->query = std::move(request->rpcRequest);
2182+
request->rpcRequest = std::unique_ptr<invokeWithGooglePlayIntegrity>(invokeIntegrity);
2183+
2184+
request->awaitingIntegrityCheck = false;
2185+
request->requestFlags &=~ RequestFlagFailOnServerErrors;
2186+
2187+
if (LOGS_ENABLED) DEBUG_D("account%d: received integrity token, wrapping %s", instanceNum, token.c_str());
2188+
2189+
processRequestQueue(request->connectionType, request->datacenterId);
2190+
2191+
return;
2192+
}
2193+
}
2194+
2195+
if (LOGS_ENABLED) DEBUG_E("account%d: received integrity token but no request %d found", instanceNum, requestToken);
2196+
});
2197+
}
2198+
21572199
void ConnectionsManager::onDatacenterHandshakeComplete(Datacenter *datacenter, HandshakeType type, int32_t timeDiff) {
21582200
saveConfig();
21592201
uint32_t datacenterId = datacenter->getDatacenterId();
@@ -2474,13 +2516,13 @@ void ConnectionsManager::processRequestQueue(uint32_t connectionTypes, uint32_t
24742516
forceThisRequest = false;
24752517
}
24762518

2477-
if (forceThisRequest || (
2519+
if ((forceThisRequest || (
24782520
abs(currentTime - request->startTime) > maxTimeout && (
24792521
currentTime >= request->minStartTime ||
24802522
(request->failedByFloodWait != 0 && (request->minStartTime - currentTime) > request->failedByFloodWait) ||
24812523
(request->failedByFloodWait == 0 && abs(currentTime - request->minStartTime) >= 60)
24822524
)
2483-
)) {
2525+
)) && !request->awaitingIntegrityCheck) {
24842526
if (!forceThisRequest && request->connectionToken > 0) {
24852527
if ((request->connectionType & ConnectionTypeGeneric || request->connectionType & ConnectionTypeTemp) && request->connectionToken == connection->getConnectionToken()) {
24862528
if (LOGS_ENABLED) DEBUG_D("request token is valid, not retrying %s (%p)", typeInfo.name(), request->rawRequest);
@@ -3519,12 +3561,9 @@ void ConnectionsManager::applyDnsConfig(NativeByteBuffer *buffer, std::string ph
35193561
if (LOGS_ENABLED) DEBUG_D("can't decrypt dns config");
35203562
} else {
35213563
delete config;
3522-
if (LOGS_ENABLED) DEBUG_D("dns config not valid due to date or expire");
3564+
if (LOGS_ENABLED) DEBUG_D("dns config not valid due to date or expire, current date = %d, config date = %d, config expired = %d", currentDate, config->date, config->expires);
35233565
}
3524-
if (requestingSecondAddress == 2) {
3525-
requestingSecondAddress = 3;
3526-
delegate->onRequestNewServerIpAndPort(requestingSecondAddress, instanceNum);
3527-
} else if (requestingSecondAddress == 1) {
3566+
if (requestingSecondAddress == 1) {
35283567
requestingSecondAddress = 2;
35293568
delegate->onRequestNewServerIpAndPort(requestingSecondAddress, instanceNum);
35303569
} else if (requestingSecondAddress == 0) {

TMessagesProj/jni/tgnet/ConnectionsManager.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ class ConnectionsManager {
8282

8383
void reconnect(int32_t datacentrId, int32_t connectionType);
8484
void failNotRunningRequest(int32_t token);
85+
void receivedIntegrityCheckClassic(int32_t requestToken, std::string nonce, std::string token);
8586

8687
private:
8788
static void *ThreadProc(void *data);

TMessagesProj/jni/tgnet/Datacenter.cpp

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -593,14 +593,26 @@ void Datacenter::serializeToStream(NativeByteBuffer *stream) {
593593
}
594594
stream->writeInt64(authKeyMediaTempId);
595595
stream->writeInt32(authorized ? 1 : 0);
596-
stream->writeInt32((int32_t) (size = serverSalts.size()));
597-
for (uint32_t a = 0; a < size; a++) {
596+
597+
size = 0;
598+
for (uint32_t a = 0; a < serverSalts.size(); a++) {
599+
if (serverSalts[a] != nullptr) size++;
600+
}
601+
stream->writeInt32((int32_t) size);
602+
for (uint32_t a = 0; a < serverSalts.size(); a++) {
603+
if (serverSalts[a] == nullptr) continue;
598604
stream->writeInt32(serverSalts[a]->valid_since);
599605
stream->writeInt32(serverSalts[a]->valid_until);
600606
stream->writeInt64(serverSalts[a]->salt);
601607
}
602-
stream->writeInt32((int32_t) (size = mediaServerSalts.size()));
603-
for (uint32_t a = 0; a < size; a++) {
608+
609+
size = 0;
610+
for (uint32_t a = 0; a < mediaServerSalts.size(); a++) {
611+
if (mediaServerSalts[a] != nullptr) size++;
612+
}
613+
stream->writeInt32((int32_t) size);
614+
for (uint32_t a = 0; a < mediaServerSalts.size(); a++) {
615+
if (mediaServerSalts[a] == nullptr) continue;
604616
stream->writeInt32(mediaServerSalts[a]->valid_since);
605617
stream->writeInt32(mediaServerSalts[a]->valid_until);
606618
stream->writeInt64(mediaServerSalts[a]->salt);

0 commit comments

Comments
 (0)