diff --git a/include/application/application.h b/include/application/application.h index 4788c83..9e88acb 100644 --- a/include/application/application.h +++ b/include/application/application.h @@ -33,6 +33,7 @@ #include "storage/storage.h" #include "session.h" #include "user.h" +#include "uuid.h" struct randval { @@ -50,6 +51,12 @@ CLASS(Application) { Storage users; Storage passwords; + Storage roles; + + Uuid user_namespace; + + Hash roles_user_index; + Hash roles_resource_index; const char * version; }; diff --git a/include/auth/interface/auth.h b/include/auth/interface/auth.h index 8dccfa2..9e4b696 100644 --- a/include/auth/interface/auth.h +++ b/include/auth/interface/auth.h @@ -31,9 +31,10 @@ #include #include "class.h" +#include "uuid.h" #include "auth/credential.h" -typedef int (* fptr_authenticate)(void *, Credential); +typedef int (* fptr_authenticate)(void *, Credential, Uuid); extern const struct interface i_Auth; @@ -42,7 +43,7 @@ struct i_Auth { fptr_authenticate authenticate; }; -extern int authenticate(void *, Credential); +extern int authenticate(void *, Credential, Uuid); #endif // __AUTH_INTERFACE_AUTH_H__ diff --git a/include/interface/indexable.h b/include/interface/indexable.h new file mode 100644 index 0000000..74a037d --- /dev/null +++ b/include/interface/indexable.h @@ -0,0 +1,49 @@ +/** + * \file + * This interface provides only one function at all. + * indexUuid will generate a uuid to the current object. + * + * \todo + * Maybe merge hashable and indexable. Thus we might get an + * easy way to exchange the hashing mechanism used for my + * associative arrays. + * + * \author Georg Hopp + * + * \copyright + * Copyright © 2012 Georg Hopp + * + * 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 3 of the License, or + * (at your option) any later version. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __INDEXABLE_H__ +#define __INDEXABLE_H__ + +#include "uuid.h" + + +typedef Uuid (* fptr_indexUuid)(void *, Uuid); + +extern const struct interface i_Indexable; + +struct i_Indexable { + const struct interface * const _; + fptr_indexUuid uuid; +}; + +extern Uuid indexUuid(void *, Uuid); + +#endif // __INDEXABLE_H__ + +// vim: set ts=4 sw=4: diff --git a/include/interface/serializable.h b/include/interface/serializable.h new file mode 100644 index 0000000..742197e --- /dev/null +++ b/include/interface/serializable.h @@ -0,0 +1,42 @@ +/** + * \file + * + * \author Georg Hopp + * + * \copyright + * Copyright © 2012 Georg Hopp + * + * 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 3 of the License, or + * (at your option) any later version. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __SERIALIZABLE_H__ +#define __SERIALIZABLE_H__ + +typedef void (* fptr_serialize)(void *, unsigned char **, size_t *); +typedef void (* fptr_unserialize)(void *, const unsigned char *, size_t); + +extern const struct interface i_Serializable; + +struct i_Serializable { + const struct interface * const _; + fptr_serialize serialize; + fptr_unserialize unserialize; +}; + +extern void serialize(void *, unsigned char **, size_t *); +extern void unserialize(void *, const unsigned char *, size_t); + +#endif // __SERIALIZABLE_H__ + +// vim: set ts=4 sw=4: diff --git a/src/Makefile.am b/src/Makefile.am index b3eaf63..a5fd50b 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -10,7 +10,9 @@ TRUTILS = utils/hash.c \ utils/mime_type.c TRBASESRC = interface/subject.c \ - interface/observer.c + interface/observer.c \ + interface/serializable.c \ + interface/indexable.c TRBASELIBS = class/libclass.la \ cbuf/libcbuf.la \ diff --git a/src/application/application.c b/src/application/application.c index 04eda1e..c9754f7 100644 --- a/src/application/application.c +++ b/src/application/application.c @@ -26,6 +26,7 @@ #include "class.h" #include "hash.h" +#include "uuid.h" #include "application/application.h" #include "storage/storage.h" @@ -50,6 +51,9 @@ applicationCtor(void * _this, va_list * params) */ this->users = va_arg(*params, Storage); this->passwords = va_arg(*params, Storage); + //this->roles = va_arg(*params, Storage); + + this->user_namespace = uuidParse(va_arg(*params, char *)); // initialize authenticators to use. this->nauth = va_arg(*params, size_t); @@ -75,6 +79,8 @@ applicationDtor(void * _this) Application this = _this; size_t i; + delete(this->user_namespace); + for (i=0; iactive_sessions[i]); } diff --git a/src/application/login.c b/src/application/login.c index 237e16c..039e15e 100644 --- a/src/application/login.c +++ b/src/application/login.c @@ -28,6 +28,11 @@ #include "class.h" #include "auth.h" +#include "uuid.h" +#include "storage/storage.h" + +#include "interface/serializable.h" +#include "interface/indexable.h" #include "utils/memory.h" #include "application/application.h" @@ -40,40 +45,63 @@ applicationLogin( Session session) { size_t i; + Uuid search; + int authenticated = 0; + + User user = new(User, NULL); + + user->email = CRED_PWD(credential).user; + user->nemail = &CRED_PWD(credential).nuser; + search = indexUuid(user, this->user_namespace); for (i=0; inauth; i++) { - if (authenticate(this->auth[i], credential)) { - session->user = new(User, NULL); + if (authenticate(this->auth[i], credential, search)) { + session->user = user; switch (credential->type) { case CRED_PASSWORD: - session->user->email = CRED_PWD(credential).user; - session->user->nemail = &CRED_PWD(credential).nuser; - - if (NULL == userLoad(session->user, this->users)) { - // this is an ldap user that has not yet set - // additional user informations. - /** \todo again...change the keys to id's */ - session->user->email = NULL; - delete(session->user); - session->user = new(User, - CRED_PWD(credential).user, - CRED_PWD(credential).nuser, - CSTRA(""), - CSTRA("")); - } + { + char * user_serialized; + size_t nuser_serialized; + + storageGet( + this->users, + (char *)(search->uuid).value, + sizeof((search->uuid).value), + &user_serialized, + &nuser_serialized); + if (NULL != user_serialized) { + unserialize( + session->user, + (unsigned char *)user_serialized, + nuser_serialized); + MEM_FREE(user_serialized); + } else { + // this is a user authenticated via another method + // than the password database and has not yet set + // additional user informations. + session->user = NULL; + delete(session->user); + session->user = new(User, + CRED_PWD(credential).user, + CRED_PWD(credential).nuser, + CSTRA(""), + CSTRA("")); + } + } break; default: break; } - return 1; + authenticated = 1; + break; } } - return 0; + return authenticated; } // vim: set ts=4 sw=4: diff --git a/src/application/session_cleanup.c b/src/application/session_cleanup.c index 22f576a..0625464 100644 --- a/src/application/session_cleanup.c +++ b/src/application/session_cleanup.c @@ -43,7 +43,7 @@ applicationSessionCleanup(Application this, time_t now) } if (0 < expired && SESSION_LIVETIME > expired) { - Hash * tmp_buf = memCalloc(SESSION_LIVETIME, sizeof(Hash)); + Hash * tmp_buf = memCalloc(SESSION_LIVETIME, sizeof(Hash)); memcpy( &(tmp_buf[expired]), diff --git a/src/application/signup.c b/src/application/signup.c index f6a3114..716deb3 100644 --- a/src/application/signup.c +++ b/src/application/signup.c @@ -29,8 +29,13 @@ #include "class.h" #include "auth.h" #include "user.h" +#include "uuid.h" +#include "storage/storage.h" #include "application/application.h" +#include "interface/serializable.h" +#include "interface/indexable.h" + #include "utils/memory.h" #include "commons.h" @@ -44,17 +49,12 @@ applicationSignup( unsigned char hash_data[SALT_SIZE+HASH_SIZE]; unsigned char * salt = NULL; unsigned char * hash = hash_data+SALT_SIZE; + char * user_serialized; + size_t nuser_serialized; + Uuid index; - if (NULL != userLoad(user, this->users)) { - /* - * if any user is found with this email return false - * as on signup equal email adresses are not allowed - * at all. - */ - return 0; - } - - userSave(user, this->users); + index = indexUuid(user, this->user_namespace); + serialize(user, (unsigned char **)&user_serialized, &nuser_serialized); if (FALSE == hash_pw( CRED_PWD(cred).pass, @@ -69,13 +69,23 @@ applicationSignup( } memcpy(hash_data, salt, SALT_SIZE); - MEM_FREE(salt); + /** + * \todo + * Add error handling here... + */ + storagePut( + this->users, + (char *)(index->uuid).value, + sizeof((index->uuid).value), + user_serialized, + nuser_serialized); + storagePut( this->passwords, - CRED_PWD(cred).user, - CRED_PWD(cred).nuser, + (char *)(index->uuid).value, + sizeof((index->uuid).value), (char *)hash_data, SALT_SIZE + HASH_SIZE); diff --git a/src/auth/interface/auth.c b/src/auth/interface/auth.c index fa98183..a2745d6 100644 --- a/src/auth/interface/auth.c +++ b/src/auth/interface/auth.c @@ -20,6 +20,7 @@ * along with this program. If not, see . */ +#include "uuid.h" #include "auth/auth.h" #include "auth/credential.h" #include "auth/interface/auth.h" @@ -30,11 +31,11 @@ const struct interface i_Auth = { }; int -authenticate(void * auth, Credential cred) +authenticate(void * auth, Credential cred, Uuid user_index) { int ret; - RETCALL(auth, Auth, authenticate, ret, cred); + RETCALL(auth, Auth, authenticate, ret, cred, user_index); return ret; } diff --git a/src/auth/ldap.c b/src/auth/ldap.c index efffdf1..82c9f8e 100644 --- a/src/auth/ldap.c +++ b/src/auth/ldap.c @@ -27,6 +27,7 @@ #include #include "class.h" +#include "uuid.h" #include "utils/memory.h" #include "commons.h" @@ -69,7 +70,7 @@ authLdapDtor(void * _this) static int -authLdapAuthenticate(void * _this, Credential cred) +authLdapAuthenticate(void * _this, Credential cred, Uuid user_index) { AuthLdap this = _this; char who[256]; diff --git a/src/auth/storage/storage.c b/src/auth/storage/storage.c index f8eef61..4210ebc 100644 --- a/src/auth/storage/storage.c +++ b/src/auth/storage/storage.c @@ -23,6 +23,8 @@ #include "class.h" #include "storage/storage.h" #include "auth.h" +#include "uuid.h" +#include "user.h" #include "commons.h" #include "utils/memory.h" @@ -45,7 +47,7 @@ authStorageDtor(void * _this) static int -authStorageAuthenticate(void * _this, Credential cred) +authStorageAuthenticate(void * _this, Credential cred, Uuid user_index) { AuthStorage this = _this; @@ -59,8 +61,8 @@ authStorageAuthenticate(void * _this, Credential cred) storageGet( this->store, - CRED_PWD(cred).user, - CRED_PWD(cred).nuser, + (char *)(user_index->uuid).value, + sizeof((user_index->uuid).value), (char **)&found_hash, &nfound_hash); diff --git a/src/user/save.c b/src/interface/indexable.c similarity index 65% rename from src/user/save.c rename to src/interface/indexable.c index f4280d2..82f734f 100644 --- a/src/user/save.c +++ b/src/interface/indexable.c @@ -20,32 +20,23 @@ * along with this program. If not, see . */ -#include -#include - -#include "user.h" -#include "storage/storage.h" #include "class.h" +#include "uuid.h" +#include "interface/indexable.h" -#include "utils/memory.h" - +const struct interface i_Indexable = { + "indexable", + 1 +}; -void -userSave(User this, Storage storage) +Uuid +indexUuid(void * indexable, Uuid namespace) { - size_t storage_size = - *this->nemail + 1 + - *this->nfirstname + 1 + - *this->nsurname + 1 + - 3 * sizeof(size_t); + Uuid ret; + + RETCALL(indexable, Indexable, uuid, ret, namespace); - /** - * \todo user return value for error handling - */ - storageUpdate( - storage, - this->id, 36, - this->email, storage_size); + return ret; } // vim: set ts=4 sw=4: diff --git a/src/user/load.c b/src/interface/serializable.c similarity index 50% rename from src/user/load.c rename to src/interface/serializable.c index bc25453..528e3fb 100644 --- a/src/user/load.c +++ b/src/interface/serializable.c @@ -20,48 +20,30 @@ * along with this program. If not, see . */ -#include -#include - -#include "user.h" -#include "storage/storage.h" #include "class.h" - -#include "utils/memory.h" - - -User -userLoad(User this, Storage storage) +#include "interface/serializable.h" + +const struct interface i_Serializable = { + "serializable", + 2 +}; + +void +serialize( + void * serializable, + unsigned char ** serialized, + size_t * nserialized) { - char * storage_data; - size_t nstorage_data; - size_t * user_data_sizes; - - if (NULL == storage) { - return NULL; - } - - storageGet( - storage, - this->email, *this->nemail, - &storage_data, &nstorage_data); - - if (NULL == storage_data) { - return NULL; - } - - user_data_sizes = - (size_t *)(storage_data + nstorage_data - 3 * sizeof(size_t)); - - this->nemail = user_data_sizes; - this->nfirstname = user_data_sizes + 1; - this->nsurname = user_data_sizes + 2; + CALL(serializable, Serializable, serialize, serialized, nserialized); +} - this->email = storage_data; - this->firstname = this->email + *this->nemail + 1; - this->surname = this->firstname + *this->nfirstname + 1; - - return this; +void +unserialize( + void * serializable, + const unsigned char * serialized, + size_t nserialized) +{ + CALL(serializable, Serializable, unserialize, serialized, nserialized); } // vim: set ts=4 sw=4: diff --git a/src/taskrambler.c b/src/taskrambler.c index 1565916..7103951 100644 --- a/src/taskrambler.c +++ b/src/taskrambler.c @@ -207,6 +207,7 @@ main() value, users, passwords, + "14de9e60-d497-4754-be72-f3bed52541fc", 2, authLdap, authStorage); diff --git a/src/user/Makefile.am b/src/user/Makefile.am index 3c1af04..6b8174b 100644 --- a/src/user/Makefile.am +++ b/src/user/Makefile.am @@ -5,5 +5,5 @@ AM_CFLAGS += -I../../include/ noinst_LTLIBRARIES = libuser.la -libuser_la_SOURCES = user.c load.c save.c +libuser_la_SOURCES = user.c libuser_la_CFLAGS = $(AM_CFLAGS) diff --git a/src/user/user.c b/src/user/user.c index db77a10..e7cdb10 100644 --- a/src/user/user.c +++ b/src/user/user.c @@ -21,9 +21,12 @@ */ #include "user.h" -#include "storage/storage.h" +#include "uuid.h" #include "class.h" +#include "interface/serializable.h" +#include "interface/indexable.h" + #include "utils/memory.h" @@ -31,9 +34,8 @@ static int userCtor(void * _this, va_list * params) { - User this = _this; - - char * email = va_arg(* params, char *); + User this = _this; + char * email = va_arg(* params, char *); if (NULL != email) { size_t nemail = va_arg(* params, size_t); @@ -84,7 +86,66 @@ userDtor(void * _this) } } +static +void +userSerialize( + void * _this, + unsigned char ** serialized, + size_t * nserialized) +{ + User this = _this; + + *nserialized = + *this->nemail + 1 + + *this->nfirstname + 1 + + *this->nsurname + 1 + + 3 * sizeof(size_t); + + *serialized = memMalloc(*nserialized); + + memcpy(*serialized, this->email, *nserialized); +} + +static +void +userUnserialize( + void * _this, + const unsigned char * serialized, + size_t nserialized) +{ + User this = _this; + size_t * user_data_sizes; + + this->email = memMalloc(nserialized); + memcpy(this->email, serialized, nserialized); + + user_data_sizes = + (size_t *)(this->email + nserialized - 3 * sizeof(size_t)); + + this->nemail = user_data_sizes; + this->nfirstname = user_data_sizes + 1; + this->nsurname = user_data_sizes + 2; + + this->firstname = this->email + *this->nemail + 1; + this->surname = this->firstname + *this->nfirstname + 1; +} + +static +Uuid +userIndexUuid(void * _this, Uuid namespace) +{ + User this = _this; + + return uuidVersion3( + (unsigned char *)this->email, + *this->nemail, + namespace); +} + + INIT_IFACE(Class, userCtor, userDtor, NULL); -CREATE_CLASS(User, NULL, IFACE(Class)); +INIT_IFACE(Serializable, userSerialize, userUnserialize); +INIT_IFACE(Indexable, userIndexUuid); +CREATE_CLASS(User, NULL, IFACE(Class), IFACE(Serializable), IFACE(Indexable)); // vim: set ts=4 sw=4: