Commit a9b233865524abe8dea5a11d6add78066e4b5b77

Authored by Georg Hopp
1 parent 666813e9

add session removal by ip

... ... @@ -42,25 +42,30 @@ struct randval {
42 42 int value;
43 43 };
44 44
  45 +struct sessinfo {
  46 + TR_Hash sessions;
  47 + TR_Tree ip_index;
  48 +};
  49 +
45 50 TR_CLASS(Application) {
46   - TR_Hash * active_sessions;
  51 + struct sessinfo * active_sessions;
47 52 time_t session_time_ofs;
48 53
49 54 Auth auth;
50 55
51   - struct randval * val;
  56 + struct randval * val;
52 57
53   - Storage users;
54   - Storage passwords;
55   - Storage roles;
  58 + Storage users;
  59 + Storage passwords;
  60 + Storage roles;
56 61
57   - TR_Uuid user_namespace;
  62 + TR_Uuid user_namespace;
58 63
59   - TR_Hash roles_user_index;
60   - TR_Hash roles_resource_index;
  64 + TR_Hash roles_user_index;
  65 + TR_Hash roles_resource_index;
61 66
62   - const char * version;
63   - const char * loc;
  67 + const char * version;
  68 + const char * loc;
64 69 };
65 70
66 71 int applicationLogin(Application, Credential, Session);
... ... @@ -70,8 +75,8 @@ TR_Uuid applicationUpdateUser(Application, User);
70 75 User applicationGetUser(Application, TR_Uuid);
71 76 int applicationUpdatePassword(Application, Credential, User);
72 77
73   -Session applicationSessionStart(Application);
74   -Session applicationSessionGet(Application, const char *);
  78 +Session applicationSessionStart(Application, uint32_t);
  79 +Session applicationSessionGet(Application, const char *, uint32_t);
75 80 void applicationSessionStop(Application, Session);
76 81 void applicationSessionCleanup(Application, time_t);
77 82
... ...
... ... @@ -29,6 +29,7 @@
29 29
30 30 #include "trbase.h"
31 31 #include "trdata.h"
  32 +#include "trio.h"
