Browse Source

remove specialized load and save from user, add serializable and indexable interface and make user utilize both and store a user and its credentials keyed by its uuid

v0.1.8
Georg Hopp 12 years ago
parent
commit
080add7222
  1. 7
      include/application/application.h
  2. 5
      include/auth/interface/auth.h
  3. 49
      include/interface/indexable.h
  4. 42
      include/interface/serializable.h
  5. 4
      src/Makefile.am
  6. 6
      src/application/application.c
  7. 50
      src/application/login.c
  8. 36
      src/application/signup.c
  9. 5
      src/auth/interface/auth.c
  10. 3
      src/auth/ldap.c
  11. 8
      src/auth/storage/storage.c
  12. 33
      src/interface/indexable.c
  13. 60
      src/interface/serializable.c
  14. 1
      src/taskrambler.c
  15. 2
      src/user/Makefile.am
  16. 67
      src/user/user.c

7
include/application/application.h

@ -33,6 +33,7 @@
#include "storage/storage.h" #include "storage/storage.h"
#include "session.h" #include "session.h"
#include "user.h" #include "user.h"
#include "uuid.h"
struct randval { struct randval {
@ -50,6 +51,12 @@ CLASS(Application) {
Storage users; Storage users;
Storage passwords; Storage passwords;
Storage roles;
Uuid user_namespace;
Hash roles_user_index;
Hash roles_resource_index;
const char * version; const char * version;
}; };

5
include/auth/interface/auth.h

@ -31,9 +31,10 @@
#include <stdarg.h> #include <stdarg.h>
#include "class.h" #include "class.h"
#include "uuid.h"
#include "auth/credential.h" #include "auth/credential.h"
typedef int (* fptr_authenticate)(void *, Credential);
typedef int (* fptr_authenticate)(void *, Credential, Uuid);
extern const struct interface i_Auth; extern const struct interface i_Auth;
@ -42,7 +43,7 @@ struct i_Auth {
fptr_authenticate authenticate; fptr_authenticate authenticate;
}; };
extern int authenticate(void *, Credential);
extern int authenticate(void *, Credential, Uuid);
#endif // __AUTH_INTERFACE_AUTH_H__ #endif // __AUTH_INTERFACE_AUTH_H__

49
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 <http://www.gnu.org/licenses/>.
*/
#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:

42
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 <http://www.gnu.org/licenses/>.
*/
#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:

4
src/Makefile.am

@ -10,7 +10,9 @@ TRUTILS = utils/hash.c \
utils/mime_type.c utils/mime_type.c
TRBASESRC = interface/subject.c \ TRBASESRC = interface/subject.c \
interface/observer.c
interface/observer.c \
interface/serializable.c \
interface/indexable.c
TRBASELIBS = class/libclass.la \ TRBASELIBS = class/libclass.la \
cbuf/libcbuf.la \ cbuf/libcbuf.la \

6
src/application/application.c

@ -26,6 +26,7 @@
#include "class.h" #include "class.h"
#include "hash.h" #include "hash.h"
#include "uuid.h"
#include "application/application.h" #include "application/application.h"
#include "storage/storage.h" #include "storage/storage.h"
@ -50,6 +51,9 @@ applicationCtor(void * _this, va_list * params)
*/ */
this->users = va_arg(*params, Storage); this->users = va_arg(*params, Storage);
this->passwords = 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. // initialize authenticators to use.
this->nauth = va_arg(*params, size_t); this->nauth = va_arg(*params, size_t);
@ -75,6 +79,8 @@ applicationDtor(void * _this)
Application this = _this; Application this = _this;
size_t i; size_t i;
delete(this->user_namespace);
for (i=0; i<SESSION_LIVETIME; i++) { for (i=0; i<SESSION_LIVETIME; i++) {
delete(this->active_sessions[i]); delete(this->active_sessions[i]);
} }

50
src/application/login.c

