Blame tests/test_ssh_bind_accept_fd.c

Packit 6c0a39
/* Test the ability to use ssh_bind_accept_fd.
Packit 6c0a39
 *
Packit 6c0a39
 * Expected behavior: Prints "SUCCESS!"
Packit 6c0a39
 *
Packit 6c0a39
 * Faulty behavior observed before change: Connection timeout
Packit 6c0a39
 */
Packit 6c0a39
Packit 6c0a39
#include <arpa/inet.h>
Packit 6c0a39
#include <err.h>
Packit 6c0a39
#include <libssh/libssh.h>
Packit 6c0a39
#include <libssh/server.h>
Packit 6c0a39
#include <netinet/in.h>
Packit 6c0a39
#include <pthread.h>
Packit 6c0a39
#include <stdio.h>
Packit 6c0a39
#include <stdlib.h>
Packit 6c0a39
#include <sys/types.h>
Packit 6c0a39
#include <sys/socket.h>
Packit 6c0a39
#include <unistd.h>
Packit 6c0a39
Packit 6c0a39
struct options {
Packit 6c0a39
  const char *server_keyfile;
Packit 6c0a39
} options;
Packit 6c0a39
Packit 6c0a39
const char HOST[] = "127.0.0.1";
Packit 6c0a39
const int PORT = 3333;
Packit 6c0a39
Packit 6c0a39
int get_connection() {
Packit 6c0a39
  int rc, server_socket, client_conn = -1;
Packit 6c0a39
  struct sockaddr_in server_socket_addr;
Packit 6c0a39
  struct sockaddr_storage client_conn_addr;
Packit 6c0a39
  socklen_t client_conn_addr_size = sizeof(client_conn_addr);
Packit 6c0a39
Packit 6c0a39
  server_socket = socket(PF_INET, SOCK_STREAM, 0);
Packit 6c0a39
  if (server_socket < 0) {
Packit 6c0a39
    goto out;
Packit 6c0a39
  }
Packit 6c0a39
Packit 6c0a39
  server_socket_addr.sin_family = AF_INET;
Packit 6c0a39
  server_socket_addr.sin_port = htons(PORT);
Packit 6c0a39
  if (inet_pton(AF_INET, HOST, &server_socket_addr.sin_addr) != 1) {
Packit 6c0a39
    goto out;
Packit 6c0a39
  }
Packit 6c0a39
Packit 6c0a39
  rc = bind(server_socket, (struct sockaddr *)&server_socket_addr,
Packit 6c0a39
            sizeof(server_socket_addr));
Packit 6c0a39
  if (rc < 0) {
Packit 6c0a39
    goto out;
Packit 6c0a39
  }
Packit 6c0a39
Packit 6c0a39
  if (listen(server_socket, 0) < 0) {
Packit 6c0a39
    goto out;
Packit 6c0a39
  }
Packit 6c0a39
Packit 6c0a39
  client_conn = accept(server_socket,
Packit 6c0a39
                       (struct sockaddr *)&client_conn_addr,
Packit 6c0a39
                       &client_conn_addr_size);
Packit 6c0a39
Packit 6c0a39
 out:
Packit 6c0a39
  return client_conn;
Packit 6c0a39
}
Packit 6c0a39
Packit 6c0a39
void ssh_server() {
Packit 6c0a39
  ssh_bind bind;
Packit 6c0a39
  ssh_session session;
Packit 6c0a39
Packit 6c0a39
  int client_conn = get_connection();
Packit 6c0a39
  if (client_conn < 0) {
Packit 6c0a39
    err(1, "get_connection");
Packit 6c0a39
  }
Packit 6c0a39
Packit 6c0a39
  bind = ssh_bind_new();
Packit 6c0a39
  if (!bind) {
Packit 6c0a39
    errx(1, "ssh_bind_new");
Packit 6c0a39
  }
Packit 6c0a39
Packit 6c0a39
#ifdef HAVE_DSA
Packit 6c0a39
  /*TODO mbedtls this is probably required */
Packit 6c0a39
  if (ssh_bind_options_set(bind, SSH_BIND_OPTIONS_DSAKEY,
Packit 6c0a39
                           options.server_keyfile) != SSH_OK) {
Packit 6c0a39
    errx(1, "ssh_bind_options_set(SSH_BIND_OPTIONS_DSAKEY");
Packit 6c0a39
  }
Packit 6c0a39
#else
Packit 6c0a39
  if (ssh_bind_options_set(bind, SSH_BIND_OPTIONS_RSAKEY,
Packit 6c0a39
                           options.server_keyfile) != SSH_OK) {
Packit 6c0a39
    errx(1, "ssh_bind_options_set(SSH_BIND_OPTIONS_RSAKEY");
Packit 6c0a39
  }
Packit 6c0a39
#endif
Packit 6c0a39
Packit 6c0a39
  session = ssh_new();
Packit 6c0a39
  if (!session) {
Packit 6c0a39
    errx(1, "ssh_new");
Packit 6c0a39
  }
Packit 6c0a39
Packit 6c0a39
  if (ssh_bind_accept_fd(bind, session, client_conn) != SSH_OK) {
Packit 6c0a39
    errx(1, "ssh_bind_accept: %s", ssh_get_error(bind));
Packit 6c0a39
  }
Packit 6c0a39
Packit 6c0a39
  if (ssh_handle_key_exchange(session) != SSH_OK) {
Packit 6c0a39
    errx(1, "ssh_handle_key_exchange: %s", ssh_get_error(session));
Packit 6c0a39
  }
Packit 6c0a39
Packit 6c0a39
  printf("SUCCESS!\n");
Packit 6c0a39
}
Packit 6c0a39
Packit 6c0a39
void ssh_client() {
Packit 6c0a39
  ssh_session session;
Packit 6c0a39
Packit 6c0a39
  session = ssh_new();
Packit 6c0a39
  if (!session) {
Packit 6c0a39
    errx(1, "ssh_new");
Packit 6c0a39
  }
Packit 6c0a39
Packit 6c0a39
  if (ssh_options_set(session, SSH_OPTIONS_HOST, HOST) < 0) {
Packit 6c0a39
    errx(1, "ssh_options_set(SSH_OPTIONS_HOST)");
Packit 6c0a39
  }
Packit 6c0a39
  if (ssh_options_set(session, SSH_OPTIONS_PORT, &PORT) < 0) {
Packit 6c0a39
    errx(1, "ssh_options_set(SSH_OPTIONS_PORT)");
Packit 6c0a39
  }
Packit 6c0a39
Packit 6c0a39
  if (ssh_connect(session) != SSH_OK) {
Packit 6c0a39
    errx(1, "ssh_connect: %s", ssh_get_error(session));
Packit 6c0a39
  }
Packit 6c0a39
}
Packit 6c0a39
Packit 6c0a39
int main(int argc, const char *argv[]) {
Packit 6c0a39
  if (argc != 2) {
Packit 6c0a39
    printf("Usage: %s <private key file>\n", argv[0]);
Packit 6c0a39
    exit(1);
Packit 6c0a39
  }
Packit 6c0a39
Packit 6c0a39
  options.server_keyfile = argv[1];
Packit 6c0a39
Packit 6c0a39
  pid_t pid = fork();
Packit 6c0a39
  if (pid < 0) {
Packit 6c0a39
    errx(1, "fork");
Packit 6c0a39
  }
Packit 6c0a39
  if (pid == 0) {
Packit 6c0a39
    /* Allow the server to get set up */
Packit 6c0a39
    sleep(3);
Packit 6c0a39
Packit 6c0a39
    ssh_client();
Packit 6c0a39
  } else {
Packit 6c0a39
    ssh_server();
Packit 6c0a39
  }
Packit 6c0a39
Packit 6c0a39
  return 0;
Packit 6c0a39
}