static selene_error_t * sln_io_alert(selene_t *s, sln_alert_level_e level, sln_alert_description_e desc) { sln_bucket_t *btls = NULL; sln_bucket_t *balert = NULL; sln_msg_alert_t alert; sln_msg_tls_t tls; alert.level = level; alert.description = desc; SELENE_ERR(sln_alert_unparse(s, &alert, &balert)); tls.content_type = SLN_CONTENT_TYPE_ALERT; tls.version_major = 3; tls.version_minor = 1; tls.length = balert->size; SELENE_ERR(sln_tls_unparse_header(s, &tls, &btls)); SLN_BRIGADE_INSERT_TAIL(s->bb.out_enc, btls); SLN_BRIGADE_INSERT_TAIL(s->bb.out_enc, balert); return SELENE_SUCCESS; }
static void brigade_flatten_leftover(void **state) { char buf[80]; char bufcmp[80]; char buf2[2]; char bufcmp2[2]; size_t len = sizeof(buf); size_t len2 = sizeof(buf2); sln_brigade_t *bb; sln_bucket_t *e1; sln_bucket_t *e2; SLN_ERR(sln_brigade_create(&bb)); SLN_ERR(sln_bucket_create_empty(&e1, 40)); memset(e1->data, 'A', e1->size); SLN_BRIGADE_INSERT_TAIL(bb, e1); SLN_ERR(sln_bucket_create_empty(&e2, 42)); memset(e2->data, 'B', e2->size); SLN_BRIGADE_INSERT_TAIL(bb, e2); SLN_ERR(sln_brigade_flatten(bb, &buf[0], &len)); assert_int_equal(len, 80); assert_int_equal(sln_brigade_size(bb), 2); SLN_ERR(sln_brigade_flatten(bb, &buf2[0], &len2)); assert_int_equal(len2, 2); sln_brigade_destroy(bb); memset(&bufcmp[0], 'A', 40); memset(&bufcmp[0]+40, 'B', 40); assert_memory_equal(buf, bufcmp, 80); memset(&bufcmp2[0], 'B', 2); assert_memory_equal(buf2, bufcmp2, 2); }
static void tls_io_slowly(void **state) { selene_error_t *err; sln_parser_baton_t *baton; selene_conf_t *conf = NULL; selene_t *s = NULL; sln_bucket_t *e1; size_t maxlen = sizeof(openssl_client_hello_basic); size_t i; init_ctxt(state, &s, &conf); baton = (sln_parser_baton_t *)s->backend_baton; for (i = 0; i <= maxlen; i++) { SLN_ERR(sln_bucket_create_copy_bytes( sln_test_alloc, &e1, (const char *)openssl_client_hello_basic, i)); SLN_BRIGADE_INSERT_TAIL(s->bb.in_enc, e1); err = sln_io_tls_read(s, baton); if (err) { SLN_ASSERT(err->err == SELENE_EINVAL); } else if (baton->peer_version_major != 0) { assert_int_equal(baton->peer_version_major, 3); assert_int_equal(baton->peer_version_minor, 1); } sln_brigade_clear(baton->in_handshake); sln_brigade_clear(s->bb.in_enc); } destroy_ctxt(state, s, conf); }
static void tls_http_accident(void **state) { selene_error_t *err; sln_parser_baton_t *baton; selene_conf_t *conf = NULL; selene_t *s = NULL; http_cb_t cbb; sln_bucket_t *e1; init_ctxt(state, &s, &conf); baton = (sln_parser_baton_t *)s->backend_baton; cbb.gotit = 0; selene_handler_set(s, SELENE_EVENT_TLS_GOT_HTTP, http_cb, &cbb); SLN_ERR(sln_bucket_create_copy_bytes(sln_test_alloc, &e1, http_message, strlen(http_message))); SLN_BRIGADE_INSERT_TAIL(s->bb.in_enc, e1); err = sln_io_tls_read(s, baton); SLN_ASSERT(err != NULL); SLN_ASSERT(err->err == SELENE_EINVAL); selene_error_clear(err); assert_int_equal(1, cbb.gotit); destroy_ctxt(state, s, conf); }
static void handshake_io_slowly(void **state) { selene_error_t *err; sln_parser_baton_t *baton; selene_conf_t *conf = NULL; selene_t *s = NULL; sln_bucket_t *e1; size_t maxlen = sizeof(openssl_client_hello_basic); size_t i; selene_conf_create(&conf); SLN_ERR(selene_conf_use_reasonable_defaults(conf)); SLN_ERR(selene_server_create(conf, &s)); SLN_ASSERT_CONTEXT(s); baton = (sln_parser_baton_t *)s->backend_baton; for (i = maxlen; i <= maxlen; i++) { SLN_ERR(sln_bucket_create_copy_bytes(sln_test_alloc, &e1, openssl_client_hello_basic, i)); SLN_BRIGADE_INSERT_TAIL(baton->in_handshake, e1); err = sln_io_handshake_read(s, baton); if (err) { SLN_ASSERT(err->err == SELENE_EINVAL); } else { /* TODO: more asserts */ } sln_brigade_clear(baton->in_handshake); } selene_destroy(s); selene_conf_destroy(conf); }
static void brigade_pread_simple(void **state) { sln_brigade_t *bb; sln_bucket_t *e; char buf[5]; size_t len = 0; SLN_ERR(sln_brigade_create(&bb)); SLN_ERR(sln_bucket_create_empty(&e, 20)); SLN_BRIGADE_INSERT_TAIL(bb, e); memset(e->data, 'B', e->size); memset(e->data, 'A', 1); SLN_ERR(sln_brigade_pread_bytes(bb, 0, 1, &buf[0], &len)); assert_int_equal(len, 1); assert_memory_equal(buf, "A", 1); SLN_ERR(sln_brigade_pread_bytes(bb, 1, 1, &buf[0], &len)); assert_int_equal(len, 1); assert_memory_equal(buf, "B", 1); SLN_ERR(sln_brigade_pread_bytes(bb, 0, 2, &buf[0], &len)); assert_int_equal(len, 2); assert_memory_equal(buf, "AB", 2); SLN_ERR(sln_brigade_pread_bytes(bb, 2, 2, &buf[0], &len)); assert_int_equal(len, 2); assert_memory_equal(buf, "BB", 2); sln_brigade_destroy(bb); }
static void brigade_copy_into(void **state) { sln_brigade_t *source; sln_brigade_t *dest; sln_bucket_t *e1; char buf[20]; size_t len = 0; SLN_ERR(sln_brigade_create(sln_test_alloc, &source)); SLN_ERR(sln_bucket_create_empty(sln_test_alloc, &e1, 10)); SLN_BRIGADE_INSERT_TAIL(source, e1); memset(e1->data, 'A', e1->size); SLN_ERR(sln_brigade_create(sln_test_alloc, &dest)); SLN_ERR(sln_brigade_copy_into(source, 0, 10, dest)); assert_int_equal(sln_brigade_size(dest), 10); SLN_ERR(sln_brigade_pread_bytes(dest, 0, 10, &buf[0], &len)); assert_memory_equal(buf, "AAAAAAAAAA", 2); sln_brigade_clear(dest); sln_brigade_destroy(dest); SLN_ERR(sln_brigade_create(sln_test_alloc, &dest)); SLN_ERR(sln_brigade_copy_into(source, 2, 4, dest)); assert_int_equal(sln_brigade_size(dest), 4); SLN_ERR(sln_brigade_pread_bytes(dest, 0, 4, &buf[0], &len)); assert_memory_equal(buf, "AAAA", 4); sln_brigade_clear(dest); sln_brigade_destroy(dest); sln_brigade_destroy(source); }
static void brigade_chomp(void **state) { sln_brigade_t *bb; sln_bucket_t *e1; char buf[20]; size_t len = 0; SLN_ERR(sln_brigade_create(sln_test_alloc, &bb)); SLN_ERR(sln_bucket_create_empty(sln_test_alloc, &e1, 10)); SLN_BRIGADE_INSERT_TAIL(bb, e1); memset(e1->data, 'A', e1->size); assert_int_equal(sln_brigade_size(bb), 10); SLN_ERR(sln_brigade_chomp(bb, 1)); assert_int_equal(sln_brigade_size(bb), 9); SLN_ERR(sln_brigade_chomp(bb, 8)); assert_int_equal(sln_brigade_size(bb), 1); sln_brigade_destroy(bb); SLN_ERR(sln_brigade_create(sln_test_alloc, &bb)); SLN_ERR(sln_bucket_create_empty(sln_test_alloc, &e1, 10)); SLN_BRIGADE_INSERT_TAIL(bb, e1); memset(e1->data, 'A', e1->size); SLN_ERR(sln_bucket_create_empty(sln_test_alloc, &e1, 10)); SLN_BRIGADE_INSERT_TAIL(bb, e1); memset(e1->data, 'B', e1->size); assert_int_equal(sln_brigade_size(bb), 20); SLN_ERR(sln_brigade_chomp(bb, 8)); assert_int_equal(sln_brigade_size(bb), 12); SLN_ERR(sln_brigade_pread_bytes(bb, 0, 4, &buf[0], &len)); assert_memory_equal(buf, "AABB", 4); SLN_ERR(sln_brigade_chomp(bb, 2)); assert_int_equal(sln_brigade_size(bb), 10); SLN_ERR(sln_brigade_pread_bytes(bb, 0, 4, &buf[0], &len)); assert_memory_equal(buf, "BBBB", 4); SLN_ERR(sln_brigade_chomp(bb, 2)); SLN_ERR(sln_brigade_pread_bytes(bb, 0, 8, &buf[0], &len)); assert_memory_equal(buf, "BBBBBBBB", 8); assert_int_equal(sln_brigade_size(bb), 8); sln_brigade_destroy(bb); }
static void brigade_operations(void **state) { sln_brigade_t *bb; sln_bucket_t *e; SLN_ERR(sln_brigade_create(&bb)); assert_int_equal(sln_brigade_size(bb), 0); SLN_ERR(sln_bucket_create_empty(&e, 40)); SLN_BRIGADE_INSERT_TAIL(bb, e); assert_int_equal(sln_brigade_size(bb), 40); SLN_BUCKET_REMOVE(e); assert_int_equal(sln_brigade_size(bb), 0); sln_brigade_destroy(bb); }
static void brigade_pread_more_buckets(void **state) { sln_brigade_t *bb; sln_bucket_t *e1; sln_bucket_t *e2; char buf[20]; size_t len = 0; SLN_ERR(sln_brigade_create(&bb)); SLN_ERR(sln_bucket_create_empty(&e1, 10)); SLN_BRIGADE_INSERT_TAIL(bb, e1); memset(e1->data, 'A', e1->size); SLN_ERR(sln_bucket_create_empty(&e2, 10)); SLN_BRIGADE_INSERT_TAIL(bb, e2); memset(e2->data, 'B', e2->size); SLN_ERR(sln_brigade_pread_bytes(bb, 9, 1, &buf[0], &len)); assert_int_equal(len, 1); assert_memory_equal(buf, "A", 1); SLN_ERR(sln_brigade_pread_bytes(bb, 11, 1, &buf[0], &len)); assert_int_equal(len, 1); assert_memory_equal(buf, "B", 1); SLN_ERR(sln_brigade_pread_bytes(bb, 9, 2, &buf[0], &len)); assert_int_equal(len, 2); assert_memory_equal(buf, "AB", 2); SLN_ERR(sln_brigade_pread_bytes(bb, 11, 2, &buf[0], &len)); assert_int_equal(len, 2); assert_memory_equal(buf, "BB", 2); SLN_ERR(sln_brigade_pread_bytes(bb, 0, 20, &buf[0], &len)); assert_int_equal(len, 20); assert_memory_equal(buf, "AAAAAAAAAABBBBBBBBBB", 20); sln_brigade_destroy(bb); }
static void tok_bytes(void **state) { sln_brigade_t *bb; sln_bucket_t *e1; baton_t baton; baton.count = 0; SLN_ERR(sln_brigade_create(sln_test_alloc, &bb)); SLN_ERR(sln_bucket_create_empty(sln_test_alloc, &e1, 10)); SLN_BRIGADE_INSERT_TAIL(bb, e1); memset(e1->data, 'A', e1->size); SLN_ERR(sln_tok_parser(bb, tok_bytes_cb, &baton)); assert_int_equal(2, baton.count); sln_brigade_destroy(bb); }
selene_error_t *sln_tls_toss_bucket(selene_t *s, sln_content_type_e content_type, sln_bucket_t *bout) { sln_msg_tls_t tls; sln_parser_baton_t *baton = s->backend_baton; sln_bucket_t *btls = NULL; sln_bucket_t *benc = NULL; if (content_type == SLN_CONTENT_TYPE_HANDSHAKE) { sln_digest_update(baton->md5_handshake_digest, bout->data, bout->size); sln_digest_update(baton->sha1_handshake_digest, bout->data, bout->size); } SELENE_ERR(sln_tls_params_update_mac(s, bout)); SELENE_ERR(sln_tls_params_encrypt(s, bout, &benc)); tls.content_type = content_type; sln_parser_tls_set_current_version(s, &tls.version_major, &tls.version_minor); if (benc != NULL) { tls.length = benc->size; } else { tls.length = bout->size; } SELENE_ERR(sln_tls_serialize_header(s, &tls, &btls)); SLN_BRIGADE_INSERT_TAIL(s->bb.out_enc, btls); if (benc != NULL) { SLN_BRIGADE_INSERT_TAIL(s->bb.out_enc, benc); } else { SLN_BRIGADE_INSERT_TAIL(s->bb.out_enc, bout); } return SELENE_SUCCESS; }
static void tls_v2_hello(void **state) { selene_error_t *err; sln_parser_baton_t *baton; selene_conf_t *conf = NULL; selene_t *s = NULL; sln_bucket_t *e1; init_ctxt(state, &s, &conf); baton = (sln_parser_baton_t *)s->backend_baton; SLN_ERR(sln_bucket_create_copy_bytes(sln_test_alloc, &e1, (const char *)openssl_client_hello_sslv2, sizeof(openssl_client_hello_sslv2))); SLN_BRIGADE_INSERT_TAIL(s->bb.in_enc, e1); err = sln_io_tls_read(s, baton); /* TODO: successfully parse the sslv2 client hello... enough to know it was * sslv2. */ /* SLN_ASSERT(err == NULL); */ selene_error_clear(err); destroy_ctxt(state, s, conf); }