Browse Source

add session removal by ip

next
Georg Hopp 12 years ago
parent
commit
a9b2338655
  1. 11
      include/application/application.h
  2. 2
      include/http/worker.h
  3. 13
      include/session.h
  4. 7
      src/application/adapter/http/update.c
  5. 9
      src/application/application.c
  6. 12
      src/application/session_cleanup.c
  7. 55
      src/application/session_get.c
  8. 30
      src/application/session_start.c
  9. 25
      src/application/session_stop.c
  10. 7
      src/server/handle_accept.c
  11. 2
      src/session/session.c

11
include/application/application.h

@ -42,8 +42,13 @@ struct randval {
int value;
};
struct sessinfo {
TR_Hash sessions;
TR_Tree ip_index;
};
TR_CLASS(Application) {
TR_Hash * active_sessions;
struct sessinfo * active_sessions;
time_t session_time_ofs;
Auth auth;
@ -70,8 +75,8 @@ TR_Uuid applicationUpdateUser(Application, User);
User applicationGetUser(Application, TR_Uuid);
int applicationUpdatePassword(Application, Credential, User);
Session applicationSessionStart(Application);
Session applicationSessionGet(Application, const char *);
Session applicationSessionStart(Application, uint32_t);
Session applicationSessionGet(Application, const char *, uint32_t);
void applicationSessionStop(Application, Session);
void applicationSessionCleanup(Application, time_t);

2
include/http/worker.h

@ -29,6 +29,7 @@
#include "trbase.h"
#include "trdata.h"
#include "trio.h"
#include "http/parser.h"
#include "http/writer.h"
#include "session.h"
@ -39,6 +40,7 @@
TR_CLASS(HttpWorker) {
char * id;
TR_Sock socket;
TR_Cbuf pbuf;
TR_Hash asset_pool;

13
include/session.h

@ -24,6 +24,7 @@
#define __SESSION_H__
#include <time.h>
#include <stdint.h>
#include <sys/types.h>
#include <user.h>
@ -54,16 +55,7 @@
* This sums up to 10GB of used memory within the 5 minutes
* session livetime.
*
* @TODO
* One possible solution is to prevent the creation of sessions
* for subsequent requests from the same connection or ip within
* a given time range. This time range should be the session
* livetime. This would effectively prevent such malicious requests
* from doing harm but also prevents non attackers that did a
* first request from another client (lets say telnet) from getting
* a session in their browser. This might be accaptable if the user
* gets a fitting error message.
* To prevent this we could associate the session with the ip it was
* To prevent this I associate the session with the ip it was
* created on. If there then is a subsequent request from the same ip
* without a sessionid, the old session can be removed and a new one
* can be created. This might give a small but acceptable performance
@ -73,6 +65,7 @@
TR_CLASS(Session) {
char id[37];
unsigned long hash;
uint32_t ip;
time_t livetime;
User user;

7
src/application/adapter/http/update.c

@ -23,10 +23,12 @@
#define _GNU_SOURCE
#include <stdio.h>
#include <stdint.h>
#include <sys/types.h>
#include "trbase.h"
#include "trdata.h"
#include "trio.h"
#include "application/application.h"
#include "application/adapter/http.h"
@ -58,6 +60,7 @@ applicationAdapterHttpUpdate(void * _this, void * subject)
HttpWorker worker = (HttpWorker)subject;
Session session = NULL;
time_t now = time(NULL);
uint32_t ip = TR_socketGetIp(worker->socket);
char * sid;
char buf[1000];
@ -66,10 +69,10 @@ applicationAdapterHttpUpdate(void * _this, void * subject)
applicationSessionCleanup(this->application, now);
sid = getSessionId(worker->current_request->cookies);
session = applicationSessionGet(this->application, sid);
session = applicationSessionGet(this->application, sid, ip);
if (NULL == session) {
session = applicationSessionStart(this->application);
session = applicationSessionStart(this->application, ip);
}
// send session cookie

9
src/application/application.c

@ -57,9 +57,11 @@ applicationCtor(void * _this, va_list * params)
this->auth = va_arg(*params, void *);
this->active_sessions = TR_calloc(SESSION_LIVETIME, sizeof(TR_Hash));
this->active_sessions = TR_calloc(
SESSION_LIVETIME,
sizeof(struct sessinfo));
for (i=0; i<SESSION_LIVETIME; i++) {
this->active_sessions[i] = TR_new(TR_Hash);
this->active_sessions[i].sessions = TR_new(TR_Hash);
}
this->version = VERSION;
@ -76,7 +78,8 @@ applicationDtor(void * _this)
size_t i;
for (i=0; i<SESSION_LIVETIME; i++) {
TR_delete(this->active_sessions[i]);
TR_delete(this->active_sessions[i].sessions);
TR_delete(this->active_sessions[i].ip_index);
}
TR_MEM_FREE(this->active_sessions);

12
src/application/session_cleanup.c

@ -23,6 +23,7 @@
#define _GNU_SOURCE
#include <stdlib.h>
#include <stdint.h>
#include <sys/types.h>
#include "trdata.h"
@ -43,23 +44,26 @@ applicationSessionCleanup(Application this, time_t now)
}
if (0 < expired && SESSION_LIVETIME > expired) {
TR_Hash * tmp_buf = TR_calloc(SESSION_LIVETIME, sizeof(TR_Hash));
struct sessinfo * tmp_buf = TR_calloc(
SESSION_LIVETIME,
sizeof(struct sessinfo));
memcpy(
&(tmp_buf[expired]),
this->active_sessions,
(SESSION_LIVETIME - expired) * sizeof(TR_Hash));
(SESSION_LIVETIME - expired) * sizeof(struct sessinfo));
memcpy(
tmp_buf,
&(this->active_sessions[SESSION_LIVETIME - expired]),
expired * sizeof(TR_Hash));
expired * sizeof(struct sessinfo));
TR_MEM_FREE(this->active_sessions);
this->active_sessions = tmp_buf;
}
for (i=0; i<expired; i++) {
TR_hashCleanup(this->active_sessions[i]);
TR_treeDestroy(&(this->active_sessions[i].ip_index), NULL);
TR_hashCleanup(this->active_sessions[i].sessions);
}
this->session_time_ofs = now;