@ -28,6 +28,11 @@
#include "class.h" #include "class.h"
#include "auth.h" #include "auth.h"
#include "uuid.h"
#include "storage/storage.h"
#include "interface/serializable.h"
#include "interface/indexable.h"
#include "utils/memory.h" #include "utils/memory.h"
#include "application/application.h" #include "application/application.h"
@ -40,21 +45,43 @@ applicationLogin(
Session session) Session session)
{ {
size_t i; 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; i<this->nauth; i++) { for (i=0; i<this->nauth; 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) { switch (credential->type) {
case CRED_PASSWORD: case CRED_PASSWORD:
session->user->email = CRED_PWD(credential).user;
session->user->nemail = &CRED_PWD(credential).nuser;
{
char * user_serialized;
size_t nuser_serialized;
storageGet(
this->users,
(char *)(search->uuid).value,
sizeof((search->uuid).value),
&user_serialized,
&nuser_serialized);
if (NULL == userLoad(session->user, this->users)) {
// this is an ldap user that has not yet set
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. // additional user informations.
/** \todo again...change the keys to id's */
session->user->email = NULL;
session->user = NULL;
delete(session->user); delete(session->user);
session->user = new(User, session->user = new(User,
CRED_PWD(credential).user, CRED_PWD(credential).user,
@ -62,18 +89,19 @@ applicationLogin(
CSTRA(""), CSTRA(""),
CSTRA("")); CSTRA(""));
} }
}
break; break;
default: default:
break; break;
} }
return 1;
authenticated = 1;
break;
} }
} }
return 0;
return authenticated;
} }
// vim: set ts=4 sw=4: // vim: set ts=4 sw=4:

36
src/application/signup.c

