Showing
11 changed files
with
160 additions
and
55 deletions
... | ... | @@ -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