aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJulien Dessaux2019-02-14 20:51:41 +0100
committerJulien Dessaux2019-02-14 21:07:27 +0100
commita3f34674c6317930362c99f0fc40d835234843e5 (patch)
tree6c4c3afa605acf567b6b5997db4a3277738c9c68 /src
parentSwitched from standard makefile to cmake (diff)
downloadbastion-a3f34674c6317930362c99f0fc40d835234843e5.tar.gz
bastion-a3f34674c6317930362c99f0fc40d835234843e5.tar.bz2
bastion-a3f34674c6317930362c99f0fc40d835234843e5.zip
Moved code around
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt9
-rw-r--r--src/client.c224
-rw-r--r--src/client.h22
-rw-r--r--src/main.c133
-rw-r--r--src/mysql.c188
-rw-r--r--src/mysql.h22
-rw-r--r--src/proxy.c219
-rw-r--r--src/proxy.h18
-rw-r--r--src/recording.c126
-rw-r--r--src/recording.h12
-rw-r--r--src/session.c118
-rw-r--r--src/session.h18
-rw-r--r--src/state.c80
-rw-r--r--src/state.h12
14 files changed, 0 insertions, 1201 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
deleted file mode 100644
index f885850..0000000
--- a/src/CMakeLists.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-include_directories("${bastion_SOURCE_DIR}/termrec/libtty/")
-
-file(GLOB_RECURSE SOURCES *.c)
-
-add_executable(bastion ${SOURCES})
-add_library(libtty.a STATIC IMPORTED)
-set_property(TARGET libtty.a PROPERTY IMPORTED_LOCATION "${bastion_SOURCE_DIR}/libtty.a")
-target_link_libraries(bastion libtty.a)
-target_link_libraries(bastion bz2 curl lzma mysqlclient pthread ssh z)
diff --git a/src/client.c b/src/client.c
deleted file mode 100644
index 11757fc..0000000
--- a/src/client.c
+++ /dev/null
@@ -1,224 +0,0 @@
-#include <libssh/callbacks.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "../config.h"
-#include "client.h"
-#ifdef SESSION_RECORDING
-#include "recording.h"
-#endif
-#include "mysql.h"
-#include "state.h"
-
-// callback function for channel data and exceptions
-static int client_data_function(ssh_session session, ssh_channel channel, void *data,
- uint32_t len, int is_stderr, void *userdata) {
- struct client_channel_data_struct *cdata = (struct client_channel_data_struct *) userdata;
- (void) session;
- (void) channel;
- (void) is_stderr;
-
- if (ssh_channel_is_open(cdata->proxy_channel)) {
-#ifdef SESSION_RECORDING
- record(data, len);
-#endif
- return ssh_channel_write(cdata->proxy_channel, (char*) data, len);
- } else
- return SSH_ERROR;
-}
-
-static void client_channel_eof_callback (ssh_session session, ssh_channel channel, void *userdata)
-{
- struct client_channel_data_struct *cdata = (struct client_channel_data_struct *) userdata;
- (void) session;
- (void) channel;
-
- if (ssh_channel_is_open(cdata->proxy_channel))
- ssh_channel_send_eof(cdata->proxy_channel);
-}
-
-static void client_channel_close_callback (ssh_session session, ssh_channel channel, void *userdata)
-{
- struct client_channel_data_struct *cdata = (struct client_channel_data_struct *) userdata;
- (void) session;
- (void) channel;
-
- if (ssh_channel_is_open(cdata->proxy_channel))
- ssh_channel_close(cdata->proxy_channel);
-}
-
-static void client_channel_exit_status_callback (ssh_session session, ssh_channel channel, int exit_status, void *userdata)
-{
- (void) session;
- (void) channel;
- (void) userdata;
- printf("client exit status callback %d\n", exit_status);
-}
-
-static void client_channel_signal_callback (ssh_session session, ssh_channel channel,
- const char *signal, void *userdata) {
- (void) session;
- (void) channel;
- (void) signal;
- (void) userdata;
- printf("client signal callback\n");
-}
-
-static void client_channel_exit_signal_callback (ssh_session session, ssh_channel channel,
- const char *signal, int core, const char *errmsg,
- const char *lang, void *userdata) {
- (void) session;
- (void) channel;
- (void) signal;
- (void) core;
- (void) errmsg;
- (void) lang;
- (void) userdata;
- printf("client exit signal callback\n");
-}
-
-struct client_channel_data_struct* client_dial(ssh_event event, struct proxy_channel_data_struct *pdata)
-{
- const char * hostname = state_get_ssh_destination();
- struct client_channel_data_struct *cdata = malloc(sizeof(*cdata));
- cdata->event = event;
- cdata->my_session = NULL;
- cdata->my_channel = NULL;
- cdata->proxy_channel = pdata->my_channel;
- cdata->client_channel_cb = NULL;
-
- /* First we try to add the private key that the server will accept */
- struct db_host_info * info = db_get_host_info(hostname);
- if (info == NULL)
- goto host_info_clean;
-
- ssh_key privkey = NULL;
- if (ssh_pki_import_privkey_base64(info->privkeytxt, NULL, NULL, NULL, &privkey) != SSH_OK) {
- printf("Error importing private key");
- goto privkey_clean;
- }
-
- /* We try to connect to the remote server */
- printf("Connecting to %s\n", hostname);
- cdata->my_session = ssh_new();
-
- ssh_options_set(cdata->my_session, SSH_OPTIONS_HOST, info->address);
- ssh_options_set(cdata->my_session, SSH_OPTIONS_USER, info->username);
-#ifdef LIBSSH_VERBOSE_OUTPOUT
- int verbosity = SSH_LOG_PROTOCOL;
- ssh_options_set(cdata->my_session, SSH_OPTIONS_LOG_VERBOSITY, &verbosity);
-#endif
-
- if (ssh_connect(cdata->my_session) != SSH_OK) {
- printf("Error connecting to %s: %s\n", hostname, ssh_get_error(cdata->my_session));
- goto session_clean;
- }
-
- /* We now validate the remote server's public key */
- ssh_key server_pub_key = NULL;
- unsigned char * hash = NULL;
- size_t hlen;
- char * hexa = NULL;
- if (ssh_get_server_publickey(cdata->my_session, &server_pub_key) != SSH_OK) {
- fprintf(stderr, "Error getting server publickey: %s\n", ssh_get_error(cdata->my_session));
- goto pubkey_clean;
- }
- if (ssh_get_publickey_hash(server_pub_key, SSH_PUBLICKEY_HASH_SHA1, &hash, &hlen) != SSH_OK) {
- fprintf(stderr, "Error getting publickey hash: %s\n", ssh_get_error(cdata->my_session));
- goto pubkey_hash_clean;
- }
- hexa = ssh_get_hexa(hash, hlen);
- if (strlen(info->hostkeyhash) > 0) {
- if (strcmp(hexa, info->hostkeyhash) != 0) {
- fprintf(stderr, "Error invalid host key for %s\n", hostname);
- goto pubkey_hexa_clean;
- }
- } else {
- // TODO we got a broken sshportal record, we need to fix it but only
- // after we completed the migration from sshportal
- //db_set_host_publickey_hash(hostname, hexa);
- }
- ssh_string_free_char(hexa);
- ssh_clean_pubkey_hash(&hash);
- ssh_key_free(server_pub_key);
-
- /* With the server checked, we can authenticate */
- if(ssh_userauth_publickey(cdata->my_session, NULL, privkey) == SSH_AUTH_SUCCESS){
- printf("Authentication success\n");
- } else {
- printf("Error private key was rejected\n");
- goto session_clean;
- }
-
- /* we open the client channel */
- cdata->my_channel = ssh_channel_new(cdata->my_session);
- if (cdata->my_channel == NULL) {
- printf("Couldn't open client channel to %s\n", hostname);
- goto channel_clean;
- }
-
- /* we open a session channel for the future shell, not suitable for tcp
- * forwarding */
- if (ssh_channel_open_session(cdata->my_channel) != SSH_OK) {
- printf("Couldn't open the session channel\n");
- goto channel_clean;
- }
-
- cdata->client_channel_cb = malloc(sizeof(*cdata->client_channel_cb));
- memset(cdata->client_channel_cb, 0, sizeof(*cdata->client_channel_cb));
- cdata->client_channel_cb->userdata = cdata;
- cdata->client_channel_cb->channel_data_function = client_data_function;
- cdata->client_channel_cb->channel_eof_function = client_channel_eof_callback;
- cdata->client_channel_cb->channel_close_function = client_channel_close_callback;
- cdata->client_channel_cb->channel_exit_status_function = client_channel_exit_status_callback;
- cdata->client_channel_cb->channel_signal_function = client_channel_signal_callback;
- cdata->client_channel_cb->channel_exit_signal_function = client_channel_exit_signal_callback;
-
- ssh_callbacks_init(cdata->client_channel_cb);
- ssh_set_channel_callbacks(cdata->my_channel, cdata->client_channel_cb);
- ssh_event_add_session(event, cdata->my_session);
-
- // TODO only start recording upong shell_exec or pty_request in proxy.c.
- // It will be important when we start supporting scp
-#ifdef SESSION_RECORDING
- if (init_recorder() != 0) {
- goto channel_clean;
- }
-#endif
-
- ssh_key_free(privkey);
- db_free_host_info(info);
- return cdata;
-
-channel_clean:
- ssh_channel_free(cdata->my_channel);
- goto session_clean;
-pubkey_hexa_clean:
- ssh_string_free_char(hexa);
-pubkey_hash_clean:
- ssh_clean_pubkey_hash(&hash);
-pubkey_clean:
- ssh_key_free(server_pub_key);
-session_clean:
- ssh_disconnect(cdata->my_session);
- ssh_free(cdata->my_session);
- db_free_host_info(info);
-privkey_clean:
- ssh_key_free(privkey);
-host_info_clean:
- free(cdata);
- return NULL;
-}
-
-void client_cleanup(struct client_channel_data_struct *cdata)
-{
-#ifdef SESSION_RECORDING
- clean_recorder();
-#endif
- ssh_event_remove_session(cdata->event, cdata->my_session);
- ssh_channel_free(cdata->my_channel);
- ssh_disconnect(cdata->my_session);
- ssh_free(cdata->my_session);
- free(cdata->client_channel_cb);
- free(cdata);
-}
diff --git a/src/client.h b/src/client.h
deleted file mode 100644
index 307b115..0000000
--- a/src/client.h
+++ /dev/null
@@ -1,22 +0,0 @@
-#ifndef CLIENT_H_
-#define CLIENT_H_
-
-#include <libssh/libssh.h>
-
-#include "proxy.h"
-#include "session.h"
-
-/* A userdata struct for channel. */
-struct client_channel_data_struct {
- /* Event which is used to poll */
- ssh_event event;
- ssh_session my_session;
- ssh_channel my_channel;
- ssh_channel proxy_channel;
- struct ssh_channel_callbacks_struct * client_channel_cb;
-};
-
-struct client_channel_data_struct* client_dial(ssh_event event, struct proxy_channel_data_struct *pdata);
-void client_cleanup(struct client_channel_data_struct *cdata);
-
-#endif
diff --git a/src/main.c b/src/main.c
deleted file mode 100644
index 6ea6bcb..0000000
--- a/src/main.c
+++ /dev/null
@@ -1,133 +0,0 @@
-#include <libssh/callbacks.h>
-#include <libssh/server.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/wait.h>
-
-#include "../config.h"
-#include "mysql.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);
-}
-
-/* SIGINT handler for cleaning up on forced exit. */
-static ssh_bind sshbind = NULL;
-static ssh_session session = NULL;
-
-__attribute__((noreturn)) static void sigint_handler(int signo)
-{
- (void) signo;
- ssh_disconnect(session);
- ssh_free(session);
- ssh_bind_free(sshbind);
- ssh_finalize();
- db_clean();
- exit(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;
- }
- // Set up SIGINT handler
- struct sigaction sa2;
- sa2.sa_handler = sigint_handler;
- sigemptyset(&sa2.sa_mask);
- sa2.sa_flags = 0;
- if (sigaction(SIGINT, &sa2, NULL) != 0) {
- fprintf(stderr, "Failed to register SIGINT handler\n");
- return 1;
- }
-
- // Initializing ssh context
- ssh_init();
-
- // Initializing ssh_bind
- sshbind = ssh_bind_new();
- if (sshbind == NULL) {
- fprintf(stderr, "Error initializing ssh_bind\n");
- exit(-1);
- }
- int listen_port = LISTEN_PORT;
- ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_BINDPORT, &listen_port);
- ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_DSAKEY, DSAKEY_PATH);
- ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_RSAKEY, RSAKEY_PATH);
- ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_ECDSAKEY, ECDSAKEY_PATH);
-
- if (ssh_bind_listen(sshbind) < 0) {
- printf("Error listening to socket: %s\n", ssh_get_error(sshbind));
- ssh_bind_free(sshbind);
- ssh_finalize();
- return 1;
- }
-
- while (1) {
- session = ssh_new();
- if (session == NULL) {
- fprintf(stderr, "Error initializing ssh_session\n");
- break;
- }
-#ifdef LIBSSH_VERBOSE_OUTPOUT
- int verbosity = SSH_LOG_PROTOCOL;
- ssh_options_set(session, SSH_OPTIONS_LOG_VERBOSITY, &verbosity);
-#endif
-
- // 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);
- sshbind = NULL;
-
- if (db_init() !=0)
- goto child_cleaning;
-
- ssh_event event = ssh_event_new();
- if (event != NULL) {
- /* Blocks until the SSH session ends */
- handle_session(event, session);
- ssh_event_free(event);
- } else {
- fprintf(stderr, "Could not create polling context\n");
- }
-child_cleaning:
- ssh_disconnect(session);
- ssh_free(session);
- ssh_finalize();
-
- return 0;
- case -1:
- fprintf(stderr, "Failed to fork\n");
- }
- } else {
- fprintf(stderr, "Error accepting a connection : %s\n", ssh_get_error(sshbind));
- ssh_disconnect(session);
- ssh_free(session);
- ssh_bind_free(sshbind);
- ssh_finalize();
- return 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();
- db_clean();
- return 0;
-}
diff --git a/src/mysql.c b/src/mysql.c
deleted file mode 100644
index 0931116..0000000
--- a/src/mysql.c
+++ /dev/null
@@ -1,188 +0,0 @@
-#include <libssh/server.h>
-#include <mysql/mysql.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "../config.h"
-#include "mysql.h"
-
-static MYSQL *db;
-
-char // returns 0 if ok, greater than 0 otherwise
-db_init(void)
-{
- printf("MySQL client version: %s\n", mysql_get_client_info());
- db = mysql_init(NULL);
- if (db == NULL) {
- fprintf(stderr, "%s\n", mysql_error(db));
- return 1;
- }
- if (mysql_real_connect(db, MYSQL_HOST, MYSQL_USER, MYSQL_PASS, MYSQL_DB, 0, NULL, 0) == NULL) {
- fprintf(stderr, "%s\n", mysql_error(db));
- mysql_close(db);
- return 1;
- }
- return 0;
-}
-
-void db_clean(void)
-{
- mysql_close(db);
- db = NULL;
-}
-
-char * // returns NULL if no user found, this char * is to be freed from the calling code
-db_get_username_from_pubkey(ssh_key pubkey)
-{
- int res = mysql_query(db, "SELECT name, authorized_key FROM users, user_keys WHERE users.id = user_keys.user_id");
- if (res != 0) {
- fprintf(stderr, "WARNING: Couldn't get usernames from database.\n");
- return NULL;
- }
- MYSQL_RES *result = mysql_store_result(db);
- if (result == NULL) {
- fprintf(stderr, "FATAL: Couldn't retrieve public keys from database.\n");
- return NULL;
- }
-
- MYSQL_ROW row;
- while ((row = mysql_fetch_row(result))) {
- char * rsa = "ssh-rsa ";
- if (strncmp (row[1], rsa, strlen(rsa)) != 0) {
- fprintf(stderr, "Unsupported public key type for user %s : %s\n", row[0], row[1]);
- } else {
- ssh_key tmp_key;
- if (ssh_pki_import_pubkey_base64(row[1] + strlen(rsa), SSH_KEYTYPE_RSA, &tmp_key) != SSH_OK) {
- fprintf(stderr, "Error importing public key for user %s : %s\n", row[0], row[1]);
- } else if (!ssh_key_cmp(pubkey, tmp_key, SSH_KEY_CMP_PUBLIC)) {
- size_t len = strlen(row[0]);
- char * username = malloc(len+1);
- strcpy(username, row[0]);
- ssh_key_free(tmp_key);
- mysql_free_result(result);
- return username;
- } else {
- ssh_key_free(tmp_key);
- }
- }
- }
-
- fprintf(stderr, "ERROR: Didn't find public key in database.\n");
- mysql_free_result(result);
- return NULL;
-}
-
-struct db_host_info * // returns NULL if no key found, this char * is to be freed from the calling code
-db_get_host_info(const char * hostname)
-{
- char buff[255];
- sprintf(buff, "SELECT priv_key, url, host_key FROM ssh_keys, hosts WHERE ssh_keys.id = hosts.ssh_key_id and hosts.name = \"%s\"", hostname);
- int res = mysql_query(db, buff);
- if (res != 0) {
- fprintf(stderr, "WARNING: Couldn't query db for server infos for host %s\n", hostname);
- return NULL;
- }
- MYSQL_RES *result = mysql_store_result(db);
- if (result == NULL) {
- fprintf(stderr, "FATAL: Couldn't retrieve server infos for %s from database.\n", hostname);
- return NULL;
- }
-
- MYSQL_ROW row = mysql_fetch_row(result);
- if (row == NULL) {
- fprintf(stderr, "FATAL: Couldn't retrieve server db results for %s from database.\n", hostname);
- mysql_free_result(result);
- return NULL;
- }
-
- struct db_host_info * info = malloc(sizeof(struct db_host_info));
- memset(info, 0, sizeof(struct db_host_info));
-
- size_t len = strlen(row[0]);
- info->privkeytxt = malloc(len+1);
- strcpy(info->privkeytxt, row[0]);
-
- if (strncmp(row[1], "ssh://", 6) != 0) {
- fprintf(stderr, "FATAL: invalid host url %s\n", row[1]);
- return NULL;
- }
- size_t at_pos = 0;
- char done = 0;
- for(size_t i = 6; !done; ++i) {
- switch(*(row[1]+i)) {
- case '@':
- info->username = malloc(i-6+1);
- strncpy(info->username, row[1]+6, i-6);
- info->username[i-6] = '\0';
- at_pos = i;
- break;
- case '\0':
- info->address = malloc(i-at_pos);
- strncpy(info->address, row[1]+at_pos+1, i-at_pos-1);
- info->address[i-at_pos-1] = '\0';
- done = 1;
- break;
- }
- if (i > MAX_HOSTNAME_LENGTH + MAX_USERNAME_LENGTH + 6 + 1) {
- fprintf(stderr, "FATAL: Couldn't parse host url for host %s, too long.\n", hostname);
- if (info->username != NULL)
- free(info->username);
- return NULL;
- }
- }
-
- len = strlen(row[2]);
- info->hostkeyhash = malloc(len+1);
- strcpy(info->hostkeyhash, row[2]);
-
- mysql_free_result(result);
- return info;
-}
-
-void db_set_host_publickey_hash(const char * hostname, const char * hash)
-{
- char buff[255];
- sprintf(buff, "UPDATE ssh_keys, hosts SET host_key = \"%s\" WHERE ssh_keys.id = hosts.ssh_key_id and hosts.name = \"%s\"", hash, hostname);
- int res = mysql_query(db, buff);
- if (res != 0) {
- fprintf(stderr, "WARNING: Couldn't set host key for host %s: %s\n", hostname, hash);
- return;
- }
- res = mysql_commit(db);
- if (res != 0) {
- fprintf(stderr, "WARNING: Couldn't commit after setting host key for host %s: %s\n", hostname, hash);
- }
-}
-
-unsigned long long // returns 0 on error, or the session_id
-db_init_session_and_get_id(const char * hostname, const char * username)
-{
- char buff[255];
- sprintf(buff, "INSERT INTO sessions (created_at, status, user_id, host_id) SELECT NOW(), \"opened\", users.id, hosts.id from users, hosts WHERE users.name = \"%s\" and hosts.name = \"%s\"", username, hostname);
- int res = mysql_query(db, buff);
- if (res != 0) {
- fprintf(stderr, "FATAL: Couldn't insert new session in database for %s to %s\n", username, hostname);
- return 0;
- }
- unsigned long long id = mysql_insert_id(db);
- if (id == 0) {
- fprintf(stderr, "FATAL: Didn't get proper mysql last insert id after inserting new session for %s to %s\n", username, hostname);
- return 0;
- }
- res = mysql_commit(db);
- if (res != 0) {
- fprintf(stderr, "FATAL: Couldn't commit after inserting session for %s to %s\n", username, hostname);
- return 0;
- }
- return id;
-}
-
-void db_free_host_info(struct db_host_info * info)
-{
- free(info->privkeytxt);
- free(info->address);
- free(info->username);
- free(info->hostkeyhash);
- free(info);
-}
diff --git a/src/mysql.h b/src/mysql.h
deleted file mode 100644
index 8c6040f..0000000
--- a/src/mysql.h
+++ /dev/null
@@ -1,22 +0,0 @@
-#ifndef MYSQL_H_
-#define MYSQL_H_
-
-struct db_host_info {
- char * privkeytxt;
- char * address;
- char * username;
- char * hostkeyhash;
-};
-
-char db_init(void);
-void db_clean(void);
-char * // returns NULL if no user found, this char * is to be freed from the calling code
-db_get_username_from_pubkey(ssh_key pubkey);
-struct db_host_info * // returns NULL if no key found, this char * is to be freed from the calling code
-db_get_host_info(const char * hostname);
-void db_set_host_publickey_hash(const char * hostname, const char * hash);
-unsigned long long // returns 0 on error, or the session_id
-db_init_session_and_get_id(const char * hostname, const char * username);
-void db_free_host_info(struct db_host_info * info);
-
-#endif
diff --git a/src/proxy.c b/src/proxy.c
deleted file mode 100644
index 7d410db..0000000
--- a/src/proxy.c
+++ /dev/null
@@ -1,219 +0,0 @@
-#include <libssh/callbacks.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "client.h"
-#include "mysql.h"
-#include "proxy.h"
-#include "state.h"
-
-// callback function for channel data and exceptions
-static int proxy_data_function(ssh_session session, ssh_channel channel, void *data,
- uint32_t len, int is_stderr, void *userdata) {
- struct proxy_channel_data_struct *pdata = (struct proxy_channel_data_struct *) userdata;
- (void) session;
- (void) channel;
- (void) is_stderr;
-
- if (ssh_channel_is_open(pdata->client_channel))
- return ssh_channel_write(pdata->client_channel, (char*) data, len);
- else
- return SSH_ERROR;
-}
-
-// callback function for SSH channel PTY request from a client
-static int proxy_pty_request(ssh_session session, ssh_channel channel,
- const char *term, int cols, int rows, int py, int px,
- void *userdata) {
- struct proxy_channel_data_struct *pdata = (struct proxy_channel_data_struct *)userdata;
-
- (void) session;
- (void) channel;
- (void) py;
- (void) px;
-
- // TODO record pty size in recorder
- if (ssh_channel_is_open(pdata->client_channel)) {
- if (ssh_channel_request_pty_size(pdata->client_channel, term, cols, rows) == SSH_OK)
- return SSH_OK;
- else
- fprintf(stderr, "pty request failed\n");
- } else {
- fprintf(stderr, "pty request while client_channel not opened\n");
- }
- return SSH_ERROR;
-}
-
-// callback function for SSH channel PTY resize from a client
-static int proxy_pty_resize(ssh_session session, ssh_channel channel, int cols,
- int rows, int py, int px, void *userdata) {
- struct proxy_channel_data_struct *pdata = (struct proxy_channel_data_struct *)userdata;
-
- (void) session;
- (void) channel;
- (void) py;
- (void) px;
-
- // TODO record pty size in recorder
- if (ssh_channel_is_open(pdata->client_channel)) {
- if (ssh_channel_change_pty_size(pdata->client_channel, cols, rows) == SSH_OK)
- return SSH_OK;
- else
- fprintf(stderr, "pty resize failed\n");
- } else {
- fprintf(stderr, "pty resize while client_channel not opened\n");
- }
- return SSH_ERROR;
-}
-
-static int proxy_exec_request(ssh_session session, ssh_channel channel,
- const char *command, void *userdata) {
- struct proxy_channel_data_struct *pdata = (struct proxy_channel_data_struct *) userdata;
-
- (void) session;
- (void) channel;
-
- if (ssh_channel_is_open(pdata->client_channel)) {
- if (ssh_channel_request_exec(pdata->client_channel, command) == SSH_OK)
- return SSH_OK;
- else
- printf("exec request failed\n");
- } else {
- fprintf(stderr, "exec request while client_channel not opened\n");
- }
- return SSH_ERROR;
-}
-
-static int proxy_shell_request(ssh_session session, ssh_channel channel,
- void *userdata) {
- struct proxy_channel_data_struct *pdata = (struct proxy_channel_data_struct *) userdata;
-
- (void) session;
- (void) channel;
-
- if (ssh_channel_is_open(pdata->client_channel)) {
- if (ssh_channel_request_shell(pdata->client_channel) == SSH_OK)
- return SSH_OK;
- else
- fprintf(stderr, "shell request failed\n");
- } else {
- fprintf(stderr, "shell request while client channel not opened\n");
- }
- return SSH_ERROR;
-}
-
-static int proxy_subsystem_request(ssh_session session, ssh_channel channel,
- const char *subsystem, void *userdata) {
- (void) session;
- (void) channel;
- (void) subsystem;
- (void) userdata;
- return SSH_ERROR; // TODO ssh subsystem request
- //if (ssh_channel_is_open(pdata->client_channel)) {
- //}
-}
-
-static void proxy_channel_eof_callback (ssh_session session, ssh_channel channel, void *userdata)
-{
- struct proxy_channel_data_struct *pdata = (struct proxy_channel_data_struct *) userdata;
- (void) session;
- (void) channel;
- if (ssh_channel_is_open(pdata->client_channel))
- ssh_channel_send_eof(pdata->client_channel);
-}
-
-static void proxy_channel_close_callback (ssh_session session, ssh_channel channel, void *userdata)
-{
- struct proxy_channel_data_struct *pdata = (struct proxy_channel_data_struct *) userdata;
- (void) session;
- (void) channel;
- if (ssh_channel_is_open(pdata->client_channel))
- ssh_channel_close(pdata->client_channel);
-}
-
-static void proxy_channel_exit_status_callback (ssh_session session, ssh_channel channel, int exit_status, void *userdata)
-{
- (void) session;
- (void) channel;
- (void) exit_status;
- (void) userdata;
- printf("proxy exit status callback\n");
-}
-
-static void proxy_channel_signal_callback (ssh_session session, ssh_channel channel,
- const char *signal, void *userdata) {
- (void) session;
- (void) channel;
- (void) signal;
- (void) userdata;
- printf("proxy signal callback\n");
-}
-
-static void proxy_channel_exit_signal_callback (ssh_session session, ssh_channel channel,
- const char *signal, int core, const char *errmsg,
- const char *lang, void *userdata) {
- (void) session;
- (void) channel;
- (void) signal;
- (void) core;
- (void) errmsg;
- (void) lang;
- (void) userdata;
- printf("proxy exit signal callback\n");
-}
-
-void handle_proxy_session(ssh_event event, ssh_session session, ssh_channel my_channel)
-{
- struct client_channel_data_struct * cdata;
-
- struct proxy_channel_data_struct pdata = {
- .event = event,
- .my_session = session,
- .my_channel = my_channel,
- .client_channel = NULL,
- };
-
- cdata = client_dial(event, &pdata);
-
- if (cdata == NULL) {
- return;
- }
- pdata.client_channel = cdata->my_channel;
-
- /* We tie everything together */
- struct ssh_channel_callbacks_struct channel_cb = {
- .userdata = &pdata,
- .channel_data_function = proxy_data_function,
- .channel_eof_function = proxy_channel_eof_callback,
- .channel_close_function = proxy_channel_close_callback,
- .channel_signal_function = proxy_channel_signal_callback,
- .channel_exit_status_function = proxy_channel_exit_status_callback,
- .channel_exit_signal_function = proxy_channel_exit_signal_callback,
- .channel_pty_request_function = proxy_pty_request,
- .channel_shell_request_function = proxy_shell_request,
- .channel_pty_window_change_function = proxy_pty_resize,
- .channel_exec_request_function = proxy_exec_request,
- .channel_subsystem_request_function = proxy_subsystem_request,
- .channel_auth_agent_req_function = NULL,
- .channel_x11_req_function = NULL,
- .channel_env_request_function = NULL,
- .channel_write_wontblock_function = NULL,
- };
- ssh_callbacks_init(&channel_cb);
- ssh_set_channel_callbacks(my_channel, &channel_cb);
-
- db_clean(); // we close the mysql connection before the main loop, as to not waste ressources
-
- do {
- /* Poll the main event which takes care of the sessions and channels */
- if (ssh_event_dopoll(event, -1) == SSH_ERROR) {
- break;
- }
- } while(ssh_channel_is_open(my_channel) && ssh_channel_is_open(pdata.client_channel));
- if (ssh_channel_is_open(my_channel))
- ssh_channel_close(my_channel);
- if (ssh_channel_is_open(cdata->my_channel))
- ssh_channel_close(cdata->my_channel);
-
- client_cleanup(cdata);
-}
diff --git a/src/proxy.h b/src/proxy.h
deleted file mode 100644
index 0e42bdc..0000000
--- a/src/proxy.h
+++ /dev/null
@@ -1,18 +0,0 @@
-#ifndef PROXY_H_
-#define PROXY_H_
-
-#include <libssh/libssh.h>
-
-#include "session.h"
-
-/* A userdata struct for channel. */
-struct proxy_channel_data_struct {
- /* Event which is used to poll */
- ssh_event event;
- ssh_session my_session;
- ssh_channel my_channel;
- ssh_channel client_channel;
-};
-void handle_proxy_session(ssh_event event, ssh_session session, ssh_channel my_channel);
-
-#endif
diff --git a/src/recording.c b/src/recording.c
deleted file mode 100644
index 7692ff1..0000000
--- a/src/recording.c
+++ /dev/null
@@ -1,126 +0,0 @@
-#include <dirent.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/time.h>
-#include <time.h>
-#include <ttyrec.h>
-
-#include "../config.h"
-#include "recording.h"
-#include "state.h"
-
-#ifdef SESSION_RECORDING
-static recorder recorder_handle = NULL;
-
-void clean_recorder(void)
-{
- ttyrec_w_close(recorder_handle);
- recorder_handle = NULL;
-}
-
-static char * // returns NULL if error, this char * is to be freed from the calling code
-make_filename(void)
-{
- char * format = LOG_FILENAME_FORMAT;
- char * filename = NULL;
- unsigned int fname_pos = 0;
- unsigned int format_pos = 0;
-
- filename = malloc(LOG_FILENAME_MAX_LEN+1);
-
- size_t format_len = strlen(format);
- while (format_pos < format_len + 1 && fname_pos < LOG_FILENAME_MAX_LEN +1) {
- if (format[format_pos] == '$') {
- format_pos++;
- if (format[format_pos] == 'd') {
- time_t t;
- struct tm * tm;
- time(&t);
- tm = localtime(&t);
- fname_pos += strftime(filename + fname_pos, LOG_FILENAME_MAX_LEN - fname_pos, "%F", tm);
- } else if (format[format_pos] == 'h') {
- const char * hostname = state_get_ssh_destination();
- size_t len = strlen(hostname);
- strcpy(filename + fname_pos, hostname);
- fname_pos += len;
- } else if (format[format_pos] == 'u') {
- const char * username = state_get_bastion_username();
- size_t len = strlen(username);
- strcpy(filename + fname_pos, username);
- fname_pos += len;
- } else if (format[format_pos] == 'i') {
- sprintf(filename + fname_pos, "%llu", state_get_session_id());
- fname_pos += strlen(filename + fname_pos);
- }
- format_pos++;
- } else {
- filename[fname_pos] = format[format_pos];
- if (filename[fname_pos] == '/') { // We create the corresponding directory if it doesn't exist
- filename[fname_pos+1] = '\0';
- DIR* dir = opendir(filename);
- if (dir)
- closedir(dir);
- else {
- int ret = mkdir(filename, LOG_DIRECTORY_MODE);
- if (ret != 0) {
- fprintf(stderr, "Couldn't create log directory %s : %s\n", filename, strerror( errno ));
- }
- }
- }
- format_pos++;
- fname_pos++;
- }
- }
-
- if (filename[fname_pos-1] != '\0') {
- fprintf(stderr, "Log file name is too long, check LOG_FILENAME_FORMAT and LOG_FILENAME_MAX_LEN\n");
- free(filename);
- filename = NULL;
- }
- return filename;
-}
-
-char // returns 0 if ok, 1 otherwise
-init_recorder(void)
-{
- char * filename = make_filename();
- if (filename == NULL)
- return 1;
- struct timeval tm;
- if (gettimeofday(&tm, NULL) != 0) {
- fprintf(stderr, "OUPS gettimeofday failed!\n");
- return 1;
- }
- recorder_handle = ttyrec_w_open(-1, "ttyrec", filename, &tm);
- free(filename);
- if (recorder_handle == NULL) {
- fprintf(stderr, "Couldn't open the session termrec log file.\n");
- return 1;
- }
-
- return 0;
-}
-
-char // returns 0 if ok, greater than 0 otherwise
-record(void* data, size_t len)
-{
- if(recorder_handle == NULL)
- return 0;
-
- struct timeval tm;
- if (gettimeofday(&tm, NULL) != 0) {
- fprintf(stderr, "OUPS gettimeofday failed!\n");
- return 1;
- }
- if (ttyrec_w_write(recorder_handle, &tm, data, (int) len) == 0) {
- fprintf(stderr, "OUPS ttyrec_w_write failed!\n");
- return 2;
- }
- return 0;
-}
-#endif
diff --git a/src/recording.h b/src/recording.h
deleted file mode 100644
index fec76af..0000000
--- a/src/recording.h
+++ /dev/null
@@ -1,12 +0,0 @@
-#include "../config.h"
-
-#ifdef SESSION_RECORDING
-#ifndef RECORDING_H_
-#define RECORDING_H_
-
-void clean_recorder(void);
-char init_recorder(void);
-char record(void* data, size_t len);
-
-#endif
-#endif
diff --git a/src/session.c b/src/session.c
deleted file mode 100644
index 3d3b1b7..0000000
--- a/src/session.c
+++ /dev/null
@@ -1,118 +0,0 @@
-#include <libssh/callbacks.h>
-#include <libssh/server.h>
-#include <poll.h>
-#include <pty.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/wait.h>
-
-#include "../config.h"
-#include "mysql.h"
-#include "proxy.h"
-#include "session.h"
-#include "state.h"
-
-static int auth_pubkey(ssh_session session, const char *user, ssh_key pubkey, char signature_state,
- void *userdata) {
- struct session_data_struct *sdata = (struct session_data_struct *) userdata;
- (void) session;
-
- // For some reason, libssh can call this twice for the same key
- if (sdata->authenticated == 1)
- return SSH_ERROR;
-
- if (signature_state != SSH_PUBLICKEY_STATE_NONE && signature_state != SSH_PUBLICKEY_STATE_VALID) {
- fprintf(stderr, "Invalid signature state\n");
- sdata->auth_attempts++;
- return SSH_AUTH_DENIED;
- }
-
- // TODO check for an invite
-
- char * bastion_username = db_get_username_from_pubkey(pubkey);
- if (bastion_username != NULL) {
- sdata->authenticated = 1;
- if (state_set_ssh_destination(user) != 0)
- return SSH_ERROR;
- // TODO check access rights and host configs
- state_set_bastion_username(bastion_username);
- unsigned long long session_id = db_init_session_and_get_id(user, bastion_username);
- state_set_session_id(session_id);
- free(bastion_username);
- return SSH_AUTH_SUCCESS;
- } else {
- free(bastion_username);
- sdata->auth_attempts++;
- return SSH_AUTH_DENIED;
- }
-}
-
-static ssh_channel channel_open(ssh_session session, void *userdata) {
- struct session_data_struct *sdata = (struct session_data_struct *) userdata;
-
- if (sdata->channel == NULL) {
- sdata->channel = ssh_channel_new(session);
- return sdata->channel;
- } else {
- // Only one channel allowed
- return NULL;
- }
-}
-
-void handle_session(ssh_event event, ssh_session session) {
- /* Our struct holding information about the session. */
- struct session_data_struct sdata = {
- .channel = NULL,
- .auth_attempts = 0,
- .authenticated = 0,
- };
-
- struct ssh_server_callbacks_struct server_cb = {
- .userdata = &sdata,
- .auth_pubkey_function = auth_pubkey,
- .channel_open_request_session_function = channel_open,
- };
- ssh_callbacks_init(&server_cb);
- ssh_set_server_callbacks(session, &server_cb);
-
- if (ssh_handle_key_exchange(session) != SSH_OK) {
- fprintf(stderr, "%s\n", ssh_get_error(session));
- return;
- }
-
- ssh_set_auth_methods(session, SSH_AUTH_METHOD_PUBLICKEY);
- ssh_event_add_session(event, session);
-
- for (int n=0; sdata.authenticated == 0 || sdata.channel == NULL; n++) {
- /* If the user has used up all attempts, or if he hasn't been able to
- * authenticate in 10 seconds (n * 100ms), disconnect. */
- if (sdata.auth_attempts >= 3) {
- fprintf(stderr, "Closing connection after 3 failed auth attempts\n");
- return;
- }
- if (n >= 100) {
- fprintf(stderr, "Closing connection after 10 seconds without successfull authentication\n");
- return;
- }
-
- if (ssh_event_dopoll(event, 100) == SSH_ERROR) {
- fprintf(stderr, "%s\n", ssh_get_error(session));
- return;
- }
- }
-
- handle_proxy_session(event, session, sdata.channel);
-
- if (ssh_channel_is_open(sdata.channel)) {
- ssh_channel_close(sdata.channel);
- }
-
- /* Wait up to 5 seconds for the client to terminate the session. */
- for (int n = 0; n < 50 && (ssh_get_status(session) & SESSION_END) == 0; n++) {
- ssh_event_dopoll(event, 100);
- }
- state_clean();
- ssh_event_remove_session(event, session);
-}
diff --git a/src/session.h b/src/session.h
deleted file mode 100644
index d0c8eab..0000000
--- a/src/session.h
+++ /dev/null
@@ -1,18 +0,0 @@
-#ifndef SESSION_H_
-#define SESSION_H_
-
-#include <libssh/libssh.h>
-
-#define SESSION_END (SSH_CLOSED | SSH_CLOSED_ERROR)
-
-/* A userdata struct for session. */
-struct session_data_struct {
- /* Pointer to the channel the session will allocate. */
- ssh_channel channel;
- int auth_attempts;
- int authenticated;
-};
-
-void handle_session(ssh_event event, ssh_session session);
-
-#endif
diff --git a/src/state.c b/src/state.c
deleted file mode 100644
index dd9cbf3..0000000
--- a/src/state.c
+++ /dev/null
@@ -1,80 +0,0 @@
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "../config.h"
-#include "state.h"
-
-struct state {
- unsigned long long session_id;
- char * destination;
- char * bastion_username;
-};
-
-static struct state state = {0};
-
-char // returns 0 if ok, greater than 0 otherwise
-state_set_ssh_destination(const char * name)
-{
- if (state.destination != NULL) {
- fprintf(stderr, "BUG found, attempting to overwrite state.destination that has already been set\n");
- return 1;
- }
- size_t len = strnlen(name, MAX_HOSTNAME_LENGTH + 1);
- if (len >= MAX_HOSTNAME_LENGTH + 1) {
- fprintf(stderr, "Hostname too long, max length is %d.\n", MAX_HOSTNAME_LENGTH);
- return 2;
- }
- state.destination = malloc(len+1);
- strncpy(state.destination, name, len+1);
- return 0;
-}
-
-const char * state_get_ssh_destination(void)
-{
- return state.destination;
-}
-
-char // return 0 if ok, greater than 0 otherwise
-state_set_bastion_username(const char * name)
-{
- if (state.bastion_username != NULL) {
- fprintf(stderr, "BUG found, attempting to overwrite state.bastion_username that has already been set\n");
- return 1;
- }
- size_t len = strnlen(name, MAX_USERNAME_LENGTH + 1);
- if (len >= MAX_USERNAME_LENGTH + 1) {
- fprintf(stderr, "Username too long, max length is %d.\n", MAX_USERNAME_LENGTH);
- return 1;
- }
- state.bastion_username = malloc(len+1);
- strncpy(state.bastion_username, name, len+1);
- return 0;
-}
-
-const char * state_get_bastion_username(void)
-{
- return state.bastion_username;
-}
-
-char // return 0 if ok, greater than 0 otherwise
-state_set_session_id(const unsigned long long id)
-{
- if (state.session_id != 0) {
- fprintf(stderr, "BUG found, attempting to set a state.session_id that has already been set\n");
- return 1;
- }
- state.session_id = id;
- return 0;
-}
-
-unsigned long long state_get_session_id(void)
-{
- return state.session_id;
-}
-
-void state_clean(void)
-{
- free(state.destination);
- state.destination = NULL;
-}
diff --git a/src/state.h b/src/state.h
deleted file mode 100644
index 0ab70bc..0000000
--- a/src/state.h
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef STATE_H_
-#define STATE_H_
-
-char state_set_ssh_destination(const char * dest);
-const char * state_get_ssh_destination(void);
-char state_set_bastion_username(const char * name);
-const char * state_get_bastion_username(void);
-char state_set_session_id(const unsigned long long id);
-unsigned long long state_get_session_id(void);
-void state_clean(void);
-
-#endif