Blame tests/unittests/torture_server_x11.c

Packit Service 31306d
#define LIBSSH_STATIC
Packit Service 31306d
Packit Service 31306d
#include <errno.h>
Packit Service 31306d
#include <pthread.h>
Packit Service 31306d
#include <stdlib.h>
Packit Service 31306d
#include <sys/types.h>
Packit Service 31306d
#include <sys/stat.h>
Packit Service 31306d
Packit Service 31306d
#include <libssh/libssh.h>
Packit Service 31306d
#include "torture.h"
Packit Service 31306d
Packit Service 31306d
#define TEST_SERVER_PORT 2222
Packit Service 31306d
Packit Service 31306d
struct hostkey_state {
Packit Service 31306d
    const char *hostkey;
Packit Service 31306d
    char *hostkey_path;
Packit Service 31306d
    enum ssh_keytypes_e key_type;
Packit Service 31306d
    int fd;
Packit Service 31306d
};
Packit Service 31306d
Packit Service 31306d
static int setup(void **state) {
Packit Service 31306d
    struct hostkey_state *h;
Packit Service 31306d
    mode_t mask;
Packit Service 31306d
    int rc;
Packit Service 31306d
Packit Service 31306d
    ssh_threads_set_callbacks(ssh_threads_get_pthread());
Packit Service 31306d
    rc = ssh_init();
Packit Service 31306d
    if (rc != SSH_OK) {
Packit Service 31306d
        return -1;
Packit Service 31306d
    }
Packit Service 31306d
Packit Service 31306d
    h = malloc(sizeof(struct hostkey_state));
Packit Service 31306d
    assert_non_null(h);
Packit Service 31306d
Packit Service 31306d
    h->hostkey_path = strdup("/tmp/libssh_hostkey_XXXXXX");
Packit Service 31306d
Packit Service 31306d
    mask = umask(S_IRWXO | S_IRWXG);
Packit Service 31306d
    h->fd = mkstemp(h->hostkey_path);
Packit Service 31306d
    umask(mask);
Packit Service 31306d
    assert_return_code(h->fd, errno);
Packit Service 31306d
    close(h->fd);
Packit Service 31306d
Packit Service 31306d
    h->key_type = SSH_KEYTYPE_ECDSA_P256;
Packit Service 31306d
    h->hostkey = torture_get_testkey(h->key_type, 0);
Packit Service 31306d
Packit Service 31306d
    torture_write_file(h->hostkey_path, h->hostkey);
Packit Service 31306d
Packit Service 31306d
    *state = h;
Packit Service 31306d
Packit Service 31306d
    return 0;
Packit Service 31306d
}
Packit Service 31306d
Packit Service 31306d
static int teardown(void **state) {
Packit Service 31306d
    struct hostkey_state *h = (struct hostkey_state *)*state;
Packit Service 31306d
Packit Service 31306d
    unlink(h->hostkey);
Packit Service 31306d
    free(h->hostkey_path);
Packit Service 31306d
    free(h);
Packit Service 31306d
Packit Service 31306d
    ssh_finalize();
Packit Service 31306d
Packit Service 31306d
    return 0;
Packit Service 31306d
}
Packit Service 31306d
Packit Service 31306d
/* For x11_screen_number, need something that is not equal to htonl
Packit Service 31306d
   itself */
