/* Test that data values are written and read with proper alignment. */ static void test_alignment(void) { void *ctx = ralloc_context(NULL); struct blob *blob; struct blob_reader reader; uint8_t bytes[] = "ABCDEFGHIJKLMNOP"; size_t delta, last, num_bytes; blob = blob_create(ctx); /* First, write an intptr value to the blob and capture that size. This is * the expected offset between any pair of intptr values (if written with * alignment). */ blob_write_intptr(blob, (intptr_t) blob); delta = blob->size; last = blob->size; /* Then loop doing the following: * * 1. Write an unaligned number of bytes * 2. Verify that write results in an unaligned size * 3. Write an intptr_t value * 2. Verify that that write results in an aligned size */ for (num_bytes = 1; num_bytes < sizeof(intptr_t); num_bytes++) { blob_write_bytes(blob, bytes, num_bytes); expect_unequal(delta, blob->size - last, "unaligned write of bytes"); blob_write_intptr(blob, (intptr_t) blob); expect_equal(2 * delta, blob->size - last, "aligned write of intptr"); last = blob->size; } /* Finally, test that reading also does proper alignment. Since we know * that values were written with all the right alignment, all we have to do * here is verify that correct values are read. */ blob_reader_init(&reader, blob->data, blob->size); expect_equal((intptr_t) blob, blob_read_intptr(&reader), "read of initial, aligned intptr_t"); for (num_bytes = 1; num_bytes < sizeof(intptr_t); num_bytes++) { expect_equal_bytes(bytes, blob_read_bytes(&reader, num_bytes), num_bytes, "unaligned read of bytes"); expect_equal((intptr_t) blob, blob_read_intptr(&reader), "aligned read of intptr_t"); } ralloc_free(ctx); }
/* Test that we detect overrun. */ static void test_overrun(void) { void *ctx =ralloc_context(NULL); struct blob *blob; struct blob_reader reader; uint32_t value = 0xdeadbeef; blob = blob_create(ctx); blob_write_uint32(blob, value); blob_reader_init(&reader, blob->data, blob->size); expect_equal(value, blob_read_uint32(&reader), "read before overrun"); expect_equal(false, reader.overrun, "overrun flag not set"); expect_equal(0, blob_read_uint32(&reader), "read at overrun"); expect_equal(true, reader.overrun, "overrun flag set"); ralloc_free(ctx); }
/* Test that we can read and write some large objects, (exercising the code in * the blob_write functions to realloc blob->data. */ static void test_big_objects(void) { void *ctx = ralloc_context(NULL); struct blob *blob; struct blob_reader reader; int size = 1000; int count = 1000; size_t i; char *buf; blob = blob_create(ctx); /* Initialize our buffer. */ buf = ralloc_size(ctx, size); for (i = 0; i < size; i++) { buf[i] = i % 256; } /* Write it many times. */ for (i = 0; i < count; i++) { blob_write_bytes(blob, buf, size); } blob_reader_init(&reader, blob->data, blob->size); /* Read and verify it many times. */ for (i = 0; i < count; i++) { expect_equal_bytes((uint8_t *) buf, blob_read_bytes(&reader, size), size, "read of large objects"); } expect_equal(reader.end - reader.data, reader.current - reader.data, "number of bytes read reading large objects"); expect_equal(false, reader.overrun, "overrun flag not set reading large objects"); ralloc_free(ctx); }
unsigned char s2_authclient_get_account_info(T_S2_AUTHCLIENT *authclient) { unsigned char result; if (recv(authclient->serverclient.socket, &result, 1, 0) < 0) { ERROR("result recv"); return 1; } if (result != 0) { switch (result) { case 1: ERROR("No such account!"); return 1; case 2: ERROR("Invalid password!"); return 1; case 4: ERROR("Account disabled!"); return 1; default: ERROR("Unknown error!"); return 1; } return 1; } unsigned long long login_time; unsigned long long login_expiry; if (recv(authclient->serverclient.socket, &login_time, 8, 0) < 0) { ERROR("recv"); return 1; } if (recv(authclient->serverclient.socket, &login_expiry, 8, 0) < 0) { ERROR("recv"); return 1; } unsigned char *packet; unsigned int packet_length; if (s2_serverclient_read((T_S2_SERVERCLIENT *)authclient, (void**)&packet, &packet_length)) { ERROR("read"); return 1; } unsigned int offset = 0; unsigned short version = ntohs(*(unsigned short *)packet + offset); offset += 2; unsigned char *tgt_iv = packet + offset; offset += 16; unsigned short tgt_plaintext_size = ntohs(*(unsigned short *)(packet + offset)); offset += 2; unsigned short tgt_ciphertext_size = ntohs(*(unsigned short *)(packet + offset)); offset += 2; unsigned char *tgt_ciphertext = packet + offset; unsigned int tgt_plaintext_size_self; void *tgt_plaintext; util_aes_decrypt(tgt_ciphertext, tgt_ciphertext_size, authclient->key, tgt_iv, (void **)&tgt_plaintext, &tgt_plaintext_size_self); memcpy((void*)&authclient->tgt, tgt_plaintext, tgt_plaintext_size); if (tgt_plaintext_size_self != tgt_plaintext_size) { ERROR("decrypt"); free(tgt_plaintext); free(packet); return 1; } printf("[i] Version %i, tgt size %i/%i.\n", version, tgt_plaintext_size, tgt_ciphertext_size); offset += tgt_ciphertext_size; printf("Offset: %i\n", offset); unsigned short server_tgt_size = ntohs(*(unsigned short *)(packet + offset)); offset += 2; printf("Offset: %i\n", offset); offset += server_tgt_size; unsigned int account_record_size = ntohl(*(unsigned int *)(packet + offset)); offset += 4; printf("Offset: %i\n", offset); unsigned char *account_data = packet + offset; T_BLOB *auth_blob = blob_create(account_data, packet_length - offset, authclient->tgt.account_record_key); free(packet); free(tgt_plaintext); return 0; }
/* Test at least one call of each blob_write_foo and blob_read_foo function, * verifying that we read out everything we wrote, that every bytes is * consumed, and that the overrun bit is not set. */ static void test_write_and_read_functions (void) { void *ctx = ralloc_context(NULL); struct blob *blob; struct blob_reader reader; uint8_t *reserved; size_t str_offset, uint_offset; uint8_t reserve_buf[sizeof(reserve_test_str)]; blob = blob_create(ctx); /*** Test blob by writing one of every possible kind of value. */ blob_write_bytes(blob, bytes_test_str, sizeof(bytes_test_str)); reserved = blob_reserve_bytes(blob, sizeof(reserve_test_str)); memcpy(reserved, reserve_test_str, sizeof(reserve_test_str)); /* Write a placeholder, (to be replaced later via overwrite_bytes) */ str_offset = blob->size; blob_write_bytes(blob, placeholder_str, sizeof(placeholder_str)); blob_write_uint32(blob, uint32_test); /* Write a placeholder, (to be replaced later via overwrite_uint32) */ uint_offset = blob->size; blob_write_uint32(blob, uint32_placeholder); blob_write_uint64(blob, uint64_test); blob_write_intptr(blob, (intptr_t) blob); blob_write_string(blob, string_test_str); /* Finally, overwrite our placeholders. */ blob_overwrite_bytes(blob, str_offset, overwrite_test_str, sizeof(overwrite_test_str)); blob_overwrite_uint32(blob, uint_offset, uint32_overwrite); /*** Now read each value and verify. */ blob_reader_init(&reader, blob->data, blob->size); expect_equal_str(bytes_test_str, blob_read_bytes(&reader, sizeof(bytes_test_str)), "blob_write/read_bytes"); blob_copy_bytes(&reader, reserve_buf, sizeof(reserve_buf)); expect_equal_str(reserve_test_str, (char *) reserve_buf, "blob_reserve_bytes/blob_copy_bytes"); expect_equal_str(overwrite_test_str, blob_read_bytes(&reader, sizeof(overwrite_test_str)), "blob_overwrite_bytes"); expect_equal(uint32_test, blob_read_uint32(&reader), "blob_write/read_uint32"); expect_equal(uint32_overwrite, blob_read_uint32(&reader), "blob_overwrite_uint32"); expect_equal(uint64_test, blob_read_uint64(&reader), "blob_write/read_uint64"); expect_equal((intptr_t) blob, blob_read_intptr(&reader), "blob_write/read_intptr"); expect_equal_str(string_test_str, blob_read_string(&reader), "blob_write/read_string"); expect_equal(reader.end - reader.data, reader.current - reader.data, "read_consumes_all_bytes"); expect_equal(false, reader.overrun, "read_does_not_overrun"); ralloc_free(ctx); }