merged the modularization branch (credentials) back to trunk
This commit is contained in:
+3
-14
@@ -1,27 +1,16 @@
|
||||
ipsec_PROGRAMS = manager.fcgi
|
||||
|
||||
manager_fcgi_SOURCES = \
|
||||
main.c manager.c manager.h gateway.h gateway.c database.h database.c \
|
||||
main.c manager.c manager.h gateway.h gateway.c storage.h storage.c xml.h xml.c \
|
||||
controller/auth_controller.c controller/auth_controller.h \
|
||||
controller/ikesa_controller.c controller/ikesa_controller.h \
|
||||
controller/control_controller.c controller/control_controller.h \
|
||||
controller/config_controller.c controller/config_controller.h \
|
||||
controller/gateway_controller.c controller/gateway_controller.h
|
||||
|
||||
manager_fcgi_LDADD = $(top_builddir)/src/manager/libappserv.la -lsqlite3
|
||||
manager_fcgi_LDADD = $(top_builddir)/src/libfast/libfast.la ${xml_LIBS}
|
||||
|
||||
|
||||
|
||||
lib_LTLIBRARIES = libappserv.la
|
||||
|
||||
libappserv_la_SOURCES = \
|
||||
lib/context.h lib/dispatcher.c lib/request.h lib/session.h \
|
||||
lib/controller.h lib/dispatcher.h lib/request.c lib/session.c \
|
||||
lib/xml.h lib/xml.c
|
||||
|
||||
libappserv_la_LIBADD = $(top_builddir)/src/libstrongswan/libstrongswan.la -lfcgi -lpthread -lneo_cgi -lneo_cs -lneo_utl ${xml_LIBS}
|
||||
|
||||
INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/manager/lib -I/usr/include/ClearSilver ${xml_CFLAGS}
|
||||
INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libfast ${xml_CFLAGS}
|
||||
AM_CFLAGS = -rdynamic -DIPSECDIR=\"${ipsecdir}\" -DIPSEC_PIDDIR=\"${piddir}\"
|
||||
|
||||
ipsec_DATA = manager.db
|
||||
|
||||
@@ -1,10 +1,3 @@
|
||||
/**
|
||||
* @file auth_controller.c
|
||||
*
|
||||
* @brief Implementation of auth_controller_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2007 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
@@ -18,6 +11,8 @@
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include "auth_controller.h"
|
||||
|
||||
@@ -1,10 +1,3 @@
|
||||
/**
|
||||
* @file auth_controller.h
|
||||
*
|
||||
* @brief Interface of auth_controller_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2007 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
@@ -18,6 +11,13 @@
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup auth_controller auth_controller
|
||||
* @{ @ingroup controller
|
||||
*/
|
||||
|
||||
#ifndef AUTH_CONTROLLER_H_
|
||||
@@ -29,7 +29,7 @@
|
||||
typedef struct auth_controller_t auth_controller_t;
|
||||
|
||||
/**
|
||||
* @brief Authentication controller.
|
||||
* Authentication controller.
|
||||
*/
|
||||
struct auth_controller_t {
|
||||
|
||||
@@ -40,8 +40,8 @@ struct auth_controller_t {
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Create a auth_controller controller instance.
|
||||
* Create a auth_controller controller instance.
|
||||
*/
|
||||
controller_t *auth_controller_create(context_t *context, void *param);
|
||||
|
||||
#endif /* AUTH_CONTROLLER_H_ */
|
||||
#endif /* AUTH_CONTROLLER_H_ @} */
|
||||
|
||||
@@ -1,10 +1,3 @@
|
||||
/**
|
||||
* @file config_controller.c
|
||||
*
|
||||
* @brief Implementation of config_controller_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2007 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
@@ -18,6 +11,8 @@
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include "config_controller.h"
|
||||
|
||||
@@ -1,10 +1,3 @@
|
||||
/**
|
||||
* @file config_controller.h
|
||||
*
|
||||
* @brief Interface of config_controller_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2007 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
@@ -18,6 +11,13 @@
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup config_controller config_controller
|
||||
* @{ @ingroup controller
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_CONTROLLER_H_
|
||||
@@ -29,7 +29,7 @@
|
||||
typedef struct config_controller_t config_controller_t;
|
||||
|
||||
/**
|
||||
* @brief Status controller.
|
||||
* Status controller.
|
||||
*/
|
||||
struct config_controller_t {
|
||||
|
||||
@@ -40,8 +40,8 @@ struct config_controller_t {
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Create a config_controller controller instance.
|
||||
* Create a config_controller controller instance.
|
||||
*/
|
||||
controller_t *config_controller_create(context_t *context, void *param);
|
||||
|
||||
#endif /* CONFIG_CONTROLLER_H_ */
|
||||
#endif /* CONFIG_CONTROLLER_H_ @} */
|
||||
|
||||
@@ -1,10 +1,3 @@
|
||||
/**
|
||||
* @file control_controller.c
|
||||
*
|
||||
* @brief Implementation of control_controller_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2007 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
@@ -18,6 +11,8 @@
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include "control_controller.h"
|
||||
|
||||
@@ -1,10 +1,3 @@
|
||||
/**
|
||||
* @file control_controller.h
|
||||
*
|
||||
* @brief Interface of control_controller_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2007 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
@@ -18,6 +11,13 @@
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup control_controller control_controller
|
||||
* @{ @ingroup controller
|
||||
*/
|
||||
|
||||
#ifndef CONTROL_CONTROLLER_H_
|
||||
@@ -29,7 +29,7 @@
|
||||
typedef struct control_controller_t control_controller_t;
|
||||
|
||||
/**
|
||||
* @brief Status controller.
|
||||
* Control controller.
|
||||
*/
|
||||
struct control_controller_t {
|
||||
|
||||
@@ -40,7 +40,7 @@ struct control_controller_t {
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Create a control_controller controller instance.
|
||||
* Create a control_controller controller instance.
|
||||
*/
|
||||
controller_t *control_controller_create(context_t *context, void *param);
|
||||
|
||||
|
||||
@@ -1,10 +1,3 @@
|
||||
/**
|
||||
* @file gateway_controller.c
|
||||
*
|
||||
* @brief Implementation of gateway_controller_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2007 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
@@ -18,6 +11,8 @@
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include "gateway_controller.h"
|
||||
|
||||
@@ -1,10 +1,3 @@
|
||||
/**
|
||||
* @file gateway_controller.h
|
||||
*
|
||||
* @brief Interface of gateway_controller_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2007 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
@@ -18,6 +11,13 @@
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup gateway_controller gateway_controller
|
||||
* @{ @ingroup controller
|
||||
*/
|
||||
|
||||
#ifndef GATEWAY_CONTROLLER_H_
|
||||
@@ -29,7 +29,7 @@
|
||||
typedef struct gateway_controller_t gateway_controller_t;
|
||||
|
||||
/**
|
||||
* @brief Status controller.
|
||||
* Status controller.
|
||||
*/
|
||||
struct gateway_controller_t {
|
||||
|
||||
@@ -40,8 +40,8 @@ struct gateway_controller_t {
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Create a gateway_controller controller instance.
|
||||
* Create a gateway_controller controller instance.
|
||||
*/
|
||||
controller_t *gateway_controller_create(context_t *context, void *param);
|
||||
|
||||
#endif /* GATEWAY_CONTROLLER_H_ */
|
||||
#endif /* GATEWAY_CONTROLLER_H_ @} */
|
||||
|
||||
@@ -1,10 +1,3 @@
|
||||
/**
|
||||
* @file ikesa_controller.c
|
||||
*
|
||||
* @brief Implementation of ikesa_controller_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2007 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
@@ -18,6 +11,8 @@
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include "ikesa_controller.h"
|
||||
|
||||
@@ -1,10 +1,3 @@
|
||||
/**
|
||||
* @file ikesa_controller.h
|
||||
*
|
||||
* @brief Interface of ikesa_controller_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2007 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
@@ -18,6 +11,13 @@
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup ikesa_controller ikesa_controller
|
||||
* @{ @ingroup controller
|
||||
*/
|
||||
|
||||
#ifndef IKESA_CONTROLLER_H_
|
||||
@@ -29,7 +29,7 @@
|
||||
typedef struct ikesa_controller_t ikesa_controller_t;
|
||||
|
||||
/**
|
||||
* @brief Status controller.
|
||||
* Status controller.
|
||||
*/
|
||||
struct ikesa_controller_t {
|
||||
|
||||
@@ -40,8 +40,8 @@ struct ikesa_controller_t {
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Create a ikesa_controller controller instance.
|
||||
* Create a ikesa_controller controller instance.
|
||||
*/
|
||||
controller_t *ikesa_controller_create(context_t *context, void *param);
|
||||
|
||||
#endif /* IKESA_CONTROLLER_H_ */
|
||||
#endif /* IKESA_CONTROLLER_H_ @} */
|
||||
|
||||
@@ -1,183 +0,0 @@
|
||||
/**
|
||||
* @file database.c
|
||||
*
|
||||
* @brief Implementation of database_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2007 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include "database.h"
|
||||
|
||||
#include <sqlite3.h>
|
||||
#include <library.h>
|
||||
#include <crypto/hashers/hasher.h>
|
||||
|
||||
|
||||
typedef struct private_database_t private_database_t;
|
||||
|
||||
/**
|
||||
* private data of database
|
||||
*/
|
||||
struct private_database_t {
|
||||
|
||||
/**
|
||||
* public functions
|
||||
*/
|
||||
database_t public;
|
||||
|
||||
/**
|
||||
* SQLite database handle
|
||||
*/
|
||||
sqlite3 *db;
|
||||
};
|
||||
|
||||
/**
|
||||
* database enumerator implements enumerator_t
|
||||
*/
|
||||
typedef struct {
|
||||
enumerator_t enumerator;
|
||||
sqlite3_stmt *stmt;
|
||||
} db_enumerator_t;
|
||||
|
||||
/**
|
||||
* destroy a database enumerator
|
||||
*/
|
||||
static void db_enumerator_destroy(db_enumerator_t* this)
|
||||
{
|
||||
sqlite3_finalize(this->stmt);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* create a database enumerator
|
||||
*/
|
||||
static enumerator_t *db_enumerator_create(bool(*enumerate)(db_enumerator_t*,void*,...),
|
||||
sqlite3_stmt *stmt)
|
||||
{
|
||||
db_enumerator_t *this = malloc_thing(db_enumerator_t);
|
||||
this->enumerator.enumerate = (void*)enumerate;
|
||||
this->enumerator.destroy = (void*)db_enumerator_destroy;
|
||||
this->stmt = stmt;
|
||||
return &this->enumerator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of database_t.login.
|
||||
*/
|
||||
static int login(private_database_t *this, char *username, char *password)
|
||||
{
|
||||
sqlite3_stmt *stmt;
|
||||
hasher_t *hasher;
|
||||
chunk_t hash, data;
|
||||
size_t username_len, password_len;
|
||||
int uid = 0;
|
||||
char *str;
|
||||
|
||||
/* hash = SHA1( username | password ) */
|
||||
hasher = hasher_create(HASH_SHA1);
|
||||
hash = chunk_alloca(hasher->get_hash_size(hasher));
|
||||
username_len = strlen(username);
|
||||
password_len = strlen(password);
|
||||
data = chunk_alloca(username_len + password_len);
|
||||
memcpy(data.ptr, username, username_len);
|
||||
memcpy(data.ptr + username_len, password, password_len);
|
||||
hasher->get_hash(hasher, data, hash.ptr);
|
||||
hasher->destroy(hasher);
|
||||
str = chunk_to_hex(hash, FALSE);
|
||||
|
||||
if (sqlite3_prepare_v2(this->db,
|
||||
"SELECT oid FROM users WHERE username = ? AND password = ?;",
|
||||
-1, &stmt, NULL) == SQLITE_OK)
|
||||
{
|
||||
if (sqlite3_bind_text(stmt, 1, username, -1, SQLITE_STATIC) == SQLITE_OK &&
|
||||
sqlite3_bind_text(stmt, 2, str, -1, SQLITE_STATIC) == SQLITE_OK &&
|
||||
sqlite3_step(stmt) == SQLITE_ROW)
|
||||
{
|
||||
uid = sqlite3_column_int(stmt, 0);
|
||||
}
|
||||
sqlite3_finalize(stmt);
|
||||
}
|
||||
free(str);
|
||||
return uid;
|
||||
}
|
||||
|
||||
/**
|
||||
* enumerate function for gateway enumrator
|
||||
*/
|
||||
static bool gateway_enumerate(db_enumerator_t* e, int *id, const char **name,
|
||||
int *port, const char **address)
|
||||
{
|
||||
if (sqlite3_step(e->stmt) == SQLITE_ROW)
|
||||
{
|
||||
*id = sqlite3_column_int(e->stmt, 0);
|
||||
*name = sqlite3_column_text(e->stmt, 1);
|
||||
*port = sqlite3_column_int(e->stmt, 2);
|
||||
*address = sqlite3_column_text(e->stmt, 3);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of database_t.create_gateway_enumerator.
|
||||
*/
|
||||
static enumerator_t* create_gateway_enumerator(private_database_t *this, int user)
|
||||
{
|
||||
sqlite3_stmt *stmt;
|
||||
|
||||
if (sqlite3_prepare_v2(this->db,
|
||||
"SELECT gateways.oid AS gid, name, port, address FROM "
|
||||
"gateways, user_gateway AS ug ON gid = ug.gateway WHERE ug.user = ?;",
|
||||
-1, &stmt, NULL) == SQLITE_OK)
|
||||
{
|
||||
if (sqlite3_bind_int(stmt, 1, user) == SQLITE_OK)
|
||||
{
|
||||
return db_enumerator_create((void*)gateway_enumerate, stmt);
|
||||
}
|
||||
sqlite3_finalize(stmt);
|
||||
}
|
||||
return enumerator_create_empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of database_t.destroy
|
||||
*/
|
||||
static void destroy(private_database_t *this)
|
||||
{
|
||||
sqlite3_close(this->db);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* see header file
|
||||
*/
|
||||
database_t *database_create(char *dbfile)
|
||||
{
|
||||
private_database_t *this = malloc_thing(private_database_t);
|
||||
|
||||
this->public.login = (int(*)(database_t*, char *username, char *password))login;
|
||||
this->public.create_gateway_enumerator = (enumerator_t*(*)(database_t*,int))create_gateway_enumerator;
|
||||
this->public.destroy = (void(*)(database_t*))destroy;
|
||||
|
||||
if (sqlite3_open(dbfile, &this->db) != SQLITE_OK)
|
||||
{
|
||||
destroy(this);
|
||||
return NULL;
|
||||
}
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
@@ -1,10 +1,3 @@
|
||||
/**
|
||||
* @file gateway.c
|
||||
*
|
||||
* @brief Implementation of gateway_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2007 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
@@ -18,6 +11,8 @@
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include "gateway.h"
|
||||
@@ -29,7 +24,7 @@
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
|
||||
#include <lib/xml.h>
|
||||
#include <xml.h>
|
||||
|
||||
typedef struct private_gateway_t private_gateway_t;
|
||||
|
||||
|
||||
+17
-17
@@ -1,10 +1,3 @@
|
||||
/**
|
||||
* @file gateway.h
|
||||
*
|
||||
* @brief Interface of gateway_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2007 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
@@ -18,6 +11,13 @@
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup gateway gateway
|
||||
* @{ @ingroup manager
|
||||
*/
|
||||
|
||||
#ifndef GATEWAY_H_
|
||||
@@ -29,12 +29,12 @@
|
||||
typedef struct gateway_t gateway_t;
|
||||
|
||||
/**
|
||||
* @brief A connection to a gateway.
|
||||
* A connection to a gateway.
|
||||
*/
|
||||
struct gateway_t {
|
||||
|
||||
/**
|
||||
* @brief Send an XML request to the gateway.
|
||||
* Send an XML request to the gateway.
|
||||
*
|
||||
* @param xml xml request string
|
||||
* @return allocated xml response string
|
||||
@@ -42,21 +42,21 @@ struct gateway_t {
|
||||
char* (*request)(gateway_t *this, char *xml);
|
||||
|
||||
/**
|
||||
* @brief Query the list of IKE_SAs and all its children.
|
||||
* Query the list of IKE_SAs and all its children.
|
||||
*
|
||||
* @return enumerator over ikesa XML elements
|
||||
*/
|
||||
enumerator_t* (*query_ikesalist)(gateway_t *this);
|
||||
|
||||
/**
|
||||
* @brief Query the list of peer configs and its subconfigs.
|
||||
* Query the list of peer configs and its subconfigs.
|
||||
*
|
||||
* @return enumerator over peerconfig XML elements
|
||||
*/
|
||||
enumerator_t* (*query_configlist)(gateway_t *this);
|
||||
|
||||
/**
|
||||
* @brief Terminate an IKE or a CHILD SA.
|
||||
* Terminate an IKE or a CHILD SA.
|
||||
*
|
||||
* @param ike TRUE for IKE-, FALSE for a CHILD-SA
|
||||
* @param id ID of the SA to terminate
|
||||
@@ -65,7 +65,7 @@ struct gateway_t {
|
||||
enumerator_t* (*terminate)(gateway_t *this, bool ike, u_int32_t id);
|
||||
|
||||
/**
|
||||
* @brief Initiate an IKE or a CHILD SA.
|
||||
* Initiate an IKE or a CHILD SA.
|
||||
*
|
||||
* @param ike TRUE for IKE-, FALSE for CHILD-SA
|
||||
* @param name name of the peer/child config
|
||||
@@ -74,13 +74,13 @@ struct gateway_t {
|
||||
enumerator_t* (*initiate)(gateway_t *this, bool ike, char *name);
|
||||
|
||||
/**
|
||||
* @brief Destroy a gateway instance.
|
||||
* Destroy a gateway instance.
|
||||
*/
|
||||
void (*destroy)(gateway_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Create a gateway instance using a TCP connection.
|
||||
* Create a gateway instance using a TCP connection.
|
||||
*
|
||||
* @param name name of the gateway
|
||||
* @param host gateway connection endpoint
|
||||
@@ -89,11 +89,11 @@ struct gateway_t {
|
||||
gateway_t *gateway_create_tcp(char *name, host_t *host);
|
||||
|
||||
/**
|
||||
* @brief Create a gateway instance using a UNIX socket.
|
||||
* Create a gateway instance using a UNIX socket.
|
||||
*
|
||||
* @param name name of the gateway
|
||||
* @param
|
||||
*/
|
||||
gateway_t *gateway_create_unix(char *name);
|
||||
|
||||
#endif /* GATEWAY_H_ */
|
||||
#endif /* GATEWAY_H_ @} */
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
/**
|
||||
* @file context.h
|
||||
*
|
||||
* @brief Interface of context_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2007 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#ifndef CONTEXT_H_
|
||||
#define CONTEXT_H_
|
||||
|
||||
typedef struct context_t context_t;
|
||||
|
||||
/**
|
||||
* @brief Constructor function for a context
|
||||
*/
|
||||
typedef context_t *(*context_constructor_t)(void *param);
|
||||
|
||||
/**
|
||||
* @brief Custom session context
|
||||
*
|
||||
*/
|
||||
struct context_t {
|
||||
|
||||
/**
|
||||
* @brief Destroy the context_t.
|
||||
*
|
||||
* @param this calling object
|
||||
*/
|
||||
void (*destroy) (context_t *this);
|
||||
};
|
||||
|
||||
#endif /* CONTEXT_H_ */
|
||||
@@ -1,84 +0,0 @@
|
||||
/**
|
||||
* @file controller.h
|
||||
*
|
||||
* @brief Interface controller_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2007 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#ifndef CONTROLLER_H_
|
||||
#define CONTROLLER_H_
|
||||
|
||||
#include "request.h"
|
||||
#include "context.h"
|
||||
|
||||
typedef struct controller_t controller_t;
|
||||
|
||||
/**
|
||||
* @brief Controller action handle function
|
||||
*
|
||||
* @param request http request
|
||||
* @param response http response
|
||||
*/
|
||||
typedef void *(*controller_handler_t)(controller_t *this, request_t *request);
|
||||
|
||||
/**
|
||||
* @brief Constructor function for a controller
|
||||
*
|
||||
* @param context session specific context
|
||||
* @param param user supplied param
|
||||
*/
|
||||
typedef controller_t *(*controller_constructor_t)(context_t* context, void *param);
|
||||
|
||||
/**
|
||||
* @brief Controller interface, to be implemented by users controllers.
|
||||
*
|
||||
*/
|
||||
struct controller_t {
|
||||
|
||||
/**
|
||||
* @brief Get the name of the controller.
|
||||
*
|
||||
* @return name of the controller
|
||||
*/
|
||||
char* (*get_name)(controller_t *this);
|
||||
|
||||
/**
|
||||
* @brief Handle a HTTP request for that controller.
|
||||
*
|
||||
* Request URLs are parsed in the form
|
||||
* controller_name/p1/p2/p3/p4/p5 with a maximum of 5 parameters. Each
|
||||
* parameter not found in the request URL is set to NULL.
|
||||
*
|
||||
* @param request HTTP request
|
||||
* @param p1 first parameter
|
||||
* @param p2 second parameter
|
||||
* @param p3 third parameter
|
||||
* @param p4 forth parameter
|
||||
* @param p5 fifth parameter
|
||||
* @return
|
||||
*/
|
||||
void (*handle)(controller_t *this, request_t *request,
|
||||
char *a1, char *a2, char *a3, char *a4, char *a5);
|
||||
|
||||
/**
|
||||
* @brief Destroy the controller instance.
|
||||
*/
|
||||
void (*destroy) (controller_t *this);
|
||||
};
|
||||
|
||||
#endif /* CONTROLLER_H_ */
|
||||
@@ -1,401 +0,0 @@
|
||||
/**
|
||||
* @file dispatcher.c
|
||||
*
|
||||
* @brief Implementation of dispatcher_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2007 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include "dispatcher.h"
|
||||
|
||||
#include "request.h"
|
||||
#include "session.h"
|
||||
|
||||
#include <fcgiapp.h>
|
||||
#include <pthread.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <debug.h>
|
||||
#include <utils/linked_list.h>
|
||||
|
||||
typedef struct private_dispatcher_t private_dispatcher_t;
|
||||
|
||||
/**
|
||||
* private data of the task manager
|
||||
*/
|
||||
struct private_dispatcher_t {
|
||||
|
||||
/**
|
||||
* public functions
|
||||
*/
|
||||
dispatcher_t public;
|
||||
|
||||
/**
|
||||
* fcgi socket fd
|
||||
*/
|
||||
int fd;
|
||||
|
||||
/**
|
||||
* thread list
|
||||
*/
|
||||
pthread_t *threads;
|
||||
|
||||
/**
|
||||
* number of threads in "threads"
|
||||
*/
|
||||
int thread_count;
|
||||
|
||||
/**
|
||||
* session locking mutex
|
||||
*/
|
||||
pthread_mutex_t mutex;
|
||||
|
||||
/**
|
||||
* List of sessions
|
||||
*/
|
||||
linked_list_t *sessions;
|
||||
|
||||
/**
|
||||
* session timeout
|
||||
*/
|
||||
time_t timeout;
|
||||
|
||||
/**
|
||||
* List of controllers controller_constructor_t
|
||||
*/
|
||||
linked_list_t *controllers;
|
||||
|
||||
/**
|
||||
* constructor function to create session context (in constructor_entry_t)
|
||||
*/
|
||||
context_constructor_t context_constructor;
|
||||
|
||||
/**
|
||||
* user param to context constructor
|
||||
*/
|
||||
void *param;
|
||||
|
||||
/**
|
||||
* thread specific initialization handler
|
||||
*/
|
||||
void (*init)(void *param);
|
||||
|
||||
/**
|
||||
* argument to pass to thread intiializer
|
||||
*/
|
||||
void *init_param;
|
||||
|
||||
/**
|
||||
* thread specific deinitialization handler
|
||||
*/
|
||||
void (*deinit)(void *param);
|
||||
|
||||
/**
|
||||
* param tho thread specific deinitialization handler
|
||||
*/
|
||||
void *deinit_param;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
/** constructor function */
|
||||
controller_constructor_t constructor;
|
||||
/** parameter to constructor */
|
||||
void *param;
|
||||
} constructor_entry_t;
|
||||
|
||||
typedef struct {
|
||||
/** session instance */
|
||||
session_t *session;
|
||||
/** condvar to wait for session */
|
||||
pthread_cond_t cond;
|
||||
/** TRUE if session is in use */
|
||||
bool in_use;
|
||||
/** last use of the session */
|
||||
time_t used;
|
||||
} session_entry_t;
|
||||
|
||||
/**
|
||||
* create a session and instanciate controllers
|
||||
*/
|
||||
static session_t* load_session(private_dispatcher_t *this)
|
||||
{
|
||||
iterator_t *iterator;
|
||||
constructor_entry_t *entry;
|
||||
session_t *session;
|
||||
context_t *context = NULL;
|
||||
controller_t *controller;
|
||||
|
||||
if (this->context_constructor)
|
||||
{
|
||||
context = this->context_constructor(this->param);
|
||||
}
|
||||
session = session_create(context);
|
||||
|
||||
iterator = this->controllers->create_iterator(this->controllers, TRUE);
|
||||
while (iterator->iterate(iterator, (void**)&entry))
|
||||
{
|
||||
controller = entry->constructor(context, entry->param);
|
||||
session->add_controller(session, controller);
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
|
||||
return session;
|
||||
}
|
||||
|
||||
/**
|
||||
* create a new session entry
|
||||
*/
|
||||
static session_entry_t *session_entry_create(private_dispatcher_t *this)
|
||||
{
|
||||
session_entry_t *entry;
|
||||
|
||||
entry = malloc_thing(session_entry_t);
|
||||
entry->in_use = FALSE;
|
||||
pthread_cond_init(&entry->cond, NULL);
|
||||
entry->session = load_session(this);
|
||||
entry->used = time(NULL);
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
static void session_entry_destroy(session_entry_t *entry)
|
||||
{
|
||||
entry->session->destroy(entry->session);
|
||||
free(entry);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of dispatcher_t.add_controller.
|
||||
*/
|
||||
static void add_controller(private_dispatcher_t *this,
|
||||
controller_constructor_t constructor, void *param)
|
||||
{
|
||||
constructor_entry_t *entry = malloc_thing(constructor_entry_t);
|
||||
|
||||
entry->constructor = constructor;
|
||||
entry->param = param;
|
||||
this->controllers->insert_last(this->controllers, entry);
|
||||
}
|
||||
|
||||
/**
|
||||
* Actual dispatching code
|
||||
*/
|
||||
static void dispatch(private_dispatcher_t *this)
|
||||
{
|
||||
FCGX_Request fcgi_req;
|
||||
|
||||
if (FCGX_InitRequest(&fcgi_req, this->fd, 0) == 0)
|
||||
{
|
||||
while (TRUE)
|
||||
{
|
||||
request_t *request;
|
||||
session_entry_t *current, *found = NULL;
|
||||
iterator_t *iterator;
|
||||
time_t now;
|
||||
char *sid;
|
||||
int accepted;
|
||||
|
||||
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
|
||||
accepted = FCGX_Accept_r(&fcgi_req);
|
||||
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
|
||||
|
||||
if (accepted != 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
/* prepare */
|
||||
request = request_create(&fcgi_req, TRUE);
|
||||
if (request == NULL)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
sid = request->get_cookie(request, "SID");
|
||||
now = time(NULL);
|
||||
|
||||
/* find session */
|
||||
pthread_mutex_lock(&this->mutex);
|
||||
iterator = this->sessions->create_iterator(this->sessions, TRUE);
|
||||
while (iterator->iterate(iterator, (void**)¤t))
|
||||
{
|
||||
/* check all sessions for timeout */
|
||||
if (!current->in_use &&
|
||||
current->used < now - this->timeout)
|
||||
{
|
||||
iterator->remove(iterator);
|
||||
session_entry_destroy(current);
|
||||
continue;
|
||||
}
|
||||
if (!found && sid &&
|
||||
streq(current->session->get_sid(current->session), sid))
|
||||
{
|
||||
found = current;
|
||||
}
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
|
||||
if (found)
|
||||
{ /* wait until session is unused */
|
||||
while (found->in_use)
|
||||
{
|
||||
pthread_cond_wait(&found->cond, &this->mutex);
|
||||
}
|
||||
}
|
||||
else
|
||||
{ /* create a new session if not found */
|
||||
found = session_entry_create(this);
|
||||
this->sessions->insert_first(this->sessions, found);
|
||||
}
|
||||
found->in_use = TRUE;
|
||||
pthread_mutex_unlock(&this->mutex);
|
||||
|
||||
/* start processing */
|
||||
found->session->process(found->session, request);
|
||||
found->used = time(NULL);
|
||||
|
||||
/* release session */
|
||||
pthread_mutex_lock(&this->mutex);
|
||||
found->in_use = FALSE;
|
||||
pthread_cond_signal(&found->cond);
|
||||
pthread_mutex_unlock(&this->mutex);
|
||||
|
||||
/* cleanup */
|
||||
request->destroy(request);
|
||||
|
||||
/*
|
||||
FCGX_FPrintF(fcgi_req.out, "<ul>");
|
||||
char **env = fcgi_req.envp;
|
||||
while (*env)
|
||||
{
|
||||
FCGX_FPrintF(fcgi_req.out, "<li>%s</li>", *env);
|
||||
env++;
|
||||
}
|
||||
FCGX_FPrintF(fcgi_req.out, "</ul>");
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup thread and start dispatching
|
||||
*/
|
||||
static void start_dispatching(private_dispatcher_t *this)
|
||||
{
|
||||
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
|
||||
if (this->init)
|
||||
{
|
||||
this->init(this->init_param);
|
||||
}
|
||||
if (this->deinit)
|
||||
{
|
||||
pthread_cleanup_push(this->deinit, this->deinit_param);
|
||||
dispatch(this);
|
||||
pthread_cleanup_pop(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
dispatch(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of dispatcher_t.run.
|
||||
*/
|
||||
static void run(private_dispatcher_t *this, int threads,
|
||||
void(*init)(void *param), void *init_param,
|
||||
void(*deinit)(void *param), void *deinit_param)
|
||||
{
|
||||
this->init = init;
|
||||
this->init_param = init_param;
|
||||
this->deinit = deinit;
|
||||
this->deinit_param = deinit_param;
|
||||
this->thread_count = threads;
|
||||
this->threads = malloc(sizeof(pthread_t) * threads);
|
||||
while (threads)
|
||||
{
|
||||
if (pthread_create(&this->threads[threads - 1],
|
||||
NULL, (void*)start_dispatching, this) == 0)
|
||||
{
|
||||
threads--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of dispatcher_t.waitsignal.
|
||||
*/
|
||||
static void waitsignal(private_dispatcher_t *this)
|
||||
{
|
||||
sigset_t set;
|
||||
int sig;
|
||||
|
||||
sigemptyset(&set);
|
||||
sigaddset(&set, SIGINT);
|
||||
sigaddset(&set, SIGTERM);
|
||||
sigaddset(&set, SIGHUP);
|
||||
sigprocmask(SIG_BLOCK, &set, NULL);
|
||||
sigwait(&set, &sig);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of dispatcher_t.destroy
|
||||
*/
|
||||
static void destroy(private_dispatcher_t *this)
|
||||
{
|
||||
FCGX_ShutdownPending();
|
||||
while (this->thread_count--)
|
||||
{
|
||||
pthread_cancel(this->threads[this->thread_count]);
|
||||
pthread_join(this->threads[this->thread_count], NULL);
|
||||
}
|
||||
this->sessions->destroy_function(this->sessions, (void*)session_entry_destroy);
|
||||
this->controllers->destroy_function(this->controllers, free);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* see header file
|
||||
*/
|
||||
dispatcher_t *dispatcher_create(char *socket, int timeout,
|
||||
context_constructor_t constructor, void *param)
|
||||
{
|
||||
private_dispatcher_t *this = malloc_thing(private_dispatcher_t);
|
||||
|
||||
this->public.add_controller = (void(*)(dispatcher_t*, controller_constructor_t, void*))add_controller;
|
||||
this->public.run = (void(*)(dispatcher_t*, int threads,void(*)(void *),void *,void(*)(void *),void *))run;
|
||||
this->public.waitsignal = (void(*)(dispatcher_t*))waitsignal;
|
||||
this->public.destroy = (void(*)(dispatcher_t*))destroy;
|
||||
|
||||
this->sessions = linked_list_create();
|
||||
this->controllers = linked_list_create();
|
||||
this->context_constructor = constructor;
|
||||
pthread_mutex_init(&this->mutex, NULL);
|
||||
this->param = param;
|
||||
this->fd = 0;
|
||||
this->timeout = timeout;
|
||||
|
||||
FCGX_Init();
|
||||
|
||||
if (socket)
|
||||
{
|
||||
unlink(socket);
|
||||
this->fd = FCGX_OpenSocket(socket, 10);
|
||||
}
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
@@ -1,95 +0,0 @@
|
||||
/**
|
||||
* @file dispatcher.h
|
||||
*
|
||||
* @brief Interface of dispatcher_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2007 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#ifndef DISPATCHER_H_
|
||||
#define DISPATCHER_H_
|
||||
|
||||
#include "controller.h"
|
||||
|
||||
typedef struct dispatcher_t dispatcher_t;
|
||||
|
||||
/**
|
||||
* @brief Dispatcher, accepts connections using multiple threads.
|
||||
*
|
||||
* The dispatcher creates a session for each client (using SID cookies). In
|
||||
* each session, a session context is created using the context constructor.
|
||||
* Each controller is instanciated in the session using the controller
|
||||
* constructor added with add_controller.
|
||||
*/
|
||||
struct dispatcher_t {
|
||||
|
||||
/**
|
||||
* @brief Register a controller to the dispatcher.
|
||||
*
|
||||
* The first controller added serves as default controller. Client's
|
||||
* get redirected to it if no other controller matches.
|
||||
*
|
||||
* @param constructor constructor function to the conntroller
|
||||
* @param param param to pass to constructor
|
||||
*/
|
||||
void (*add_controller)(dispatcher_t *this,
|
||||
controller_constructor_t constructor, void *param);
|
||||
|
||||
/**
|
||||
* @brief Start with dispatching.
|
||||
*
|
||||
* It may be necessary to call per-thread initialization functions.
|
||||
* If init is not NULL, the handler is called right after thread
|
||||
* creation (by the created thread) and the deinit function is called
|
||||
* before the thread gets destroyed (again by the thread itself).
|
||||
*
|
||||
* @param thread number of dispatching threads
|
||||
* @param init thread specific initialization function, or NULL
|
||||
* @param init_param param to pass to init function
|
||||
* @param deinit thread dpecific deinitialization function, or NULL
|
||||
* @param deinit_param param to pass to deinit function
|
||||
*/
|
||||
void (*run)(dispatcher_t *this, int threads,
|
||||
void(*init)(void *param), void *init_param,
|
||||
void(*deinit)(void *param), void *deinit_param);
|
||||
|
||||
/**
|
||||
* @brief Wait for a relevant signal action.
|
||||
*/
|
||||
void (*waitsignal)(dispatcher_t *this);
|
||||
|
||||
/**
|
||||
* @brief Destroy the dispatcher_t.
|
||||
*/
|
||||
void (*destroy) (dispatcher_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Create a dispatcher.
|
||||
*
|
||||
* The context constructor is invoked to create a session context for
|
||||
* each session.
|
||||
*
|
||||
* @param socket FastCGI socket path, NULL for dynamic
|
||||
* @param timeout session timeout
|
||||
* @param constructor construction function for session context
|
||||
* @param param parameter to supply to context constructor
|
||||
*/
|
||||
dispatcher_t *dispatcher_create(char *socket, int timeout,
|
||||
context_constructor_t constructor, void *param);
|
||||
|
||||
#endif /* DISPATCHER_H_ */
|
||||
@@ -1,341 +0,0 @@
|
||||
/**
|
||||
* @file request.c
|
||||
*
|
||||
* @brief Implementation of request_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2007 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include "request.h"
|
||||
|
||||
#include <library.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <pthread.h>
|
||||
#include <ClearSilver/ClearSilver.h>
|
||||
|
||||
typedef struct private_request_t private_request_t;
|
||||
|
||||
/**
|
||||
* private data of the task manager
|
||||
*/
|
||||
struct private_request_t {
|
||||
|
||||
/**
|
||||
* public functions
|
||||
*/
|
||||
request_t public;
|
||||
|
||||
/**
|
||||
* FastCGI request object
|
||||
*/
|
||||
FCGX_Request *req;
|
||||
|
||||
/**
|
||||
* ClearSilver CGI Kit context
|
||||
*/
|
||||
CGI *cgi;
|
||||
|
||||
/**
|
||||
* ClearSilver HDF dataset for this request
|
||||
*/
|
||||
HDF *hdf;
|
||||
};
|
||||
|
||||
/**
|
||||
* key to a thread specific FCGX_Request, used for ClearSilver cgiwrap callbacks.
|
||||
* ClearSilver cgiwrap is not threadsave, so we use a private
|
||||
* context for each thread.
|
||||
*/
|
||||
static pthread_key_t req_key;
|
||||
|
||||
/**
|
||||
* length of param list in req->envp
|
||||
*/
|
||||
static pthread_key_t req_env_len_key;
|
||||
|
||||
/**
|
||||
* control variable for pthread_once
|
||||
*/
|
||||
pthread_once_t once = PTHREAD_ONCE_INIT;
|
||||
|
||||
/**
|
||||
* fcgiwrap read callback
|
||||
*/
|
||||
static int read_cb(void *null, char *buf, int size)
|
||||
{
|
||||
FCGX_Request *req = (FCGX_Request*)pthread_getspecific(req_key);
|
||||
return FCGX_GetStr(buf, size, req->in);
|
||||
}
|
||||
|
||||
/**
|
||||
* fcgiwrap writef callback
|
||||
*/
|
||||
static int writef_cb(void *null, const char *format, va_list args)
|
||||
{
|
||||
FCGX_Request *req = (FCGX_Request*)pthread_getspecific(req_key);
|
||||
FCGX_VFPrintF(req->out, format, args);
|
||||
return 0;
|
||||
}
|
||||
/**
|
||||
* fcgiwrap write callback
|
||||
*/
|
||||
static int write_cb(void *null, const char *buf, int size)
|
||||
{
|
||||
FCGX_Request *req = (FCGX_Request*)pthread_getspecific(req_key);
|
||||
return FCGX_PutStr(buf, size, req->out);
|
||||
}
|
||||
|
||||
/**
|
||||
* fcgiwrap getenv callback
|
||||
*/
|
||||
static char *getenv_cb(void *null, const char *key)
|
||||
{
|
||||
char *value;
|
||||
FCGX_Request *req = (FCGX_Request*)pthread_getspecific(req_key);
|
||||
value = FCGX_GetParam(key, req->envp);
|
||||
return value ? strdup(value) : NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* fcgiwrap getenv callback
|
||||
*/
|
||||
static int putenv_cb(void *null, const char *key, const char *value)
|
||||
{
|
||||
/* not supported */
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* fcgiwrap iterenv callback
|
||||
*/
|
||||
static int iterenv_cb(void *null, int num, char **key, char **value)
|
||||
{
|
||||
*key = NULL;
|
||||
*value = NULL;
|
||||
FCGX_Request *req = (FCGX_Request*)pthread_getspecific(req_key);
|
||||
int req_env_len = (int)pthread_getspecific(req_env_len_key);
|
||||
if (num < req_env_len)
|
||||
{
|
||||
char *eq;
|
||||
|
||||
eq = strchr(req->envp[num], '=');
|
||||
if (eq)
|
||||
{
|
||||
*key = strndup(req->envp[num], eq - req->envp[num]);
|
||||
*value = strdup(eq + 1);
|
||||
}
|
||||
if (*key == NULL || *value == NULL)
|
||||
{
|
||||
free(*key);
|
||||
free(*value);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of request_t.get_cookie.
|
||||
*/
|
||||
static char* get_cookie(private_request_t *this, char *name)
|
||||
{
|
||||
return hdf_get_valuef(this->hdf, "Cookie.%s", name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of request_t.get_path.
|
||||
*/
|
||||
static char* get_path(private_request_t *this)
|
||||
{
|
||||
char * path = FCGX_GetParam("PATH_INFO", this->req->envp);
|
||||
return path ? path : "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of request_t.get_post_data.
|
||||
*/
|
||||
static char* get_query_data(private_request_t *this, char *name)
|
||||
{
|
||||
return hdf_get_valuef(this->hdf, "Query.%s", name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of request_t.add_cookie.
|
||||
*/
|
||||
static void add_cookie(private_request_t *this, char *name, char *value)
|
||||
{
|
||||
cgi_cookie_set (this->cgi, name, value,
|
||||
FCGX_GetParam("SCRIPT_NAME", this->req->envp),
|
||||
NULL, NULL, 0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of request_t.redirect.
|
||||
*/
|
||||
static void redirect(private_request_t *this, char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
FCGX_FPrintF(this->req->out, "Status: 303 See Other\n");
|
||||
FCGX_FPrintF(this->req->out, "Location: %s%s",
|
||||
FCGX_GetParam("SCRIPT_NAME", this->req->envp),
|
||||
*fmt == '/' ? "" : "/");
|
||||
va_start(args, fmt);
|
||||
FCGX_VFPrintF(this->req->out, fmt, args);
|
||||
va_end(args);
|
||||
FCGX_FPrintF(this->req->out, "\n\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of request_t.get_base.
|
||||
*/
|
||||
static char* get_base(private_request_t *this)
|
||||
{
|
||||
return FCGX_GetParam("SCRIPT_NAME", this->req->envp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of request_t.serve.
|
||||
*/
|
||||
static void serve(private_request_t *this, char *headers, chunk_t chunk)
|
||||
{
|
||||
FCGX_FPrintF(this->req->out, "%s\n\n", headers);
|
||||
|
||||
FCGX_PutStr(chunk.ptr, chunk.len, this->req->out);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of request_t.render.
|
||||
*/
|
||||
static void render(private_request_t *this, char *template)
|
||||
{
|
||||
NEOERR* err;
|
||||
|
||||
err = cgi_display(this->cgi, template);
|
||||
if (err)
|
||||
{
|
||||
cgi_neo_error(this->cgi, err);
|
||||
nerr_log_error(err);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of request_t.set.
|
||||
*/
|
||||
static void set(private_request_t *this, char *key, char *value)
|
||||
{
|
||||
hdf_set_value(this->hdf, key, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of request_t.setf.
|
||||
*/
|
||||
static void setf(private_request_t *this, char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start(args, format);
|
||||
hdf_set_valuevf(this->hdf, format, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of request_t.destroy
|
||||
*/
|
||||
static void destroy(private_request_t *this)
|
||||
{
|
||||
cgi_destroy(&this->cgi);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* This initialization method is guaranteed to run only once
|
||||
* for all threads.
|
||||
*/
|
||||
static void init(void)
|
||||
{
|
||||
cgiwrap_init_emu(NULL, read_cb, writef_cb, write_cb,
|
||||
getenv_cb, putenv_cb, iterenv_cb);
|
||||
pthread_key_create(&req_key, NULL);
|
||||
pthread_key_create(&req_env_len_key, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* see header file
|
||||
*/
|
||||
request_t *request_create(FCGX_Request *request, bool debug)
|
||||
{
|
||||
NEOERR* err;
|
||||
private_request_t *this = malloc_thing(private_request_t);
|
||||
|
||||
this->public.get_path = (char*(*)(request_t*))get_path;
|
||||
this->public.get_base = (char*(*)(request_t*))get_base;
|
||||
this->public.add_cookie = (void(*)(request_t*, char *name, char *value))add_cookie;
|
||||
this->public.get_cookie = (char*(*)(request_t*,char*))get_cookie;
|
||||
this->public.get_query_data = (char*(*)(request_t*, char *name))get_query_data;
|
||||
this->public.redirect = (void(*)(request_t*, char *fmt,...))redirect;
|
||||
this->public.render = (void(*)(request_t*,char*))render;
|
||||
this->public.serve = (void(*)(request_t*,char*,chunk_t))serve;
|
||||
this->public.set = (void(*)(request_t*, char *, char*))set;
|
||||
this->public.setf = (void(*)(request_t*, char *format, ...))setf;
|
||||
this->public.destroy = (void(*)(request_t*))destroy;
|
||||
|
||||
pthread_once(&once, init);
|
||||
|
||||
this->req = request;
|
||||
pthread_setspecific(req_key, (void*)request);
|
||||
|
||||
int req_env_len = 0;
|
||||
while (request->envp[req_env_len] != NULL)
|
||||
{
|
||||
req_env_len++;
|
||||
}
|
||||
|
||||
pthread_setspecific(req_env_len_key, (void*)req_env_len);
|
||||
|
||||
err = hdf_init(&this->hdf);
|
||||
if (!err)
|
||||
{
|
||||
hdf_set_value(this->hdf, "base", get_base(this));
|
||||
hdf_set_value(this->hdf, "Config.NoCache", "true");
|
||||
if (!debug)
|
||||
{
|
||||
hdf_set_value(this->hdf, "Config.TimeFooter", "0");
|
||||
hdf_set_value(this->hdf, "Config.CompressionEnabled", "1");
|
||||
hdf_set_value(this->hdf, "Config.WhiteSpaceStrip", "2");
|
||||
}
|
||||
|
||||
err = cgi_init(&this->cgi, this->hdf);
|
||||
if (!err)
|
||||
{
|
||||
err = cgi_parse(this->cgi);
|
||||
if (!err)
|
||||
{
|
||||
return &this->public;
|
||||
}
|
||||
cgi_destroy(&this->cgi);
|
||||
}
|
||||
}
|
||||
nerr_log_error(err);
|
||||
free(this);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1,135 +0,0 @@
|
||||
/**
|
||||
* @file request.h
|
||||
*
|
||||
* @brief Interface of request_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2007 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#ifndef REQUEST_H_
|
||||
#define REQUEST_H_
|
||||
|
||||
#include <fcgiapp.h>
|
||||
#include <library.h>
|
||||
|
||||
typedef struct request_t request_t;
|
||||
|
||||
/**
|
||||
* @brief A HTTP request, encapsulates FCGX_Request.
|
||||
*
|
||||
*/
|
||||
struct request_t {
|
||||
|
||||
/**
|
||||
* @brief Add a cookie to the reply (Set-Cookie header).
|
||||
*
|
||||
* @param name name of the cookie to set
|
||||
* @param value value of the cookie
|
||||
*/
|
||||
void (*add_cookie)(request_t *this, char *name, char *value);
|
||||
|
||||
/**
|
||||
* @brief Get a cookie the client sent in the request.
|
||||
*
|
||||
* @param name name of the cookie
|
||||
* @return cookie value, NULL if no such cookie found
|
||||
*/
|
||||
char* (*get_cookie)(request_t *this, char *name);
|
||||
|
||||
/**
|
||||
* @brief Get the request path relative to the application.
|
||||
*
|
||||
* @return path
|
||||
*/
|
||||
char* (*get_path)(request_t *this);
|
||||
|
||||
/**
|
||||
* @brief Get the base path of the application.
|
||||
*
|
||||
* @return base path
|
||||
*/
|
||||
char* (*get_base)(request_t *this);
|
||||
|
||||
/**
|
||||
* @brief Get a post/get variable included in the request.
|
||||
*
|
||||
* @param name name of the POST/GET variable
|
||||
* @return value, NULL if not found
|
||||
*/
|
||||
char* (*get_query_data)(request_t *this, char *name);
|
||||
|
||||
/**
|
||||
* @brief Redirect the client to another location.
|
||||
*
|
||||
* @param fmt location format string
|
||||
* @param ... variable argument for fmt
|
||||
*/
|
||||
void (*redirect)(request_t *this, char *fmt, ...);
|
||||
|
||||
/**
|
||||
* @brief Set a template value.
|
||||
*
|
||||
* @param key key to set
|
||||
* @param value value to set key to
|
||||
*/
|
||||
void (*set)(request_t *this, char *key, char *value);
|
||||
|
||||
/**
|
||||
* @brief Set a template value using format strings.
|
||||
*
|
||||
* Format string is in the form "key=value", where printf like format
|
||||
* substitution occurs over the whole string.
|
||||
*
|
||||
* @param format printf like format string
|
||||
* @param ... variable argument list
|
||||
*/
|
||||
void (*setf)(request_t *this, char *format, ...);
|
||||
|
||||
/**
|
||||
* @brief Render a template.
|
||||
*
|
||||
* The render() function additionally sets a HDF variable "base"
|
||||
* which points to the root of the web application and allows to point to
|
||||
* other targets without to worry about path location.
|
||||
*
|
||||
* @param template clearsilver template file location
|
||||
*/
|
||||
void (*render)(request_t *this, char *template);
|
||||
|
||||
/**
|
||||
* @brief Serve a request with headers and a body.
|
||||
*
|
||||
* @param headers HTTP headers, \n separated
|
||||
* @param chunk body to write to output
|
||||
*/
|
||||
void (*serve)(request_t *this, char *headers, chunk_t chunk);
|
||||
|
||||
/**
|
||||
* @brief Destroy the request_t.
|
||||
*/
|
||||
void (*destroy) (request_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Create a request from the fastcgi struct.
|
||||
*
|
||||
* @param request the FCGI request
|
||||
* @param debug no stripping, no compression, timing information
|
||||
*/
|
||||
request_t *request_create(FCGX_Request *request, bool debug);
|
||||
|
||||
#endif /* REQUEST_H_ */
|
||||
@@ -1,175 +0,0 @@
|
||||
/**
|
||||
* @file session.c
|
||||
*
|
||||
* @brief Implementation of session_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2007 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include "session.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <fcgiapp.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <utils/linked_list.h>
|
||||
#include <utils/randomizer.h>
|
||||
|
||||
typedef struct private_session_t private_session_t;
|
||||
|
||||
/**
|
||||
* private data of the task manager
|
||||
*/
|
||||
struct private_session_t {
|
||||
|
||||
/**
|
||||
* public functions
|
||||
*/
|
||||
session_t public;
|
||||
|
||||
/**
|
||||
* session ID
|
||||
*/
|
||||
char *sid;
|
||||
|
||||
/**
|
||||
* list of controller instances controller_t
|
||||
*/
|
||||
linked_list_t *controllers;
|
||||
|
||||
/**
|
||||
* user defined session context
|
||||
*/
|
||||
context_t *context;
|
||||
};
|
||||
|
||||
/**
|
||||
* Implementation of session_t.load_controller.
|
||||
*/
|
||||
static void add_controller(private_session_t *this, controller_t *controller)
|
||||
{
|
||||
this->controllers->insert_last(this->controllers, controller);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a session ID and a cookie
|
||||
*/
|
||||
static void create_sid(private_session_t *this, request_t *request)
|
||||
{
|
||||
char buf[16];
|
||||
chunk_t chunk = chunk_from_buf(buf);
|
||||
randomizer_t *randomizer = randomizer_create();
|
||||
|
||||
randomizer->get_pseudo_random_bytes(randomizer, sizeof(buf), buf);
|
||||
this->sid = chunk_to_hex(chunk, FALSE);
|
||||
request->add_cookie(request, "SID", this->sid);
|
||||
randomizer->destroy(randomizer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of session_t.process.
|
||||
*/
|
||||
static void process(private_session_t *this, request_t *request)
|
||||
{
|
||||
char *pos, *start, *param[6] = {NULL, NULL, NULL, NULL, NULL, NULL};
|
||||
iterator_t *iterator;
|
||||
bool handled = FALSE;
|
||||
controller_t *current;
|
||||
int i = 0;
|
||||
|
||||
if (this->sid == NULL)
|
||||
{
|
||||
create_sid(this, request);
|
||||
}
|
||||
|
||||
start = request->get_path(request);
|
||||
if (start)
|
||||
{
|
||||
if (*start == '/') start++;
|
||||
while ((pos = strchr(start, '/')) != NULL && i < 5)
|
||||
{
|
||||
param[i++] = strndup(start, pos - start);
|
||||
start = pos + 1;
|
||||
}
|
||||
param[i] = strdup(start);
|
||||
iterator = this->controllers->create_iterator(this->controllers, TRUE);
|
||||
while (iterator->iterate(iterator, (void**)¤t))
|
||||
{
|
||||
if (streq(current->get_name(current), param[0]))
|
||||
{
|
||||
current->handle(current, request, param[1], param[2], param[3],
|
||||
param[4], param[5]);
|
||||
handled = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
for (i = 0; i < 6; i++)
|
||||
{
|
||||
free(param[i]);
|
||||
}
|
||||
}
|
||||
if (!handled)
|
||||
{
|
||||
if (this->controllers->get_first(this->controllers,
|
||||
(void**)¤t) == SUCCESS)
|
||||
{
|
||||
request->redirect(request, current->get_name(current));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of session_t.get_sid.
|
||||
*/
|
||||
static char* get_sid(private_session_t *this)
|
||||
{
|
||||
return this->sid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of session_t.destroy
|
||||
*/
|
||||
static void destroy(private_session_t *this)
|
||||
{
|
||||
this->controllers->destroy_offset(this->controllers, offsetof(controller_t, destroy));
|
||||
if (this->context) this->context->destroy(this->context);
|
||||
free(this->sid);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* see header file
|
||||
*/
|
||||
session_t *session_create(context_t *context)
|
||||
{
|
||||
private_session_t *this = malloc_thing(private_session_t);
|
||||
|
||||
this->public.add_controller = (void(*)(session_t*, controller_t*))add_controller;
|
||||
this->public.process = (void(*)(session_t*,request_t*))process;
|
||||
this->public.get_sid = (char*(*)(session_t*))get_sid;
|
||||
this->public.destroy = (void(*)(session_t*))destroy;
|
||||
|
||||
this->sid = NULL;
|
||||
this->controllers = linked_list_create();
|
||||
this->context = context;
|
||||
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
@@ -1,73 +0,0 @@
|
||||
/**
|
||||
* @file session.h
|
||||
*
|
||||
* @brief Interface of session_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2007 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#ifndef SESSION_H_
|
||||
#define SESSION_H_
|
||||
|
||||
#include "request.h"
|
||||
#include "controller.h"
|
||||
|
||||
typedef struct session_t session_t;
|
||||
|
||||
/**
|
||||
* @brief A session, identified by a session ID.
|
||||
*
|
||||
*/
|
||||
struct session_t {
|
||||
|
||||
/**
|
||||
* @brief Get the session ID of the session.
|
||||
*
|
||||
* @return session ID
|
||||
*/
|
||||
char* (*get_sid)(session_t *this);
|
||||
|
||||
/**
|
||||
* @brief Add a controller instance to the session.
|
||||
*
|
||||
* @param controller controller to add
|
||||
*/
|
||||
void (*add_controller)(session_t *this, controller_t *controller);
|
||||
|
||||
/**
|
||||
* @brief Process a request in this session.
|
||||
*
|
||||
* @param request request to process
|
||||
*/
|
||||
void (*process)(session_t *this, request_t *request);
|
||||
|
||||
/**
|
||||
* @brief Destroy the session_t.
|
||||
*
|
||||
* @param this calling object
|
||||
*/
|
||||
void (*destroy) (session_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Create a session.
|
||||
*
|
||||
* @param context user defined session context instance
|
||||
*/
|
||||
session_t *session_create(context_t *context);
|
||||
|
||||
#endif /* SESSION_H_ */
|
||||
+16
-15
@@ -1,10 +1,3 @@
|
||||
/**
|
||||
* @file main.c
|
||||
*
|
||||
* @brief Implementation of dispatcher_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2007 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
@@ -18,13 +11,15 @@
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <dispatcher.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "manager.h"
|
||||
#include "database.h"
|
||||
#include "storage.h"
|
||||
#include "controller/auth_controller.h"
|
||||
#include "controller/ikesa_controller.h"
|
||||
#include "controller/gateway_controller.h"
|
||||
@@ -38,34 +33,40 @@
|
||||
int main (int arc, char *argv[])
|
||||
{
|
||||
dispatcher_t *dispatcher;
|
||||
database_t *database;
|
||||
storage_t *storage;
|
||||
char *socket = NULL;
|
||||
bool debug = FALSE;
|
||||
|
||||
#ifdef FCGI_SOCKET
|
||||
socket = FCGI_SOCKET;
|
||||
debug = TRUE;
|
||||
#endif /* FCGI_SOCKET */
|
||||
|
||||
library_init(IPSECDIR "/manager.conf");
|
||||
|
||||
database = database_create(DBFILE);
|
||||
if (database == NULL)
|
||||
storage = storage_create("sqlite://"DBFILE);
|
||||
if (storage == NULL)
|
||||
{
|
||||
fprintf(stderr, "opening database '%s' failed.\n", DBFILE);
|
||||
return 1;
|
||||
}
|
||||
|
||||
dispatcher = dispatcher_create(socket, SESSION_TIMEOUT,
|
||||
(context_constructor_t)manager_create, database);
|
||||
dispatcher = dispatcher_create(socket, debug, SESSION_TIMEOUT,
|
||||
(context_constructor_t)manager_create, storage);
|
||||
dispatcher->add_controller(dispatcher, ikesa_controller_create, NULL);
|
||||
dispatcher->add_controller(dispatcher, gateway_controller_create, NULL);
|
||||
dispatcher->add_controller(dispatcher, auth_controller_create, NULL);
|
||||
dispatcher->add_controller(dispatcher, control_controller_create, NULL);
|
||||
dispatcher->add_controller(dispatcher, config_controller_create, NULL);
|
||||
|
||||
dispatcher->run(dispatcher, THREADS, NULL, NULL, NULL, NULL);
|
||||
dispatcher->run(dispatcher, THREADS);
|
||||
|
||||
dispatcher->waitsignal(dispatcher);
|
||||
|
||||
dispatcher->destroy(dispatcher);
|
||||
database->destroy(database);
|
||||
storage->destroy(storage);
|
||||
|
||||
library_deinit();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
+9
-14
@@ -1,10 +1,3 @@
|
||||
/**
|
||||
* @file manager.c
|
||||
*
|
||||
* @brief Implementation of manager_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2007 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
@@ -18,6 +11,8 @@
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include "manager.h"
|
||||
@@ -39,9 +34,9 @@ struct private_manager_t {
|
||||
manager_t public;
|
||||
|
||||
/**
|
||||
* underlying database
|
||||
* underlying storage database
|
||||
*/
|
||||
database_t *db;
|
||||
storage_t *store;
|
||||
|
||||
/**
|
||||
* user id, if we are logged in
|
||||
@@ -59,7 +54,7 @@ struct private_manager_t {
|
||||
*/
|
||||
static enumerator_t* create_gateway_enumerator(private_manager_t *this)
|
||||
{
|
||||
return this->db->create_gateway_enumerator(this->db, this->user);
|
||||
return this->store->create_gateway_enumerator(this->store, this->user);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -77,7 +72,7 @@ static gateway_t* select_gateway(private_manager_t *this, int select_id)
|
||||
if (this->gateway) this->gateway->destroy(this->gateway);
|
||||
this->gateway = NULL;
|
||||
|
||||
enumerator = this->db->create_gateway_enumerator(this->db, this->user);
|
||||
enumerator = this->store->create_gateway_enumerator(this->store, this->user);
|
||||
while (enumerator->enumerate(enumerator, &id, &name, &port, &address))
|
||||
{
|
||||
if (select_id == id)
|
||||
@@ -117,7 +112,7 @@ static bool login(private_manager_t *this, char *username, char *password)
|
||||
{
|
||||
if (!this->user)
|
||||
{
|
||||
this->user = this->db->login(this->db, username, password);
|
||||
this->user = this->store->login(this->store, username, password);
|
||||
}
|
||||
return this->user != 0;
|
||||
}
|
||||
@@ -147,7 +142,7 @@ static void destroy(private_manager_t *this)
|
||||
/*
|
||||
* see header file
|
||||
*/
|
||||
manager_t *manager_create(database_t *database)
|
||||
manager_t *manager_create(storage_t *storage)
|
||||
{
|
||||
private_manager_t *this = malloc_thing(private_manager_t);
|
||||
|
||||
@@ -159,7 +154,7 @@ manager_t *manager_create(database_t *database)
|
||||
this->public.context.destroy = (void(*)(context_t*))destroy;
|
||||
|
||||
this->user = 0;
|
||||
this->db = database;
|
||||
this->store = storage;
|
||||
this->gateway = NULL;
|
||||
|
||||
return &this->public;
|
||||
|
||||
+22
-17
@@ -1,10 +1,3 @@
|
||||
/**
|
||||
* @file manager.h
|
||||
*
|
||||
* @brief Interface of manager_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2007 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
@@ -18,12 +11,24 @@
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup manager manager
|
||||
*
|
||||
* @defgroup controller controller
|
||||
* @ingroup manager
|
||||
*
|
||||
* @defgroup manager_i manager
|
||||
* @{ @ingroup manager
|
||||
*/
|
||||
|
||||
#ifndef MANAGER_H_
|
||||
#define MANAGER_H_
|
||||
|
||||
#include "database.h"
|
||||
#include "storage.h"
|
||||
#include "gateway.h"
|
||||
|
||||
#include <context.h>
|
||||
@@ -33,7 +38,7 @@
|
||||
typedef struct manager_t manager_t;
|
||||
|
||||
/**
|
||||
* @brief The manager, manages multiple gateways.
|
||||
* The manager, manages multiple gateways.
|
||||
*/
|
||||
struct manager_t {
|
||||
|
||||
@@ -43,7 +48,7 @@ struct manager_t {
|
||||
context_t context;
|
||||
|
||||
/**
|
||||
* @brief Create an iterator over all configured gateways.
|
||||
* Create an iterator over all configured gateways.
|
||||
*
|
||||
* enumerate() arguments: int id, char *name, int port, char *address
|
||||
* If port is 0, address is a Unix socket address.
|
||||
@@ -53,7 +58,7 @@ struct manager_t {
|
||||
enumerator_t* (*create_gateway_enumerator)(manager_t *this);
|
||||
|
||||
/**
|
||||
* @brief Select a gateway.
|
||||
* Select a gateway.
|
||||
*
|
||||
* If id is 0, the previously selected gateway is returned. If none has
|
||||
* been selected yet, NULL is returned.
|
||||
@@ -64,7 +69,7 @@ struct manager_t {
|
||||
gateway_t* (*select_gateway)(manager_t *this, int id);
|
||||
|
||||
/**
|
||||
* @brief Try to log in.
|
||||
* Try to log in.
|
||||
*
|
||||
* @param username username
|
||||
* @param password cleartext password
|
||||
@@ -73,21 +78,21 @@ struct manager_t {
|
||||
bool (*login)(manager_t *this, char *username, char *password);
|
||||
|
||||
/**
|
||||
* @brief Check if user logged in.
|
||||
* Check if user logged in.
|
||||
*
|
||||
* @return TRUE if logged in
|
||||
*/
|
||||
bool (*logged_in)(manager_t *this);
|
||||
|
||||
/**
|
||||
* @brief Log out.
|
||||
* Log out.
|
||||
*/
|
||||
void (*logout)(manager_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Create a manager instance.
|
||||
* Create a manager instance.
|
||||
*/
|
||||
manager_t *manager_create(database_t *database);
|
||||
manager_t *manager_create(storage_t *storage);
|
||||
|
||||
#endif /* MANAGER_H_ */
|
||||
#endif /* MANAGER_H_ @} */
|
||||
|
||||
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
* Copyright (C) 2007 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include "storage.h"
|
||||
|
||||
#include <library.h>
|
||||
#include <crypto/hashers/hasher.h>
|
||||
|
||||
|
||||
typedef struct private_storage_t private_storage_t;
|
||||
|
||||
/**
|
||||
* private data of storage
|
||||
*/
|
||||
struct private_storage_t {
|
||||
|
||||
/**
|
||||
* public functions
|
||||
*/
|
||||
storage_t public;
|
||||
|
||||
/**
|
||||
* database connection
|
||||
*/
|
||||
database_t *db;
|
||||
};
|
||||
|
||||
/**
|
||||
* Implementation of storage_t.login.
|
||||
*/
|
||||
static int login(private_storage_t *this, char *username, char *password)
|
||||
{
|
||||
hasher_t *hasher;
|
||||
chunk_t hash, data;
|
||||
size_t username_len, password_len;
|
||||
int uid = 0;
|
||||
char *str;
|
||||
enumerator_t *enumerator;
|
||||
|
||||
/* hash = SHA1( username | password ) */
|
||||
hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
|
||||
if (hasher == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
hash = chunk_alloca(hasher->get_hash_size(hasher));
|
||||
username_len = strlen(username);
|
||||
password_len = strlen(password);
|
||||
data = chunk_alloca(username_len + password_len);
|
||||
memcpy(data.ptr, username, username_len);
|
||||
memcpy(data.ptr + username_len, password, password_len);
|
||||
hasher->get_hash(hasher, data, hash.ptr);
|
||||
hasher->destroy(hasher);
|
||||
str = chunk_to_hex(hash, FALSE);
|
||||
|
||||
enumerator = this->db->query(this->db,
|
||||
"SELECT oid FROM users WHERE username = ? AND password = ?;",
|
||||
DB_TEXT, username, DB_TEXT, str,
|
||||
DB_INT);
|
||||
if (enumerator)
|
||||
{
|
||||
enumerator->enumerate(enumerator, &uid);
|
||||
enumerator->destroy(enumerator);
|
||||
}
|
||||
free(str);
|
||||
return uid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of storage_t.create_gateway_enumerator.
|
||||
*/
|
||||
static enumerator_t* create_gateway_enumerator(private_storage_t *this, int user)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
|
||||
enumerator = this->db->query(this->db,
|
||||
"SELECT gateways.oid AS gid, name, port, address FROM "
|
||||
"gateways, user_gateway AS ug ON gid = ug.gateway WHERE ug.user = ?;",
|
||||
DB_INT, user,
|
||||
DB_INT, DB_TEXT, DB_INT, DB_TEXT);
|
||||
if (!enumerator)
|
||||
{
|
||||
enumerator = enumerator_create_empty();
|
||||
}
|
||||
return enumerator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of storage_t.destroy
|
||||
*/
|
||||
static void destroy(private_storage_t *this)
|
||||
{
|
||||
this->db->destroy(this->db);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* see header file
|
||||
*/
|
||||
storage_t *storage_create(char *uri)
|
||||
{
|
||||
private_storage_t *this = malloc_thing(private_storage_t);
|
||||
|
||||
this->public.login = (int(*)(storage_t*, char *username, char *password))login;
|
||||
this->public.create_gateway_enumerator = (enumerator_t*(*)(storage_t*,int))create_gateway_enumerator;
|
||||
this->public.destroy = (void(*)(storage_t*))destroy;
|
||||
|
||||
this->db = lib->db->create(lib->db, uri);
|
||||
if (this->db == NULL)
|
||||
{
|
||||
free(this);
|
||||
return NULL;
|
||||
}
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
@@ -1,10 +1,3 @@
|
||||
/**
|
||||
* @file database.h
|
||||
*
|
||||
* @brief Interface of database_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2007 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
@@ -18,32 +11,39 @@
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifndef DATABASE_H_
|
||||
#define DATABASE_H_
|
||||
/**
|
||||
* @defgroup storage storage
|
||||
* @{ @ingroup manager
|
||||
*/
|
||||
|
||||
#ifndef STORAGE_H_
|
||||
#define STORAGE_H_
|
||||
|
||||
#include <utils/enumerator.h>
|
||||
|
||||
|
||||
typedef struct database_t database_t;
|
||||
typedef struct storage_t storage_t;
|
||||
|
||||
/**
|
||||
* @brief Persistent database.
|
||||
* Persistent database storage.
|
||||
*/
|
||||
struct database_t {
|
||||
struct storage_t {
|
||||
|
||||
/**
|
||||
* @brief Try to log in using specified credentials.
|
||||
* Try to log in using specified credentials.
|
||||
*
|
||||
* @param username username
|
||||
* @param password plaintext password
|
||||
* @return user ID if login good, 0 otherwise
|
||||
*/
|
||||
int (*login)(database_t *this, char *username, char *password);
|
||||
int (*login)(storage_t *this, char *username, char *password);
|
||||
|
||||
/**
|
||||
* @brief Create an iterator over the gateways.
|
||||
* Create an iterator over the gateways.
|
||||
*
|
||||
* enumerate() arguments: int id, char *name, int port, char *address
|
||||
* If port is 0, address is a Unix socket address.
|
||||
@@ -51,19 +51,19 @@ struct database_t {
|
||||
* @param user user Id
|
||||
* @return enumerator
|
||||
*/
|
||||
enumerator_t* (*create_gateway_enumerator)(database_t *this, int user);
|
||||
enumerator_t* (*create_gateway_enumerator)(storage_t *this, int user);
|
||||
|
||||
/**
|
||||
* @brief Destroy a database instance.
|
||||
* Destroy a storage instance.
|
||||
*/
|
||||
void (*destroy)(database_t *this);
|
||||
void (*destroy)(storage_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Create a database instance.
|
||||
* Create a storage instance.
|
||||
*
|
||||
* @param dbfile SQLite database file
|
||||
* @param uri database connection URI
|
||||
*/
|
||||
database_t *database_create(char *dbfile);
|
||||
storage_t *storage_create(char *uri);
|
||||
|
||||
#endif /* DATABASE_H_ */
|
||||
#endif /* STORAGE_H_ @} */
|
||||
@@ -1,10 +1,3 @@
|
||||
/**
|
||||
* @file xml.c
|
||||
*
|
||||
* @brief Implementation of xml_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2007 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
@@ -18,6 +11,8 @@
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include "xml.h"
|
||||
@@ -1,10 +1,3 @@
|
||||
/**
|
||||
* @file xml.h
|
||||
*
|
||||
* @brief Interface of xml_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2007 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
@@ -18,6 +11,13 @@
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup xml xml
|
||||
* @{ @ingroup manager
|
||||
*/
|
||||
|
||||
#ifndef XML_H_
|
||||
@@ -28,7 +28,7 @@
|
||||
typedef struct xml_t xml_t;
|
||||
|
||||
/**
|
||||
* @brief Simple enumerator based XML parser.
|
||||
* Simple enumerator based XML parser.
|
||||
*
|
||||
* An xml_t is a single node of the XML tree, but also serves as root node
|
||||
* and therefore the document.
|
||||
@@ -38,7 +38,7 @@ typedef struct xml_t xml_t;
|
||||
struct xml_t {
|
||||
|
||||
/**
|
||||
* @brief Create an enumerator over all children.
|
||||
* Create an enumerator over all children.
|
||||
*
|
||||
* Enumerated values must not be manipulated or freed.
|
||||
*
|
||||
@@ -47,7 +47,7 @@ struct xml_t {
|
||||
enumerator_t* (*children)(xml_t *this);
|
||||
|
||||
/**
|
||||
* @brief Get an attribute value by its name.
|
||||
* Get an attribute value by its name.
|
||||
*
|
||||
* @param name name of the attribute
|
||||
* @return attribute value, NULL if not found
|
||||
@@ -56,8 +56,8 @@ struct xml_t {
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Create a xml instance.
|
||||
* Create a xml instance.
|
||||
*/
|
||||
xml_t *xml_create(char *xml);
|
||||
|
||||
#endif /* XML_H_ */
|
||||
#endif /* XML_H_ @} */
|
||||
Reference in New Issue
Block a user