static void http_request_done(struct evhttp_request *req, void *ctx) { struct client_rpc_callback_with_data *m_ctx = (struct client_rpc_callback_with_data *)ctx; rpc_callback client_cb = m_ctx->cb; void *data = m_ctx->data; struct evhttp_connection *evcon = m_ctx->evcon; free(m_ctx); if(req == NULL) { client_cb(NULL, "(req=NULL) Unknown error occurred while remote procedure", data); return; } int res_code = evhttp_request_get_response_code(req); char *res_code_line = "Internal server error"; printf("Got response for req %p with ctx = %p res_code = %d\n", req, ctx, res_code); if(res_code == 500) { client_cb(NULL, res_code_line, data); } else if(res_code != HTTP_OK) { if(res_code == 0) { client_cb(NULL, "host not reachable", data); } else { client_cb(NULL, "communication error", data); } } else { char *json = read_req_buffer(req); if(!json) { client_cb(NULL, "(json=NULL) Unknown error occurred while remote procedure", data); return; } char *err = NULL; struct data_t *result = deserialize_result(json, &err); client_cb(result, err, data); if(result) { free_data_t(result); } if(err) { free(err); } if(json) { free(json); } } if(evcon) { evhttp_connection_free(evcon); } }
/* if @host is NULL certificate check is skipped */ static int _test_cli_serv(gnutls_certificate_credentials_t server_cred, gnutls_certificate_credentials_t client_cred, const char *serv_prio, const char *cli_prio, const char *host, void *priv, callback_func *client_cb, callback_func *server_cb, unsigned expect_verification_failure, unsigned require_cert, int serv_err, int cli_err) { int exit_code = EXIT_SUCCESS; int ret; /* Server stuff. */ gnutls_session_t server; int sret = GNUTLS_E_AGAIN; /* Client stuff. */ gnutls_session_t client; int cret = GNUTLS_E_AGAIN; /* General init. */ reset_buffers(); /* Init server */ gnutls_init(&server, GNUTLS_SERVER); gnutls_credentials_set(server, GNUTLS_CRD_CERTIFICATE, server_cred); gnutls_priority_set_direct(server, serv_prio, NULL); gnutls_transport_set_push_function(server, server_push); gnutls_transport_set_pull_function(server, server_pull); gnutls_transport_set_ptr(server, server); if (require_cert) gnutls_certificate_server_set_request(server, GNUTLS_CERT_REQUIRE); ret = gnutls_init(&client, GNUTLS_CLIENT); if (ret < 0) exit(1); if (host) { if (strncmp(host, "raw:", 4) == 0) { assert(_gnutls_server_name_set_raw(client, GNUTLS_NAME_DNS, host+4, strlen(host+4))>=0); host += 4; } else { assert(gnutls_server_name_set(client, GNUTLS_NAME_DNS, host, strlen(host))>=0); } } ret = gnutls_credentials_set(client, GNUTLS_CRD_CERTIFICATE, client_cred); if (ret < 0) exit(1); gnutls_priority_set_direct(client, cli_prio, NULL); gnutls_transport_set_push_function(client, client_push); gnutls_transport_set_pull_function(client, client_pull); gnutls_transport_set_ptr(client, client); if (cli_err == 0 && serv_err == 0) { HANDSHAKE(client, server); } else { HANDSHAKE_EXPECT(client, server, cli_err, serv_err); } /* check the number of certificates received and verify */ if (host) { gnutls_typed_vdata_st data[2]; unsigned status; memset(data, 0, sizeof(data)); data[0].type = GNUTLS_DT_DNS_HOSTNAME; data[0].data = (void*)host; data[1].type = GNUTLS_DT_KEY_PURPOSE_OID; data[1].data = (void*)GNUTLS_KP_TLS_WWW_SERVER; ret = gnutls_certificate_verify_peers(client, data, 2, &status); if (ret < 0) { fail("could not verify certificate: %s\n", gnutls_strerror(ret)); exit(1); } if (expect_verification_failure && status != 0) { ret = status; goto cleanup; } else if (expect_verification_failure && status == 0) { fail("expected verification failure but verification succeeded!\n"); } if (status != 0) { gnutls_datum_t t; assert(gnutls_certificate_verification_status_print(status, GNUTLS_CRT_X509, &t, 0)>=0); fail("could not verify certificate for '%s': %.4x: %s\n", host, status, t.data); gnutls_free(t.data); exit(1); } /* check gnutls_certificate_verify_peers3 */ ret = gnutls_certificate_verify_peers3(client, host, &status); if (ret < 0) { fail("could not verify certificate: %s\n", gnutls_strerror(ret)); exit(1); } if (status != 0) { gnutls_datum_t t; assert(gnutls_certificate_verification_status_print(status, GNUTLS_CRT_X509, &t, 0)>=0); fail("could not verify certificate3: %.4x: %s\n", status, t.data); gnutls_free(t.data); exit(1); } } ret = 0; cleanup: if (client_cb) client_cb(client, priv); if (server_cb) server_cb(server, priv); gnutls_bye(client, GNUTLS_SHUT_RDWR); gnutls_bye(server, GNUTLS_SHUT_RDWR); gnutls_deinit(client); gnutls_deinit(server); if (debug > 0) { if (exit_code == 0) puts("Self-test successful"); else puts("Self-test failed"); } return ret; }