From 7c95977d674bab7d18969d8df85a8328b9f0f8b8 Mon Sep 17 00:00:00 2001 From: Andrea Zagli Date: Wed, 18 May 2016 16:05:14 +0200 Subject: [PATCH] Added function ZakCgiSession::is_valid. --- src/session.c | 193 +++++++++++++++++++++++++++++------------------- src/session.h | 4 +- tests/session.c | 11 ++- 3 files changed, 126 insertions(+), 82 deletions(-) diff --git a/src/session.c b/src/session.c index ee0d63a..fac3af5 100644 --- a/src/session.c +++ b/src/session.c @@ -98,13 +98,11 @@ ZakCgiSession { GHashTable *ht_cookies; - GError *error; + GDateTime *gdt_now; ZakCgiSession *zak_cgi_session; ZakCgiSessionPrivate *priv; - gchar *val; - zak_cgi_session = ZAK_CGI_SESSION (g_object_new (zak_cgi_session_get_type (), NULL)); priv = ZAK_CGI_SESSION_GET_PRIVATE (zak_cgi_session); @@ -119,83 +117,21 @@ ZakCgiSession } ht_cookies = zak_cgi_main_get_cookies (priv->zakcgimain); - priv->sid = g_hash_table_lookup (ht_cookies, "ZAKCGISID"); + priv->sid = g_strdup (g_value_get_string (g_hash_table_lookup (ht_cookies, "ZAKCGISID"))); - if (priv->sid != NULL) + if (zak_cgi_session_is_valid (zak_cgi_session)) { - /* open the file */ - priv->gfile = g_file_new_for_path (g_build_filename (priv->path != NULL ? priv->path : g_get_tmp_dir (), priv->sid, NULL)); - - error = NULL; - - /* check the content */ - priv->kfile = g_key_file_new (); - if (!g_key_file_load_from_file (priv->kfile, - g_file_get_path (priv->gfile), - G_KEY_FILE_NONE, - &error) - || error != NULL) - { - /* TODO */ - } - else + /* update timestamp */ + gdt_now = g_date_time_new_now_local (); + g_key_file_set_string (priv->kfile, "ZAKCGI", "TIMESTAMP", g_date_time_format (gdt_now, "%FT%T")); + g_key_file_save_to_file (priv->kfile, g_file_get_path (priv->gfile), NULL); + g_date_time_unref (gdt_now); + } + else + { + if (priv->sid != NULL) { - val = g_key_file_get_string (priv->kfile, "ZAKCGI", "REMOTE_ADDR", NULL); - if (val == NULL - || g_strcmp0 (val, g_getenv ("REMOTE_ADDR")) != 0) - { - zak_cgi_session_close (zak_cgi_session); - } - - val = g_key_file_get_string (priv->kfile, "ZAKCGI", "TIMESTAMP", NULL); - if (val == NULL) - { - zak_cgi_session_close (zak_cgi_session); - } - else - { - GTimeVal tval; - - if (g_time_val_from_iso8601 (val, &tval)) - { - GDateTime *gdt; - GDateTime *gdt_now; - GDateTime *gdt_plus; - - gdt = g_date_time_new_from_timeval_local (&tval); - if (gdt == NULL) - { - zak_cgi_session_close (zak_cgi_session); - } - else - { - /* TODO - * add a property for minutes number */ - gdt_plus = g_date_time_add_minutes (gdt, 5); - gdt_now = g_date_time_new_now_local (); - if (g_date_time_compare (gdt_plus, gdt_now) == -1) - { - /* session expired */ - zak_cgi_session_close (zak_cgi_session); - } - else - { - /* update timestamp */ - g_key_file_set_string (priv->kfile, "ZAKCGI", "TIMESTAMP", g_date_time_format (gdt_now, "%FT%T")); - g_key_file_save_to_file (priv->kfile, g_file_get_path (priv->gfile), NULL); - } - - g_date_time_unref (gdt_plus); - g_date_time_unref (gdt_now); - } - - g_date_time_unref (gdt); - } - else - { - zak_cgi_session_close (zak_cgi_session); - } - } + zak_cgi_session_close (zak_cgi_session); } } @@ -331,6 +267,109 @@ gchar return ret; } +/** + * zak_cgi_session_is_valid: + * @session: + * + */ +gboolean +zak_cgi_session_is_valid (ZakCgiSession *session) +{ + gboolean ret; + + GError *error; + + gchar *filename; + gchar *val; + + GTimeVal tval; + GDateTime *gdt; + GDateTime *gdt_now; + GDateTime *gdt_plus; + + ZakCgiSessionPrivate *priv = ZAK_CGI_SESSION_GET_PRIVATE (session); + + ret = FALSE; + + if (priv->sid != NULL) + { + /* open the file */ + filename = g_build_filename (priv->path != NULL ? priv->path : g_get_tmp_dir (), priv->sid, NULL); + priv->gfile = g_file_new_for_path (filename); + g_free (filename); + + error = NULL; + + /* check the content */ + priv->kfile = g_key_file_new (); + if (g_key_file_load_from_file (priv->kfile, + g_file_get_path (priv->gfile), + G_KEY_FILE_NONE, + &error) + && error == NULL) + { + val = g_key_file_get_string (priv->kfile, "ZAKCGI", "REMOTE_ADDR", NULL); + if (val != NULL + && g_strcmp0 (val, g_getenv ("REMOTE_ADDR")) == 0) + { + val = g_key_file_get_string (priv->kfile, "ZAKCGI", "TIMESTAMP", NULL); + if (val != NULL) + { + if (g_time_val_from_iso8601 (val, &tval)) + { + gdt = g_date_time_new_from_timeval_local (&tval); + if (gdt != NULL) + { + /* TODO + * add a property for minutes number */ + gdt_plus = g_date_time_add_minutes (gdt, 5); + gdt_now = g_date_time_new_now_local (); + if (g_date_time_compare (gdt_plus, gdt_now) > -1) + { + ret = TRUE; + } + else + { + g_warning ("Session expired."); + } + + g_date_time_unref (gdt_plus); + g_date_time_unref (gdt_now); + } + else + { + g_warning ("Session expired."); + } + + g_date_time_unref (gdt); + } + else + { + g_warning ("Session expired."); + } + } + else + { + g_warning ("Session expired."); + } + } + else + { + g_warning ("Possibile session hijackin: right addr %s; current addr %s", + val, g_getenv ("REMOTE_ADDR")); + } + } + else + { + g_warning ("Unable to open session file «%s»: %s.", + g_file_get_path (priv->gfile), + error != NULL && error->message != NULL ? error->message : "no details"); + } + } + + return ret; +} + /** * zak_cgi_session_close: * @session: diff --git a/src/session.h b/src/session.h index caa23c2..74230c8 100644 --- a/src/session.h +++ b/src/session.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 Andrea Zagli + * Copyright (C) 2015-2016 Andrea Zagli * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -60,6 +60,8 @@ gchar *zak_cgi_session_get_header (ZakCgiSession *session); void zak_cgi_session_set_value (ZakCgiSession *session, const gchar *name, const gchar *value); gchar *zak_cgi_session_get_value (ZakCgiSession *session, const gchar *name); +gboolean zak_cgi_session_is_valid (ZakCgiSession *session); + void zak_cgi_session_close (ZakCgiSession *session); diff --git a/tests/session.c b/tests/session.c index bdbe0b2..5296563 100644 --- a/tests/session.c +++ b/tests/session.c @@ -28,20 +28,23 @@ main (int argc, char *argv[]) GString *header; GHashTable *ht; GHashTable *ht_stdin; + ZakCgiMain *zakcgimain; ZakCgiSession *session; gchar *method; - session = zak_cgi_session_new (NULL, NULL, NULL); + zakcgimain = zak_cgi_main_new (); + + session = zak_cgi_session_new (zakcgimain, NULL, NULL); str = g_string_new ("\n" "Session Cookie\n" "\n"); - ht = zak_cgi_main_get_env (NULL); + ht = zak_cgi_main_get_env (zakcgimain); if (ht != NULL) { - method = g_hash_table_lookup (ht, "REQUEST_METHOD"); + method = g_value_get_string (g_hash_table_lookup (ht, "REQUEST_METHOD")); if (g_strcmp0 (method, "POST") == 0) { const gchar *content_type = g_getenv ("CONTENT_TYPE"); @@ -50,7 +53,7 @@ main (int argc, char *argv[]) { gchar **boundary = g_strsplit (splitted[1], "=", 2); - env = zak_cgi_main_get_stdin (NULL); + env = zak_cgi_main_get_stdin (zakcgimain); ht_stdin = zak_cgi_main_parse_stdin (env, boundary[1]); -- 2.49.0