Packit Service 31306d
static const uint32_t x11_screen_number = 1;
Packit Service 31306d
Packit Service 31306d
static void *client_thread(void *arg) {
Packit Service 31306d
    unsigned int test_port = TEST_SERVER_PORT;
Packit Service 31306d
    int rc;
Packit Service 31306d
    ssh_session session;
Packit Service 31306d
    ssh_channel channel;
Packit Service 31306d
Packit Service 31306d
    /* unused */
Packit Service 31306d
    (void)arg;
Packit Service 31306d
Packit Service 31306d
    usleep(200);
Packit Service 31306d
    session = torture_ssh_session(NULL, "localhost",
Packit Service 31306d
                                  &test_port,
Packit Service 31306d
                                  "foo", "bar");
Packit Service 31306d
    assert_non_null(session);
Packit Service 31306d
Packit Service 31306d
    channel = ssh_channel_new(session);
Packit Service 31306d
    assert_non_null(channel);
Packit Service 31306d
Packit Service 31306d
    rc = ssh_channel_open_session(channel);
Packit Service 31306d
    assert_int_equal(rc, SSH_OK);
Packit Service 31306d
Packit Service 31306d
    rc = ssh_channel_request_x11(channel, 0, NULL, NULL,
Packit Service 31306d
                                 (uint32_t)x11_screen_number);
Packit Service 31306d
    assert_int_equal(rc, SSH_OK);
Packit Service 31306d
Packit Service 31306d
    ssh_free(session);
Packit Service 31306d
    return NULL;
Packit Service 31306d
}
Packit Service 31306d
Packit Service 31306d
static int auth_password_accept(ssh_session session,
Packit Service 31306d
                                const char *user,
Packit Service 31306d
                                const char *password,
Packit Service 31306d
                                void *userdata) {
Packit Service 31306d
    /* unused */
Packit Service 31306d
    (void)session;
Packit Service 31306d
    (void)user;
Packit Service 31306d
    (void)password;
Packit Service 31306d
    (void)userdata;
Packit Service 31306d
Packit Service 31306d
    return SSH_AUTH_SUCCESS;
Packit Service 31306d
}
Packit Service 31306d
Packit Service 31306d
struct channel_data {
Packit Service 31306d
    int req_seen;
Packit Service 31306d
    uint32_t screen_number;
Packit Service 31306d
};
Packit Service 31306d
Packit Service 31306d
static void ssh_channel_x11_req(ssh_session session,
Packit Service 31306d
                                ssh_channel channel,
Packit Service 31306d
                                int single_connection,
Packit Service 31306d
                                const char *auth_protocol,
Packit Service 31306d
                                const char *auth_cookie,
Packit Service 31306d
                                uint32_t screen_number,
Packit Service 31306d
                                void *userdata) {
Packit Service 31306d
    struct channel_data *channel_data = userdata;
Packit Service 31306d
Packit Service 31306d
    /* unused */
Packit Service 31306d
    (void)session;
Packit Service 31306d
    (void)channel;
Packit Service 31306d
    (void)single_connection;
Packit Service 31306d
    (void)auth_protocol;
Packit Service 31306d
    (void)auth_cookie;
Packit Service 31306d
Packit Service 31306d
    /* We've seen an x11 request.  Record the screen number */
Packit Service 31306d
    channel_data->req_seen = 1;
Packit Service 31306d
    channel_data->screen_number = screen_number;
Packit Service 31306d
}
Packit Service 31306d
Packit Service 31306d
static ssh_channel channel_open(ssh_session session, void *userdata) {
Packit Service 31306d
    ssh_channel channel = NULL;
Packit Service 31306d
    ssh_channel_callbacks channel_cb = userdata;
Packit Service 31306d
Packit Service 31306d
    /* unused */
Packit Service 31306d
    (void)userdata;
Packit Service 31306d
Packit Service 31306d
    channel = ssh_channel_new(session);
Packit Service 31306d
    if (channel == NULL) {
Packit Service 31306d
        goto out;
Packit Service 31306d
    }
Packit Service 31306d
    ssh_set_channel_callbacks(channel, channel_cb);
Packit Service 31306d
Packit Service 31306d
 out:
Packit Service 31306d
    return channel;
Packit Service 31306d
}
Packit Service 31306d
Packit Service 31306d
static void test_ssh_channel_request_x11(void **state) {
Packit Service 31306d
    struct hostkey_state *h = (struct hostkey_state *)*state;
Packit Service 31306d
    int rc, event_rc;
Packit Service 31306d
    pthread_t client_pthread;
Packit Service 31306d
    ssh_bind sshbind;
Packit Service 31306d
    ssh_session server;
Packit Service 31306d
    ssh_event event;
Packit Service 31306d
Packit Service 31306d
    struct channel_data channel_data;
Packit Service 31306d
    struct ssh_channel_callbacks_struct channel_cb = {
Packit Service 31306d
        .userdata = &channel_data,
Packit Service 31306d
        .channel_x11_req_function = ssh_channel_x11_req
Packit Service 31306d
    };
Packit Service 31306d
    struct ssh_server_callbacks_struct server_cb = {
Packit Service 31306d
        .userdata = &channel_cb,
Packit Service 31306d
        .auth_password_function = auth_password_accept,
Packit Service 31306d
        .channel_open_request_session_function = channel_open
Packit Service 31306d
    };
Packit Service 31306d
Packit Service 31306d
    memset(&channel_data, 0, sizeof(channel_data));
Packit Service 31306d
    ssh_callbacks_init(&channel_cb);
Packit Service 31306d
    ssh_callbacks_init(&server_cb);
Packit Service 31306d
Packit Service 31306d
    /* Create server */
Packit Service 31306d
    sshbind = torture_ssh_bind("localhost",
Packit Service 31306d
                               TEST_SERVER_PORT,
Packit Service 31306d
                               h->key_type,
Packit Service 31306d
                               h->hostkey_path);
Packit Service 31306d
    assert_non_null(sshbind);
Packit Service 31306d
Packit Service 31306d
    /* Get client to connect */
Packit Service 31306d
    rc = pthread_create(&client_pthread, NULL, client_thread, NULL);
Packit Service 31306d
    assert_return_code(rc, errno);
Packit Service 31306d
Packit Service 31306d
    server = ssh_new();
Packit Service 31306d
    assert_non_null(server);
Packit Service 31306d
Packit Service 31306d
    rc = ssh_bind_accept(sshbind, server);
Packit Service 31306d
    assert_int_equal(rc, SSH_OK);
Packit Service 31306d
Packit Service 31306d
    /* Handle client connection */
Packit Service 31306d
    ssh_set_server_callbacks(server, &server_cb);
Packit Service 31306d
Packit Service 31306d
    rc = ssh_handle_key_exchange(server);
Packit Service 31306d
    assert_int_equal(rc, SSH_OK);
Packit Service 31306d
Packit Service 31306d
    event = ssh_event_new();
Packit Service 31306d
    assert_non_null(event);
Packit Service 31306d
Packit Service 31306d
    ssh_event_add_session(event, server);
Packit Service 31306d
Packit Service 31306d
    event_rc = SSH_OK;
Packit Service 31306d
    while (!channel_data.req_seen && event_rc == SSH_OK) {
Packit Service 31306d
        event_rc = ssh_event_dopoll(event, -1);
Packit Service 31306d
    }
Packit Service 31306d
Packit Service 31306d
    /* Cleanup */
Packit Service 31306d
    ssh_event_free(event);
Packit Service 31306d
    ssh_free(server);
Packit Service 31306d
    ssh_bind_free(sshbind);
Packit Service 31306d
Packit Service 31306d
    rc = pthread_join(client_pthread, NULL);
Packit Service 31306d
    assert_int_equal(rc, 0);
Packit Service 31306d
Packit Service 31306d
    assert_true(channel_data.req_seen);
Packit Service 31306d
    assert_int_equal(channel_data.screen_number,
Packit Service 31306d
                     x11_screen_number);
Packit Service 31306d
}
Packit Service 31306d
Packit Service 31306d
int torture_run_tests(void) {
Packit Service 31306d
    int rc;
Packit Service 31306d
    const struct CMUnitTest tests[] = {
Packit Service 31306d
        cmocka_unit_test_setup_teardown(test_ssh_channel_request_x11,
Packit Service 31306d
                                        setup,
Packit Service 31306d
                                        teardown)
Packit Service 31306d
    };
Packit Service 31306d
Packit Service 31306d
    rc = cmocka_run_group_tests(tests, NULL, NULL);
Packit Service 31306d
    return rc;
Packit Service 31306d
}
Packit Service 31306d