From 03f712e58327e5b15856082074062b22fccb30bd Mon Sep 17 00:00:00 2001
From: Julien Dessaux <julien.dessaux@adyxax.org>
Date: Sat, 3 Nov 2018 00:49:22 +0100
Subject: [PATCH] Implemented session id management and session logs in
 database

---
 src/mysql.c     | 23 +++++++++++++++++++++++
 src/mysql.h     | 10 +++++++---
 src/recording.c |  2 +-
 src/session.c   |  4 ++--
 src/state.c     |  9 ++++-----
 src/state.h     |  4 ++--
 6 files changed, 39 insertions(+), 13 deletions(-)

diff --git a/src/mysql.c b/src/mysql.c
index b2a271e..0931116 100644
--- a/src/mysql.c
+++ b/src/mysql.c
@@ -155,6 +155,29 @@ 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)
+{
+    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);
diff --git a/src/mysql.h b/src/mysql.h
index 46e607e..8c6040f 100644
--- a/src/mysql.h
+++ b/src/mysql.h
@@ -10,9 +10,13 @@ struct db_host_info {
 
 char db_init(void);
 void db_clean(void);
-char * db_get_username_from_pubkey(ssh_key pubkey);
-struct db_host_info * db_get_host_info(const char * hostname);
-void db_free_host_info(struct db_host_info * info);
+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/recording.c b/src/recording.c
index a001607..7692ff1 100644
--- a/src/recording.c
+++ b/src/recording.c
@@ -54,7 +54,7 @@ make_filename(void)
                 strcpy(filename + fname_pos, username);
                 fname_pos += len;
             } else if (format[format_pos] == 'i') {
-                sprintf(filename + fname_pos, "%d", state_get_session_id());
+                sprintf(filename + fname_pos, "%llu", state_get_session_id());
                 fname_pos += strlen(filename + fname_pos);
             }
             format_pos++;
diff --git a/src/session.c b/src/session.c
index 2261242..3d3b1b7 100644
--- a/src/session.c
+++ b/src/session.c
@@ -38,9 +38,9 @@ static int auth_pubkey(ssh_session session, const char *user, ssh_key pubkey, ch
             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);
-        // TODO log session creation in db
-        state_set_session_id(1337);
         return SSH_AUTH_SUCCESS;
     } else {
         free(bastion_username);
diff --git a/src/state.c b/src/state.c
index d9577e7..dd9cbf3 100644
--- a/src/state.c
+++ b/src/state.c
@@ -6,10 +6,9 @@
 #include "state.h"
 
 struct state {
+    unsigned long long session_id;
     char * destination;
     char * bastion_username;
-    int session_id;
-    int padding; // makes compiler happy
 };
 
 static struct state state = {0};
@@ -59,17 +58,17 @@ const char * state_get_bastion_username(void)
 }
 
 char // return 0 if ok, greater than 0 otherwise
-state_set_session_id(const int id)
+state_set_session_id(const unsigned long long id)
 {
     if (state.session_id != 0) {
-        fprintf(stderr, "BUG found, attempting to overwrite state.username that has already been set\n");
+        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;
 }
 
-int state_get_session_id(void)
+unsigned long long state_get_session_id(void)
 {
     return state.session_id;
 }
diff --git a/src/state.h b/src/state.h
index df5bd6e..0ab70bc 100644
--- a/src/state.h
+++ b/src/state.h
@@ -5,8 +5,8 @@ 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 int id);
-int state_get_session_id(void);
+char state_set_session_id(const unsigned long long id);
+unsigned long long state_get_session_id(void);
 void state_clean(void);
 
 #endif