32 33 #include "http/parser.h"
33 34 #include "http/writer.h"
34 35 #include "session.h"
... ... @@ -39,6 +40,7 @@
39 40
40 41 TR_CLASS(HttpWorker) {
41 42 char * id;
  43 + TR_Sock socket;
42 44
43 45 TR_Cbuf pbuf;
44 46 TR_Hash asset_pool;
... ...
... ... @@ -24,6 +24,7 @@
24 24 #define __SESSION_H__
25 25
26 26 #include <time.h>
  27 +#include <stdint.h>
27 28 #include <sys/types.h>
28 29 #include <user.h>
29 30
... ... @@ -54,16 +55,7 @@
54 55 * This sums up to 10GB of used memory within the 5 minutes
55 56 * session livetime.
56 57 *
57   - * @TODO
58   - * One possible solution is to prevent the creation of sessions
59   - * for subsequent requests from the same connection or ip within
60   - * a given time range. This time range should be the session
61   - * livetime. This would effectively prevent such malicious requests
62   - * from doing harm but also prevents non attackers that did a
63   - * first request from another client (lets say telnet) from getting
64   - * a session in their browser. This might be accaptable if the user
65   - * gets a fitting error message.
66   - * To prevent this we could associate the session with the ip it was
  58 + * To prevent this I associate the session with the ip it was
67 59 * created on. If there then is a subsequent request from the same ip
68 60 * without a sessionid, the old session can be removed and a new one
69 61 * can be created. This might give a small but acceptable performance
... ... @@ -73,6 +65,7 @@
73 65 TR_CLASS(Session) {
74 66 char id[37];
75 67 unsigned long hash;
  68 + uint32_t ip;
76 69
77 70 time_t livetime;
78 71 User user;
... ...
... ... @@ -23,10 +23,12 @@
23 23 #define _GNU_SOURCE
24 24
25 25 #include <stdio.h>
  26 +#include <stdint.h>
26 27 #include <sys/types.h>
27 28
28 29 #include "trbase.h"
29 30 #include "trdata.h"
  31 +#include "trio.h"
30 32
31 33 #include "application/application.h"
32 34 #include "application/adapter/http.h"
... ... @@ -58,6 +60,7 @@ applicationAdapterHttpUpdate(void * _this, void * subject)
58 60 HttpWorker worker = (HttpWorker)subject;
59 61 Session session = NULL;
60 62 time_t now = time(NULL);
  63 + uint32_t ip = TR_socketGetIp(worker->socket);
61 64
62 65 char * sid;
63 66 char buf[1000];
... ... @@ -66,10 +69,10 @@ applicationAdapterHttpUpdate(void * _this, void * subject)
66 69 applicationSessionCleanup(this->application, now);
67 70
68 71 sid = getSessionId(worker->current_request->cookies);
69   - session = applicationSessionGet(this->application, sid);
  72 + session = applicationSessionGet(this->application, sid, ip);
70 73
71 74 if (NULL == session) {
72   - session = applicationSessionStart(this->application);
  75 + session = applicationSessionStart(this->application, ip);
73 76 }
74 77
75 78 // send session cookie
... ...
... ... @@ -57,9 +57,11 @@ applicationCtor(void * _this, va_list * params)
57 57
58 58 this->auth = va_arg(*params, void *);
59 59
60   - this->active_sessions = TR_calloc(SESSION_LIVETIME, sizeof(TR_Hash));
  60 + this->active_sessions = TR_calloc(
  61 + SESSION_LIVETIME,
  62 + sizeof(struct sessinfo));
61 63 for (i=0; i<SESSION_LIVETIME; i++) {
62   - this->active_sessions[i] = TR_new(TR_Hash);
  64 + this->active_sessions[i].sessions = TR_new(TR_Hash);
63 65 }
64 66
65 67 this->version = VERSION;
... ... @@ -76,7 +78,8 @@ applicationDtor(void * _this)
76 78 size_t i;
77 79
78 80 for (i=0; i<SESSION_LIVETIME; i++) {
79   - TR_delete(this->active_sessions[i]);
  81 + TR_delete(this->active_sessions[i].sessions);
  82 + TR_delete(this->active_sessions[i].ip_index);
80 83 }
81 84
82 85 TR_MEM_FREE(this->active_sessions);
... ...
... ... @@ -23,6 +23,7 @@
23 23 #define _GNU_SOURCE
24 24
25 25 #include <stdlib.h>
  26 +#include <stdint.h>
26 27 #include <sys/types.h>
27 28
28 29 #include "trdata.h"
... ... @@ -43,23 +44,26 @@ applicationSessionCleanup(Application this, time_t now)
43 44 }
44 45
45 46 if (0 < expired && SESSION_LIVETIME > expired) {
46   - TR_Hash * tmp_buf = TR_calloc(SESSION_LIVETIME, sizeof(TR_Hash));
  47 + struct sessinfo * tmp_buf = TR_calloc(
  48 + SESSION_LIVETIME,
  49 + sizeof(struct sessinfo));
47 50
48 51 memcpy(
49 52 &(tmp_buf[expired]),
50 53 this->active_sessions,
51   - (SESSION_LIVETIME - expired) * sizeof(TR_Hash));
  54 + (SESSION_LIVETIME - expired) * sizeof(struct sessinfo));
52 55 memcpy(
53 56 tmp_buf,
54 57 &(this->active_sessions[SESSION_LIVETIME - expired]),
55   - expired * sizeof(TR_Hash));
  58 + expired * sizeof(struct sessinfo));
