diff --git a/source/stream.c b/source/stream.c index b8040946d..968449949 100644 --- a/source/stream.c +++ b/source/stream.c @@ -287,7 +287,7 @@ struct aws_input_stream *aws_input_stream_new_from_file(struct aws_allocator *al struct aws_input_stream_file_impl *impl = aws_mem_calloc(allocator, 1, sizeof(struct aws_input_stream_file_impl)); - impl->file = aws_fopen(file_name, "r+b"); + impl->file = aws_fopen(file_name, "rb"); if (impl->file == NULL) { goto on_error; } diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 710cd7af7..e59e7b22a 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -32,9 +32,10 @@ add_pipe_test_case(pipe_clean_up_cancels_pending_writes) add_test_case(event_loop_xthread_scheduled_tasks_execute) add_test_case(event_loop_canceled_tasks_run_in_el_thread) -if (USE_IO_COMPLETION_PORTS) + +if(USE_IO_COMPLETION_PORTS) add_test_case(event_loop_completion_events) -else () +else() add_test_case(event_loop_subscribe_unsubscribe) add_test_case(event_loop_writable_event_on_subscribe) add_test_case(event_loop_no_readable_event_before_write) @@ -42,7 +43,7 @@ else () add_test_case(event_loop_readable_event_on_subscribe_if_data_present) add_test_case(event_loop_readable_event_on_2nd_time_readable) add_test_case(event_loop_no_events_after_unsubscribe) -endif () +endif() add_test_case(event_loop_stop_then_restart) add_test_case(event_loop_multiple_stops) @@ -58,9 +59,10 @@ add_net_test_case(udp_socket_communication) add_test_case(udp_bind_connect_communication) add_net_test_case(connect_timeout) add_net_test_case(connect_timeout_cancelation) -if (USE_VSOCK) - add_test_case(vsock_loopback_socket_communication) -endif () + +if(USE_VSOCK) + add_test_case(vsock_loopback_socket_communication) +endif() add_test_case(outgoing_local_sock_errors) add_test_case(outgoing_tcp_sock_error) @@ -75,7 +77,7 @@ add_test_case(cleanup_in_accept_doesnt_explode) add_test_case(cleanup_in_write_cb_doesnt_explode) add_test_case(sock_write_cb_is_async) -if (WIN32) +if(WIN32) add_test_case(local_socket_pipe_connected_race) endif() @@ -120,8 +122,8 @@ add_test_case(socket_handler_echo_and_backpressure) add_test_case(socket_handler_close) add_test_case(socket_pinned_event_loop) -if (NOT BYO_CRYPTO) - if (USE_S2N) +if(NOT BYO_CRYPTO) + if(USE_S2N) add_net_test_case(default_pki_path_exists) endif() @@ -131,11 +133,11 @@ if (NOT BYO_CRYPTO) # # We don't use the interception suite since that's a host configuration issue # We also don't check the domain security policy suite: - # 1. s2n does not support revocation checks and we do not currently enable any revocation checks - # in windows or osx, although we may add configurable support to those platforms(off-by-default) at a - # later date - # 2. s2n does not support public key pinning and, given its deprecated and http-centric position, there are no - # plans to add support nor investigate osx/windows support as well. + # 1. s2n does not support revocation checks and we do not currently enable any revocation checks + # in windows or osx, although we may add configurable support to those platforms(off-by-default) at a + # later date + # 2. s2n does not support public key pinning and, given its deprecated and http-centric position, there are no + # plans to add support nor investigate osx/windows support as well. # Badssl - Certificate Validation endpoint suite # For each failure case, we also include a positive test that verifies success when peer verification is disabled @@ -161,13 +163,13 @@ if (NOT BYO_CRYPTO) # Badssl - Legacy crypto suite, includes both negative and positive tests, with override checks where appropriate # Our current baseline/default is platform-specific, whereas badssl expects a baseline of 1.2 - # Linux - tls1.1 - # Windows - system default (1.0 is the only thing we could reasonable fixate to given win7 support) - # Mac - system default + # Linux - tls1.1 + # Windows - system default (1.0 is the only thing we could reasonable fixate to given win7 support) + # Mac - system default # We skip the cbc and 3des checks, as a positive connection result there does not yet represent a security risk # We don't include dh2048 as it succeeds on the windows baseline configuration and there does not seem # to be a way to disable it - if(NOT (WIN32 AND NOT CMAKE_SYSTEM_VERSION MATCHES "10\.0\.1.*")) + if(NOT(WIN32 AND NOT CMAKE_SYSTEM_VERSION MATCHES "10\.0\.1.*")) # Skip TLS 1.0 and TLS 1.1 test for windows later than windows server 2022, as they droped old TLS add_net_test_case(tls_client_channel_negotiation_error_legacy_crypto_tls10) add_net_test_case(tls_client_channel_negotiation_override_legacy_crypto_tls10) @@ -197,6 +199,7 @@ if (NOT BYO_CRYPTO) add_net_test_case(tls_client_channel_negotiation_success_rsa2048) add_net_test_case(tls_client_channel_negotiation_success_ecc256) add_net_test_case(tls_client_channel_negotiation_success_ecc384) + # add_net_test_case(tls_client_channel_negotiation_success_extended_validation) test disabled until badssl updates cert (expired 2022.08.10) add_net_test_case(tls_client_channel_negotiation_success_mozilla_modern) @@ -253,6 +256,7 @@ add_test_case(test_input_stream_file_seek_end) add_test_case(test_input_stream_memory_length) add_test_case(test_input_stream_file_length) add_test_case(test_input_stream_binary) +add_test_case(test_input_stream_read_only) add_test_case(async_input_stream_fill_completes_on_thread) add_test_case(async_input_stream_fill_completes_immediately) @@ -264,7 +268,7 @@ add_test_case(open_channel_statistics_test) add_test_case(shared_library_open_failure) -if (BUILD_SHARED_LIBS) +if(BUILD_SHARED_LIBS) add_test_case(shared_library_open_success) add_test_case(shared_library_find_function_failure) add_test_case(shared_library_find_function_success) @@ -283,7 +287,7 @@ add_test_case(test_standard_retry_strategy_failure_exhausts_bucket) add_test_case(test_standard_retry_strategy_failure_recovers) # See PKCS11.md for instructions on running these tests -if (ENABLE_PKCS11_TESTS) +if(ENABLE_PKCS11_TESTS) add_test_case(pkcs11_lib_sanity_check) add_test_case(pkcs11_lib_behavior_default) add_test_case(pkcs11_lib_behavior_omit_initialize) @@ -306,7 +310,7 @@ if (ENABLE_PKCS11_TESTS) add_test_case(pkcs11_login_tests) # TLS with PKCS#11 not currently supported on every platform - if (USE_S2N) + if(USE_S2N) add_test_case(pkcs11_tls_rsa_negotiation_succeeds) add_test_case(pkcs11_tls_ec_negotiation_succeeds) endif() @@ -315,11 +319,11 @@ endif() set(TEST_BINARY_NAME ${PROJECT_NAME}-tests) generate_test_driver(${TEST_BINARY_NAME}) -if (USE_S2N) +if(USE_S2N) target_compile_definitions(${PROJECT_NAME}-tests PRIVATE "-DUSE_S2N") endif() -#SSL certificates to use for testing. +# SSL certificates to use for testing. add_custom_command(TARGET ${TEST_BINARY_NAME} PRE_BUILD - COMMAND ${CMAKE_COMMAND} -E copy_directory - ${CMAKE_CURRENT_SOURCE_DIR}/resources $) + COMMAND ${CMAKE_COMMAND} -E copy_directory + ${CMAKE_CURRENT_SOURCE_DIR}/resources $) diff --git a/tests/stream_test.c b/tests/stream_test.c index 0af7b5ca8..355804550 100644 --- a/tests/stream_test.c +++ b/tests/stream_test.c @@ -9,14 +9,18 @@ #include #include +#include + +#ifdef _WIN32 +# include +#endif + AWS_STATIC_STRING_FROM_LITERAL(s_simple_test, "SimpleTest"); /* 0x1A represents the Windows end-of-file character. Having this in the test data set allows us to verify that file * stream reads on binary files do not terminate early on Windows.*/ const uint8_t s_simple_binary_test[] = {'a', 'b', 'c', 'd', 'e', 'f', 0x1A, 'g', 'h', 'i', 'j', 'k'}; -const char *s_test_file_name = "stream.dat"; - static struct aws_input_stream *s_create_memory_stream(struct aws_allocator *allocator) { struct aws_byte_cursor test_cursor = aws_byte_cursor_from_string(s_simple_test); return aws_input_stream_new_from_cursor(allocator, &test_cursor); @@ -26,30 +30,48 @@ static void s_destroy_memory_stream(struct aws_input_stream *stream) { aws_input_stream_destroy(stream); } -static struct aws_input_stream *s_create_file_stream(struct aws_allocator *allocator) { - remove(s_test_file_name); +static struct aws_input_stream *s_create_file_stream(struct aws_allocator *allocator, const char *file_path) { + remove(file_path); - FILE *file = aws_fopen(s_test_file_name, "w+"); + FILE *file = aws_fopen(file_path, "w"); fprintf(file, "%s", (char *)s_simple_test->bytes); fclose(file); - return aws_input_stream_new_from_file(allocator, s_test_file_name); + return aws_input_stream_new_from_file(allocator, file_path); } -static struct aws_input_stream *s_create_binary_file_stream(struct aws_allocator *allocator) { - remove(s_test_file_name); +static struct aws_input_stream *s_create_binary_file_stream(struct aws_allocator *allocator, const char *file_path) { + remove(file_path); - FILE *file = aws_fopen(s_test_file_name, "w+b"); + FILE *file = aws_fopen(file_path, "wb"); fwrite(s_simple_binary_test, sizeof(uint8_t), sizeof(s_simple_binary_test), file); fclose(file); - return aws_input_stream_new_from_file(allocator, s_test_file_name); + return aws_input_stream_new_from_file(allocator, file_path); } -static void s_destroy_file_stream(struct aws_input_stream *stream) { +static struct aws_input_stream *s_create_read_only_file_stream(struct aws_allocator *allocator, const char *file_path) { + remove(file_path); + + FILE *file = aws_fopen(file_path, "w"); + fprintf(file, "%s", (char *)s_simple_test->bytes); + fclose(file); +#ifdef _WIN32 + if (_chmod(file_path, _S_IREAD)) { + return NULL; + } +#else + if (chmod(file_path, S_IRUSR | S_IRGRP | S_IROTH)) { + return NULL; + } +#endif + return aws_input_stream_new_from_file(allocator, file_path); +} + +static void s_destroy_file_stream(struct aws_input_stream *stream, const char *file_path) { aws_input_stream_destroy(stream); - remove(s_test_file_name); + remove(file_path); } static int s_do_simple_input_stream_test( @@ -125,12 +147,13 @@ AWS_TEST_CASE(test_input_stream_memory_iterate, s_test_input_stream_memory_itera static int s_test_input_stream_file_simple(struct aws_allocator *allocator, void *ctx) { (void)ctx; - struct aws_input_stream *stream = s_create_file_stream(allocator); + const char *file_path = "test_input_stream_file_simple.txt"; /* unique name */ + struct aws_input_stream *stream = s_create_file_stream(allocator, file_path); struct aws_byte_cursor test_cursor = aws_byte_cursor_from_string(s_simple_test); ASSERT_TRUE(s_do_simple_input_stream_test(stream, allocator, 100, &test_cursor) == AWS_OP_SUCCESS); - s_destroy_file_stream(stream); + s_destroy_file_stream(stream, file_path); return AWS_OP_SUCCESS; } @@ -140,12 +163,13 @@ AWS_TEST_CASE(test_input_stream_file_simple, s_test_input_stream_file_simple); static int s_test_input_stream_file_iterate(struct aws_allocator *allocator, void *ctx) { (void)ctx; - struct aws_input_stream *stream = s_create_file_stream(allocator); + const char *file_path = "test_input_stream_file_iterate.txt"; /* unique name */ + struct aws_input_stream *stream = s_create_file_stream(allocator, file_path); struct aws_byte_cursor test_cursor = aws_byte_cursor_from_string(s_simple_test); ASSERT_TRUE(s_do_simple_input_stream_test(stream, allocator, 2, &test_cursor) == AWS_OP_SUCCESS); - s_destroy_file_stream(stream); + s_destroy_file_stream(stream, file_path); return AWS_OP_SUCCESS; } @@ -196,7 +220,8 @@ AWS_TEST_CASE(test_input_stream_memory_seek_beginning, s_test_input_stream_memor static int s_test_input_stream_file_seek_beginning(struct aws_allocator *allocator, void *ctx) { (void)ctx; - struct aws_input_stream *stream = s_create_file_stream(allocator); + const char *file_path = "test_input_stream_file_seek_beginning.txt"; /* unique name */ + struct aws_input_stream *stream = s_create_file_stream(allocator, file_path); struct aws_byte_cursor test_cursor = aws_byte_cursor_from_string(s_simple_test); aws_byte_cursor_advance(&test_cursor, SEEK_BEGINNING_OFFSET); @@ -204,7 +229,7 @@ static int s_test_input_stream_file_seek_beginning(struct aws_allocator *allocat s_do_input_stream_seek_test(stream, allocator, SEEK_BEGINNING_OFFSET, AWS_SSB_BEGIN, &test_cursor) == AWS_OP_SUCCESS); - s_destroy_file_stream(stream); + s_destroy_file_stream(stream, file_path); return AWS_OP_SUCCESS; } @@ -279,14 +304,15 @@ AWS_TEST_CASE(test_input_stream_memory_seek_multiple_times, s_test_input_stream_ static int s_test_input_stream_file_seek_end(struct aws_allocator *allocator, void *ctx) { (void)ctx; - struct aws_input_stream *stream = s_create_file_stream(allocator); + const char *file_path = "test_input_stream_file_seek_end.txt"; /* unique name */ + struct aws_input_stream *stream = s_create_file_stream(allocator, file_path); struct aws_byte_cursor test_cursor = aws_byte_cursor_from_string(s_simple_test); aws_byte_cursor_advance(&test_cursor, (size_t)((int64_t)s_simple_test->len + SEEK_END_OFFSET)); ASSERT_TRUE( s_do_input_stream_seek_test(stream, allocator, SEEK_END_OFFSET, AWS_SSB_END, &test_cursor) == AWS_OP_SUCCESS); - s_destroy_file_stream(stream); + s_destroy_file_stream(stream, file_path); return AWS_OP_SUCCESS; } @@ -360,8 +386,8 @@ AWS_TEST_CASE(test_input_stream_memory_length, s_test_input_stream_memory_length static int s_test_input_stream_file_length(struct aws_allocator *allocator, void *ctx) { (void)ctx; - struct aws_input_stream *stream = s_create_file_stream(allocator); - + const char *file_path = "test_input_stream_file_length.txt"; /* unique name */ + struct aws_input_stream *stream = s_create_file_stream(allocator, file_path); int64_t length = 0; ASSERT_TRUE(aws_input_stream_get_length(stream, &length) == AWS_OP_SUCCESS); ASSERT_TRUE(length == (int64_t)s_simple_test->len); @@ -372,7 +398,7 @@ static int s_test_input_stream_file_length(struct aws_allocator *allocator, void ASSERT_TRUE(aws_input_stream_get_length(stream, &length) == AWS_OP_SUCCESS); ASSERT_TRUE(length == (int64_t)s_simple_test->len); - s_destroy_file_stream(stream); + s_destroy_file_stream(stream, file_path); return AWS_OP_SUCCESS; } @@ -382,7 +408,8 @@ AWS_TEST_CASE(test_input_stream_file_length, s_test_input_stream_file_length); static int s_test_input_stream_binary(struct aws_allocator *allocator, void *ctx) { (void)ctx; - struct aws_input_stream *stream = s_create_binary_file_stream(allocator); + const char *file_path = "test_input_stream_binary.dat"; /* unique name */ + struct aws_input_stream *stream = s_create_binary_file_stream(allocator, file_path); struct aws_byte_cursor test_cursor = { .ptr = (uint8_t *)s_simple_binary_test, @@ -391,9 +418,26 @@ static int s_test_input_stream_binary(struct aws_allocator *allocator, void *ctx ASSERT_TRUE(s_do_simple_input_stream_test(stream, allocator, 100, &test_cursor) == AWS_OP_SUCCESS); - s_destroy_file_stream(stream); + s_destroy_file_stream(stream, file_path); return AWS_OP_SUCCESS; } AWS_TEST_CASE(test_input_stream_binary, s_test_input_stream_binary); + +static int s_test_input_stream_read_only(struct aws_allocator *allocator, void *ctx) { + (void)ctx; + + const char *file_path = "test_input_stream_read_only.txt"; /* unique name */ + struct aws_input_stream *stream = s_create_read_only_file_stream(allocator, file_path); + ASSERT_NOT_NULL(stream); + + struct aws_byte_cursor test_cursor = aws_byte_cursor_from_string(s_simple_test); + ASSERT_TRUE(s_do_simple_input_stream_test(stream, allocator, 100, &test_cursor) == AWS_OP_SUCCESS); + + s_destroy_file_stream(stream, file_path); + + return AWS_OP_SUCCESS; +} + +AWS_TEST_CASE(test_input_stream_read_only, s_test_input_stream_read_only);