From 9d2b9ee61d56b6ce9fe0f5b01a7cb62896f6e515 Mon Sep 17 00:00:00 2001 From: Wilco Baan Hofman Date: Mon, 28 Nov 2016 10:12:19 +0100 Subject: [PATCH] Add more Chiron protocol information. Handshake works, though it's hardcoded in proving-correct mode for now. --- chiron.idl | 59 +++++++--- chirond.c | 332 +++++++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 311 insertions(+), 80 deletions(-) diff --git a/chiron.idl b/chiron.idl index 72b288c..0148b44 100644 --- a/chiron.idl +++ b/chiron.idl @@ -8,34 +8,31 @@ interface chiron CHIRON_ACCOUNT = 0x41, /* 'A' */ CHIRON_CHALLENGE = 0x43, /* 'C' */ CHIRON_RESPONSE = 0x52, /* 'R' */ - CHIRON_KEY = 0x4B, /* 'K' */ + CHIRON_HANDSHAKE = 0x4B, /* 'K' */ CHIRON_ACK = 0x55, /* 'U' */ - CHIRON_HANDSHAKE = 0x48, /* 'H' */ + CHIRON_UNKNOWN = 0x48, /* 'H' */ CHIRON_TRANSPARENT = 0x54 /* 'T' */ } chiron_msg_type; typedef [public,enum8bit] enum { CHIRON_EL_DEVSTATE = 0x0C, - CHIRON_EL_DEVICEID = 0x17, - CHIRON_EL_UNKNOWN2 = 0x20, - CHIRON_EL_UNKNOWN3 = 0x21 + CHIRON_EL_UNKNOWN_BOOL1 = 0x16, + CHIRON_EL_DEVICEID1 = 0x17, + CHIRON_EL_DEVICEID2 = 0x18, + CHIRON_EL_MODE_ENABLED = 0x20, /* == 0x13 */ + CHIRON_EL_GSM_SETTING_G6 = 0x21, + CHIRON_EL_UNKNOWN_BOOL2 = 0x22, + CHIRON_EL_THREEBYTE_STATUS = 0x26, + CHIRON_EL_GSM_SETTING_G3_G19 = 0x27, + CHIRON_EL_UNKNOWN_BYTE1 = 0x2C, + CHIRON_EL_TROUBLE_MESSAGE1 = 0x2D, + CHIRON_EL_TROUBLE_MESSAGE2 = 0x36, + CHIRON_EL_GSM_SETTING_G4 = 0x40 } chiron_element_tag; - typedef [public,flag(LIBNDR_FLAG_NOALIGN)] struct { - chiron_element_tag el_tag; - uint8 opt_len; - uint8 payload[opt_len]; - } chiron_response_element; - - typedef [public,flag(LIBNDR_FLAG_NOALIGN)] struct { - uint8 mac_octets[3]; - // FIXME: TLVs can't be represented in pidl, move to ASN.1 parsing - // chiron_response_element elements[*]; - } chiron_msg_inner_response; - typedef [public,flag(LIBNDR_FLAG_NOALIGN)] struct { uint8 length; - uint8 account_code[4]; + uint8 account_code[length]; } chiron_msg_account; typedef [public,flag(LIBNDR_FLAG_NOALIGN)] struct { @@ -50,6 +47,16 @@ interface chiron uint8 payload[length - MD5_HASH_LEN]; } chiron_msg_response; + typedef [public,flag(LIBNDR_FLAG_NOALIGN)] struct { + uint8 length; + uint8 data[length]; + } chiron_msg_handshake; + + typedef [public,flag(LIBNDR_FLAG_NOALIGN)] struct { + uint8 length; // Always 0 + uint8 data[length]; + } chiron_msg_ack; + typedef [public,flag(LIBNDR_FLAG_NOALIGN)] struct { uint8 length; uint8 data[length]; @@ -59,14 +66,28 @@ interface chiron [case(CHIRON_ACCOUNT)] chiron_msg_account account; [case(CHIRON_CHALLENGE)] chiron_msg_challenge challenge; [case(CHIRON_RESPONSE)] chiron_msg_response response; + [case(CHIRON_HANDSHAKE)] chiron_msg_handshake handshake; + [case(CHIRON_ACK)] chiron_msg_ack ack; [default] chiron_msg_unknown unknown; } chiron_msg_union; + // Alternative format + typedef [public,flag(LIBNDR_FLAG_NOALIGN)] struct { + uint8 something01; // seen only 01 + uint8 otherthing01; // seen only 01 + uint8 seq; + uint8 someflag; // seen 00 and 01, 01 after the response handshake, and message 0x48 'H' is issued. + uint8 something00; //seen only 00 + uint8 length; + chiron_msg_type msg_type; + [switch_is(msg_type)] chiron_msg_union msg; + } chiron_alt_message; + typedef [public,flag(LIBNDR_FLAG_NOALIGN)] struct { chiron_msg_type msg_type; uint8 seq; uint8 flags; - [switch_is(msg_type)] chiron_msg_union msg; + [switch_is(msg_type)] chiron_msg_union msg; } chiron_message; } diff --git a/chirond.c b/chirond.c index b830c59..697484b 100644 --- a/chirond.c +++ b/chirond.c @@ -23,11 +23,56 @@ #define CHIRON_PORT "53165" +// Function was licensed WTFPL, origin stack: overflow +// I am too lazy to write this myself, these days. +void hexdump (const char *desc, const void *addr, const int len) { + int i; + unsigned char buff[17]; + unsigned char *pc = (unsigned char*)addr; + + // Output description if given. + if (desc != NULL) + fprintf(stderr, "%s:\n", desc); + + if (len == 0) { + fprintf(stderr, " ZERO LENGTH\n"); + return; + } + if (len < 0) { + fprintf(stderr, " NEGATIVE LENGTH: %i\n",len); + return; + } + + for (i = 0; i < len; i++) { + if ((i % 16) == 0) { + if (i != 0) + fprintf(stderr, " %s\n", buff); + + fprintf(stderr, " %04x ", i); + } + + fprintf(stderr, " %02x", pc[i]); + + if ((pc[i] < 0x20) || (pc[i] > 0x7e)) + buff[i % 16] = '.'; + else + buff[i % 16] = pc[i]; + buff[(i % 16) + 1] = '\0'; + } + + while ((i % 16) != 0) { + fprintf(stderr, " "); + i++; + } + + fprintf(stderr, " %s\n", buff); +} + struct chiron_context { int clientfd; struct sockaddr *clientaddr; char *account_code; - char *device_id; + char device_id[3]; uint8_t md5_last_out[0x10]; uint8_t rc4key[0x10]; }; @@ -44,21 +89,85 @@ char *ndr_print_chiron_msg_type_enum(TALLOC_CTX *mem_ctx, enum chiron_msg_type m return ret; } -STATUS handle_chiron_msg_response(struct chiron_context *ctx, struct chiron_message *msg) { -#if 0 // TLV, move to ASN.1 parsing - DATA_BLOB crypted, decrypted; - enum ndr_err_code ndr_err; - struct chiron_msg_inner_response *inner_response; +struct ll_tlv { + struct ll_tlv *next; + enum chiron_msg_type type; + uint8_t length; + void *data_ptr; +}; + +STATUS tlv_to_linked_list(TALLOC_CTX *mem_ctx, DATA_BLOB data, struct ll_tlv **first_element) { + uint8_t *tlvptr = data.data; + struct ll_tlv *prev_elem = NULL; + while (tlvptr + 2 < data.data + data.length) { + struct ll_tlv *element = talloc_zero(mem_ctx, struct ll_tlv); + if (prev_elem == NULL) { + *first_element = element; + } else { + prev_elem->next = element; + } + + element->type = *tlvptr++; + + element->length = *tlvptr++; + if (tlvptr + element->length > data.data + data.length) { + prev_elem->next = NULL; + talloc_free(element); + return ST_PARSE_ERROR; + } + element->data_ptr = tlvptr; + + + tlvptr += element->length; + prev_elem = element; + } + if (tlvptr < data.data + data.length) { + DEBUG(1, "Error: Left over bytes in TLV"); + return ST_PARSE_ERROR; + } + return ST_OK; +} +STATUS handle_chiron_msg_ack(struct chiron_context *ctx, struct chiron_message *msg) { + DEBUG(3, "Received ACK"); + return ST_OK; +} + +STATUS send_chiron_msg_handshake(struct chiron_context *ctx, struct chiron_message *in) { + struct chiron_message *out = talloc_zero(in, struct chiron_message); + out->msg_type = CHIRON_HANDSHAKE; + out->seq = in->seq; + out->flags = 0xC0; /* FIXME: What does this do? */ + + const uint8_t payload[] = { 0x27, 0, 0x32, 0, 0x18, 0, 0x2D, 0 }; + out->msg.handshake.data = talloc_memdup(out, payload, sizeof(payload)); + out->msg.handshake.length = sizeof(payload); + struct arcfour_ctx rc4; - char *deviceid_string; + arcfour_set_key(&rc4, MD5_HASH_LEN, ctx->rc4key); + arcfour_crypt(&rc4, sizeof(payload), out->msg.handshake.data, payload); + hexdump("Crypted outgoing payload", out->msg.handshake.data, sizeof(payload)); + + DATA_BLOB raw_out; + enum ndr_err_code ndr_err = ndr_push_struct_blob(&raw_out, out, out, (ndr_push_flags_fn_t)ndr_push_chiron_message); + if (ndr_err != NDR_ERR_SUCCESS) { + DEBUG(0, "Error writing NDR data blob."); + return ST_WRITE_ERROR; + } + write(ctx->clientfd, raw_out.data, raw_out.length); + talloc_free(out); + return ST_OK; +} + +STATUS handle_chiron_msg_response(struct chiron_context *ctx, struct chiron_message *msg) { + DATA_BLOB crypted, decrypted; + struct arcfour_ctx rc4; + struct ll_tlv *element; if (memcmp(msg->msg.response.md5_check, ctx->md5_last_out, 0x10)) { DEBUG(0, "MD5 does not match!\n"); return ST_PARSE_ERROR; } DEBUG(0, "Handling the response"); - inner_response = talloc(msg, struct chiron_msg_inner_response); - NO_MEM_RETURN(inner_response); /* Copy packet to crypted data blob */ crypted.length = msg->msg.response.length - MD5_HASH_LEN; @@ -68,25 +177,24 @@ STATUS handle_chiron_msg_response(struct chiron_context *ctx, struct chiron_mess decrypted.data = talloc_array(msg, uint8_t, crypted.length); NO_MEM_RETURN(decrypted.data); decrypted.length = crypted.length; - + arcfour_set_key(&rc4, MD5_HASH_LEN, ctx->rc4key); arcfour_crypt(&rc4, crypted.length, decrypted.data, crypted.data); + hexdump("Decrypted", decrypted.data, decrypted.length); - /* Parse the packet */ - ndr_err = ndr_pull_struct_blob_all(&decrypted, inner_response, inner_response, (ndr_pull_flags_fn_t)ndr_pull_chiron_msg_inner_response); + /* The message starts with 3 bytes device_id, and then the TLV starts */ + memcpy(ctx->device_id, decrypted.data, 3); + decrypted.data += 3; + decrypted.length -= 3; - if (ndr_err != NDR_ERR_SUCCESS) { - DEBUG(0, "Could not parse the inner response"); - return ST_PARSE_ERROR; + tlv_to_linked_list(msg, decrypted, &element); + while (element != NULL) { + DEBUG(1, "Type: %x, Length: %d", element->type, element->length); + hexdump("Data", element->data_ptr, element->length); + element = element->next; } - DEBUG(0, "%s", ndr_print_struct_string(msg,(ndr_print_fn_t)ndr_print_chiron_msg_inner_response, "chiron payload", inner_response)); + send_chiron_msg_handshake(ctx, msg); - deviceid_string = talloc_zero_array(msg, char, inner_response->dev_len + 1); - memcpy(deviceid_string, inner_response->deviceid, inner_response->dev_len); - - DEBUG(0, "Remote device: %s", deviceid_string); -#endif - //send_chiron_msg_key return ST_OK; } @@ -115,6 +223,7 @@ STATUS send_chiron_msg_challenge(struct chiron_context *ctx, struct chiron_messa out->msg.challenge.md5_check = talloc_array(out, uint8_t, MD5_HASH_LEN); NO_MEM_RETURN(out->msg.challenge.md5_check); + md5_init(&md5); md5_update(&md5, in->msg.account.length + 1, md5input); md5_digest(&md5, MD5_HASH_LEN, out->msg.challenge.md5_check); @@ -124,6 +233,7 @@ STATUS send_chiron_msg_challenge(struct chiron_context *ctx, struct chiron_messa out->msg.challenge.length = MD5_HASH_LEN + CHALLENGE_LEN; out->msg.challenge.challenge = talloc_zero_array(out, uint8_t, CHALLENGE_LEN); NO_MEM_RETURN(out->msg.challenge.challenge); +#if 0 out->msg.challenge.challenge[0] = 0xd0; out->msg.challenge.challenge[1] = 0x8b; out->msg.challenge.challenge[2] = 0x29; @@ -133,6 +243,30 @@ STATUS send_chiron_msg_challenge(struct chiron_context *ctx, struct chiron_messa out->msg.challenge.challenge[6] = 0xb5; out->msg.challenge.challenge[7] = 0xc6; out->msg.challenge.challenge[8] = 0x1e; +#endif +//0x04, 0x0d, 0x49, 0xc1, 0x3d, 0xc8, 0x1f, 0x5f, 0x47 +#if 0 + out->msg.challenge.challenge[0] = 0x04; + out->msg.challenge.challenge[1] = 0x0d; + out->msg.challenge.challenge[2] = 0x49; + out->msg.challenge.challenge[3] = 0xc1; + out->msg.challenge.challenge[4] = 0x3d; + out->msg.challenge.challenge[5] = 0xc8; + out->msg.challenge.challenge[6] = 0x1f; + out->msg.challenge.challenge[7] = 0x5f; + out->msg.challenge.challenge[8] = 0x47; +#endif +// 0x96, 0xf4, 0xc4, 0x86, +// 0xd9, 0x83, 0x4d, 0x87, 0x48 + out->msg.challenge.challenge[0] = 0x96; + out->msg.challenge.challenge[1] = 0xf4; + out->msg.challenge.challenge[2] = 0xc4; + out->msg.challenge.challenge[3] = 0x86; + out->msg.challenge.challenge[4] = 0xd9; + out->msg.challenge.challenge[5] = 0x83; + out->msg.challenge.challenge[6] = 0x4d; + out->msg.challenge.challenge[7] = 0x87; + out->msg.challenge.challenge[8] = 0x48; ndr_err = ndr_push_struct_blob(&raw_out, out, out, (ndr_push_flags_fn_t)ndr_push_chiron_message); if (ndr_err != NDR_ERR_SUCCESS) { @@ -140,13 +274,16 @@ STATUS send_chiron_msg_challenge(struct chiron_context *ctx, struct chiron_messa return ST_WRITE_ERROR; } + + /* Update the md5 check for the next message (last 9 bytes with the seq byte appended). */ md5input = talloc_array(in, uint8_t, CHALLENGE_LEN + 1); NO_MEM_RETURN(md5input); memcpy(md5input, &raw_out.data[MSG_HDR_LEN + MD5_HASH_LEN], CHALLENGE_LEN); md5input[CHALLENGE_LEN] = in->seq; - + + md5_init(&md5); md5_update(&md5, CHALLENGE_LEN + 1, md5input); md5_digest(&md5, MD5_HASH_LEN, ctx->md5_last_out); @@ -159,7 +296,7 @@ STATUS send_chiron_msg_challenge(struct chiron_context *ctx, struct chiron_messa md5_update(&md5, CHALLENGE_LEN + 1, md5input); md5_digest(&md5, MD5_HASH_LEN, ctx->rc4key); - DEBUG(0, "The expected md5sum for the next entry is %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", + DEBUG(0, "The expected md5sum for the next entry is %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", ctx->md5_last_out[0], ctx->md5_last_out[1], ctx->md5_last_out[2], ctx->md5_last_out[3], ctx->md5_last_out[4], ctx->md5_last_out[5], ctx->md5_last_out[6], ctx->md5_last_out[9], ctx->md5_last_out[8], ctx->md5_last_out[9], ctx->md5_last_out[10], ctx->md5_last_out[11], @@ -176,16 +313,53 @@ STATUS handle_chiron_msg_account(struct chiron_context *ctx, struct chiron_messa NO_MEM_RETURN(ctx->account_code); send_chiron_msg_challenge(ctx, msg); - return ST_OK; + return ST_OK; +} + +STATUS handle_message(struct chiron_context *ctx, DATA_BLOB data) { + struct chiron_message *msg; + enum ndr_err_code ndr_err; + STATUS status; + msg = talloc(data.data, struct chiron_message); + NO_MEM_RETURN(msg); + + /* Parse the packet */ + ndr_err = ndr_pull_struct_blob_all(&data, msg, msg, (ndr_pull_flags_fn_t)ndr_pull_chiron_message); + + if (ndr_err != NDR_ERR_SUCCESS) { + DEBUG(0, "Could not parse this message"); + return ST_PARSE_ERROR; + } + DEBUG(0, "%s", ndr_print_struct_string(msg,(ndr_print_fn_t)ndr_print_chiron_message, "chiron message", msg)); + + switch (msg->msg_type) { + case CHIRON_ACCOUNT: + status = handle_chiron_msg_account(ctx, msg); + break; + case CHIRON_RESPONSE: + status = handle_chiron_msg_response(ctx, msg); + break; + case CHIRON_ACK: + status = handle_chiron_msg_ack(ctx, msg); + default: + DEBUG(0, "Got unexpected message type: %s.", + ndr_print_chiron_msg_type_enum(msg, msg->msg_type)); + break; + } + + if (status != ST_OK) { + return status; + } + + talloc_free(msg); + + return ST_OK; } STATUS handle_connection(struct chiron_context *ctx) { int n; - struct chiron_message *msg; - enum ndr_err_code ndr_err; char buf[1024]; /* Purposefully static length */ DATA_BLOB data; - STATUS status; while ((n = read(ctx->clientfd, buf, sizeof(buf)))) { @@ -197,41 +371,12 @@ STATUS handle_connection(struct chiron_context *ctx) { return ST_PARSE_ERROR; } - msg = talloc(ctx, struct chiron_message); - NO_MEM_RETURN(msg); - /* Copy packet to data blob */ data.length = n; - data.data = talloc_memdup(msg, buf, n); + data.data = talloc_memdup(ctx, buf, n); NO_MEM_RETURN(data.data); - - /* Parse the packet */ - ndr_err = ndr_pull_struct_blob_all(&data, msg, msg, (ndr_pull_flags_fn_t)ndr_pull_chiron_message); - if (ndr_err != NDR_ERR_SUCCESS) { - DEBUG(0, "Could not parse this message"); - return ST_PARSE_ERROR; - } - DEBUG(0, "%s", ndr_print_struct_string(msg,(ndr_print_fn_t)ndr_print_chiron_message, "chiron message", msg)); - - switch (msg->msg_type) { - case CHIRON_ACCOUNT: - status = handle_chiron_msg_account(ctx, msg); - break; - case CHIRON_RESPONSE: - status = handle_chiron_msg_response(ctx, msg); - break; - default: - DEBUG(0, "Got unexpected message type: %s.", - ndr_print_chiron_msg_type_enum(msg, msg->msg_type)); - break; - } - - if (status != ST_OK) { - return status; - } - - talloc_free(msg); + talloc_free(data.data); } return ST_OK; } @@ -246,7 +391,7 @@ static STATUS daemonize(char *pid_file) { if ((pid = fork())) { /* Write PID file */ pidfile = fopen(pid_file, "w"); - if (pidfile < 0) + if (pidfile == NULL) exit(1); fprintf(pidfile, "%d\n", pid); @@ -289,7 +434,7 @@ static STATUS listen_server(TALLOC_CTX *mem_ctx, const char *bindaddr, const cha listen(sock, 128); freeaddrinfo(first_server); - DEBUG(0, "Started %s and waiting for Chiron messages on port %s", + DEBUG(0, "Started %s and waiting for Chiron messages on port %s", get_process_name(), CHIRON_PORT); /* @@ -354,6 +499,71 @@ int main (int argc, char **argv) { if (!conf->foreground) { daemonize(conf->pid_file); } + struct chiron_context *client_ctx = talloc_zero(mem_ctx, struct chiron_context); + NO_MEM_RETURN(client_ctx); + client_ctx->clientfd = 1; + client_ctx->clientaddr = (struct sockaddr *)talloc_zero(mem_ctx, struct sockaddr_storage); +#if 0 + // Account + const uint8_t in_message1[] = { 0x41, 0x01, 0xa8, 0x04, 0x33, 0x35, 0x30, 0x30 }; + + // Challenge + const uint8_t out_message1[] = { 0x43, 0x01, 0xa8, 0x19, 0x28, 0xd5, 0xdc, 0x57, + 0x44, 0x77, 0x0d, 0xea, 0xc0, 0x03, 0x56, 0xca, + 0x42, 0x72, 0x18, 0x30, 0xd0, 0x8b, 0x29, 0xd3, + 0x7c, 0xfd, 0xb5, 0xc6, 0x1e }; + + // Response + const uint8_t in_message2[] = { 0x52, 0x01, 0xa8, 0x37, 0x62, 0x7f, 0xd0, 0xb8, 0xbc, 0x70, 0x6a, 0x44, 0x44, 0x21, 0x15, 0xb4, 0x94, 0x20, 0x62, 0x98, 0x7a, 0xe2, 0xde, 0xc2, 0xed, 0x76, 0x84, 0x5f, 0xe6, 0x16, 0x2b, 0x6b, 0xb9, 0x10, 0xa3, 0x6c, 0x14, 0x44, 0x56, 0xca, 0x45, 0xc6, 0xc2, 0xeb, 0xec, 0x1b, 0xd8, 0x7a, 0xa4, 0x4c, 0xc0, 0xb4, 0x88, 0x64, 0x6e, 0x2b, 0xee, 0x11, 0x54 }; + + // Handshake + const uint8_t out_message2[] = { 0x4b, 0x01, 0xc0, 0x08, 0x5d, 0x4f, 0x2b, 0xce, 0xf1, 0xde, 0x77, 0xa1 }; + + // Ack + const uint8_t in_message3[] = { 0x55, 0x01, 0xa8, 0x00 }; +#endif +#if 0 + const uint8_t in_message1[] = { 0x41, 0x02, 0xa8, 0x04, 0x33, 0x35, 0x30, 0x30 }; + const uint8_t out_message1[] = { 0x43, 0x02, 0xa8, 0x19, 0x08, 0x71, 0x4f, 0xad, 0xed, 0xa3, 0xaf, 0x37, 0x88, 0xcc, 0x00, 0x51, 0xe4, 0xcb, 0xad, 0x7c, 0x04, 0x0d, 0x49, 0xc1, 0x3d, 0xc8, 0x1f, 0x5f, 0x47 }; + const uint8_t in_message2[] = { 0x52, 0x02, 0xa8, 0x46, 0xc8, 0xa8, 0xb6, 0x50, 0x34, 0xd5, 0x7a, 0x26, 0x90, 0x63, 0x92, 0x56, 0xe5, 0x4d, 0xde, 0xa0, 0x6a, 0x60, 0x19, 0xdc, 0x67, 0xbb, 0xe8, 0x9e, 0x8e, 0xfc, 0x79, 0x55, 0xed, 0x66, 0x26, 0x21, 0x1a, 0x6b, 0x4a, 0x9c, 0x7c, 0xe6, 0x1d, 0x01, 0xab, 0x57, 0xfb, 0xd9, 0x6d, 0x15, 0xbd, 0xe6, 0xe3, 0x94, 0xd6, 0xe7, 0xde, 0xc3, 0x89, 0x52, 0x65, 0x5f, 0x0c, 0x97, 0x4e, 0x4f, 0x6d, 0x9f, 0x5a, 0xb9, 0xc2, 0x12, 0xdd, 0x74 }; + + const uint8_t out_message2[] = { 0x4b, 0x02, 0xc0, 0x00 }; +#endif + + const uint8_t in_message1[] = { + 0x41, 0x03, 0x88, 0x04, 0x33, 0x35, 0x30, 0x30 }; + const uint8_t out_message1[] = { + 0x43, 0x03, 0x88, 0x19, 0xaa, 0xd9, 0xaa, 0x5f, + 0x30, 0x5d, 0x95, 0x0d, 0x96, 0x8d, 0x4e, 0x26, + 0x02, 0x1a, 0x1a, 0xd8, 0x96, 0xf4, 0xc4, 0x86, + 0xd9, 0x83, 0x4d, 0x87, 0x48 }; + const uint8_t in_message2[] = { + 0x52, 0x03, 0x88, 0x1f, 0xe5, 0x65, 0x48, 0x30, + 0x56, 0x8e, 0x3b, 0x42, 0x02, 0x6c, 0xcc, 0x9b, + 0xdc, 0x82, 0xb0, 0x17, 0xba, 0xef, 0x52, 0x61, + 0xe8, 0xce, 0x7b, 0xcb, 0x57, 0x85, 0x2b, 0x18, + 0xbf, 0xfa, 0xf1 }; + const uint8_t out_message2[] = { + 0x4b, 0x03, 0xc0, 0x00 }; + DATA_BLOB data; + data.data = talloc_memdup(client_ctx, in_message1, sizeof(in_message1)); + data.length = sizeof(in_message1); + handle_message(client_ctx, data); + talloc_free(data.data); + + data.data = talloc_memdup(client_ctx, in_message2, sizeof(in_message2)); + data.length = sizeof(in_message2); + handle_message(client_ctx, data); + talloc_free(data.data); + + struct arcfour_ctx rc4; + arcfour_set_key(&rc4, MD5_HASH_LEN, client_ctx->rc4key); + uint8_t buf[sizeof(out_message2)] = {0}; + arcfour_crypt(&rc4, sizeof(out_message2) - 4, buf, out_message2 + 4); + hexdump("Decrypted outgoing payload", buf, sizeof(out_message2) - 4); + + + return 0; /* * Open up a TCP socket the Chiron port