55
src/application/session_get.c

@ -23,37 +23,76 @@
#define _GNU_SOURCE
#include <sys/types.h>
#include <stdint.h>
#include <inttypes.h>
#include <stdio.h>
#include "trdata.h"
#include "session.h"
#include "application/application.h"
static
inline
int
sessionIpIndexComp(const void * a, const void * b)
{
Session sess_a = (Session)a;
uint32_t ip = *(uint32_t *)b;
if (sess_a->ip < ip) {
return -1;
}
if (sess_a->ip > ip) {
return 1;
}
return 0;
}
Session
applicationSessionGet(Application this, const char * sid)
applicationSessionGet(Application this, const char * sid, uint32_t ip)
{
Session sess = NULL;
int index;
if (NULL != sid) {
/**
* now get the session if not expired
*/
for (index=0; index<SESSION_LIVETIME; index++) {
if (NULL != sid) {
sess = (Session)TR_hashDelete(
(this->active_sessions)[index], sid, 36);
if (NULL != sess) {
break;
}
(this->active_sessions)[index].sessions, sid, 36);
}
if (NULL != sess) {
/**
* update livetime of session if found
*/
if (NULL != sess) {
sess->livetime = this->session_time_ofs + SESSION_LIVETIME;
TR_hashAdd((this->active_sessions)[0], sess);
sess = (Session)TR_treeDelete(
&((this->active_sessions)[index].ip_index),
&ip, sessionIpIndexComp);
TR_hashAdd((this->active_sessions)[0].sessions, sess);
TR_treeInsert(
&((this->active_sessions)[0].ip_index),
sess,
sessionIpIndexComp);
break;
} else {
sess = (Session)TR_treeDelete(
&((this->active_sessions)[index].ip_index),
&ip, sessionIpIndexComp);
if (NULL != sess) {
// we have a previous session from this ip, remove it.
TR_hashDelete(
(this->active_sessions)[index].sessions,
sess->id, 36);
TR_delete(sess);
break;
}
}
}

30
src/application/session_start.c

@ -23,6 +23,7 @@
#define _GNU_SOURCE
#include <stdlib.h>
#include <stdint.h>
#include <sys/types.h>
#include "trbase.h"
@ -32,12 +33,35 @@
#include "application/application.h"
static
inline
int
sessionIpIndexComp(const void * a, const void * b)
{
Session sess_a = (Session)a;
Session sess_b = (Session)b;
if (sess_a->ip < sess_b->ip) {
return -1;
}
if (sess_a->ip > sess_b->ip) {
return 1;
}
return 0;
}
Session
applicationSessionStart(Application this)
applicationSessionStart(Application this, uint32_t ip)
{
Session sess = TR_new(Session);
Session sess = TR_new(Session, ip);
TR_hashAdd((this->active_sessions)[0], sess);
TR_hashAdd((this->active_sessions)[0].sessions, sess);
TR_treeInsert(
&((this->active_sessions)[0].ip_index),
sess,
sessionIpIndexComp);
return sess;
}

25
src/application/session_stop.c

@ -29,6 +29,24 @@
#include "session.h"
#include "application/application.h"
static
inline
int
sessionIpIndexComp(const void * a, const void * b)
{
Session sess_a = (Session)a;
Session sess_b = (Session)b;
if (sess_a->ip < sess_b->ip) {
return -1;
}
if (sess_a->ip > sess_b->ip) {
return 1;
}
return 0;
}
void
applicationSessionStop(Application this, Session session)
@ -37,7 +55,12 @@ applicationSessionStop(Application this, Session session)
(session->livetime - this->session_time_ofs);
if (SESSION_LIVETIME > index) {
TR_hashDeleteByVal((this->active_sessions)[index], session->hash);
TR_hashDeleteByVal(
(this->active_sessions)[index].sessions,
session->hash);
TR_treeDelete(
&((this->active_sessions)[index].ip_index),
session, sessionIpIndexComp);
}
}

7
src/server/handle_accept.c

@ -73,6 +73,13 @@ serverHandleAccept(Server this, unsigned int i)
// clone worker
(this->conns)[acc->handle].worker = TR_clone(this->worker);
/**
* TODO
* workers need an interface to set the socket within them...
* as I currently only have http workers I do a cast here
* but this is not future save.
*/
((HttpWorker)(this->conns)[acc->handle].worker)->socket = acc;
(this->conns)[acc->handle].stream = st;
(this->fds)[this->nfds].fd = acc->handle;

2
src/session/session.c

@ -23,6 +23,7 @@
#include <time.h>
#include <stdarg.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <stdio.h>
#include <sys/types.h>
@ -47,6 +48,7 @@ sessionCtor(void * _this, va_list * params)
uuid_unparse(uuid, this->id);
this->hash = TR_sdbm((unsigned char *)this->id, 36);
this->ip = va_arg(*params, uint32_t);
return 0;
}

Loading…
Cancel
Save