56 59
57 60 TR_MEM_FREE(this->active_sessions);
58 61 this->active_sessions = tmp_buf;
59 62 }
60 63
61 64 for (i=0; i<expired; i++) {
62   - TR_hashCleanup(this->active_sessions[i]);
  65 + TR_treeDestroy(&(this->active_sessions[i].ip_index), NULL);
  66 + TR_hashCleanup(this->active_sessions[i].sessions);
63 67 }
64 68
65 69 this->session_time_ofs = now;
... ...
... ... @@ -23,37 +23,76 @@
23 23 #define _GNU_SOURCE
24 24
25 25 #include <sys/types.h>
  26 +#include <stdint.h>
  27 +
  28 +#include <inttypes.h>
  29 +#include <stdio.h>
26 30
27 31 #include "trdata.h"
28 32
29 33 #include "session.h"
30 34 #include "application/application.h"
31 35
  36 +static
  37 +inline
  38 + int
  39 +sessionIpIndexComp(const void * a, const void * b)
  40 +{
  41 + Session sess_a = (Session)a;
  42 + uint32_t ip = *(uint32_t *)b;
  43 +
  44 + if (sess_a->ip < ip) {
  45 + return -1;
  46 + }
  47 +
  48 + if (sess_a->ip > ip) {
  49 + return 1;
  50 + }
  51 +
  52 + return 0;
  53 +}
32 54
33 55 Session
34   -applicationSessionGet(Application this, const char * sid)
  56 +applicationSessionGet(Application this, const char * sid, uint32_t ip)
35 57 {
36 58 Session sess = NULL;
37 59 int index;
38 60
39   - if (NULL != sid) {
40   - /**
41   - * now get the session if not expired
42   - */
43   - for (index=0; index<SESSION_LIVETIME; index++) {
  61 + /**
  62 + * now get the session if not expired
  63 + */
  64 + for (index=0; index<SESSION_LIVETIME; index++) {
  65 + if (NULL != sid) {
44 66 sess = (Session)TR_hashDelete(
45   - (this->active_sessions)[index], sid, 36);
46   - if (NULL != sess) {
47   - break;
48   - }
  67 + (this->active_sessions)[index].sessions, sid, 36);
49 68 }
50 69
51   - /**
52   - * update livetime of session if found
53   - */
54 70 if (NULL != sess) {
  71 + /**
  72 + * update livetime of session if found
  73 + */
55 74 sess->livetime = this->session_time_ofs + SESSION_LIVETIME;
56   - TR_hashAdd((this->active_sessions)[0], sess);
  75 + sess = (Session)TR_treeDelete(
  76 + &((this->active_sessions)[index].ip_index),
  77 + &ip, sessionIpIndexComp);
  78 + TR_hashAdd((this->active_sessions)[0].sessions, sess);
  79 + TR_treeInsert(
  80 + &((this->active_sessions)[0].ip_index),
  81 + sess,
  82 + sessionIpIndexComp);
  83 + break;
  84 + } else {
  85 + sess = (Session)TR_treeDelete(
  86 + &((this->active_sessions)[index].ip_index),
  87 + &ip, sessionIpIndexComp);
  88 + if (NULL != sess) {
  89 + // we have a previous session from this ip, remove it.
  90 + TR_hashDelete(
  91 + (this->active_sessions)[index].sessions,
  92 + sess->id, 36);
  93 + TR_delete(sess);
  94 + break;
  95 + }
57 96 }
58 97 }
59 98
... ...
... ... @@ -23,6 +23,7 @@
23 23 #define _GNU_SOURCE
24 24
25 25 #include <stdlib.h>
  26 +#include <stdint.h>
26 27 #include <sys/types.h>
27 28
28 29 #include "trbase.h"
... ... @@ -32,12 +33,35 @@
32 33 #include "application/application.h"
33 34
34 35
  36 +static
  37 +inline
  38 +int
  39 +sessionIpIndexComp(const void * a, const void * b)
  40 +{
  41 + Session sess_a = (Session)a;
  42 + Session sess_b = (Session)b;
  43 +
  44 + if (sess_a->ip < sess_b->ip) {
  45 + return -1;
  46 + }
  47 +
  48 + if (sess_a->ip > sess_b->ip) {
  49 + return 1;
  50 + }
  51 +
  52 + return 0;
  53 +}
  54 +
35 55 Session
36   -applicationSessionStart(Application this)
  56 +applicationSessionStart(Application this, uint32_t ip)
37 57 {
38   - Session sess = TR_new(Session);
  58 + Session sess = TR_new(Session, ip);
39 59
40   - TR_hashAdd((this->active_sessions)[0], sess);
  60 + TR_hashAdd((this->active_sessions)[0].sessions, sess);
  61 + TR_treeInsert(
  62 + &((this->active_sessions)[0].ip_index),
  63 + sess,
  64 + sessionIpIndexComp);
41 65
42 66 return sess;
43 67 }
... ...
... ... @@ -29,6 +29,24 @@
29 29 #include "session.h"
30 30 #include "application/application.h"
31 31
  32 +static
  33 +inline
  34 +int
  35 +sessionIpIndexComp(const void * a, const void * b)
  36 +{
  37 + Session sess_a = (Session)a;
  38 + Session sess_b = (Session)b;
  39 +
  40 + if (sess_a->ip < sess_b->ip) {
  41 + return -1;
  42 + }
  43 +
  44 + if (sess_a->ip > sess_b->ip) {
  45 + return 1;
  46 + }
  47 +
  48 + return 0;
  49 +}
32 50
33 51 void
34 52 applicationSessionStop(Application this, Session session)
... ... @@ -37,7 +55,12 @@ applicationSessionStop(Application this, Session session)
37 55 (session->livetime - this->session_time_ofs);
38 56
39 57 if (SESSION_LIVETIME > index) {
40   - TR_hashDeleteByVal((this->active_sessions)[index], session->hash);
  58 + TR_hashDeleteByVal(
  59 + (this->active_sessions)[index].sessions,
  60 + session->hash);
  61 + TR_treeDelete(
  62 + &((this->active_sessions)[index].ip_index),
  63 + session, sessionIpIndexComp);
41 64 }
42 65 }
43 66
... ...
... ... @@ -69,14 +69,21 @@ serverHandleAccept(Server this, unsigned int i)
69 69 }
70 70
71 71 // save the socket handle
72   - (this->conns)[acc->handle].sock = acc;
  72 + (this->conns)[acc->handle].sock = acc;
