diff --git a/lib/include/chiaki/ctrl.h b/lib/include/chiaki/ctrl.h index 29021a1..a60fd02 100644 --- a/lib/include/chiaki/ctrl.h +++ b/lib/include/chiaki/ctrl.h @@ -34,6 +34,7 @@ typedef struct chiaki_ctrl_t int sock; uint8_t recv_buf[512]; size_t recv_buf_size; + uint64_t crypt_counter_remote; } ChiakiCtrl; CHIAKI_EXPORT ChiakiErrorCode chiaki_ctrl_start(ChiakiCtrl *ctrl, struct chiaki_session_t *session); diff --git a/lib/include/chiaki/log.h b/lib/include/chiaki/log.h index 04a7bcd..ed70a30 100644 --- a/lib/include/chiaki/log.h +++ b/lib/include/chiaki/log.h @@ -18,6 +18,9 @@ #ifndef CHIAKI_LOG_H #define CHIAKI_LOG_H +#include +#include + #ifdef __cplusplus extern "C" { #endif @@ -34,6 +37,7 @@ typedef struct chiaki_log_t } ChiakiLog; void chiaki_log(ChiakiLog *log, ChiakiLogLevel level, const char *fmt, ...); +void chiaki_log_hexdump(ChiakiLog *log, ChiakiLogLevel level, const uint8_t *buf, size_t buf_size); #define CHIAKI_LOGD(log, ...) do { chiaki_log((log), CHIAKI_LOG_DEBUG, __VA_ARGS__); } while(0); #define CHIAKI_LOGI(log, ...) do { chiaki_log((log), CHIAKI_LOG_INFO, __VA_ARGS__); } while(0); diff --git a/lib/include/chiaki/session.h b/lib/include/chiaki/session.h index 42c5e46..47980c5 100644 --- a/lib/include/chiaki/session.h +++ b/lib/include/chiaki/session.h @@ -33,6 +33,7 @@ extern "C" { #define CHIAKI_RP_DID_SIZE 32 +#define CHIAKI_SESSION_ID_SIZE_MAX 80 typedef struct chiaki_connect_info_t { @@ -93,6 +94,7 @@ typedef struct chiaki_session_t uint8_t nonce[CHIAKI_KEY_BYTES]; ChiakiRPCrypt rpcrypt; + char session_id[CHIAKI_SESSION_ID_SIZE_MAX]; ChiakiQuitReason quit_reason; diff --git a/lib/src/ctrl.c b/lib/src/ctrl.c index eb5a0e8..bb0b1f1 100644 --- a/lib/src/ctrl.c +++ b/lib/src/ctrl.c @@ -29,6 +29,10 @@ #define SESSION_CTRL_PORT 9295 +typedef enum ctrl_message_type_t { + CTRL_MESSAGE_TYPE_SESSION_ID = 0x33 +} CtrlMessageType; + static void *ctrl_thread_func(void *user); @@ -108,9 +112,67 @@ static void *ctrl_thread_func(void *user) } +static void ctrl_message_received_session_id(ChiakiCtrl *ctrl, uint8_t *payload, size_t payload_size); + static void ctrl_message_received(ChiakiCtrl *ctrl, uint16_t msg_type, uint8_t *payload, size_t payload_size) { - CHIAKI_LOGI(&ctrl->session->log, "Received Ctrl Message Type %#x\n", msg_type); + if(payload_size > 0) + { + ChiakiErrorCode err = chiaki_rpcrypt_decrypt(&ctrl->session->rpcrypt, ctrl->crypt_counter_remote++, payload, payload, payload_size); + if(err != CHIAKI_ERR_SUCCESS) + { + CHIAKI_LOGE(&ctrl->session->log, "Failed to decrypt payload for Ctrl Message type %#x\n", msg_type); + return; + } + } + + switch(msg_type) + { + case CTRL_MESSAGE_TYPE_SESSION_ID: + ctrl_message_received_session_id(ctrl, payload, payload_size); + break; + default: + CHIAKI_LOGW(&ctrl->session->log, "Received Ctrl Message with unknown type %#x\n", msg_type); + break; + } +} + + +static void ctrl_message_received_session_id(ChiakiCtrl *ctrl, uint8_t *payload, size_t payload_size) +{ + if(payload_size < 2 || (char)payload[0] != 'J') + { + CHIAKI_LOGE(&ctrl->session->log, "Invalid Session Id received\n"); + return; + } + + // skip the 'J' + payload++; + payload_size--; + + if(payload_size >= CHIAKI_SESSION_ID_SIZE_MAX - 1) + { + CHIAKI_LOGE(&ctrl->session->log, "Received Session Id is too long\n"); + return; + } + + for(uint8_t *cur=payload; cur= 'a' && c <= 'z') + continue; + if(c >= 'A' && c <= 'Z') + continue; + if(c >= '0' && c <= '9') + continue; + CHIAKI_LOGE(&ctrl->session->log, "Received Session Id contains invalid characters\n"); + return; + } + + memcpy(ctrl->session->session_id, payload, payload_size); + ctrl->session->session_id[payload_size] = '\0'; + + CHIAKI_LOGI(&ctrl->session->log, "Received valid Session Id: %s\n", ctrl->session->session_id); } @@ -146,6 +208,8 @@ static void parse_ctrl_response(CtrlResponse *response, ChiakiHttpResponse *http static ChiakiErrorCode ctrl_connect(ChiakiCtrl *ctrl) { + ctrl->crypt_counter_remote = 0; + ChiakiSession *session = ctrl->session; struct addrinfo *addr = session->connect_info.host_addrinfo_selected; struct sockaddr *sa = malloc(addr->ai_addrlen); @@ -274,7 +338,11 @@ static ChiakiErrorCode ctrl_connect(ChiakiCtrl *ctrl) if(response.server_type_valid) { - ChiakiErrorCode err2 = chiaki_rpcrypt_decrypt(&session->rpcrypt, 0, response.rp_server_type, response.rp_server_type, sizeof(response.rp_server_type)); + ChiakiErrorCode err2 = chiaki_rpcrypt_decrypt(&session->rpcrypt, + ctrl->crypt_counter_remote++, + response.rp_server_type, + response.rp_server_type, + sizeof(response.rp_server_type)); response.server_type_valid = err2 == CHIAKI_ERR_SUCCESS; } diff --git a/lib/src/log.c b/lib/src/log.c index 76216ff..a62b1ca 100644 --- a/lib/src/log.c +++ b/lib/src/log.c @@ -26,27 +26,90 @@ void chiaki_log(ChiakiLog *log, ChiakiLogLevel level, const char *fmt, ...) va_start(args, fmt); char c; + const char *color = NULL; switch(level) { case CHIAKI_LOG_DEBUG: c = 'D'; + color = "34"; break; case CHIAKI_LOG_INFO: c = 'I'; break; case CHIAKI_LOG_WARNING: c = 'W'; + color = "33"; break; case CHIAKI_LOG_ERROR: c = 'E'; + color = "31"; break; default: c = '?'; break; } + if(color) + printf("\033[38;5;%sm", color); printf("[%c] ", c); + if(color) + printf("\033[0m"); vprintf(fmt, args); va_end(args); +} + +#define HEXDUMP_WIDTH 0x10 + +static const char hex_char[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; + +void chiaki_log_hexdump(ChiakiLog *log, ChiakiLogLevel level, const uint8_t *buf, size_t buf_size) +{ + chiaki_log(log, level, "offset 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef\n"); + + size_t offset = 0; + + char hex_buf[HEXDUMP_WIDTH * 3 + 1]; + char ascii_buf[HEXDUMP_WIDTH + 1]; + for(size_t i=0; i 0) + { + for(size_t i=0; i> 4]; + hex_buf[i*3+1] = hex_char[b & 0xf]; + + if(b > 0x20 && b < 0x7f) + ascii_buf[i] = (char)b; + else + ascii_buf[i] = '.'; + } + else + { + hex_buf[i*3] = ' '; + hex_buf[i*3+1] = ' '; + ascii_buf[i] = ' '; + } + + hex_buf[i*3+2] = ' '; + } + + chiaki_log(log, level, "%6x %s%s\n", offset, hex_buf, ascii_buf); + + if(buf_size > HEXDUMP_WIDTH) + { + buf_size -= HEXDUMP_WIDTH; + buf += HEXDUMP_WIDTH; + offset += HEXDUMP_WIDTH; + } + else + break; + } } \ No newline at end of file