@ -29,8 +29,13 @@
#include "class.h" #include "class.h"
#include "auth.h" #include "auth.h"
#include "user.h" #include "user.h"
#include "uuid.h"
#include "storage/storage.h"
#include "application/application.h" #include "application/application.h"
#include "interface/serializable.h"
#include "interface/indexable.h"
#include "utils/memory.h" #include "utils/memory.h"
#include "commons.h" #include "commons.h"
@ -44,17 +49,12 @@ applicationSignup(
unsigned char hash_data[SALT_SIZE+HASH_SIZE]; unsigned char hash_data[SALT_SIZE+HASH_SIZE];
unsigned char * salt = NULL; unsigned char * salt = NULL;
unsigned char * hash = hash_data+SALT_SIZE; 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( if (FALSE == hash_pw(
CRED_PWD(cred).pass, CRED_PWD(cred).pass,
@ -69,13 +69,23 @@ applicationSignup(
} }
memcpy(hash_data, salt, SALT_SIZE); memcpy(hash_data, salt, SALT_SIZE);
MEM_FREE(salt); MEM_FREE(salt);
/**
* \todo
* Add error handling here...
*/
storagePut(
this->users,
(char *)(index->uuid).value,
sizeof((index->uuid).value),
user_serialized,
nuser_serialized);
storagePut( storagePut(
this->passwords, this->passwords,
CRED_PWD(cred).user,
CRED_PWD(cred).nuser,
(char *)(index->uuid).value,
sizeof((index->uuid).value),
(char *)hash_data, (char *)hash_data,
SALT_SIZE + HASH_SIZE); SALT_SIZE + HASH_SIZE);

5
src/auth/interface/auth.c

@ -20,6 +20,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "uuid.h"
#include "auth/auth.h" #include "auth/auth.h"
#include "auth/credential.h" #include "auth/credential.h"
#include "auth/interface/auth.h" #include "auth/interface/auth.h"
@ -30,11 +31,11 @@ const struct interface i_Auth = {
}; };
int int
authenticate(void * auth, Credential cred)
authenticate(void * auth, Credential cred, Uuid user_index)
{ {
int ret; int ret;
RETCALL(auth, Auth, authenticate, ret, cred);
RETCALL(auth, Auth, authenticate, ret, cred, user_index);
return ret; return ret;
} }

3
src/auth/ldap.c

@ -27,6 +27,7 @@
#include <ldap.h> #include <ldap.h>
#include "class.h" #include "class.h"
#include "uuid.h"
#include "utils/memory.h" #include "utils/memory.h"
#include "commons.h" #include "commons.h"
@ -69,7 +70,7 @@ authLdapDtor(void * _this)
static static
int int
authLdapAuthenticate(void * _this, Credential cred)
authLdapAuthenticate(void * _this, Credential cred, Uuid user_index)
{ {
AuthLdap this = _this; AuthLdap this = _this;
char who[256]; char who[256];

8
src/auth/storage/storage.c

@ -23,6 +23,8 @@
#include "class.h" #include "class.h"
#include "storage/storage.h" #include "storage/storage.h"
#include "auth.h" #include "auth.h"
#include "uuid.h"
#include "user.h"
#include "commons.h" #include "commons.h"
#include "utils/memory.h" #include "utils/memory.h"
@ -45,7 +47,7 @@ authStorageDtor(void * _this)
static static
int int
authStorageAuthenticate(void * _this, Credential cred)
authStorageAuthenticate(void * _this, Credential cred, Uuid user_index)
{ {
AuthStorage this = _this; AuthStorage this = _this;
@ -59,8 +61,8 @@ authStorageAuthenticate(void * _this, Credential cred)
storageGet( storageGet(
this->store, this->store,
CRED_PWD(cred).user,
CRED_PWD(cred).nuser,
(char *)(user_index->uuid).value,
sizeof((user_index->uuid).value),
(char **)&found_hash, (char **)&found_hash,
&nfound_hash); &nfound_hash);

33
src/user/save.c → src/interface/indexable.c

@ -20,32 +20,23 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <sys/types.h>
#include <string.h>
#include "user.h"
#include "storage/storage.h"
#include "class.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;
/**
* \todo user return value for error handling
*/
storageUpdate(
storage,
this->id, 36,
this->email, storage_size);
RETCALL(indexable, Indexable, uuid, ret, namespace);
return ret;
} }
// vim: set ts=4 sw=4: // vim: set ts=4 sw=4:

60
src/user/load.c → src/interface/serializable.c

@ -20,48 +20,30 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <sys/types.h>
#include <string.h>
#include "user.h"
#include "storage/storage.h"
#include "class.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;
this->email = storage_data;
this->firstname = this->email + *this->nemail + 1;
this->surname = this->firstname + *this->nfirstname + 1;
CALL(serializable, Serializable, serialize, serialized, nserialized);
}
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: // vim: set ts=4 sw=4:

1
src/taskrambler.c

@ -207,6 +207,7 @@ main()
value, value,
users, users,
passwords, passwords,
"14de9e60-d497-4754-be72-f3bed52541fc",
2, 2,
authLdap, authLdap,
authStorage); authStorage);

2
src/user/Makefile.am

@ -5,5 +5,5 @@ AM_CFLAGS += -I../../include/
noinst_LTLIBRARIES = libuser.la noinst_LTLIBRARIES = libuser.la
libuser_la_SOURCES = user.c load.c save.c
libuser_la_SOURCES = user.c
libuser_la_CFLAGS = $(AM_CFLAGS) libuser_la_CFLAGS = $(AM_CFLAGS)

67
src/user/user.c

@ -21,9 +21,12 @@
*/ */
#include "user.h" #include "user.h"
#include "storage/storage.h"
#include "uuid.h"
#include "class.h" #include "class.h"
#include "interface/serializable.h"
#include "interface/indexable.h"
#include "utils/memory.h" #include "utils/memory.h"
@ -32,7 +35,6 @@ int
userCtor(void * _this, va_list * params) userCtor(void * _this, va_list * params)
{ {
User this = _this; User this = _this;
char * email = va_arg(* params, char *); char * email = va_arg(* params, char *);
if (NULL != email) { if (NULL != email) {
@ -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); 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: // vim: set ts=4 sw=4:
Loading…
Cancel
Save