#include #include #include #include #include #include #include #include "assets.h" #include "sessions.h" #include "sqlite_utils.h" #include #define SESSION_LEN 30 #define DB_NAME "portal_user.db" #if defined(__linux__) #include #include KORE_SECCOMP_FILTER("sqlite3", KORE_SYSCALL_ALLOW(newfstatat), KORE_SYSCALL_ALLOW(pread64), KORE_SYSCALL_ALLOW(pwrite64), KORE_SYSCALL_ALLOW(fdatasync), KORE_SYSCALL_ALLOW_ARG(write, 0, STDOUT_FILENO) ); #endif int init(int state); int portal_user_load(struct http_request *); int v_password_func(struct http_request *, char *); int create_user(struct http_request *); int v_session_validate(struct http_request *, char *); int v_session_remove(struct http_request *); int private_portal(struct http_request *); hashtable_t *hashtable = NULL; int init(int state) { hashtable = ht_create( 65536 ); int err=0; if( hashtable == NULL ) { kore_log(LOG_ERR, "Can't create hastable sessions"); err = 1; } if ( access( DB_NAME, F_OK ) == 0 && err == 0 ) { kore_log(LOG_NOTICE, "Execute check_db()"); err = check_db(DB_NAME);} else { kore_log(LOG_NOTICE, "Create Sqlite Base"); err = init_db(DB_NAME); } if (err) return (KORE_RESULT_ERROR); else return (KORE_RESULT_OK); } int create_user(struct http_request *req) { struct kore_buf *b = NULL; u_int8_t *d = NULL; size_t len = 0; char *salt = NULL, *cryptpwd = NULL; char *zErrMsg = NULL; char *user = NULL, *pwd = NULL, name[50]; sqlite3 *db = NULL; char sql[512]; if (req->method == HTTP_METHOD_GET) http_populate_get(req); else if (req->method == HTTP_METHOD_POST) http_populate_post(req); b = kore_buf_alloc(asset_len_signup_html); kore_buf_append(b, asset_signup_html, asset_len_signup_html); if (req->method == HTTP_METHOD_GET) { kore_buf_replace_string(b, "$msg$", "GO", 4); http_response_header(req, "content-type", "text/html"); d = kore_buf_release(b, &len); http_response(req, 200, d, len); kore_free(d); return (KORE_RESULT_OK); } if (req->method == HTTP_METHOD_POST) { int rc = sqlite3_open(DB_NAME, &db); if (rc != SQLITE_OK) { kore_log(LOG_ERR, "Cannot open database: %s\n", sqlite3_errmsg(db)); sqlite3_close(db); return (KORE_RESULT_ERROR); } #if defined(__linux__) salt = crypt_gensalt("$2b$", 15, NULL, 0); //-> linux #elif defined(__OpenBSD__) salt = bcrypt_gensalt(15); #endif if (salt == NULL) { kore_log(LOG_ERR, "crypt_gensalt"); exit(EXIT_FAILURE); } kore_log(LOG_NOTICE, "bcrypt_salt réussi"); (void)snprintf(name, sizeof(name), "login"); http_argument_get_string(req, name, &user); (void)snprintf(name, sizeof(name), "password"); http_argument_get_string(req, name, &pwd); cryptpwd = crypt(pwd, salt); if (cryptpwd == NULL) { kore_log(LOG_PERROR, "Can't encrypt password"); exit(EXIT_FAILURE); } kore_log(LOG_NOTICE, "Encrypted called %s", cryptpwd ); (void)sprintf(sql, "INSERT INTO Users (Email, Password, Active) VALUES(\"%s\",\"%s\",\"yes\");", user, cryptpwd); printf ( "%s",sql); rc = sqlite3_exec(db, sql, 0, 0, &zErrMsg); if( rc != SQLITE_OK ){ kore_log(LOG_ERR, "SQL error: %s", zErrMsg); sqlite3_free(zErrMsg); } else { kore_log(LOG_NOTICE, "Database successfully created !"); } sqlite3_close(db); http_response_header(req, "location", "/"); http_response_header(req, "content-type", "text/html"); d = kore_buf_release(b, &len); http_response(req, HTTP_STATUS_FOUND, NULL, 0); kore_free(d); return (KORE_RESULT_OK); } return (KORE_RESULT_ERROR); } int portal_user_load(struct http_request *req) { struct kore_buf *b = NULL; u_int8_t *d = NULL; size_t len = 0; char *login = NULL, *pwd = NULL, name[70]; char *err_msg = 0; char salt[29], *cryptpwd = NULL; int rc = 0; sqlite3_stmt *res= NULL; sqlite3 *db = NULL; char *cookie_session = NULL; char *cookie_samesite = NULL; char *cookie = NULL; char *session_id = NULL; if (req->method == HTTP_METHOD_GET) http_populate_get(req); else if (req->method == HTTP_METHOD_POST) http_populate_post(req); b = kore_buf_alloc(asset_len_index_html); kore_buf_append(b, asset_index_html, asset_len_index_html); if (req->method == HTTP_METHOD_GET) { kore_buf_replace_string(b, "$login$", NULL, 0); kore_buf_replace_string(b, "$password$", NULL, 0); kore_buf_replace_string(b, "$msg$", "Toto", 4); http_response_header(req, "content-type", "text/html"); d = kore_buf_release(b, &len); http_response(req, 200, d, len); kore_free(d); return (KORE_RESULT_OK); } if (req->method == HTTP_METHOD_POST) { rc = sqlite3_open(DB_NAME, &db); if (rc != SQLITE_OK) { kore_log(LOG_ERR, "Cannot open database: %s\n", sqlite3_errmsg(db)); sqlite3_close(db); return (KORE_RESULT_ERROR); } char *sql = "SELECT Email, Password FROM Users WHERE Email = ?"; rc = sqlite3_prepare_v2(db, sql, -1, &res, 0); if (rc == SQLITE_OK) { (void)snprintf(name, sizeof(name), "login"); http_argument_get_string(req, name, &login); sqlite3_bind_text(res, 1, login , -1, NULL); } else { kore_log(LOG_ERR, "Failed to execute statement: %s\n", sqlite3_errmsg(db)); } sqlite3_step(res); if (rc != SQLITE_OK ) { kore_log(LOG_ERR, "SQL error: %s\n", err_msg); sqlite3_finalize(res); sqlite3_free(err_msg); sqlite3_close(db); return (KORE_RESULT_ERROR); } (void)snprintf(name, sizeof(name), "password"); http_argument_get_string(req, name, &pwd); strncpy (salt,(const char *)sqlite3_column_text(res, 1),29); cryptpwd = crypt(pwd, salt); if (cryptpwd == NULL) { kore_log(LOG_PERROR, "Can't encrypt password"); exit(EXIT_FAILURE); } if ( strcmp( (const char *)sqlite3_column_text(res, 1), cryptpwd) ) { kore_buf_replace_string(b, "$msg$", "Erreur de login ou mot de passe ", 17); } else { kore_log(LOG_NOTICE, "on va faire le set cookie"); session_id = gen_session_id(SESSION_LEN); ht_set(hashtable, session_id, login); kore_log(LOG_NOTICE, "on a ajouté le sessions dans la hastable"); cookie_session = set_cookie_header("session_id", '=', session_id); cookie_samesite = set_cookie_header("SameSite", '=', "Strict"); cookie = set_cookie_header(cookie_session, ';', cookie_samesite); kore_log(LOG_NOTICE, "on a set le cookie dans les headers"); kore_buf_replace_string(b, "$msg$", "BRAVO !!!", 13); free(session_id); free(cookie_session); free(cookie_samesite); kore_log(LOG_NOTICE, "set cookie OK"); } sqlite3_finalize(res); sqlite3_close(db); http_response_header(req, "content-type", "text/html"); if (cookie != NULL) { http_response_header(req, "set-cookie", cookie); free(cookie); } d = kore_buf_release(b, &len); http_response_header(req, "location", "/portal/bienvenue"); http_response(req, HTTP_STATUS_FOUND, NULL, 0); kore_free(d); return (KORE_RESULT_OK); } return (KORE_RESULT_ERROR); } int v_password_func(struct http_request *req, char *data) { kore_log(LOG_NOTICE, "v_password_func called %s", data); if ( strlen(data) < 128 ) return (KORE_RESULT_OK); return (KORE_RESULT_ERROR); } int v_session_remove (struct http_request *req) { char *buffer; http_populate_cookies(req); if (http_request_cookie(req, "session_id", &buffer)) kore_log(LOG_DEBUG, "Got session_id: %s", buffer); if (ht_get(hashtable, buffer) != NULL) ht_delete(hashtable, buffer); http_response_header(req, "location", "/"); http_response_header(req, "content-type", "text/html"); http_response_header(req, "set-cookie", "session_id="""); http_response(req, HTTP_STATUS_FOUND, NULL, 0); return (KORE_RESULT_OK); } int v_session_validate(struct http_request *req, char *data) { kore_log(LOG_NOTICE, "v_session_validate: %s", data); if ( ht_get(hashtable, data) != NULL ) return (KORE_RESULT_OK); else { kore_log(LOG_NOTICE, "Session Inexistante"); } return (KORE_RESULT_ERROR); } int private_portal(struct http_request *req) { struct kore_buf *b = NULL; u_int8_t *d = NULL; size_t len = 0; char *buffer =NULL ; session_t *account = NULL; if (req->method == HTTP_METHOD_GET) http_populate_get(req); http_populate_cookies(req); if (http_request_cookie(req, "session_id", &buffer)) kore_log(LOG_DEBUG, "Got session_id: %s", buffer); b = kore_buf_alloc(asset_len_signup_html); kore_buf_append(b, asset_private_html, asset_len_private_html); account = ht_get(hashtable, buffer); if (req->method == HTTP_METHOD_GET) { kore_buf_replace_string(b, "$msg$", "GO", 4); if (account != NULL) { kore_log(LOG_NOTICE, "account trouvé: %s", account->user); kore_buf_replace_string(b, "$login$", account->user, sizeof(account->user)+1); } http_response_header(req, "content-type", "text/html"); d = kore_buf_release(b, &len); http_response(req, 200, d, len); kore_free(d); } return (KORE_RESULT_OK); }