Fixed decoding fragmented packets. DOS build now working again.

This commit is contained in:
Scott Duensing 2021-12-08 19:18:05 -06:00
parent 9c0c7b712d
commit 8d5d5add73
7 changed files with 56 additions and 37 deletions

View file

@ -27,6 +27,8 @@ SHARED = $$PWD/../shared
QMAKE_CFLAGS += -O0
DEFINES *= CLIENT
DOS_HEADERS = \
src/thirdparty/serial/serial.h

View file

@ -70,6 +70,7 @@ static void taskComDebugLoop(void *data) {
r = comOpen(__configData.serialCom - 1, 57600L, 8, 'n', 1, SER_HANDSHAKING_RTSCTS);
if (r != SER_SUCCESS) {
logWrite("Unable to open COM port! Please check settings.\n");
guiStop();
return;
}
// Send a CR to clear anything in the modem.
@ -83,10 +84,11 @@ static void taskComDebugLoop(void *data) {
snprintf(buffer, 1023, "%s%c", "AT+SOCK1", 13);
comWrite(__configData.serialCom - 1, buffer, strlen(buffer));
// Wait roughly a second for "OK".
r = comWaitWithTimeout(__configData.serialCom - 1, buffer, 1023, 4, "\rOK\r");
r = comWaitWithTimeout(__configData.serialCom - 1, buffer, 1023, 4, "OK");
if (r <= 0) {
comClose(__configData.serialCom - 1);
logWrite("Modem does not support ENET! Please check settings.\n");
guiStop();
return;
}
logWrite("Modem OK\n");
@ -103,6 +105,7 @@ static void taskComDebugLoop(void *data) {
if (r <= 0) {
comClose(__configData.serialCom - 1);
logWrite("Unable to connect to server! Please check settings or try later.\n");
guiStop();
return;
}
@ -125,7 +128,7 @@ static void taskComDebugLoop(void *data) {
packetEncode(__packetThreadData, &encoded, NULL, 0); // Must encode each packet - no reusing encoded data.
packetSend(__packetThreadData, &encoded);
// Wait for PONG.
while (1) {
while (!guiHasStopped()) {
r = comRead(__configData.serialCom - 1, buffer, 1);
if (r == 1) {
if (packetDecode(__packetThreadData, &decoded, buffer, 1)) {
@ -141,6 +144,9 @@ static void taskComDebugLoop(void *data) {
}
}
}
if (guiHasStopped()) return;
// Send LOGIN.
logWrite("Sending LOGIN\n");
PacketTypeLoginT loginData;
@ -174,7 +180,7 @@ static void taskComDebugLoop(void *data) {
static void taskGuiEventLoop(void *data) {
MouseT *mouse = NULL;
ImageT *pointer = NULL;
ColorT alpha;
ColorT alpha = { 0 };
(void)data;
@ -187,6 +193,7 @@ static void taskGuiEventLoop(void *data) {
if (keyHit()) {
guiKeyboardProcess(keyASCIIGet(), keyExtendedGet(), keyScanCodeGet(), keyShiftGet(), keyControlGet(), keyAltGet());
//logWrite("Key '%d' Extended '%d' Scancode '%d' Shift '%d' Control '%d' Alt '%d'\n", keyASCIIGet(), keyExtended(), keyScanCode(), keyShift(), keyControl(), keyAlt());
if (keyASCIIGet() == 27) guiStop();
}
guiMouseProcess(mouse);
guiComposite();

View file

@ -72,11 +72,12 @@ int comWaitWithTimeout(int com, char *buffer, int len, int quarterSeconds, char
// Out of buffer.
break;
}
} else {
taskYield();
}
if (__timerQuarterSecondTick) {
quarterTicks++;
}
taskYield();
}
if (count == (int)strlen(expecting)) {

View file

@ -26,6 +26,8 @@ CONFIG += \
DESTDIR = $$OUT_PWD/bin
SHARED = $$PWD/../shared
DEFINES *= SERVER
INCLUDEPATH += \
/usr/include/mariadb \
/usr/include/mariadb/mysql \

View file

@ -104,6 +104,14 @@ void clientQueuePacket(ClientThreadT *client, uint8_t *data, uint32_t length) {
packet->length = length;
}
//consoleMessageQueue("%ld: Channel %d Bytes in %d\n", client->threadIndex, length);
/*
logWrite("Bytes %d\n\r", length);
for (size_t x=0; x<length; x++) {
logWrite("[%x] '%c'\n\r", data[x], data[x]);
}
*/
pthread_mutex_lock(&client->packetQueueMutex);
arrput(client->packetQueue, packet);
pthread_mutex_unlock(&client->packetQueueMutex);

View file

@ -63,7 +63,7 @@ static uint8_t packetCRC(char *data, uint16_t length, uint8_t startAt) {
}
uint8_t packetDecode(PacketThreadDataT *threadData, PacketDecodeDataT *data, char *input, uint16_t length) {
uint8_t packetDecode(PacketThreadDataT *threadData, PacketDecodeDataT *decodeData, char *input, uint16_t inputLength) {
uint8_t sequence = 0;
uint16_t unpadded = 0;
int32_t x = 0;
@ -74,12 +74,10 @@ uint8_t packetDecode(PacketThreadDataT *threadData, PacketDecodeDataT *data, cha
// Returns 1 on packet ready, 0 on still waiting.
// Is there input data to add to the queue?
if (input != NULL && length > 0) {
for (x=0; x<length; x++) {
if (input != NULL && inputLength > 0) {
for (x=0; x<inputLength; x++) {
threadData->decodeQueue[threadData->decodeQueueHead++] = input[x];
if (threadData->decodeQueueHead >= PACKET_INPUT_QUEUE_SIZE) {
threadData->decodeQueueHead = 0;
}
if (threadData->decodeQueueHead >= PACKET_INPUT_QUEUE_SIZE) threadData->decodeQueueHead = 0;
}
}
@ -89,15 +87,13 @@ uint8_t packetDecode(PacketThreadDataT *threadData, PacketDecodeDataT *data, cha
// Get next byte.
c = threadData->decodeQueue[threadData->decodeQueueTail++];
if (threadData->decodeQueueTail >= PACKET_INPUT_QUEUE_SIZE) {
threadData->decodeQueueTail = 0;
}
if (threadData->decodeQueueTail >= PACKET_INPUT_QUEUE_SIZE) threadData->decodeQueueTail = 0;
// New packet?
if (threadData->newPacket) {
threadData->newPacket = 0;
threadData->inEscape = 0;
data->length = 0;
threadData->length = 0;
}
// Are we escaped?
@ -108,7 +104,7 @@ uint8_t packetDecode(PacketThreadDataT *threadData, PacketDecodeDataT *data, cha
threadData->newPacket = 1;
// Check CRC.
if ((uint8_t)threadData->decodeBuffer[data->length - 1] != packetCRC(threadData->decodeBuffer, data->length - 1, 0)) continue;
if ((uint8_t)threadData->decodeBuffer[threadData->length - 1] != packetCRC(threadData->decodeBuffer, threadData->length - 1, 0)) continue;
// Get sequence value.
sequence = ((uint8_t)threadData->decodeBuffer[0]) & 0x1f;
@ -156,36 +152,38 @@ uint8_t packetDecode(PacketThreadDataT *threadData, PacketDecodeDataT *data, cha
}
// Fill decoded data fields.
data->packetType = threadData->decodeBuffer[1];
data->channel = threadData->decodeBuffer[2];
decodeData->packetType = threadData->decodeBuffer[1];
decodeData->channel = threadData->decodeBuffer[2];
// AES Decryption.
if (threadData->decodeBuffer[0] & 32) {
AES_ctx_set_iv(threadData->aesContext, (uint8_t *)threadData->dhModulus);
AES_CBC_decrypt_buffer(threadData->aesContext, (uint8_t *)&threadData->decodeBuffer[3], data->length - 4);
unpadded = pkcs7_padding_data_length((uint8_t *)&threadData->decodeBuffer[3], data->length - 4, 16);
AES_CBC_decrypt_buffer(threadData->aesContext, (uint8_t *)&threadData->decodeBuffer[3], threadData->length - 4);
unpadded = pkcs7_padding_data_length((uint8_t *)&threadData->decodeBuffer[3], threadData->length - 4, 16);
// Fix length.
data->length = unpadded + 4;
threadData->length = unpadded + 4;
}
// Copy packet data to new buffer, if any.
if (data->length - 4 > 0) {
data->data = (char *)malloc(data->length - 4); // 4 for 3 byte header and 1 byte CRC.
if (!data) continue;
memcpy(data->data, &threadData->decodeBuffer[3], data->length - 4); // Skip header and CRC.
if (threadData->length - 4 > 0) {
decodeData->data = (char *)malloc(threadData->length - 4); // 4 for 3 byte header and 1 byte CRC.
if (!decodeData) continue;
memcpy(decodeData->data, &threadData->decodeBuffer[3], threadData->length - 4); // Skip header and CRC.
decodeData->length = threadData->length - 4;
} else {
// No payload.
data->data = NULL;
decodeData->data = NULL;
decodeData->length = 0;
}
// Fix length to remove header and checksum.
data->length -= 4;
threadData->length -= 4;
// Is this a DH_REQUEST?
if (data->packetType == PACKET_TYPE_DH_REQUEST) {
memcpy(threadData->dhModulus, data->data, PACKET_ENCRYPT_KEY_SIZE * sizeof(uint16_t));
memcpy(threadData->dhBase, &data->data[PACKET_ENCRYPT_KEY_SIZE * 2], PACKET_ENCRYPT_KEY_SIZE * sizeof(uint16_t));
memcpy(threadData->dhTheirPublic, &data->data[PACKET_ENCRYPT_KEY_SIZE * 4], PACKET_ENCRYPT_KEY_SIZE * sizeof(uint16_t));
DEL(data->data);
if (decodeData->packetType == PACKET_TYPE_DH_REQUEST) {
memcpy(threadData->dhModulus, decodeData->data, PACKET_ENCRYPT_KEY_SIZE * sizeof(uint16_t));
memcpy(threadData->dhBase, &decodeData->data[PACKET_ENCRYPT_KEY_SIZE * 2], PACKET_ENCRYPT_KEY_SIZE * sizeof(uint16_t));
memcpy(threadData->dhTheirPublic, &decodeData->data[PACKET_ENCRYPT_KEY_SIZE * 4], PACKET_ENCRYPT_KEY_SIZE * sizeof(uint16_t));
DEL(decodeData->data);
for (x=0; x<PACKET_ENCRYPT_KEY_SIZE; x++) {
threadData->dhMySecret[x] = rand();
threadData->dhMyPublic[x] = packetDHCompute(threadData->dhBase[x], threadData->dhMySecret[x], threadData->dhModulus[x]);
@ -202,9 +200,9 @@ uint8_t packetDecode(PacketThreadDataT *threadData, PacketDecodeDataT *data, cha
}
// Is this a DH_RESPONSE?
if (data->packetType == PACKET_TYPE_DH_RESPONSE) {
memcpy(threadData->dhTheirPublic, data->data, PACKET_ENCRYPT_KEY_SIZE * sizeof(uint16_t));
DEL(data->data);
if (decodeData->packetType == PACKET_TYPE_DH_RESPONSE) {
memcpy(threadData->dhTheirPublic, decodeData->data, PACKET_ENCRYPT_KEY_SIZE * sizeof(uint16_t));
DEL(decodeData->data);
for (x=0; x<PACKET_ENCRYPT_KEY_SIZE; x++) {
threadData->dhSharedKey[x] = packetDHCompute(threadData->dhTheirPublic[x], threadData->dhMySecret[x], threadData->dhModulus[x]);
}
@ -223,13 +221,13 @@ uint8_t packetDecode(PacketThreadDataT *threadData, PacketDecodeDataT *data, cha
continue;
}
// Did we overflow?
if (data->length >= PACKET_MAX) {
if (threadData->length >= PACKET_MAX) {
// Yup. Dump it.
threadData->newPacket = 1;
continue;
}
// Add byte to packet.
threadData->decodeBuffer[data->length++] = c;
threadData->decodeBuffer[threadData->length++] = c;
}
}

View file

@ -101,6 +101,7 @@ typedef struct PacketThreadDataS {
uint16_t decodeQueueTail;
uint8_t inEscape;
uint8_t newPacket;
uint16_t length;
void *senderData;
uint16_t dhModulus[PACKET_ENCRYPT_KEY_SIZE];
uint16_t dhBase[PACKET_ENCRYPT_KEY_SIZE];
@ -116,7 +117,7 @@ typedef struct PacketThreadDataS {
typedef void (*packetSender)(char *data, uint32_t length, void *userData);
uint8_t packetDecode(PacketThreadDataT *threadData, PacketDecodeDataT *data, char *input, uint16_t length);
uint8_t packetDecode(PacketThreadDataT *threadData, PacketDecodeDataT *decodeData, char *input, uint16_t inputLength);
void packetDecodeDataDestroy(PacketDecodeDataT **packet);
uint8_t packetEncode(PacketThreadDataT *threadData, PacketEncodeDataT *data, char *input, uint16_t length);
void packetEncryptionSetup(PacketThreadDataT *threadData);