73 73
74 74 // clone worker
75   - (this->conns)[acc->handle].worker = TR_clone(this->worker);
76   - (this->conns)[acc->handle].stream = st;
77   -
78   - (this->fds)[this->nfds].fd = acc->handle;
79   - (this->fds)[this->nfds].events = POLLIN;
  75 + (this->conns)[acc->handle].worker = TR_clone(this->worker);
  76 + /**
  77 + * TODO
  78 + * workers need an interface to set the socket within them...
  79 + * as I currently only have http workers I do a cast here
  80 + * but this is not future save.
  81 + */
  82 + ((HttpWorker)(this->conns)[acc->handle].worker)->socket = acc;
  83 + (this->conns)[acc->handle].stream = st;
  84 +
  85 + (this->fds)[this->nfds].fd = acc->handle;
  86 + (this->fds)[this->nfds].events = POLLIN;
80 87 this->nfds++;
81 88 } else {
82 89 TR_delete(acc);
... ...
... ... @@ -23,6 +23,7 @@
23 23 #include <time.h>
24 24 #include <stdarg.h>
25 25 #include <stdlib.h>
  26 +#include <stdint.h>
26 27 #include <string.h>
27 28 #include <stdio.h>
28 29 #include <sys/types.h>
... ... @@ -47,6 +48,7 @@ sessionCtor(void * _this, va_list * params)
47 48 uuid_unparse(uuid, this->id);
48 49
49 50 this->hash = TR_sdbm((unsigned char *)this->id, 36);
  51 + this->ip = va_arg(*params, uint32_t);
50 52
51 53 return 0;
52 54 }
... ...
Please register or login to post a comment