Skip to content

Commit

Permalink
update to 10.13.1 (4845)
Browse files Browse the repository at this point in the history
  • Loading branch information
dkaraush committed Jun 3, 2024
1 parent d494ea8 commit 5bc1c3d
Show file tree
Hide file tree
Showing 580 changed files with 23,061 additions and 5,923 deletions.
4 changes: 3 additions & 1 deletion TMessagesProj/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,15 @@ dependencies {
implementation 'com.google.android.gms:play-services-wearable:18.0.0'
implementation 'com.google.android.gms:play-services-location:21.0.1'
implementation 'com.google.android.gms:play-services-wallet:19.1.0'
implementation 'com.google.android.gms:play-services-safetynet:18.0.1'
implementation 'com.googlecode.mp4parser:isoparser:1.0.6'
implementation 'com.stripe:stripe-android:2.0.2'
implementation 'com.google.mlkit:language-id:16.1.1'
implementation 'com.android.billingclient:billing:5.1.0'
implementation 'com.google.code.gson:gson:2.10'
implementation 'com.google.guava:guava:31.1-android'
implementation 'com.airbnb.android:lottie:6.4.0'
implementation 'com.google.android.play:integrity:1.3.0'
implementation 'com.google.android.gms:play-services-safetynet:18.0.1'

implementation 'com.google.android.gms:play-services-mlkit-subject-segmentation:16.0.0-beta1'
implementation 'com.google.android.gms:play-services-mlkit-image-labeling:16.0.8'
Expand Down
54 changes: 54 additions & 0 deletions TMessagesProj/jni/TgNetWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@
#include "tgnet/MTProtoScheme.h"
#include "tgnet/ConnectionSocket.h"
#include "tgnet/FileLog.h"
#include "tgnet/Handshake.h"
#include <openssl/rand.h>
#include <openssl/sha.h>
#include <openssl/bn.h>
#include <openssl/pem.h>
#include <openssl/aes.h>

JavaVM *java;

Expand All @@ -31,6 +37,7 @@ jmethodID jclass_ConnectionsManager_onProxyError;
jmethodID jclass_ConnectionsManager_getHostByName;
jmethodID jclass_ConnectionsManager_getInitFlags;
jmethodID jclass_ConnectionsManager_onPremiumFloodWait;
jmethodID jclass_ConnectionsManager_onIntegrityCheckClassic;

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

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

void receivedIntegrityCheckClassic(JNIEnv *env, jclass c, jint instanceNum, jint requestToken, jstring nonce, jstring token) {
const char* nonceStr = env->GetStringUTFChars(nonce, 0);
const char* tokenStr = env->GetStringUTFChars(token, 0);
std::string nonceString = nonceStr;
std::string tokenString = tokenStr;
ConnectionsManager::getInstance(instanceNum).receivedIntegrityCheckClassic(requestToken, nonceString, tokenString);
if (nonceStr != nullptr) {
env->ReleaseStringUTFChars(nonce, nonceStr);
}
if (tokenStr != nullptr) {
env->ReleaseStringUTFChars(token, tokenStr);
}
}

jboolean isGoodPrime(JNIEnv *env, jclass c, jbyteArray prime, jint g) {
jsize length = env->GetArrayLength(prime);
jbyte *bytes = env->GetByteArrayElements(prime, NULL);
if (bytes == NULL) {
DEBUG_E("isGoodPrime: failed to get byte array");
return false;
}
unsigned char *unsignedBytes = (unsigned char *)bytes;
BIGNUM *bn = BN_bin2bn(unsignedBytes, length, NULL);
if (bn == NULL) {
env->ReleaseByteArrayElements(prime, bytes, 0);
DEBUG_E("isGoodPrime: failed to convert byte array into BIGNUM");
return false;
}
bool result = Handshake::isGoodPrime(bn, g);
BN_free(bn);
env->ReleaseByteArrayElements(prime, bytes, 0);
return result;
}

void cleanUp(JNIEnv *env, jclass c, jint instanceNum, jboolean resetKeys) {
return ConnectionsManager::getInstance(instanceNum).cleanUp(resetKeys, -1);
}
Expand Down Expand Up @@ -324,6 +365,13 @@ class Delegate : public ConnectiosManagerDelegate {
void onPremiumFloodWait(int32_t instanceNum, int32_t requestToken, bool isUpload) {
jniEnv[instanceNum]->CallStaticVoidMethod(jclass_ConnectionsManager, jclass_ConnectionsManager_onPremiumFloodWait, instanceNum, requestToken, isUpload);
}

void onIntegrityCheckClassic(int32_t instanceNum, int32_t requestToken, std::string nonce) {
jstring nonceStr = jniEnv[instanceNum]->NewStringUTF(nonce.c_str());
jniEnv[instanceNum]->CallStaticVoidMethod(jclass_ConnectionsManager, jclass_ConnectionsManager_onIntegrityCheckClassic, instanceNum, requestToken, nonceStr);
jniEnv[instanceNum]->DeleteLocalRef(nonceStr);
}

};

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

inline int registerNativeMethods(JNIEnv *env, const char *className, JNINativeMethod *methods, int methodsCount) {
Expand Down Expand Up @@ -577,6 +627,10 @@ extern "C" int registerNativeTgNetFunctions(JavaVM *vm, JNIEnv *env) {
if (jclass_ConnectionsManager_onPremiumFloodWait == 0) {
return JNI_FALSE;
}
jclass_ConnectionsManager_onIntegrityCheckClassic = env->GetStaticMethodID(jclass_ConnectionsManager, "onIntegrityCheckClassic", "(IILjava/lang/String;)V");
if (jclass_ConnectionsManager_onIntegrityCheckClassic == 0) {
return JNI_FALSE;
}

return JNI_TRUE;
}
Expand Down
16 changes: 16 additions & 0 deletions TMessagesProj/jni/tgnet/ApiScheme.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -810,6 +810,9 @@ MessageEntity *MessageEntity::TLdeserialize(NativeByteBuffer *stream, uint32_t c
result = new TL_messageEntityStrike();
break;
case 0x20df5d0:
result = new TL_messageEntityBlockquote_layer180();
break;
case 0xf1ccaaac:
result = new TL_messageEntityBlockquote();
break;
case 0x9c4e7e8b:
Expand Down Expand Up @@ -1001,11 +1004,24 @@ void TL_messageEntityStrike::serializeToStream(NativeByteBuffer *stream) {
}

void TL_messageEntityBlockquote::readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error) {
flags = stream->readInt32(&error);
offset = stream->readInt32(&error);
length = stream->readInt32(&error);
}

void TL_messageEntityBlockquote_layer180::readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error) {
offset = stream->readInt32(&error);
length = stream->readInt32(&error);
}

void TL_messageEntityBlockquote::serializeToStream(NativeByteBuffer *stream) {
stream->writeInt32(constructor);
stream->writeInt32(flags);
stream->writeInt32(offset);
stream->writeInt32(length);
}

void TL_messageEntityBlockquote_layer180::serializeToStream(NativeByteBuffer *stream) {
stream->writeInt32(constructor);
stream->writeInt32(offset);
stream->writeInt32(length);
Expand Down
10 changes: 10 additions & 0 deletions TMessagesProj/jni/tgnet/ApiScheme.h
Original file line number Diff line number Diff line change
Expand Up @@ -537,6 +537,7 @@ class TL_inputUserFromMessage : public InputUser {
class MessageEntity : public TLObject {

public:
int32_t flags;
int32_t offset;
int32_t length;
std::string url;
Expand Down Expand Up @@ -685,6 +686,15 @@ class TL_messageEntityStrike : public MessageEntity {

class TL_messageEntityBlockquote : public MessageEntity {

public:
static const uint32_t constructor = 0xf1ccaaac;

void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
void serializeToStream(NativeByteBuffer *stream);
};

class TL_messageEntityBlockquote_layer180 : public MessageEntity {

public:
static const uint32_t constructor = 0x20df5d0;

Expand Down
7 changes: 7 additions & 0 deletions TMessagesProj/jni/tgnet/Connection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ void Connection::suspendConnection(bool idle) {
connectionState = idle ? TcpConnectionStageIdle : TcpConnectionStageSuspended;
dropConnection();
ConnectionsManager::getInstance(currentDatacenter->instanceNum).onConnectionClosed(this, 0);
generation++;
firstPacketSent = false;
if (restOfTheData != nullptr) {
restOfTheData->reuse();
Expand Down Expand Up @@ -243,7 +244,11 @@ void Connection::onReceivedData(NativeByteBuffer *buffer) {

uint32_t old = buffer->limit();
buffer->limit(buffer->position() + currentPacketLength);
uint32_t current_generation = generation;
ConnectionsManager::getInstance(currentDatacenter->instanceNum).onConnectionDataReceived(this, buffer, currentPacketLength);
if (current_generation != generation) {
break;
}
buffer->position(buffer->limit());
buffer->limit(old);

Expand Down Expand Up @@ -350,6 +355,7 @@ void Connection::connect() {
reconnectTimer->stop();

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);
generation++;
firstPacketSent = false;
if (restOfTheData != nullptr) {
restOfTheData->reuse();
Expand Down Expand Up @@ -657,6 +663,7 @@ void Connection::onDisconnectedInternal(int32_t reason, int32_t error) {
currentTimeout += 2;
}
}
generation++;
firstPacketSent = false;
if (restOfTheData != nullptr) {
restOfTheData->reuse();
Expand Down
1 change: 1 addition & 0 deletions TMessagesProj/jni/tgnet/Connection.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ class Connection : public ConnectionSession, public ConnectionSocket {
int64_t usefullDataReceiveTime;
uint32_t currentTimeout = 4;
uint32_t receivedDataAmount = 0;
uint32_t generation = 0;

uint8_t temp[64];

Expand Down
63 changes: 51 additions & 12 deletions TMessagesProj/jni/tgnet/ConnectionsManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -891,8 +891,11 @@ void ConnectionsManager::onConnectionDataReceived(Connection *connection, Native
TLObject *request;
if (datacenter->isHandshaking(connection->isMediaConnection)) {
request = datacenter->getCurrentHandshakeRequest(connection->isMediaConnection);
if (request == nullptr) {
return;
}
} else {
request = getRequestWithMessageId(messageId);
return;
}

deserializingDatacenter = datacenter;
Expand Down Expand Up @@ -1287,6 +1290,7 @@ void ConnectionsManager::processServerResponse(TLObject *message, int64_t messag
static std::string authRestart = "AUTH_RESTART";
static std::string authKeyPermEmpty = "AUTH_KEY_PERM_EMPTY";
static std::string workerBusy = "WORKER_BUSY_TOO_LONG_RETRY";
static std::string integrityCheckClassic = "INTEGRITY_CHECK_CLASSIC_";
bool processEvenFailed = error->error_code == 500 && error->error_message.find(authRestart) != std::string::npos;
bool isWorkerBusy = error->error_code == 500 && error->error_message.find(workerBusy) != std::string::npos;
if (LOGS_ENABLED) DEBUG_E("request %p rpc error %d: %s", request, error->error_code, error->error_message.c_str());
Expand All @@ -1301,8 +1305,19 @@ void ConnectionsManager::processServerResponse(TLObject *message, int64_t messag
saveConfig();
datacenter->beginHandshake(connection->isMediaConnection ? HandshakeTypeMediaTemp : HandshakeTypeTemp, false);
}
} else if ((request->requestFlags & RequestFlagFailOnServerErrors) == 0 || processEvenFailed) {
if (error->error_code == 500 || error->error_code < 0) {
} else if (error->error_code == 403 && error->error_message.find(integrityCheckClassic) != std::string::npos) {
discardResponse = true;
std::string nonce = error->error_message.substr(integrityCheckClassic.size(), error->error_message.size() - integrityCheckClassic.size());
request->awaitingIntegrityCheck = true;
request->startTime = 0;
request->startTimeMillis = 0;
if (delegate != nullptr) {
delegate->onIntegrityCheckClassic(instanceNum, request->requestToken, nonce);
}
} else {
bool failServerErrors = (request->requestFlags & RequestFlagFailOnServerErrors) == 0 || processEvenFailed;
bool exceptFloodWait = (request->requestFlags & RequestFlagFailOnServerErrorsExceptFloodWait) != 0;
if (failServerErrors && (error->error_code == 500 || error->error_code < 0)) {
static std::string waitFailed = "MSG_WAIT_FAILED";
static std::string waitTimeout = "MSG_WAIT_TIMEOUT";
if (error->error_message.find(waitFailed) != std::string::npos) {
Expand All @@ -1318,13 +1333,14 @@ void ConnectionsManager::processServerResponse(TLObject *message, int64_t messag
request->serverFailureCount++;
}
discardResponse = true;
} else if (error->error_code == -504) {
} else if (failServerErrors && error->error_code == -504) {
discardResponse = (request->requestFlags & RequestFlagIgnoreFloodWait) == 0;
request->failedByFloodWait = 2;
request->startTime = 0;
request->startTimeMillis = 0;
request->minStartTime = (int32_t) (getCurrentTimeMonotonicMillis() / 1000 + 2);
} else if (
(failServerErrors || exceptFloodWait) &&
error->error_code == 420 && (request->requestFlags & RequestFlagIgnoreFloodWait) == 0 &&
error->error_message.find("STORY_SEND_FLOOD") == std::string::npos
) {
Expand Down Expand Up @@ -1363,7 +1379,7 @@ void ConnectionsManager::processServerResponse(TLObject *message, int64_t messag
if (isPremiumFloodWait && delegate != nullptr) {
delegate->onPremiumFloodWait(instanceNum, request->requestToken, (request->connectionType & ConnectionTypeUpload) != 0);
}
} else if (error->error_code == 400) {
} else if (failServerErrors && error->error_code == 400) {
static std::string waitFailed = "MSG_WAIT_FAILED";
static std::string bindFailed = "ENCRYPTED_MESSAGE_INVALID";
static std::string waitTimeout = "MSG_WAIT_TIMEOUT";
Expand Down Expand Up @@ -2154,6 +2170,32 @@ void ConnectionsManager::failNotRunningRequest(int32_t token) {
});
}

void ConnectionsManager::receivedIntegrityCheckClassic(int32_t requestToken, std::string nonce, std::string token) {
scheduleTask([&, requestToken, nonce, token] {
for (auto iter = runningRequests.begin(); iter != runningRequests.end(); iter++) {
Request *request = iter->get();
if (requestToken != 0 && request->requestToken == requestToken) {
auto invokeIntegrity = new invokeWithGooglePlayIntegrity();
invokeIntegrity->nonce = nonce;
invokeIntegrity->token = token;
invokeIntegrity->query = std::move(request->rpcRequest);
request->rpcRequest = std::unique_ptr<invokeWithGooglePlayIntegrity>(invokeIntegrity);

request->awaitingIntegrityCheck = false;
request->requestFlags &=~ RequestFlagFailOnServerErrors;

if (LOGS_ENABLED) DEBUG_D("account%d: received integrity token, wrapping %s", instanceNum, token.c_str());

processRequestQueue(request->connectionType, request->datacenterId);

return;
}
}

if (LOGS_ENABLED) DEBUG_E("account%d: received integrity token but no request %d found", instanceNum, requestToken);
});
}

void ConnectionsManager::onDatacenterHandshakeComplete(Datacenter *datacenter, HandshakeType type, int32_t timeDiff) {
saveConfig();
uint32_t datacenterId = datacenter->getDatacenterId();
Expand Down Expand Up @@ -2474,13 +2516,13 @@ void ConnectionsManager::processRequestQueue(uint32_t connectionTypes, uint32_t
forceThisRequest = false;
}

if (forceThisRequest || (
if ((forceThisRequest || (
abs(currentTime - request->startTime) > maxTimeout && (
currentTime >= request->minStartTime ||
(request->failedByFloodWait != 0 && (request->minStartTime - currentTime) > request->failedByFloodWait) ||
(request->failedByFloodWait == 0 && abs(currentTime - request->minStartTime) >= 60)
)
)) {
)) && !request->awaitingIntegrityCheck) {
if (!forceThisRequest && request->connectionToken > 0) {
if ((request->connectionType & ConnectionTypeGeneric || request->connectionType & ConnectionTypeTemp) && request->connectionToken == connection->getConnectionToken()) {
if (LOGS_ENABLED) DEBUG_D("request token is valid, not retrying %s (%p)", typeInfo.name(), request->rawRequest);
Expand Down Expand Up @@ -3519,12 +3561,9 @@ void ConnectionsManager::applyDnsConfig(NativeByteBuffer *buffer, std::string ph
if (LOGS_ENABLED) DEBUG_D("can't decrypt dns config");
} else {
delete config;
if (LOGS_ENABLED) DEBUG_D("dns config not valid due to date or expire");
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);
}
if (requestingSecondAddress == 2) {
requestingSecondAddress = 3;
delegate->onRequestNewServerIpAndPort(requestingSecondAddress, instanceNum);
} else if (requestingSecondAddress == 1) {
if (requestingSecondAddress == 1) {
requestingSecondAddress = 2;
delegate->onRequestNewServerIpAndPort(requestingSecondAddress, instanceNum);
} else if (requestingSecondAddress == 0) {
Expand Down
1 change: 1 addition & 0 deletions TMessagesProj/jni/tgnet/ConnectionsManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ class ConnectionsManager {

void reconnect(int32_t datacentrId, int32_t connectionType);
void failNotRunningRequest(int32_t token);
void receivedIntegrityCheckClassic(int32_t requestToken, std::string nonce, std::string token);

private:
static void *ThreadProc(void *data);
Expand Down
20 changes: 16 additions & 4 deletions TMessagesProj/jni/tgnet/Datacenter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -593,14 +593,26 @@ void Datacenter::serializeToStream(NativeByteBuffer *stream) {
}
stream->writeInt64(authKeyMediaTempId);
stream->writeInt32(authorized ? 1 : 0);
stream->writeInt32((int32_t) (size = serverSalts.size()));
for (uint32_t a = 0; a < size; a++) {

size = 0;
for (uint32_t a = 0; a < serverSalts.size(); a++) {
if (serverSalts[a] != nullptr) size++;
}
stream->writeInt32((int32_t) size);
for (uint32_t a = 0; a < serverSalts.size(); a++) {
if (serverSalts[a] == nullptr) continue;
stream->writeInt32(serverSalts[a]->valid_since);
stream->writeInt32(serverSalts[a]->valid_until);
stream->writeInt64(serverSalts[a]->salt);
}
stream->writeInt32((int32_t) (size = mediaServerSalts.size()));
for (uint32_t a = 0; a < size; a++) {

size = 0;
for (uint32_t a = 0; a < mediaServerSalts.size(); a++) {
if (mediaServerSalts[a] != nullptr) size++;
}
stream->writeInt32((int32_t) size);
for (uint32_t a = 0; a < mediaServerSalts.size(); a++) {
if (mediaServerSalts[a] == nullptr) continue;
stream->writeInt32(mediaServerSalts[a]->valid_since);
stream->writeInt32(mediaServerSalts[a]->valid_until);
stream->writeInt64(mediaServerSalts[a]->salt);
Expand Down
Loading

1 comment on commit 5bc1c3d

@diskree
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, but there were so many fixes in 10.13.3, could you update the source code so we get them? Or are you planning to do this with 10.14?

Please sign in to comment.