コード例 #1
0
static void test_io_channel_file(void)
{
    QIOChannel *src, *dst;
    QIOChannelTest *test;

#define TEST_FILE "tests/test-io-channel-file.txt"
    unlink(TEST_FILE);
    src = QIO_CHANNEL(qio_channel_file_new_path(
                          TEST_FILE,
                          O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0600,
                          &error_abort));
    dst = QIO_CHANNEL(qio_channel_file_new_path(
                          TEST_FILE,
                          O_RDONLY | O_BINARY, 0,
                          &error_abort));

    test = qio_channel_test_new();
    qio_channel_test_run_writer(test, src);
    qio_channel_test_run_reader(test, dst);
    qio_channel_test_validate(test);

    unlink(TEST_FILE);
    object_unref(OBJECT(src));
    object_unref(OBJECT(dst));
}
コード例 #2
0
static void test_io_channel_pipe(bool async)
{
    QIOChannel *src, *dst;
    QIOChannelTest *test;
    int fd[2];

    if (pipe(fd) < 0) {
        perror("pipe");
        abort();
    }

    src = QIO_CHANNEL(qio_channel_file_new_fd(fd[1]));
    dst = QIO_CHANNEL(qio_channel_file_new_fd(fd[0]));

    test = qio_channel_test_new();
    qio_channel_test_run_threads(test, async, src, dst);
    qio_channel_test_validate(test);

    object_unref(OBJECT(src));
    object_unref(OBJECT(dst));
}
コード例 #3
0
static void test_io_channel(bool async,
                            SocketAddress *listen_addr,
                            SocketAddress *connect_addr,
                            bool passFD)
{
    QIOChannel *src, *dst;
    QIOChannelTest *test;
    if (async) {
        test_io_channel_setup_async(listen_addr, connect_addr, &src, &dst);

        g_assert(!passFD ||
                 qio_channel_has_feature(src, QIO_CHANNEL_FEATURE_FD_PASS));
        g_assert(!passFD ||
                 qio_channel_has_feature(dst, QIO_CHANNEL_FEATURE_FD_PASS));
        g_assert(qio_channel_has_feature(src, QIO_CHANNEL_FEATURE_SHUTDOWN));
        g_assert(qio_channel_has_feature(dst, QIO_CHANNEL_FEATURE_SHUTDOWN));

        test = qio_channel_test_new();
        qio_channel_test_run_threads(test, true, src, dst);
        qio_channel_test_validate(test);

        object_unref(OBJECT(src));
        object_unref(OBJECT(dst));

        test_io_channel_setup_async(listen_addr, connect_addr, &src, &dst);

        g_assert(!passFD ||
                 qio_channel_has_feature(src, QIO_CHANNEL_FEATURE_FD_PASS));
        g_assert(!passFD ||
                 qio_channel_has_feature(dst, QIO_CHANNEL_FEATURE_FD_PASS));
        g_assert(qio_channel_has_feature(src, QIO_CHANNEL_FEATURE_SHUTDOWN));
        g_assert(qio_channel_has_feature(dst, QIO_CHANNEL_FEATURE_SHUTDOWN));

        test = qio_channel_test_new();
        qio_channel_test_run_threads(test, false, src, dst);
        qio_channel_test_validate(test);

        object_unref(OBJECT(src));
        object_unref(OBJECT(dst));
    } else {
        test_io_channel_setup_sync(listen_addr, connect_addr, &src, &dst);

        g_assert(!passFD ||
                 qio_channel_has_feature(src, QIO_CHANNEL_FEATURE_FD_PASS));
        g_assert(!passFD ||
                 qio_channel_has_feature(dst, QIO_CHANNEL_FEATURE_FD_PASS));
        g_assert(qio_channel_has_feature(src, QIO_CHANNEL_FEATURE_SHUTDOWN));
        g_assert(qio_channel_has_feature(dst, QIO_CHANNEL_FEATURE_SHUTDOWN));

        test = qio_channel_test_new();
        qio_channel_test_run_threads(test, true, src, dst);
        qio_channel_test_validate(test);

        object_unref(OBJECT(src));
        object_unref(OBJECT(dst));

        test_io_channel_setup_sync(listen_addr, connect_addr, &src, &dst);

        g_assert(!passFD ||
                 qio_channel_has_feature(src, QIO_CHANNEL_FEATURE_FD_PASS));
        g_assert(!passFD ||
                 qio_channel_has_feature(dst, QIO_CHANNEL_FEATURE_FD_PASS));
        g_assert(qio_channel_has_feature(src, QIO_CHANNEL_FEATURE_SHUTDOWN));
        g_assert(qio_channel_has_feature(dst, QIO_CHANNEL_FEATURE_SHUTDOWN));

        test = qio_channel_test_new();
        qio_channel_test_run_threads(test, false, src, dst);
        qio_channel_test_validate(test);

        object_unref(OBJECT(src));
        object_unref(OBJECT(dst));
    }
}
コード例 #4
0
ファイル: test-io-channel-tls.c プロジェクト: AmesianX/panda
/*
 * This tests validation checking of peer certificates
 *
 * This is replicating the checks that are done for an
 * active TLS session after handshake completes. To
 * simulate that we create our TLS contexts, skipping
 * sanity checks. When then get a socketpair, and
 * initiate a TLS session across them. Finally do
 * do actual cert validation tests
 */
