예제 #1
0
파일: rpc.c 프로젝트: dyustc/searaft
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);
    }
}
예제 #2
0
/* 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;
}