diff options
author | Julien Dessaux | 2018-05-22 17:31:56 +0200 |
---|---|---|
committer | Julien Dessaux | 2018-05-22 17:31:56 +0200 |
commit | e840c061817a797fae31a14796a790b0c979e43f (patch) | |
tree | a64752420ae1b7a91e43e4d4314b5df9f8609313 /src/main.c | |
download | bastion-e840c061817a797fae31a14796a790b0c979e43f.tar.gz bastion-e840c061817a797fae31a14796a790b0c979e43f.tar.bz2 bastion-e840c061817a797fae31a14796a790b0c979e43f.zip |
Initial import with working simple server based on libssh examples
Diffstat (limited to 'src/main.c')
-rw-r--r-- | src/main.c | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..cd8e74f --- /dev/null +++ b/src/main.c @@ -0,0 +1,103 @@ +#include <libssh/callbacks.h> +#include <libssh/server.h> +//#include <fcntl.h> +//#include <libutil.h> +//#include <poll.h> +//#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +//#include <sys/ioctl.h> +#include <sys/wait.h> +//#include <util.h> + +#include "session.h" + +/* SIGCHLD handler for cleaning up dead children. */ +static void sigchld_handler(int signo) { + (void) signo; + while (waitpid(-1, NULL, WNOHANG) > 0); +} + +int main() +{ + // Set up SIGCHLD handler + struct sigaction sa; + sa.sa_handler = sigchld_handler; + sigemptyset(&sa.sa_mask); + sa.sa_flags = SA_RESTART | SA_NOCLDSTOP; + if (sigaction(SIGCHLD, &sa, NULL) != 0) { + fprintf(stderr, "Failed to register SIGCHLD handler\n"); + return 1; + } + + // Initializing ssh context + ssh_threads_set_callbacks(ssh_threads_get_pthread()); + ssh_init(); + + // Initializing ssh_bind + ssh_bind sshbind = ssh_bind_new(); + if (sshbind == NULL) { + fprintf(stderr, "Error initializing ssh_bind\n"); + exit(-1); + } + int port = 2222; + ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_BINDPORT, &port); + ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_DSAKEY, "ssh_host_dsa_key"); + ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_RSAKEY, "ssh_host_rsa_key"); + ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_ECDSAKEY, "ssh_host_ecdsa_key"); + + if (ssh_bind_listen(sshbind) < 0) { + printf("Error listening to socket: %s\n", ssh_get_error(sshbind)); + return 1; + } + + while (1) { + ssh_session session = ssh_new(); + if (session == NULL) { + fprintf(stderr, "Error initializing ssh_session\n"); + break; + } + int verbosity = SSH_LOG_PROTOCOL; + ssh_options_set(session, SSH_OPTIONS_LOG_VERBOSITY, &verbosity); + + // Blocks until there is a new incoming connection + if (ssh_bind_accept(sshbind,session) == SSH_OK){ + switch(fork()) { + case 0: + /* Remove the SIGCHLD handler inherited from parent. */ + sa.sa_handler = SIG_DFL; + sigaction(SIGCHLD, &sa, NULL); + /* Remove socket binding, which allows us to restart the + * parent process, without terminating existing sessions. */ + ssh_bind_free(sshbind); + + ssh_event event = ssh_event_new(); + if (event != NULL) { + /* Blocks until the SSH session ends by either + * child process exiting, or client disconnecting. */ + handle_session(event, session); + ssh_event_free(event); + } else { + fprintf(stderr, "Could not create polling context\n"); + } + ssh_disconnect(session); + ssh_free(session); + + exit(0); + case -1: + fprintf(stderr, "Failed to fork\n"); + } + } else { + fprintf(stderr, "Error accepting a connection : %s\n", ssh_get_error(sshbind)); + exit(1); + } + /* Since the session has been passed to a child fork, do some cleaning + * up at the parent process. */ + ssh_disconnect(session); + ssh_free(session); + } + + ssh_bind_free(sshbind); + ssh_finalize(); + return 0; +} |