static void test_io_channel_tls(const void *opaque)
{
    struct QIOChannelTLSTestData *data =
        (struct QIOChannelTLSTestData *)opaque;
    QCryptoTLSCreds *clientCreds;
    QCryptoTLSCreds *serverCreds;
    QIOChannelTLS *clientChanTLS;
    QIOChannelTLS *serverChanTLS;
    QIOChannelSocket *clientChanSock;
    QIOChannelSocket *serverChanSock;
    qemu_acl *acl;
    const char * const *wildcards;
    int channel[2];
    struct QIOChannelTLSHandshakeData clientHandshake = { false, false };
    struct QIOChannelTLSHandshakeData serverHandshake = { false, false };
    Error *err = NULL;
    QIOChannelTest *test;
    GMainContext *mainloop;

    /* We'll use this for our fake client-server connection */
    g_assert(socketpair(AF_UNIX, SOCK_STREAM, 0, channel) == 0);

#define CLIENT_CERT_DIR "tests/test-crypto-tlssession-client/"
#define SERVER_CERT_DIR "tests/test-crypto-tlssession-server/"
    mkdir(CLIENT_CERT_DIR, 0700);
    mkdir(SERVER_CERT_DIR, 0700);

    unlink(SERVER_CERT_DIR QCRYPTO_TLS_CREDS_X509_CA_CERT);
    unlink(SERVER_CERT_DIR QCRYPTO_TLS_CREDS_X509_SERVER_CERT);
    unlink(SERVER_CERT_DIR QCRYPTO_TLS_CREDS_X509_SERVER_KEY);

    unlink(CLIENT_CERT_DIR QCRYPTO_TLS_CREDS_X509_CA_CERT);
    unlink(CLIENT_CERT_DIR QCRYPTO_TLS_CREDS_X509_CLIENT_CERT);
    unlink(CLIENT_CERT_DIR QCRYPTO_TLS_CREDS_X509_CLIENT_KEY);

    g_assert(link(data->servercacrt,
                  SERVER_CERT_DIR QCRYPTO_TLS_CREDS_X509_CA_CERT) == 0);
    g_assert(link(data->servercrt,
                  SERVER_CERT_DIR QCRYPTO_TLS_CREDS_X509_SERVER_CERT) == 0);
    g_assert(link(KEYFILE,
                  SERVER_CERT_DIR QCRYPTO_TLS_CREDS_X509_SERVER_KEY) == 0);

    g_assert(link(data->clientcacrt,
                  CLIENT_CERT_DIR QCRYPTO_TLS_CREDS_X509_CA_CERT) == 0);
    g_assert(link(data->clientcrt,
                  CLIENT_CERT_DIR QCRYPTO_TLS_CREDS_X509_CLIENT_CERT) == 0);
    g_assert(link(KEYFILE,
                  CLIENT_CERT_DIR QCRYPTO_TLS_CREDS_X509_CLIENT_KEY) == 0);

    clientCreds = test_tls_creds_create(
        QCRYPTO_TLS_CREDS_ENDPOINT_CLIENT,
        CLIENT_CERT_DIR,
        &err);
    g_assert(clientCreds != NULL);

    serverCreds = test_tls_creds_create(
        QCRYPTO_TLS_CREDS_ENDPOINT_SERVER,
        SERVER_CERT_DIR,
        &err);
    g_assert(serverCreds != NULL);

    acl = qemu_acl_init("channeltlsacl");
    qemu_acl_reset(acl);
    wildcards = data->wildcards;
    while (wildcards && *wildcards) {
        qemu_acl_append(acl, 0, *wildcards);
        wildcards++;
    }

    clientChanSock = qio_channel_socket_new_fd(
        channel[0], &err);
    g_assert(clientChanSock != NULL);
    serverChanSock = qio_channel_socket_new_fd(
        channel[1], &err);
    g_assert(serverChanSock != NULL);

    /*
     * We have an evil loop to do the handshake in a single
     * thread, so we need these non-blocking to avoid deadlock
     * of ourselves
     */
    qio_channel_set_blocking(QIO_CHANNEL(clientChanSock), false, NULL);
    qio_channel_set_blocking(QIO_CHANNEL(serverChanSock), false, NULL);

    /* Now the real part of the test, setup the sessions */
    clientChanTLS = qio_channel_tls_new_client(
        QIO_CHANNEL(clientChanSock), clientCreds,
        data->hostname, &err);
    g_assert(clientChanTLS != NULL);

    serverChanTLS = qio_channel_tls_new_server(
        QIO_CHANNEL(serverChanSock), serverCreds,
        "channeltlsacl", &err);
    g_assert(serverChanTLS != NULL);

    qio_channel_tls_handshake(clientChanTLS,
                              test_tls_handshake_done,
                              &clientHandshake,
                              NULL);
    qio_channel_tls_handshake(serverChanTLS,
                              test_tls_handshake_done,
                              &serverHandshake,
                              NULL);

    /*
     * Finally we loop around & around doing handshake on each
     * session until we get an error, or the handshake completes.
     * This relies on the socketpair being nonblocking to avoid
     * deadlocking ourselves upon handshake
     */
    mainloop = g_main_context_default();
    do {
        g_main_context_iteration(mainloop, TRUE);
    } while (!clientHandshake.finished &&
             !serverHandshake.finished);

    g_assert(clientHandshake.failed == data->expectClientFail);
    g_assert(serverHandshake.failed == data->expectServerFail);

    test = qio_channel_test_new();
    qio_channel_test_run_threads(test, false,
                                 QIO_CHANNEL(clientChanTLS),
                                 QIO_CHANNEL(serverChanTLS));
    qio_channel_test_validate(test);

    test = qio_channel_test_new();
    qio_channel_test_run_threads(test, true,
                                 QIO_CHANNEL(clientChanTLS),
                                 QIO_CHANNEL(serverChanTLS));
    qio_channel_test_validate(test);

    unlink(SERVER_CERT_DIR QCRYPTO_TLS_CREDS_X509_CA_CERT);
    unlink(SERVER_CERT_DIR QCRYPTO_TLS_CREDS_X509_SERVER_CERT);
    unlink(SERVER_CERT_DIR QCRYPTO_TLS_CREDS_X509_SERVER_KEY);

    unlink(CLIENT_CERT_DIR QCRYPTO_TLS_CREDS_X509_CA_CERT);
    unlink(CLIENT_CERT_DIR QCRYPTO_TLS_CREDS_X509_CLIENT_CERT);
    unlink(CLIENT_CERT_DIR QCRYPTO_TLS_CREDS_X509_CLIENT_KEY);

    rmdir(CLIENT_CERT_DIR);
    rmdir(SERVER_CERT_DIR);

    object_unparent(OBJECT(serverCreds));
    object_unparent(OBJECT(clientCreds));

    object_unref(OBJECT(serverChanTLS));
    object_unref(OBJECT(clientChanTLS));

    object_unref(OBJECT(serverChanSock));
    object_unref(OBJECT(clientChanSock));

    close(channel[0]);
    close(channel[1]);
}
コード例 #5
0
static void test_io_channel(bool async,
                            SocketAddress *listen_addr,
                            SocketAddress *connect_addr,
                            bool passFD)
{
    QIOChannel *src, *dst, *srv;
    QIOChannelTest *test;
    if (async) {
        test_io_channel_setup_async(listen_addr, connect_addr,
                                    &srv, &src, &dst);

        g_assert(!passFD ||
                 qio_channel_has_feature(src, QIO_CHANNEL_FEATURE_FD_PASS));
        g_assert(!passFD ||
                 qio_channel_has_feature(dst, QIO_CHANNEL_FEATURE_FD_PASS));
        g_assert(qio_channel_has_feature(src, QIO_CHANNEL_FEATURE_SHUTDOWN));
        g_assert(qio_channel_has_feature(dst, QIO_CHANNEL_FEATURE_SHUTDOWN));

        test_io_channel_socket_path_exists(listen_addr, true);

        test = qio_channel_test_new();
        qio_channel_test_run_threads(test, true, src, dst);
        qio_channel_test_validate(test);

        test_io_channel_socket_path_exists(listen_addr, true);

        /* unref without close, to ensure finalize() cleans up */

        object_unref(OBJECT(src));
        object_unref(OBJECT(dst));
        test_io_channel_socket_path_exists(listen_addr, true);

        object_unref(OBJECT(srv));
        test_io_channel_socket_path_exists(listen_addr, false);

        test_io_channel_setup_async(listen_addr, connect_addr,
                                    &srv, &src, &dst);

        g_assert(!passFD ||
                 qio_channel_has_feature(src, QIO_CHANNEL_FEATURE_FD_PASS));
        g_assert(!passFD ||
                 qio_channel_has_feature(dst, QIO_CHANNEL_FEATURE_FD_PASS));
        g_assert(qio_channel_has_feature(src, QIO_CHANNEL_FEATURE_SHUTDOWN));
        g_assert(qio_channel_has_feature(dst, QIO_CHANNEL_FEATURE_SHUTDOWN));

        test = qio_channel_test_new();
        qio_channel_test_run_threads(test, false, src, dst);
        qio_channel_test_validate(test);

        /* close before unref, to ensure finalize copes with already closed */

        qio_channel_close(src, &error_abort);
        qio_channel_close(dst, &error_abort);
        test_io_channel_socket_path_exists(listen_addr, true);

        object_unref(OBJECT(src));
        object_unref(OBJECT(dst));
        test_io_channel_socket_path_exists(listen_addr, true);

        qio_channel_close(srv, &error_abort);
        test_io_channel_socket_path_exists(listen_addr, false);

        object_unref(OBJECT(srv));
        test_io_channel_socket_path_exists(listen_addr, false);
    } else {
        test_io_channel_setup_sync(listen_addr, connect_addr,
                                   &srv, &src, &dst);

        g_assert(!passFD ||
                 qio_channel_has_feature(src, QIO_CHANNEL_FEATURE_FD_PASS));
        g_assert(!passFD ||
                 qio_channel_has_feature(dst, QIO_CHANNEL_FEATURE_FD_PASS));
        g_assert(qio_channel_has_feature(src, QIO_CHANNEL_FEATURE_SHUTDOWN));
        g_assert(qio_channel_has_feature(dst, QIO_CHANNEL_FEATURE_SHUTDOWN));

        test_io_channel_socket_path_exists(listen_addr, true);

        test = qio_channel_test_new();
        qio_channel_test_run_threads(test, true, src, dst);
        qio_channel_test_validate(test);

        test_io_channel_socket_path_exists(listen_addr, true);

        /* unref without close, to ensure finalize() cleans up */

        object_unref(OBJECT(src));
        object_unref(OBJECT(dst));
        test_io_channel_socket_path_exists(listen_addr, true);

        object_unref(OBJECT(srv));
        test_io_channel_socket_path_exists(listen_addr, false);

        test_io_channel_setup_sync(listen_addr, connect_addr,
                                   &srv, &src, &dst);

        g_assert(!passFD ||
                 qio_channel_has_feature(src, QIO_CHANNEL_FEATURE_FD_PASS));
        g_assert(!passFD ||
                 qio_channel_has_feature(dst, QIO_CHANNEL_FEATURE_FD_PASS));
        g_assert(qio_channel_has_feature(src, QIO_CHANNEL_FEATURE_SHUTDOWN));
        g_assert(qio_channel_has_feature(dst, QIO_CHANNEL_FEATURE_SHUTDOWN));

        test = qio_channel_test_new();
        qio_channel_test_run_threads(test, false, src, dst);
        qio_channel_test_validate(test);

        test_io_channel_socket_path_exists(listen_addr, true);

        /* close before unref, to ensure finalize copes with already closed */

        qio_channel_close(src, &error_abort);
        qio_channel_close(dst, &error_abort);
        test_io_channel_socket_path_exists(listen_addr, true);

        object_unref(OBJECT(src));
        object_unref(OBJECT(dst));
        test_io_channel_socket_path_exists(listen_addr, true);

        qio_channel_close(srv, &error_abort);
        test_io_channel_socket_path_exists(listen_addr, false);

        object_unref(OBJECT(srv));
        test_io_channel_socket_path_exists(listen_addr, false);
    }
}