diff options
author | Alan Dunn <amdunn@gmail.com> | 2014-01-21 08:19:32 -0600 |
---|---|---|
committer | Andreas Schneider <asn@cryptomilk.org> | 2014-01-21 16:08:12 +0100 |
commit | 809d76cbf2ae509c6a29fd491e81a92827a85f25 (patch) | |
tree | b3cbadeadfa87aad2b39438a71c00c7e451464fb | |
parent | f78a74c1604af229bf0d5dacdb4aa6a98c6a1560 (diff) | |
download | libssh-809d76cbf2ae509c6a29fd491e81a92827a85f25.tar.gz libssh-809d76cbf2ae509c6a29fd491e81a92827a85f25.tar.xz libssh-809d76cbf2ae509c6a29fd491e81a92827a85f25.zip |
Test change to ssh_bind_accept_fd
Signed-off-by: Alan Dunn <amdunn@gmail.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
-rw-r--r-- | tests/test_ssh_bind_accept_fd.c | 139 |
1 files changed, 139 insertions, 0 deletions
diff --git a/tests/test_ssh_bind_accept_fd.c b/tests/test_ssh_bind_accept_fd.c new file mode 100644 index 00000000..7611cf4c --- /dev/null +++ b/tests/test_ssh_bind_accept_fd.c @@ -0,0 +1,139 @@ +/* Test the ability to use ssh_bind_accept_fd. + * + * Expected behavior: Prints "SUCCESS!" + * + * Faulty behavior observed before change: Connection timeout + */ + +#include <arpa/inet.h> +#include <err.h> +#include <libssh/libssh.h> +#include <libssh/server.h> +#include <netinet/in.h> +#include <pthread.h> +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <unistd.h> + +struct options { + const char *server_keyfile; +} options; + +const char HOST[] = "127.0.0.1"; +const int PORT = 3333; + +int get_connection() { + int rc, server_socket, client_conn = -1; + struct sockaddr_in server_socket_addr; + struct sockaddr_storage client_conn_addr; + socklen_t client_conn_addr_size = sizeof(client_conn_addr); + + server_socket = socket(PF_INET, SOCK_STREAM, 0); + if (server_socket < 0) { + goto out; + } + + server_socket_addr.sin_family = AF_INET; + server_socket_addr.sin_port = htons(PORT); + if (inet_pton(AF_INET, HOST, &server_socket_addr.sin_addr) != 1) { + goto out; + } + + rc = bind(server_socket, (struct sockaddr *)&server_socket_addr, + sizeof(server_socket_addr)); + if (rc < 0) { + goto out; + } + + if (listen(server_socket, 0) < 0) { + goto out; + } + + client_conn = accept(server_socket, + (struct sockaddr *)&client_conn_addr, + &client_conn_addr_size); + + out: + return client_conn; +} + +void ssh_server() { + ssh_bind bind; + ssh_session session; + + int client_conn = get_connection(); + if (client_conn < 0) { + err(1, "get_connection"); + } + + bind = ssh_bind_new(); + if (!bind) { + errx(1, "ssh_bind_new"); + } + + if (ssh_bind_options_set(bind, SSH_BIND_OPTIONS_DSAKEY, + options.server_keyfile) != SSH_OK) { + errx(1, "ssh_bind_options_set(SSH_BIND_OPTIONS_DSAKEY"); + } + + session = ssh_new(); + if (!session) { + errx(1, "ssh_new"); + } + + if (ssh_bind_accept_fd(bind, session, client_conn) != SSH_OK) { + errx(1, "ssh_bind_accept: %s", ssh_get_error(bind)); + } + + if (ssh_handle_key_exchange(session) != SSH_OK) { + errx(1, "ssh_handle_key_exchange: %s", ssh_get_error(session)); + } + + printf("SUCCESS!\n"); +} + +void ssh_client() { + ssh_session session; + + session = ssh_new(); + if (!session) { + errx(1, "ssh_new"); + } + + if (ssh_options_set(session, SSH_OPTIONS_HOST, HOST) < 0) { + errx(1, "ssh_options_set(SSH_OPTIONS_HOST)"); + } + if (ssh_options_set(session, SSH_OPTIONS_PORT, &PORT) < 0) { + errx(1, "ssh_options_set(SSH_OPTIONS_PORT)"); + } + + if (ssh_connect(session) != SSH_OK) { + errx(1, "ssh_connect: %s", ssh_get_error(session)); + } +} + +int main(int argc, const char *argv[]) { + if (argc != 2) { + printf("Usage: %s <private key file>\n", argv[0]); + exit(1); + } + + options.server_keyfile = argv[1]; + + pid_t pid = fork(); + if (pid < 0) { + errx(1, "fork"); + } + if (pid == 0) { + /* Allow the server to get set up */ + sleep(3); + + ssh_client(); + } else { + ssh_server(); + } + + return 0; +} |