Fixed decoding fragmented packets. DOS build now working again.
This commit is contained in:
parent
9c0c7b712d
commit
8d5d5add73
7 changed files with 56 additions and 37 deletions
|
@ -27,6 +27,8 @@ SHARED = $$PWD/../shared
|
|||
|
||||
QMAKE_CFLAGS += -O0
|
||||
|
||||
DEFINES *= CLIENT
|
||||
|
||||
DOS_HEADERS = \
|
||||
src/thirdparty/serial/serial.h
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -26,6 +26,8 @@ CONFIG += \
|
|||
DESTDIR = $$OUT_PWD/bin
|
||||
SHARED = $$PWD/../shared
|
||||
|
||||
DEFINES *= SERVER
|
||||
|
||||
INCLUDEPATH += \
|
||||
/usr/include/mariadb \
|
||||
/usr/include/mariadb/mysql \
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Reference in a new issue