From 112c0645a9c4a0a4a42248506bda40ae8e5cae0e Mon Sep 17 00:00:00 2001 From: Georg Hopp Date: Sat, 14 Sep 2013 00:00:52 +0100 Subject: [PATCH 01/17] version bump --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 45c5842..2dd0c51 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ # Process this file with autoconf to produce a configure script. AC_PREREQ([2.68]) -AC_INIT([taskrambler], [0.1.4], [Georg Hopp ]) +AC_INIT([taskrambler], [0.1.5], [Georg Hopp ]) LT_INIT AM_INIT_AUTOMAKE #AM_INIT_AUTOMAKE([subdir-objects]) From 7fa810c47eed0546465128f7e1cb9dcd690f3932 Mon Sep 17 00:00:00 2001 From: Georg Hopp Date: Sun, 15 Sep 2013 17:16:49 +0100 Subject: [PATCH 02/17] add a ref_count to the memory segments...this way I could increase references and only insert the memory segment in the tree again if the ref_count is one. --- src/utils/memory.c | 76 +++++++++++++++------------------------------- 1 file changed, 24 insertions(+), 52 deletions(-) diff --git a/src/utils/memory.c b/src/utils/memory.c index 6c6610e..bf7106c 100644 --- a/src/utils/memory.c +++ b/src/utils/memory.c @@ -59,6 +59,7 @@ struct memSegment { + size_t ref_count; size_t size; void * ptr; @@ -75,13 +76,7 @@ struct memSegment struct memSegment * newElement(size_t size) { - long psize = sysconf(_SC_PAGESIZE); - - /* allocate only blocks of a multiple of pagesize, similar to cbuf */ - size = (0 >= size)? 1 : (0 != size%psize)? (size/psize)+1 : size/psize; - size *= psize; - - struct memSegment * element = malloc(size + sizeof(struct memSegment)); + struct memSegment * element = malloc(size); element->size = size; element->ptr = (void*)element + sizeof(struct memSegment); @@ -759,48 +754,6 @@ cleanup(struct memSegment * node, int depth) struct memSegment * segments = NULL; -// /** -// * this will interpret any memory segment that is not smaller -// * than the expected size as fitting. -// * -// * @param void * size_ptr a pointer to a size_t value searched for -// * @param void * subject a pointer to the currently analysed tree element -// */ -// static -// int -// segmentFindCmp(const void * size_ptr, const void * subject) -// { -// if (*(size_t *)size_ptr > ((struct memSegment *)subject)->size) -// return 1; -// -// return 0; -// } -// -// /** -// * this returns exact fits....uhh.....I can't relate solely on -// * the size argument as then same sized segments will never -// * be stored. -// * Maybe a tree is not the best data structure to use to store -// * these. -// * Anyway, right now take the ptr into account if size if equal. -// */ -// static -// int -// segmentSearchCmp(const void * search, const void * subject) -// { -// size_t idx = -// ((struct memSegment *)search)->size - -// ((struct memSegment *)subject)->size; -// -// if (0 == idx) { -// return -// ((struct memSegment *)search)->ptr - -// ((struct memSegment *)subject)->ptr; -// } -// -// return idx; -// } - static void segmentFree(struct memSegment * segment, int depth) @@ -812,6 +765,15 @@ segmentFree(struct memSegment * segment, int depth) } } +void * +memNewRef(void * mem) +{ + struct memSegment * seg = (mem - sizeof(struct memSegment)); + + seg->ref_count++; + + return mem; +} /* * This will always allocate a multiple of PAGESIZE @@ -820,9 +782,13 @@ void * memMalloc(size_t size) { struct memSegment * seg; - long psize = sysconf(_SC_PAGESIZE); + //long psize = sysconf(_SC_PAGESIZE); + long psize = 64; - size = (0 >= size)? 1 : (0 != size%psize)? (size/psize)+1 : size/psize; + size += sizeof(struct memSegment); + + /* allocate only blocks of a multiple of pagesize, similar to cbuf */ + size = (0>=size)?1:(0!=size%psize)?(size/psize)+1:size/psize; size *= psize; seg = findElement(segments, size); @@ -861,7 +827,13 @@ void memFree(void ** mem) { if (NULL != *mem) { - insertElement(&segments, (struct memSegment *)(*mem - sizeof(struct memSegment))); + struct memSegment * seg = (*mem - sizeof(struct memSegment)); + + if (1 < seg->ref_count) { + seg->ref_count--; + } else { + insertElement(&segments, seg); + } *mem = NULL; } From 7a319d3f761d9bc3618fd4d2a17c81d5777c7118 Mon Sep 17 00:00:00 2001 From: Georg Hopp Date: Sun, 15 Sep 2013 23:10:41 +0100 Subject: [PATCH 03/17] initialize ref_count correctly --- src/utils/memory.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/utils/memory.c b/src/utils/memory.c index bf7106c..1eeba16 100644 --- a/src/utils/memory.c +++ b/src/utils/memory.c @@ -78,16 +78,17 @@ newElement(size_t size) { struct memSegment * element = malloc(size); - element->size = size; - element->ptr = (void*)element + sizeof(struct memSegment); + element->ref_count = 1; + element->size = size; + element->ptr = (void*)element + sizeof(struct memSegment); - element->next = NULL; - element->last = NULL; + element->next = NULL; + element->last = NULL; - element->color = rbRed; - element->parent = NULL; - element->left = NULL; - element->right = NULL; + element->color = rbRed; + element->parent = NULL; + element->left = NULL; + element->right = NULL; return element; } From e58739bd63ccb82cf9a21c47bb9f08b93352da3d Mon Sep 17 00:00:00 2001 From: Georg Hopp Date: Sun, 15 Sep 2013 23:11:38 +0100 Subject: [PATCH 04/17] add first user class and persistence experiments. refs #36 --- configure.ac | 2 + include/storage.h | 43 ++++++++++++++++++++ include/user.h | 51 +++++++++++++++++++++++ src/Makefile.am | 7 +++- src/storage/Makefile.am | 7 ++++ src/storage/get.c | 53 ++++++++++++++++++++++++ src/storage/put.c | 41 +++++++++++++++++++ src/storage/storage.c | 69 +++++++++++++++++++++++++++++++ src/user/Makefile.am | 7 ++++ src/user/load.c | 64 +++++++++++++++++++++++++++++ src/user/save.c | 48 ++++++++++++++++++++++ src/user/user.c | 90 +++++++++++++++++++++++++++++++++++++++++ src/usertest.c | 59 +++++++++++++++++++++++++++ 13 files changed, 539 insertions(+), 2 deletions(-) create mode 100644 include/storage.h create mode 100644 include/user.h create mode 100644 src/storage/Makefile.am create mode 100644 src/storage/get.c create mode 100644 src/storage/put.c create mode 100644 src/storage/storage.c create mode 100644 src/user/Makefile.am create mode 100644 src/user/load.c create mode 100644 src/user/save.c create mode 100644 src/user/user.c create mode 100644 src/usertest.c diff --git a/configure.ac b/configure.ac index 2dd0c51..e9f0375 100644 --- a/configure.ac +++ b/configure.ac @@ -65,5 +65,7 @@ AC_CONFIG_FILES([Makefile src/stream/Makefile src/tree/Makefile src/application/Makefile + src/storage/Makefile + src/user/Makefile tests/Makefile]) AC_OUTPUT diff --git a/include/storage.h b/include/storage.h new file mode 100644 index 0000000..c2fcb8b --- /dev/null +++ b/include/storage.h @@ -0,0 +1,43 @@ +/** + * \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 __STORAGE_H__ +#define __STORAGE_H__ + +#include +#include + +#include "class.h" + + +CLASS(Storage) { + GDBM_FILE gdbm; + char * db_name; +}; + +void storagePut(Storage, char *, size_t, char *, size_t); +void storageGet(Storage, char *, size_t, char **, size_t *); + +#endif // __STORAGE_H__ + +// vim: set ts=4 sw=4: + diff --git a/include/user.h b/include/user.h new file mode 100644 index 0000000..8aa7c62 --- /dev/null +++ b/include/user.h @@ -0,0 +1,51 @@ +/** + * \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 __USER_H__ +#define __USER_H__ + +#include + +#include "class.h" +#include "storage.h" + + +CLASS(User) { + char * email; + char * firstname; + char * surname; + + size_t * nemail; + size_t * nfirstname; + size_t * nsurname; +}; + +User userLoad(User, Storage); +void userSave(User, Storage); + +// void userSerialize(User, void **, size_t *); +// void userDeserialize(User, void *, size_t); + +#endif // __USER_H__ + +// vim: set ts=4 sw=4: + diff --git a/src/Makefile.am b/src/Makefile.am index 9d06867..771d173 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -12,6 +12,8 @@ UTILS = utils/hash.c \ utils/mime_type.c LIBS = ./application/libapplication.a \ + ./user/libuser.a \ + ./storage/libstorage.a \ ./http/libhttp.a \ ./auth/libauth.a \ ./cbuf/libcbuf.a \ @@ -32,8 +34,9 @@ bin_PROGRAMS = taskrambler taskrambler_SOURCES = taskrambler.c $(IFACE) $(UTILS) taskrambler_CFLAGS = $(CFLAGS) -Wall -DPWD=\"$(PWD)\" -I ../include/# $(COVERAGE_CFLAGS) -taskrambler_LDADD = $(LIBS) -lrt -lssl -lldap +taskrambler_LDADD = $(LIBS) -lrt -lssl -lldap -lgdbm #taskrambler_LDFLAGS = $(COVERAGE_LDFLAGS) SUBDIRS = asset auth cbuf class hash queue http \ - logger server session socket stream tree application + logger server session socket stream tree application \ + storage user diff --git a/src/storage/Makefile.am b/src/storage/Makefile.am new file mode 100644 index 0000000..3e6aeb0 --- /dev/null +++ b/src/storage/Makefile.am @@ -0,0 +1,7 @@ +ACLOCAL_AMFLAGS = -I m4 +AUTOMAKE_OPTIONS = subdir-objects + +noinst_LIBRARIES = libstorage.a + +libstorage_a_SOURCES = storage.c get.c put.c +libstorage_a_CFLAGS = $(CFLAGS) -Wall -I ../../include/ diff --git a/src/storage/get.c b/src/storage/get.c new file mode 100644 index 0000000..1e4274b --- /dev/null +++ b/src/storage/get.c @@ -0,0 +1,53 @@ +/** + * \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 . + */ + +#include +#include +#include +#include + +#include "storage.h" +#include "class.h" + +#include "utils/memory.h" + +void +storageGet( + Storage this, + char * _key, size_t nkey, + char ** data, size_t * ndata) +{ + datum key = {_key, nkey}; + datum value; + + value = gdbm_fetch(this->gdbm, key); + + if (NULL != value.dptr) { + *ndata = value.dsize; + *data = memMalloc(value.dsize); + memcpy(*data, value.dptr, value.dsize); + + free(value.dptr); + } +} + +// vim: set ts=4 sw=4: diff --git a/src/storage/put.c b/src/storage/put.c new file mode 100644 index 0000000..f6d8079 --- /dev/null +++ b/src/storage/put.c @@ -0,0 +1,41 @@ +/** + * \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 . + */ + +#include +#include +#include + +#include "storage.h" +#include "class.h" + +#include "utils/memory.h" + +void +storagePut(Storage this, char * _key, size_t nkey, char * data, size_t ndata) +{ + datum key = {_key, nkey}; + datum value = {data, ndata}; + + gdbm_store(this->gdbm, key, value, GDBM_REPLACE); +} + +// vim: set ts=4 sw=4: diff --git a/src/storage/storage.c b/src/storage/storage.c new file mode 100644 index 0000000..c275793 --- /dev/null +++ b/src/storage/storage.c @@ -0,0 +1,69 @@ +/** + * \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 . + */ + +#include +#include +#include + +#include "storage.h" +#include "class.h" + +#include "utils/memory.h" + +static +int +storageCtor(void * _this, va_list * params) +{ + Storage this = _this; + char * db_name = va_arg(* params, void *); + + this->db_name = memMalloc(strlen(db_name) + 1); + strcpy(this->db_name, db_name); + + this->gdbm = gdbm_open( + this->db_name, + 0, + GDBM_WRCREAT, + S_IRUSR | S_IWUSR, + NULL); + + if (NULL == this->gdbm) { + return -1; + } + + return 0; +} + +static +void +storageDtor(void * _this) +{ + Storage this = _this; + + if (NULL != this->db_name) MEM_FREE(this->db_name); + if (NULL != this->gdbm) gdbm_close(this->gdbm); +} + +INIT_IFACE(Class, storageCtor, storageDtor, NULL); +CREATE_CLASS(Storage, NULL, IFACE(Class)); + +// vim: set ts=4 sw=4: diff --git a/src/user/Makefile.am b/src/user/Makefile.am new file mode 100644 index 0000000..e3cd065 --- /dev/null +++ b/src/user/Makefile.am @@ -0,0 +1,7 @@ +ACLOCAL_AMFLAGS = -I m4 +AUTOMAKE_OPTIONS = subdir-objects + +noinst_LIBRARIES = libuser.a + +libuser_a_SOURCES = user.c load.c save.c +libuser_a_CFLAGS = $(CFLAGS) -Wall -I ../../include/ diff --git a/src/user/load.c b/src/user/load.c new file mode 100644 index 0000000..ed6547f --- /dev/null +++ b/src/user/load.c @@ -0,0 +1,64 @@ +/** + * \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 . + */ + +#include +#include + +#include "user.h" +#include "storage.h" +#include "class.h" + +#include "utils/memory.h" + + +User +userLoad(User this, Storage storage) +{ + char * storage_data; + size_t nstorage_data; + + size_t * user_data_sizes; + + 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; + + return this; +} + +// vim: set ts=4 sw=4: diff --git a/src/user/save.c b/src/user/save.c new file mode 100644 index 0000000..17e546f --- /dev/null +++ b/src/user/save.c @@ -0,0 +1,48 @@ +/** + * \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 . + */ + +#include +#include + +#include "user.h" +#include "storage.h" +#include "class.h" + +#include "utils/memory.h" + + +void +userSave(User this, Storage storage) +{ + size_t storage_size = + *this->nemail + 1 + + *this->nfirstname + 1 + + *this->nsurname + 1 + + 3 * sizeof(size_t); + + storagePut( + storage, + this->email, *this->nemail, + this->email, storage_size); +} + +// vim: set ts=4 sw=4: diff --git a/src/user/user.c b/src/user/user.c new file mode 100644 index 0000000..1dac923 --- /dev/null +++ b/src/user/user.c @@ -0,0 +1,90 @@ +/** + * \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 . + */ + +#include "user.h" +#include "storage.h" +#include "class.h" + +#include "utils/memory.h" + + +static +int +userCtor(void * _this, va_list * params) +{ + User this = _this; + + char * email = va_arg(* params, char *); + + if (NULL != email) { + size_t nemail = va_arg(* params, size_t); + char * firstname = va_arg(* params, char *); + size_t nfirstname = va_arg(* params, size_t); + char * surname = va_arg(* params, char *); + size_t nsurname = va_arg(* params, size_t); + + size_t storage_size = + nemail + 1 + + nfirstname + 1 + + nsurname + 1 + + 3 * sizeof(size_t); + + this->email = memMalloc(storage_size); + memcpy(this->email, email, nemail); + this->email[nemail] = '\0'; + + this->firstname = this->email + nemail + 1; + memcpy(this->firstname, firstname, nfirstname); + this->firstname[nfirstname] = '\0'; + + this->surname = this->firstname + nfirstname + 1; + memcpy(this->surname, surname, nsurname); + this->surname[nsurname] = '\0'; + + this->nemail = (size_t *)(this->surname + nsurname + 1); + *this->nemail = nemail; + + this->nfirstname = this->nemail + 1; + *this->nfirstname = nfirstname; + + this->nsurname = this->nfirstname + 1; + *this->nsurname = nsurname; + } + + return 0; +} + +static +void +userDtor(void * _this) +{ + User this = _this; + + if (NULL != this->email) { + MEM_FREE(this->email); + } +} + +INIT_IFACE(Class, userCtor, userDtor, NULL); +CREATE_CLASS(User, NULL, IFACE(Class)); + +// vim: set ts=4 sw=4: diff --git a/src/usertest.c b/src/usertest.c new file mode 100644 index 0000000..089ff3d --- /dev/null +++ b/src/usertest.c @@ -0,0 +1,59 @@ +#include +#include +#include +#include +#include + +#include "class.h" +#include "commons.h" +#include "user.h" +#include "storage.h" + +#include "utils/memory.h" + +int +main(int argc, char * argv[]) +{ + Storage users = new(Storage, CSTRA("./users.db")); + User user; + User georg; + //User steffi; + size_t nuser; + + if (NULL == users) { + fprintf(stderr, "%s\n", gdbm_strerror(gdbm_errno)); + fprintf(stderr, "%s\n", strerror(errno)); + return 1; + } + + georg = new(User, + CSTRA("georg@steffers.org"), + CSTRA("Georg"), + CSTRA("Hopp")); + + userSave(georg, users); + delete(georg); + + user = new(User, NULL); + user->email = "georg@steffers.org"; + nuser = sizeof("georg@steffers.org") - 1; + user->nemail = &nuser; + + if (NULL == userLoad(user, users)) { + fprintf(stderr, "can't find user"); + } else { + puts("found user:"); + puts(user->email); + puts(user->firstname); + puts(user->surname); + } + + delete(user); + delete(users); + + memCleanup(); + + return 0; +} + +// vim: set et ts=4 sw=4: From 931e2afae01d97228fc369fc2190022a04bfb874 Mon Sep 17 00:00:00 2001 From: Georg Hopp Date: Mon, 16 Sep 2013 09:42:00 +0100 Subject: [PATCH 05/17] some more testing on the user class --- src/storage/get.c | 3 ++ src/usertest.c | 83 +++++++++++++++++++++++++++++++++++------------ 2 files changed, 66 insertions(+), 20 deletions(-) diff --git a/src/storage/get.c b/src/storage/get.c index 1e4274b..39aba82 100644 --- a/src/storage/get.c +++ b/src/storage/get.c @@ -47,6 +47,9 @@ storageGet( memcpy(*data, value.dptr, value.dsize); free(value.dptr); + } else { + *data = NULL; + *ndata = 0; } } diff --git a/src/usertest.c b/src/usertest.c index 089ff3d..dafbee7 100644 --- a/src/usertest.c +++ b/src/usertest.c @@ -11,14 +11,46 @@ #include "utils/memory.h" +void +printUser(Storage users, const char * key, size_t nkey) +{ + User user = new(User, NULL); + + user->email = (char *)key, + user->nemail = &nkey; + + if (NULL == userLoad(user, users)) { + fprintf(stderr, "can't find user: %s\n", key); + } else { + puts("found user:"); + puts(user->email); + puts(user->firstname); + puts(user->surname); + + delete(user); + } +} + +void +insertUser( + Storage users, + const char * email, size_t nemail, + const char * firstname, size_t nfirstname, + const char * surname, size_t nsurname) +{ + User insert = new(User, + email, nemail, + firstname, nfirstname, + surname, nsurname); + + userSave(insert, users); + delete(insert); +} + int main(int argc, char * argv[]) { Storage users = new(Storage, CSTRA("./users.db")); - User user; - User georg; - //User steffi; - size_t nuser; if (NULL == users) { fprintf(stderr, "%s\n", gdbm_strerror(gdbm_errno)); @@ -26,29 +58,40 @@ main(int argc, char * argv[]) return 1; } - georg = new(User, + insertUser( + users, CSTRA("georg@steffers.org"), CSTRA("Georg"), CSTRA("Hopp")); + insertUser( + users, + CSTRA("drachenfrau1982@gmx.net"), + CSTRA("Gundula"), + CSTRA("Hopp")); - userSave(georg, users); - delete(georg); + printUser(users, CSTRA("foo@bar.de")); + puts(""); + printUser(users, CSTRA("drachenfrau1982@gmx.net")); + puts(""); + printUser(users, CSTRA("georg@steffers.org")); - user = new(User, NULL); - user->email = "georg@steffers.org"; - nuser = sizeof("georg@steffers.org") - 1; - user->nemail = &nuser; + delete(users); - if (NULL == userLoad(user, users)) { - fprintf(stderr, "can't find user"); - } else { - puts("found user:"); - puts(user->email); - puts(user->firstname); - puts(user->surname); - } + users = new(Storage, CSTRA("./users.db")); + + insertUser( + users, + CSTRA("drachenfrau1982@gmx.net"), + CSTRA("Stefanie"), + CSTRA("Hopp")); + + puts(""); + printUser(users, CSTRA("foo@bar.de")); + puts(""); + printUser(users, CSTRA("drachenfrau1982@gmx.net")); + puts(""); + printUser(users, CSTRA("georg@steffers.org")); - delete(user); delete(users); memCleanup(); From 513ce63e542628e2b7236bd8b82e882fafb45405 Mon Sep 17 00:00:00 2001 From: Georg Hopp Date: Mon, 16 Sep 2013 09:51:15 +0100 Subject: [PATCH 06/17] add directory for application runtime information --- run/.keep-me | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 run/.keep-me diff --git a/run/.keep-me b/run/.keep-me new file mode 100644 index 0000000..e69de29 From 76d164b80c99cfc9ec73643cce21fa3255de5982 Mon Sep 17 00:00:00 2001 From: Georg Hopp Date: Mon, 16 Sep 2013 15:04:06 +0100 Subject: [PATCH 07/17] make sessions start on any request and clean them when they have timed out. --- include/application/application.h | 31 +++-- include/http/worker.h | 3 + include/session.h | 9 +- src/Makefile.am | 2 +- src/application/adapter/http/update.c | 160 +++++++++++++++----------- src/application/application.c | 25 +++- src/application/login.c | 33 +++++- src/application/session_get.c | 5 +- src/application/session_start.c | 12 +- src/application/session_stop.c | 6 +- src/application/session_update.c | 20 ++-- src/http/Makefile.am | 3 +- src/http/response/session.c | 7 +- src/http/worker.c | 7 ++ src/http/worker/add_computed_header.c | 47 ++++++++ src/http/worker/process.c | 2 + src/session/session.c | 20 ++-- src/taskrambler.c | 15 ++- src/uuid.c | 18 +++ 19 files changed, 294 insertions(+), 131 deletions(-) create mode 100644 src/http/worker/add_computed_header.c create mode 100644 src/uuid.c diff --git a/include/application/application.h b/include/application/application.h index 01c51dc..e9113c4 100644 --- a/include/application/application.h +++ b/include/application/application.h @@ -27,8 +27,11 @@ #include "class.h" #include "session.h" -#include "hash.h" +#include "queue.h" #include "auth/credential.h" +#include "storage.h" +#include "session.h" + struct randval { time_t timestamp; @@ -36,18 +39,24 @@ struct randval { }; CLASS(Application) { - Hash active_sessions; - void * auth; - struct randval * val; + // should be a list and not a queue but currently queue is + // the closest I have. + Queue active_sessions; + + void ** auth; + size_t nauth; + struct randval * val; + + Storage users; }; -// this should return a user account....now it only return success or failure. -int applicationLogin(Application, Credential); -unsigned long applicationSessionStart(Application, const char *, size_t); -void applicationSessionStop(Application, unsigned long); -void applicationSessionUpdate( - Application, unsigned long, const char *, size_t); -Session applicationSessionGet(Application, unsigned long); +int applicationLogin(Application, Credential, Session); + +Session applicationSessionStart(Application); +Session applicationSessionGet(Application, const char *); +void applicationSessionStop(Application, const char *); +void applicationSessionUpdate( + Application, const char *, const char *, size_t); #endif // __HTTP_HEADER_H__ diff --git a/include/http/worker.h b/include/http/worker.h index af935e6..00414a2 100644 --- a/include/http/worker.h +++ b/include/http/worker.h @@ -36,6 +36,7 @@ #include "http/request.h" #include "http/response.h" +#include "queue.h" #include "commons.h" @@ -50,6 +51,8 @@ CLASS(HttpWorker) { HttpRequest current_request; HttpMessage current_response; + Queue additional_headers; + HttpParser parser; HttpWriter writer; }; diff --git a/include/session.h b/include/session.h index 8ca5d56..a411c5c 100644 --- a/include/session.h +++ b/include/session.h @@ -25,17 +25,20 @@ #include #include +#include #include "class.h" -#define SESSION_LIVETIME 30 +// livetime of a session in seconds +#define SESSION_LIVETIME 300 // 5 minutes CLASS(Session) { - unsigned long id; + char id[37]; + unsigned long hash; time_t livetime; - char * username; + User user; }; #endif // __SESSION_H__ diff --git a/src/Makefile.am b/src/Makefile.am index 771d173..d1cced4 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -34,7 +34,7 @@ bin_PROGRAMS = taskrambler taskrambler_SOURCES = taskrambler.c $(IFACE) $(UTILS) taskrambler_CFLAGS = $(CFLAGS) -Wall -DPWD=\"$(PWD)\" -I ../include/# $(COVERAGE_CFLAGS) -taskrambler_LDADD = $(LIBS) -lrt -lssl -lldap -lgdbm +taskrambler_LDADD = $(LIBS) -lrt -lssl -lldap -lgdbm -luuid #taskrambler_LDFLAGS = $(COVERAGE_LDFLAGS) SUBDIRS = asset auth cbuf class hash queue http \ diff --git a/src/application/adapter/http/update.c b/src/application/adapter/http/update.c index 145a5c1..6d0a6d8 100644 --- a/src/application/adapter/http/update.c +++ b/src/application/adapter/http/update.c @@ -39,26 +39,92 @@ #include "utils/memory.h" -#define NO_SESSION_SID 0 +#define NO_SESSION_SID NULL +#define SESS_HEADER "{\"id\":\"%s\",\"timeout\":%d,\"timeleft\":%ld}" static inline -unsigned long +char * getSessionId(Hash cookies) { HashValue sidstr = hashGet(cookies, CSTRA("sid")); if (NULL != sidstr) { - return strtoul((char*)(sidstr->value), NULL, 10); + return (char*)sidstr->value; } return NO_SESSION_SID; } +static +Session +getSession(Queue sess_queue, const char * sid) +{ + Session sess = NULL; + time_t now = time(NULL); + + /** + * session start or update + * + * @TODO + * I need to walk through the whole hash at this point to find + * expired sessions and remove them....this is not good and + * probably I need another(faster) way to identify expired + * sessions.... + * + * @TODO + * Build a way to cleanup the hash by a filter...currently + * there is nothing I could use for this. + * Well this is practically impossible in reasonable time + * because every time I remove one element the tree has to + * be rebalanced.... + * + * I have to store all nodes in a different structure that + * gives me the possibility to find fast expired objects. + * These can then be removed from both structures.... + * + * Anyway this is the pure horror...because I have to compute + * the condition for every stored session....and I really have to + * do this...else the tree would grow and grow all the time... + * + * I think the best I can do at this point is, at least for the moment, + * to store the sessions in a list and not in a stack. + * Each request will than have to walk through that list, + * remove expired sessions and pick out its own.... + * this is O(n), but currently I gave no better idea at all. + */ + while (NULL != sess_queue->next) { + Session session = (Session)sess_queue->next->msg; + + if (now >= session->livetime) { + Queue to_delete = sess_queue->next; + sess_queue->next = sess_queue->next->next; + delete(session); + delete(to_delete); + continue; + } + + if (NULL != sid && 0 == memcmp(session->id, sid, 36)) { + session->livetime = time(NULL) + SESSION_LIVETIME; + sess = session; + } + + sess_queue = sess_queue->next; + } + + if (NULL == sess) { + sess = new(Session); + queuePut(sess_queue, sess); + } + + return sess; +} + + static void -loginAdapter(Application application, HttpWorker worker, unsigned long sid) +loginAdapter(Application application, HttpWorker worker, Session session) { HashValue username; HashValue password; @@ -82,34 +148,7 @@ loginAdapter(Application application, HttpWorker worker, unsigned long sid) (char *)(username->value), username->nvalue, (char *)(password->value), password->nvalue); - if (applicationLogin(application, credential)) { - char buffer[200]; - size_t nbuf; - - if (NO_SESSION_SID == sid - || NULL == applicationSessionGet(application, sid)) { - sid = applicationSessionStart( - application, - (char *)(username->value), - username->nvalue); - } else { - applicationSessionUpdate( - application, - sid, - username->value, - username->nvalue); - } - - nbuf = sprintf(buffer, "sid=%lu;Path=/", sid); - - worker->current_response = - (HttpMessage)httpResponseSession( - applicationSessionGet(application, sid)); - - hashAdd( - worker->current_response->header, - new(HttpHeader, CSTRA("Set-Cookie"), buffer, nbuf)); - } else { + if (! applicationLogin(application, credential, session)) { worker->current_response = new(HttpResponse, "HTTP/1.1", 403, "Forbidden"); } @@ -117,53 +156,42 @@ loginAdapter(Application application, HttpWorker worker, unsigned long sid) delete(credential); } - void applicationAdapterHttpUpdate(void * _this, void * subject) { ApplicationAdapterHttp this = _this; - HttpWorker worker = (HttpWorker)subject; - unsigned long sid = getSessionId(worker->current_request->cookies); - Session session = applicationSessionGet(this->application, sid); - - if (NULL != session) { - if (time(NULL) < session->livetime) { - session->livetime = time(NULL) + SESSION_LIVETIME; - } else { - applicationSessionStop(this->application, sid); - } - - } + HttpWorker worker = (HttpWorker)subject; + char * sid; + Session session; + char buf[200]; + size_t nbuf; + + sid = getSessionId(worker->current_request->cookies); + session = getSession(this->application->active_sessions, sid); + + nbuf = sprintf(buf, SESS_HEADER, + session->id, + SESSION_LIVETIME, + session->livetime - time(NULL)); + queuePut( + worker->additional_headers, + new(HttpHeader, CSTRA("X-TaskramblerSession"), buf, nbuf)); + + nbuf = sprintf(buf, "sid=%s;Path=/", session->id); + queuePut( + worker->additional_headers, + new(HttpHeader, CSTRA("Set-Cookie"), buf, nbuf)); if (0 == strcmp("POST", worker->current_request->method)) { if (0 == strcmp("/login/", worker->current_request->path)) { - loginAdapter(this->application, worker, sid); + loginAdapter(this->application, worker, session); return; } } if (0 == strcmp("GET", worker->current_request->method)) { - if (0 == strcmp("/sessinfo/", worker->current_request->path)) { - worker->current_response = - (HttpMessage)httpResponseSession( - applicationSessionGet(this->application, sid)); - return; - } - - if (0 == strcmp("/sess/", worker->current_request->path)) { - if (NO_SESSION_SID == sid - || NULL == applicationSessionGet(this->application, sid)) { - sid = applicationSessionStart(this->application, NULL, 0); - } - - worker->current_response = - (HttpMessage)httpResponseSession( - applicationSessionGet(this->application, sid)); - return; - } - if (0 == strcmp("/randval/", worker->current_request->path)) { - if (NO_SESSION_SID != sid) { + if (NO_SESSION_SID != session->id) { worker->current_response = (HttpMessage)httpResponseRandval( this->application->val->timestamp, diff --git a/src/application/application.c b/src/application/application.c index 16da56f..31c146f 100644 --- a/src/application/application.c +++ b/src/application/application.c @@ -25,8 +25,9 @@ #include #include "class.h" -#include "hash.h" +#include "queue.h" #include "application/application.h" +#include "storage.h" #include "utils/memory.h" @@ -35,11 +36,20 @@ int applicationCtor(void * _this, va_list * params) { Application this = _this; + size_t i; - this->val = va_arg(*params, struct randval *); - this->auth = va_arg(*params, void *); + this->val = va_arg(*params, struct randval *); - this->active_sessions = new(Hash); + // initialize authenticators to use. + this->nauth = va_arg(*params, size_t); + this->auth = memMalloc(this->nauth * sizeof(void*)); + for (i=0; inauth; i++) { + this->auth[i] = va_arg(*params, void *); + } + + this->active_sessions = new(Queue); + + this->users = new(Storage, "./run/users.db"); return 0; } @@ -49,8 +59,15 @@ void applicationDtor(void * _this) { Application this = _this; + size_t i; delete(this->active_sessions); + + for (i=0; inauth; i++) { + delete(this->auth[i]); + } + + MEM_FREE(this->auth); } diff --git a/src/application/login.c b/src/application/login.c index e10f5f5..02e2246 100644 --- a/src/application/login.c +++ b/src/application/login.c @@ -34,9 +34,38 @@ int -applicationLogin(Application this, Credential credential) +applicationLogin( + Application this, + Credential credential, + Session session) { - return authenticate(this->auth, credential); + size_t i; + + for (i=0; inauth; i++) { + if (authenticate(this->auth, credential)) { + session->user = new(User, NULL); + + 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)) { + session->user->email = NULL; + session->user->nemail = NULL; + } + + break; + + default: + break; + } + + return 1; + } + } + + return 0; } // vim: set ts=4 sw=4: diff --git a/src/application/session_get.c b/src/application/session_get.c index 46eaa10..db626fb 100644 --- a/src/application/session_get.c +++ b/src/application/session_get.c @@ -33,9 +33,10 @@ Session -applicationSessionGet(Application this, unsigned long sid) +applicationSessionGet(Application this, const char * sid) { - return hashGetByVal(this->active_sessions, sid); +// return hashGet(this->active_sessions, sid, 36); + return NULL; } // vim: set ts=4 sw=4: diff --git a/src/application/session_start.c b/src/application/session_start.c index 594e7e0..ec28ff1 100644 --- a/src/application/session_start.c +++ b/src/application/session_start.c @@ -26,20 +26,20 @@ #include "class.h" #include "session.h" -#include "hash.h" +#include "queue.h" #include "application/application.h" #include "utils/memory.h" -unsigned long -applicationSessionStart(Application this, const char * name, size_t nname) +Session +applicationSessionStart(Application this) { - Session session = new(Session, name, nname); + Session session = new(Session); - hashAdd(this->active_sessions, session); + queuePut(this->active_sessions, session); - return session->id; + return session; } // vim: set ts=4 sw=4: diff --git a/src/application/session_stop.c b/src/application/session_stop.c index 1d876a0..73459d5 100644 --- a/src/application/session_stop.c +++ b/src/application/session_stop.c @@ -33,10 +33,10 @@ void -applicationSessionStop(Application this, unsigned long sid) +applicationSessionStop(Application this, const char * sid) { - Session session = hashDeleteByVal(this->active_sessions, sid); - delete(session); + //Session session = hashDelete(this->active_sessions, sid, 36); + //delete(session); } // vim: set ts=4 sw=4: diff --git a/src/application/session_update.c b/src/application/session_update.c index eaa144f..7e8a8bf 100644 --- a/src/application/session_update.c +++ b/src/application/session_update.c @@ -36,19 +36,19 @@ void applicationSessionUpdate( Application this, - unsigned long sid, + const char * sid, const char * name, size_t nname) { - Session session = hashGetByVal(this->active_sessions, sid); - - if (NULL != session) { - MEM_FREE(session->username); - - session->username = memMalloc(nname + 1); - session->username[nname] = 0; - memcpy(session->username, name, nname); - } +// Session session = hashGet(this->active_sessions, sid, 36); +// +// if (NULL != session) { +// MEM_FREE(session->username); +// +// session->username = memMalloc(nname + 1); +// session->username[nname] = 0; +// memcpy(session->username, name, nname); +// } } // vim: set ts=4 sw=4: diff --git a/src/http/Makefile.am b/src/http/Makefile.am index b3745b6..0b3a9f7 100644 --- a/src/http/Makefile.am +++ b/src/http/Makefile.am @@ -31,7 +31,8 @@ WORKER = worker.c \ worker/process.c \ worker/answer.c \ worker/get_asset.c \ - worker/add_common_header.c + worker/add_common_header.c \ + worker/add_computed_header.c HEADER = header.c \ header/to_string.c diff --git a/src/http/response/session.c b/src/http/response/session.c index 5aae94a..34ec44b 100644 --- a/src/http/response/session.c +++ b/src/http/response/session.c @@ -36,7 +36,7 @@ #include "utils/memory.h" #include "hash.h" -#define RESP_DATA "{\"id\":\"%lu\",\"timeout\":%d,\"timeleft\":%ld,\"username\":\"%s\"}" +#define RESP_DATA "{\"id\":\"%s\",\"timeout\":%d,\"timeleft\":%ld}" HttpResponse httpResponseSession(Session session) @@ -53,10 +53,9 @@ httpResponseSession(Session session) new(HttpHeader, CSTRA("Content-Type"), CSTRA("application/json"))); nbuf = sprintf(buffer, RESP_DATA, - (NULL != session)? session->id : 0, + (NULL != session)? session->id : "", (NULL != session)? SESSION_LIVETIME : 0, - (NULL != session)? session->livetime - time(NULL) : 0, - (NULL != session)? session->username : ""); + (NULL != session)? session->livetime - time(NULL) : 0); message->nbody = nbuf; message->body = memMalloc(nbuf); diff --git a/src/http/worker.c b/src/http/worker.c index 6ccb07f..8d59303 100644 --- a/src/http/worker.c +++ b/src/http/worker.c @@ -33,6 +33,7 @@ #include "class.h" #include "stream.h" #include "hash.h" +#include "queue.h" #include "http/worker.h" #include "http/parser.h" #include "http/writer.h" @@ -57,6 +58,8 @@ httpWorkerCtor(void * _this, va_list * params) sprintf(cbuf_id, "%s_%s", "parser", id); this->pbuf = new(Cbuf, cbuf_id, PARSER_MAX_BUF); + this->additional_headers = new(Queue); + this->parser = new(HttpParser, this->pbuf); this->writer = new(HttpWriter); @@ -71,6 +74,8 @@ httpWorkerDtor(void * _this) MEM_FREE(this->id); + delete(this->additional_headers); + delete(this->parser); delete(this->writer); @@ -90,6 +95,8 @@ httpWorkerClone(void * _this, void * _base) this->asset_pool = base->asset_pool; this->application_adapter = base->application_adapter; + this->additional_headers = new(Queue); + this->parser = new(HttpParser, base->pbuf); /* * I am pretty sure that it is not neccessary to have a diff --git a/src/http/worker/add_computed_header.c b/src/http/worker/add_computed_header.c new file mode 100644 index 0000000..52d37e3 --- /dev/null +++ b/src/http/worker/add_computed_header.c @@ -0,0 +1,47 @@ +/** + * \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 . + */ + +#include + +#include "class.h" + +#include "http/message.h" +#include "http/header.h" +#include "http/worker.h" + +#include "queue.h" + +#include "utils/memory.h" + + +void +httpWorkerAddComputedHeader(HttpWorker this) +{ + HttpHeader header = (HttpHeader)queueGet(this->additional_headers); + + while(NULL != header) { + hashAdd(this->current_response->header, header); + header = (HttpHeader)queueGet(this->additional_headers); + } +} + +// vim: set ts=4 sw=4: diff --git a/src/http/worker/process.c b/src/http/worker/process.c index 26ccf07..2e5f90f 100644 --- a/src/http/worker/process.c +++ b/src/http/worker/process.c @@ -50,6 +50,7 @@ HttpMessage httpWorkerGetAsset(HttpWorker, const char *); void httpWorkerAddCommonHeader(HttpWorker); +void httpWorkerAddComputedHeader(HttpWorker); ssize_t @@ -117,6 +118,7 @@ httpWorkerProcess(HttpWorker this, Stream st) } httpWorkerAddCommonHeader(this); + httpWorkerAddComputedHeader(this); delete(this->current_request); queuePut(this->writer->queue, this->current_response); this->current_response = NULL; diff --git a/src/session/session.c b/src/session/session.c index fe2975c..ff46cc2 100644 --- a/src/session/session.c +++ b/src/session/session.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "session.h" #include "hash.h" @@ -40,15 +41,13 @@ int sessionCtor(void * _this, va_list * params) { Session this = _this; - char * uname = va_arg(* params, char *); - size_t nuname = va_arg(* params, size_t); + uuid_t uuid; this->livetime = time(NULL) + SESSION_LIVETIME; - this->id = sdbm((unsigned char *)uname, nuname) ^ this->livetime; + uuid_generate(uuid); + uuid_unparse(uuid, this->id); - this->username = memMalloc(nuname + 1); - this->username[nuname] = 0; - memcpy(this->username, uname, nuname); + this->hash = sdbm((unsigned char *)this->id, 36); return 0; } @@ -57,18 +56,15 @@ static void sessionDtor(void * _this) { - Session this = _this; - - MEM_FREE(this->username); } static unsigned long -sessionGetId(void * _this) +sessionGetHash(void * _this) { Session this = _this; - return this->id; + return this->hash; } static @@ -78,7 +74,7 @@ sessionHandleDouble(void * _this, void * _doub) } INIT_IFACE(Class, sessionCtor, sessionDtor, NULL); -INIT_IFACE(Hashable, sessionGetId, sessionHandleDouble); +INIT_IFACE(Hashable, sessionGetHash, sessionHandleDouble); CREATE_CLASS(Session, NULL, IFACE(Class), IFACE(Hashable)); // vim: set ts=4 sw=4: diff --git a/src/taskrambler.c b/src/taskrambler.c index 6020e92..c0eada7 100644 --- a/src/taskrambler.c +++ b/src/taskrambler.c @@ -55,6 +55,9 @@ //#define DEFAULT_SECS 1 #define DEFAULT_USECS 0 +#define LDAP_BASE "ou=user,dc=yabrog,dc=weird-web-workers,dc=org" + + void nullhandler() {} void daemonize(void); @@ -137,7 +140,7 @@ main() default: { - AuthLdap auth; + AuthLdap ldap; Application application; ApplicationAdapterHttp adapterHttp; HttpWorker worker; @@ -150,11 +153,12 @@ main() close(shm); logger = new(LoggerSyslog, LOGGER_DEBUG); - auth = new(AuthLdap, - "ldap://hosted/", - CSTRA("ou=user,dc=yabrog,dc=weird-web-workers,dc=org")); + worker = new(HttpWorker, "testserver"); - application = new(Application, value, auth); + ldap = new( + AuthLdap, "ldap://hosted/", CSTRA(LDAP_BASE)); + application = new(Application, value, 1, ldap); + adapterHttp = new(ApplicationAdapterHttp, application); subjectAttach(worker, adapterHttp); @@ -206,7 +210,6 @@ main() delete(worker); delete(adapterHttp); delete(application); - delete(auth); delete(logger); clearMimeTypes(); diff --git a/src/uuid.c b/src/uuid.c new file mode 100644 index 0000000..8ab3022 --- /dev/null +++ b/src/uuid.c @@ -0,0 +1,18 @@ +#include +#include + +int +main(int argc, char * argv[]) +{ + uuid_t uuid; + char uuid_str[37]; + + uuid_generate(uuid); + uuid_unparse(uuid, uuid_str); + + printf("%s\n", uuid_str); + + return 0; +} + +// vim: set ts=4 sw=4: From 857461fb63cee483b1161c4e0c36b7889ed884db Mon Sep 17 00:00:00 2001 From: Georg Hopp Date: Mon, 16 Sep 2013 15:04:29 +0100 Subject: [PATCH 08/17] code formatting --- src/tree/destroy.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tree/destroy.c b/src/tree/destroy.c index a60d87a..364db9d 100644 --- a/src/tree/destroy.c +++ b/src/tree/destroy.c @@ -39,8 +39,8 @@ treeDestroy(Tree * this, TreeAction action) * If we come from the right so nothing and go to our * next parent. */ - if (((NULL == TREE_LEFT(node) || previous == TREE_LEFT(node)) - && NULL == TREE_RIGHT(node)) + if (((NULL == TREE_LEFT(node) + || previous == TREE_LEFT(node)) && NULL == TREE_RIGHT(node)) || previous == TREE_RIGHT(node)) { Tree parent = TREE_PARENT(node); From 4cef3afa5c7ef17f107c00cf989c3eecd126871b Mon Sep 17 00:00:00 2001 From: Georg Hopp Date: Sat, 21 Sep 2013 17:41:03 +0100 Subject: [PATCH 09/17] use user class to load and get user informations. --- assets/js/session.js | 17 +++++-- include/http/response.h | 2 + src/application/adapter/http/update.c | 23 ++++++++- src/application/login.c | 2 +- src/http/Makefile.am | 3 +- src/http/response/user.c | 67 +++++++++++++++++++++++++++ src/usertest.c | 5 ++ 7 files changed, 112 insertions(+), 7 deletions(-) create mode 100644 src/http/response/user.c diff --git a/assets/js/session.js b/assets/js/session.js index de47615..9e3e8be 100644 --- a/assets/js/session.js +++ b/assets/js/session.js @@ -8,6 +8,9 @@ function Session(sId) this.timeout = 0; this.timeleft = 0; this.username = ""; + this.email = ""; + this.firstname = ""; + this.surname = ""; this.interval = null; this.draw(); @@ -18,12 +21,15 @@ Session.prototype.loadJSON = function(data) this.stop(); this.id = ("0" == data.id)? "none" : data.id; - this.timeout = data.timeout * 10; - this.timeleft = data.timeleft * 10; - this.username = data.username; + //this.timeout = data.timeout * 10; + //this.timeleft = data.timeleft * 10; + //this.username = data.username; + this.email = data.email; + this.firstname = data.firstname; + this.surname = data.surname; this.eSid.empty().append(this.id); - $("#main p:eq(1) span:eq(0)").empty().append(" " + this.username); + $("#main p:eq(1) span:eq(0)").empty().append(" " + this.firstname + " " + this.surname); this.draw(); if (0 < this.timeleft) @@ -68,6 +74,9 @@ Session.prototype.stop = function() this.timeout = 0; this.timeleft = 0; this.username = ""; + this.email = ""; + this.firstname = ""; + this.surname = ""; this.eSid.empty().append(this.id); $("#main p:eq(1) span:eq(0)").empty().append(" " + this.username); diff --git a/include/http/response.h b/include/http/response.h index b2e56ba..cfcc4fa 100644 --- a/include/http/response.h +++ b/include/http/response.h @@ -30,6 +30,7 @@ #include "class.h" #include "http/message.h" #include "session.h" +#include "user.h" #include "asset.h" @@ -51,6 +52,7 @@ HttpResponse httpResponseMe(); HttpResponse httpResponseLoginForm(); HttpResponse httpResponseRandval(time_t, int); HttpResponse httpResponseSession(Session); +HttpResponse httpResponseUser(User); HttpResponse httpResponseAsset(const char *, size_t); #endif // __HTTP_RESPONSE_H__ diff --git a/src/application/adapter/http/update.c b/src/application/adapter/http/update.c index 6d0a6d8..bca45e8 100644 --- a/src/application/adapter/http/update.c +++ b/src/application/adapter/http/update.c @@ -151,6 +151,9 @@ loginAdapter(Application application, HttpWorker worker, Session session) if (! applicationLogin(application, credential, session)) { worker->current_response = new(HttpResponse, "HTTP/1.1", 403, "Forbidden"); + } else { + worker->current_response = + (HttpMessage)httpResponseUser(session->user); } delete(credential); @@ -190,8 +193,26 @@ applicationAdapterHttpUpdate(void * _this, void * subject) } if (0 == strcmp("GET", worker->current_request->method)) { + if (0 == strcmp("/user/get/", worker->current_request->path)) { + worker->current_response = + (HttpMessage)httpResponseUser(session->user); + return; + } + +// if (0 == strcmp("/sess/", worker->current_request->path)) { +// if (NO_SESSION_SID == sid +// || NULL == applicationSessionGet(this->application, sid)) { +// sid = applicationSessionStart(this->application, NULL, 0); +// } +// +// worker->current_response = +// (HttpMessage)httpResponseSession( +// applicationSessionGet(this->application, sid)); +// return; +// } + if (0 == strcmp("/randval/", worker->current_request->path)) { - if (NO_SESSION_SID != session->id) { + if (NULL != session->user) { worker->current_response = (HttpMessage)httpResponseRandval( this->application->val->timestamp, diff --git a/src/application/login.c b/src/application/login.c index 02e2246..627c2b7 100644 --- a/src/application/login.c +++ b/src/application/login.c @@ -42,7 +42,7 @@ applicationLogin( size_t i; for (i=0; inauth; i++) { - if (authenticate(this->auth, credential)) { + if (authenticate(this->auth[i], credential)) { session->user = new(User, NULL); switch (credential->type) { diff --git a/src/http/Makefile.am b/src/http/Makefile.am index 0b3a9f7..a96ac38 100644 --- a/src/http/Makefile.am +++ b/src/http/Makefile.am @@ -17,7 +17,8 @@ RESP = response.c \ response/login_form.c \ response/asset.c \ response/randval.c \ - response/session.c + response/session.c \ + response/user.c PARSER = parser.c \ parser/parse.c \ parser/new_message.c \ diff --git a/src/http/response/user.c b/src/http/response/user.c new file mode 100644 index 0000000..2cde03c --- /dev/null +++ b/src/http/response/user.c @@ -0,0 +1,67 @@ +/** + * \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 . + */ + +#include +#include +#include +#include +#include + +#include "class.h" + +#include "http/response.h" +#include "http/message.h" +#include "http/header.h" +#include "session.h" + +#include "utils/memory.h" +#include "hash.h" + +#define RESP_DATA "{\"email\":\"%s\",\"firstname\":\"%s\",\"surname\":\"%s\"}" + +HttpResponse +httpResponseUser(User user) +{ + char buffer[200]; + HttpResponse response; + HttpMessage message; + size_t nbuf; + + response = new(HttpResponse, "HTTP/1.1", 200, "OK"); + message = (HttpMessage)response; + + hashAdd(message->header, + new(HttpHeader, CSTRA("Content-Type"), CSTRA("application/json"))); + + nbuf = sprintf(buffer, RESP_DATA, + (NULL != user)? user->email : "", + (NULL != user)? user->firstname : "", + (NULL != user)? user->surname : ""); + + message->nbody = nbuf; + message->body = memMalloc(nbuf); + memcpy(message->body, buffer, nbuf); + + return response; +} + +// vim: set ts=4 sw=4: diff --git a/src/usertest.c b/src/usertest.c index dafbee7..9369c68 100644 --- a/src/usertest.c +++ b/src/usertest.c @@ -58,6 +58,11 @@ main(int argc, char * argv[]) return 1; } + insertUser( + users, + CSTRA("georg"), + CSTRA("Georg"), + CSTRA("Hopp")); insertUser( users, CSTRA("georg@steffers.org"), From 6139e8f03a094dbeb57eae887bcca64b9c30e3b2 Mon Sep 17 00:00:00 2001 From: Georg Hopp Date: Sun, 22 Sep 2013 01:13:23 +0100 Subject: [PATCH 10/17] put most of the parts for simple signup/login in place...not tested now as it is late. Hopefully tomorrow I find the time to setup a small testform and bring this whole thing finally to work. refs #36 --- include/application/application.h | 3 + include/auth.h | 1 + include/auth/storage.h | 49 ++++++++++++ include/storage.h | 11 ++- src/application/adapter/http/update.c | 74 +++++++++++++++++- src/application/application.c | 12 ++- src/application/signup.c | 78 +++++++++++++++++++ src/auth/storage/hash_pw.c | 103 ++++++++++++++++++++++++++ src/auth/storage/signup.c | 53 +++++++++++++ src/auth/storage/storage.c | 95 ++++++++++++++++++++++++ src/storage/put.c | 23 +++++- src/storage/update.c | 50 +++++++++++++ src/user/save.c | 5 +- src/utils/hash.c | 19 +++++ 14 files changed, 570 insertions(+), 6 deletions(-) create mode 100644 include/auth/storage.h create mode 100644 src/application/signup.c create mode 100644 src/auth/storage/hash_pw.c create mode 100644 src/auth/storage/signup.c create mode 100644 src/auth/storage/storage.c create mode 100644 src/storage/update.c diff --git a/include/application/application.h b/include/application/application.h index e9113c4..8a89c10 100644 --- a/include/application/application.h +++ b/include/application/application.h @@ -31,6 +31,7 @@ #include "auth/credential.h" #include "storage.h" #include "session.h" +#include "user.h" struct randval { @@ -48,9 +49,11 @@ CLASS(Application) { struct randval * val; Storage users; + Storage passwords; }; int applicationLogin(Application, Credential, Session); +int applicationSignup(Application, Credential, User, Session); Session applicationSessionStart(Application); Session applicationSessionGet(Application, const char *); diff --git a/include/auth.h b/include/auth.h index 00bc28e..a3ec86a 100644 --- a/include/auth.h +++ b/include/auth.h @@ -25,6 +25,7 @@ #include "auth/auth.h" #include "auth/ldap.h" +#include "auth/storage.h" #include "auth/credential.h" #include "auth/interface/auth.h" diff --git a/include/auth/storage.h b/include/auth/storage.h new file mode 100644 index 0000000..5409f36 --- /dev/null +++ b/include/auth/storage.h @@ -0,0 +1,49 @@ +/** + * \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 __AUTH_STORAGE_H__ +#define __AUTH_STORAGE_H__ + +#include + +#include + +#include "class.h" + + +#define SALT_SIZE 32 +#define HASH_SIZE SHA512_DIGEST_LENGTH + + +CLASS(AuthStorage) { + Storage store; +}; + +/* + * @TODO In future this should use a more general purpose hash + * function, which then will be in utils/hash.c + */ +int hash_pw(const char *, const size_t, unsigned char *, unsigned char **); + +#endif // __AUTH_STORAGE_H__ + +// vim: set ts=4 sw=4: diff --git a/include/storage.h b/include/storage.h index c2fcb8b..277a9da 100644 --- a/include/storage.h +++ b/include/storage.h @@ -29,12 +29,21 @@ #include "class.h" +typedef enum e_StoragePutResults { + SPR_OK = 0, + SPR_READ_ONLY = 1, + SPR_EXISTS = 2, + SPR_UNKNOWN = -1 +} StoragePutResult; + + CLASS(Storage) { GDBM_FILE gdbm; char * db_name; }; -void storagePut(Storage, char *, size_t, char *, size_t); +StoragePutResult storagePut(Storage, char *, size_t, char *, size_t); +StoragePutResult storageUpdate(Storage, char *, size_t, char *, size_t); void storageGet(Storage, char *, size_t, char **, size_t *); #endif // __STORAGE_H__ diff --git a/src/application/adapter/http/update.c b/src/application/adapter/http/update.c index bca45e8..a78b28a 100644 --- a/src/application/adapter/http/update.c +++ b/src/application/adapter/http/update.c @@ -35,6 +35,7 @@ #include "http/header.h" #include "http/response.h" #include "auth/credential.h" +#include "user.h" #include "utils/memory.h" @@ -121,7 +122,6 @@ getSession(Queue sess_queue, const char * sid) return sess; } - static void loginAdapter(Application application, HttpWorker worker, Session session) @@ -159,6 +159,73 @@ loginAdapter(Application application, HttpWorker worker, Session session) delete(credential); } +static +void +signupAdapter(Application application, HttpWorker worker, Session session) +{ + HashValue email; + HashValue password; + HashValue pwrepeat; + HashValue firstname; + HashValue surname; + + Credential credential; + User user; + + email = hashGet( + worker->current_request->post, + CSTRA("email")); + password = hashGet( + worker->current_request->post, + CSTRA("password")); + pwrepeat = hashGet( + worker->current_request->post, + CSTRA("pwrepeat")); + firstname = hashGet( + worker->current_request->post, + CSTRA("firstname")); + surname = hashGet( + worker->current_request->post, + CSTRA("surname")); + + if ( + NULL == email || + NULL == password || + NULL == pwrepeat || + NULL == firstname || + NULL == surname) { + // maybe this is not a 500...have to check repsonse codes. + worker->current_response = httpResponse500(); + return; + } + + if (password->nvalue != pwrepeat->nvalue || + 0 != memcmp(password->value, pwrepeat->value, password->nvalue)) { + // maybe this is not a 500...have to check repsonse codes. + worker->current_response = httpResponse500(); + return; + } + + credential = new(Credential, + CRED_PASSWORD, + (char *)(email->value), email->nvalue, + (char *)(password->value), password->nvalue); + + user = new(User, + (char *)(email->value), email->nvalue, + (char *)(firstname->value), firstname->nvalue, + (char *)(surname->value), surname->nvalue); + + if (! applicationSignup(application, credential, user, session)) { + worker->current_response = httpResonse500(); + } else { + loginAdapter(application, worker, session); + } + + delete(credential); +} + + void applicationAdapterHttpUpdate(void * _this, void * subject) { @@ -190,6 +257,11 @@ applicationAdapterHttpUpdate(void * _this, void * subject) loginAdapter(this->application, worker, session); return; } + + if (0 == strcmp("/signup/", worker->current_request->path)) { + signupAdapter(this->application, worker, session); + return; + } } if (0 == strcmp("GET", worker->current_request->method)) { diff --git a/src/application/application.c b/src/application/application.c index 31c146f..ffa1d7c 100644 --- a/src/application/application.c +++ b/src/application/application.c @@ -49,7 +49,15 @@ applicationCtor(void * _this, va_list * params) this->active_sessions = new(Queue); - this->users = new(Storage, "./run/users.db"); + /* + * @TODO for both of these...each user should be identified + * by a number...that way I could use that number in the + * passwords db and no direct association between email and + * password could be made when someone get the hands on the + * password database. + */ + this->users = new(Storage, "./run/users.db"); + this->passwords = new(Storage, "./run/passwords.db") return 0; } @@ -61,6 +69,8 @@ applicationDtor(void * _this) Application this = _this; size_t i; + delete(this->passwords); + delete(this->users); delete(this->active_sessions); for (i=0; inauth; i++) { diff --git a/src/application/signup.c b/src/application/signup.c new file mode 100644 index 0000000..acd6b0c --- /dev/null +++ b/src/application/signup.c @@ -0,0 +1,78 @@ +/** + * \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 . + */ + +#define _GNU_SOURCE + +#include +#include +#include + +#include "class.h" +#include "auth.h" +#include "user.h" +#include "application/application.h" + +#include "utils/memory.h" + +int +applicationSignup( + Application this, + Credential credential, + User user, + Session session) +{ + unsigned char hash[SALT_SIZE+HASH_SIZE]; + + 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); + + if (FALSE == hash_pw( + CRED_PWD(cred).pass, + CRED_PWD(cred).npass, + &hash, + &(hash+SALT_SIZE))) { + /* + * @TODO if we come here we have to delete the previously saved + * user again... + */ + return 0; + } + + storagePut( + this->passwords, + CRED_PWD(cred).user, + CRED_PWD(cred).nuser, + hash, + SALT_SIZE + HASH_SIZE); + + return 0; +} + +// vim: set ts=4 sw=4: diff --git a/src/auth/storage/hash_pw.c b/src/auth/storage/hash_pw.c new file mode 100644 index 0000000..93228f3 --- /dev/null +++ b/src/auth/storage/hash_pw.c @@ -0,0 +1,103 @@ +/** + * \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 . + */ + +#include + +#include +#include + +#include "class.h" +#include "storage.h" +#include "utils/memory.h" + +/* + * I have to hash the passwords, maybe this will move in + * a separate class in future, but now everything is done + * here + */ +#define PBKDF2_ITERATIONS 2048 + +/* + * base64 decode via openssl... + * I do not need this i think, but I keep it...maybe I have + * use for it later. + * +#include +#include + +#define B64_SALT "q36MilkD6Ezlt6+G394aPYWrSwAdEhdnK8k=" + +BIO_METHOD * BIO_f_base64(void); + +void +base64decode(char * data) { + BIO * bio, + * b64; + FILE * b64_salt = fmemopen(B64_SALT, sizeof(B64_SALT)-1, "r"); + + b64 = BIO_new(BIO_f_base64()); + bio = BIO_new_fp(b64_salt, BIO_NOCLOSE); + bio = BIO_push(b64, bio); + + BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL); + + if (SALT_SIZE != BIO_read(bio, data, SALT_SIZE)) { + return -1; + } + + BIO_free_all(bio); + fclose(b64_salt); +} +*/ + +int +hash_pw( + const char * password, + const size_t npassword, + unsigned char * hash, + unsigned char ** salt) +{ + if (NULL == *salt) { + *salt = memMalloc(SALT_SIZE * sizeof(unsigned char)); + if (0 > RAND_pseudo_bytes(unsigned char *buf, int num)) { + MEM_FREE(*salt); + return FALSE; + } + } + + if (0 == PKCS5_PBKDF2_HMAC( + password, + npassword, + *salt, + SALT_SIZE, + PBKDF2_ITERATIONS, + EVP_sha512(), + HASH_SIZE, + hash)) { + MEM_FREE(*salt); + return FALSE; + } + + return TRUE; +} + +// vim: set ts=4 sw=4: diff --git a/src/auth/storage/signup.c b/src/auth/storage/signup.c new file mode 100644 index 0000000..2db9efb --- /dev/null +++ b/src/auth/storage/signup.c @@ -0,0 +1,53 @@ +/** + * \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 . + */ + +#include + +#include "class.h" +#include "storage.h" +#include "auth/storage.h" +#include "auth/credential.h" + +int +authStorageSignup(AuthStorage this, Credential cred) +{ + unsigned char hash[SALT_SIZE+HASH_SIZE]; + + if (FALSE == hash_pw( + CRED_PWD(cred).pass, + CRED_PWD(cred).npass, + &hash, + &(hash+SALT_SIZE))) { + return 0; + } + + storagePut( + this->store, + CRED_PWD(cred).user, + CRED_PWD(cred).nuser, + hash, + SALT_SIZE + HASH_SIZE); + + return 1; +} + +// vim: set ts=4 sw=4: diff --git a/src/auth/storage/storage.c b/src/auth/storage/storage.c new file mode 100644 index 0000000..5aa8e47 --- /dev/null +++ b/src/auth/storage/storage.c @@ -0,0 +1,95 @@ +/** + * \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 . + */ + +#include "class.h" +#include "storage.h" +#include "auth/storage.h" +#include "auth/credential.h" +#include "commons.h" + +static +int +authStorageCtor(void * _this, va_list * params) +{ + AuthStorage this = _this; + + this->store = va_arg(*params, Storage); + + return 0; +} + +static +void +authStorageDtor(void * _this) +{ +} + +static +int +authStorageAuthenticate(void * _this, Credential cred) +{ + AuthStorage this = _this; + + unsigned char current_hash[HASH_SIZE]; + unsigned char * found_hash = NULL; + size_t nfound_hash = 0; + + if (CRED_PASSWORD != cred->type) { + return FALSE; + } + + storageGet( + this->store, + CRED_PWD(cred).user, + CRED_PWD(cred).nuser, + &found_hash, + &nfound_hash); + + if (NULL == found_hash || (SALT_SIZE + HASH_SIZE) != nfound_hash) { + /* user not found or found hash is invalid */ + return FALSE; + } + + /* found_hash <=> salt+hash */ + if (FALSE == hash_pw( + CRED_PWD(cred).pass, + CRED_PWD(cred).npass, + current_hash, + &found_hash)) { + MEM_FREE(found_hash); + return FALSE; + } + + if (0 != memcmp(current_hash, found_hash+SALT_SIZE, HASH_SIZE)) { + MEM_FREE(found_hash); + return FALSE; + } + + MEM_FREE(found_hash); + return TRUE; +} + +INIT_IFACE(Class, authStorageCtor, authStorageDtor, NULL); +INIT_IFACE(Auth, authStorageAuthenticate); +CREATE_CLASS(AuthLdap, NULL, IFACE(Class), IFACE(Auth)); + +// vim: set ts=4 sw=4: diff --git a/src/storage/put.c b/src/storage/put.c index f6d8079..c992e4f 100644 --- a/src/storage/put.c +++ b/src/storage/put.c @@ -29,13 +29,32 @@ #include "utils/memory.h" -void +typedef enum e_StoragePutResults { + SPR_OK = 0, + SPR_READ_ONLY = 1, + SPR_EXISTS = 2, + SPR_UNKNOWN = -1 +} StoragePutResult; + + +StoragePutResult storagePut(Storage this, char * _key, size_t nkey, char * data, size_t ndata) { datum key = {_key, nkey}; datum value = {data, ndata}; - gdbm_store(this->gdbm, key, value, GDBM_REPLACE); + switch (gdbm_store(this->gdbm, key, value, GDBM_INSERT)) { + case 0: + return SPR_OK; + case 1: + return SPR_EXISTS; + case -1: + return SPR_READ_ONLY; + default: + return SPR_UNKNOWN; + } + + return SPR_UNKNOWN; } // vim: set ts=4 sw=4: diff --git a/src/storage/update.c b/src/storage/update.c new file mode 100644 index 0000000..a48ef96 --- /dev/null +++ b/src/storage/update.c @@ -0,0 +1,50 @@ +/** + * \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 . + */ + +#include +#include +#include + +#include "storage.h" +#include "class.h" + +#include "utils/memory.h" + +StoragePutResult +storagePut(Storage this, char * _key, size_t nkey, char * data, size_t ndata) +{ + datum key = {_key, nkey}; + datum value = {data, ndata}; + + switch (gdbm_store(this->gdbm, key, value, GDBM_REPLACE)) { + case 0: + return SPR_OK; + case -1: + return SPR_READ_ONLY; + default: + return SPR_UNKNOWN; + } + + return SPR_UNKNOWN; +} + +// vim: set ts=4 sw=4: diff --git a/src/user/save.c b/src/user/save.c index 17e546f..acb268f 100644 --- a/src/user/save.c +++ b/src/user/save.c @@ -39,7 +39,10 @@ userSave(User this, Storage storage) *this->nsurname + 1 + 3 * sizeof(size_t); - storagePut( + /* + * @TODO user return value for error handling + */ + storageUpdate( storage, this->email, *this->nemail, this->email, storage_size); diff --git a/src/utils/hash.c b/src/utils/hash.c index ea46085..aef07bc 100644 --- a/src/utils/hash.c +++ b/src/utils/hash.c @@ -24,6 +24,8 @@ #include #include +#include + #include "utils/hash.h" /** @@ -50,4 +52,21 @@ sdbm(const unsigned char * str, size_t len) return hash; } + +/* + * this will use openssl to hash a given password with a given salt. + * If salt is NULL a random salt is generated and returned in salt. + * The memory for this is allocated via memMalloc and has to be freed + * by the caller via MEM_FREE. + * The size of the salt is always SALT_SIZE and that of hash is always + * hash size. Both are defined in auth/storage.h + */ +int +hash_pw( + const char * password, + const size_t npassword, + unsigned char * pw_hash, + unsigned char ** salt) +{ +} // vim: set ts=4 sw=4: From 15710de35535d6d6e9f222f1e686442c41c3d4a6 Mon Sep 17 00:00:00 2001 From: Georg Hopp Date: Sun, 22 Sep 2013 09:19:17 +0100 Subject: [PATCH 11/17] removed signup from auth adapter as signup is no auth at all. --- src/auth/storage/signup.c | 53 --------------------------------------- 1 file changed, 53 deletions(-) delete mode 100644 src/auth/storage/signup.c diff --git a/src/auth/storage/signup.c b/src/auth/storage/signup.c deleted file mode 100644 index 2db9efb..0000000 --- a/src/auth/storage/signup.c +++ /dev/null @@ -1,53 +0,0 @@ -/** - * \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 . - */ - -#include - -#include "class.h" -#include "storage.h" -#include "auth/storage.h" -#include "auth/credential.h" - -int -authStorageSignup(AuthStorage this, Credential cred) -{ - unsigned char hash[SALT_SIZE+HASH_SIZE]; - - if (FALSE == hash_pw( - CRED_PWD(cred).pass, - CRED_PWD(cred).npass, - &hash, - &(hash+SALT_SIZE))) { - return 0; - } - - storagePut( - this->store, - CRED_PWD(cred).user, - CRED_PWD(cred).nuser, - hash, - SALT_SIZE + HASH_SIZE); - - return 1; -} - -// vim: set ts=4 sw=4: From 575f27dabcbd89351ccffe4a05c274a91c8fcc8a Mon Sep 17 00:00:00 2001 From: Georg Hopp Date: Sun, 22 Sep 2013 12:14:45 +0100 Subject: [PATCH 12/17] everything builds again --- include/auth/storage.h | 2 ++ src/Makefile.am | 2 +- src/application/Makefile.am | 1 + src/application/adapter/http/update.c | 2 +- src/application/application.c | 2 +- src/application/signup.c | 12 +++++++----- src/auth/Makefile.am | 6 +++++- src/auth/storage/hash_pw.c | 5 +++-- src/auth/storage/storage.c | 6 +++--- src/storage/Makefile.am | 2 +- src/storage/put.c | 7 ------- src/storage/update.c | 7 ++++++- 12 files changed, 31 insertions(+), 23 deletions(-) diff --git a/include/auth/storage.h b/include/auth/storage.h index 5409f36..26501da 100644 --- a/include/auth/storage.h +++ b/include/auth/storage.h @@ -28,6 +28,8 @@ #include #include "class.h" +#include // storage must move to storage/storage.h + // to be loadable with " #define SALT_SIZE 32 diff --git a/src/Makefile.am b/src/Makefile.am index d1cced4..b0ee584 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -33,7 +33,7 @@ AM_CFLAGS = -Wall -I ../include/ bin_PROGRAMS = taskrambler taskrambler_SOURCES = taskrambler.c $(IFACE) $(UTILS) -taskrambler_CFLAGS = $(CFLAGS) -Wall -DPWD=\"$(PWD)\" -I ../include/# $(COVERAGE_CFLAGS) +taskrambler_CFLAGS = $(CFLAGS) -Wall -DPWD=\"$(PWD)\" -I../include/ # $(COVERAGE_CFLAGS) taskrambler_LDADD = $(LIBS) -lrt -lssl -lldap -lgdbm -luuid #taskrambler_LDFLAGS = $(COVERAGE_LDFLAGS) diff --git a/src/application/Makefile.am b/src/application/Makefile.am index 9e9f036..c901a6e 100644 --- a/src/application/Makefile.am +++ b/src/application/Makefile.am @@ -3,6 +3,7 @@ AUTOMAKE_OPTIONS = subdir-objects APPLICATION = application.c \ login.c \ + signup.c \ session_start.c \ session_stop.c \ session_update.c \ diff --git a/src/application/adapter/http/update.c b/src/application/adapter/http/update.c index a78b28a..01eb375 100644 --- a/src/application/adapter/http/update.c +++ b/src/application/adapter/http/update.c @@ -217,7 +217,7 @@ signupAdapter(Application application, HttpWorker worker, Session session) (char *)(surname->value), surname->nvalue); if (! applicationSignup(application, credential, user, session)) { - worker->current_response = httpResonse500(); + worker->current_response = httpResponse500(); } else { loginAdapter(application, worker, session); } diff --git a/src/application/application.c b/src/application/application.c index ffa1d7c..d038370 100644 --- a/src/application/application.c +++ b/src/application/application.c @@ -57,7 +57,7 @@ applicationCtor(void * _this, va_list * params) * password database. */ this->users = new(Storage, "./run/users.db"); - this->passwords = new(Storage, "./run/passwords.db") + this->passwords = new(Storage, "./run/passwords.db"); return 0; } diff --git a/src/application/signup.c b/src/application/signup.c index acd6b0c..8e3afe3 100644 --- a/src/application/signup.c +++ b/src/application/signup.c @@ -36,11 +36,13 @@ int applicationSignup( Application this, - Credential credential, + Credential cred, User user, Session session) { - unsigned char hash[SALT_SIZE+HASH_SIZE]; + unsigned char hash_data[SALT_SIZE+HASH_SIZE]; + unsigned char * salt = hash_data; + unsigned char * hash = hash_data + SALT_SIZE; if (NULL != userLoad(user, this->users)) { /* @@ -56,8 +58,8 @@ applicationSignup( if (FALSE == hash_pw( CRED_PWD(cred).pass, CRED_PWD(cred).npass, - &hash, - &(hash+SALT_SIZE))) { + hash, + &salt)) { /* * @TODO if we come here we have to delete the previously saved * user again... @@ -69,7 +71,7 @@ applicationSignup( this->passwords, CRED_PWD(cred).user, CRED_PWD(cred).nuser, - hash, + (char *)hash_data, SALT_SIZE + HASH_SIZE); return 0; diff --git a/src/auth/Makefile.am b/src/auth/Makefile.am index 3233da7..6a8c9d0 100644 --- a/src/auth/Makefile.am +++ b/src/auth/Makefile.am @@ -3,5 +3,9 @@ AUTOMAKE_OPTIONS = subdir-objects noinst_LIBRARIES = libauth.a -libauth_a_SOURCES = interface/auth.c credential.c ldap.c +libauth_a_SOURCES = interface/auth.c \ + credential.c \ + ldap.c \ + storage/storage.c \ + storage/hash_pw.c libauth_a_CFLAGS = $(CFLAGS) -Wall -I ../../include/ diff --git a/src/auth/storage/hash_pw.c b/src/auth/storage/hash_pw.c index 93228f3..9614630 100644 --- a/src/auth/storage/hash_pw.c +++ b/src/auth/storage/hash_pw.c @@ -26,8 +26,9 @@ #include #include "class.h" -#include "storage.h" +#include "auth/storage.h" #include "utils/memory.h" +#include "commons.h" /* * I have to hash the passwords, maybe this will move in @@ -78,7 +79,7 @@ hash_pw( { if (NULL == *salt) { *salt = memMalloc(SALT_SIZE * sizeof(unsigned char)); - if (0 > RAND_pseudo_bytes(unsigned char *buf, int num)) { + if (0 > RAND_pseudo_bytes(*salt, SALT_SIZE)) { MEM_FREE(*salt); return FALSE; } diff --git a/src/auth/storage/storage.c b/src/auth/storage/storage.c index 5aa8e47..86373d3 100644 --- a/src/auth/storage/storage.c +++ b/src/auth/storage/storage.c @@ -22,9 +22,9 @@ #include "class.h" #include "storage.h" -#include "auth/storage.h" -#include "auth/credential.h" +#include "auth.h" #include "commons.h" +#include "utils/memory.h" static int @@ -61,7 +61,7 @@ authStorageAuthenticate(void * _this, Credential cred) this->store, CRED_PWD(cred).user, CRED_PWD(cred).nuser, - &found_hash, + (char **)&found_hash, &nfound_hash); if (NULL == found_hash || (SALT_SIZE + HASH_SIZE) != nfound_hash) { diff --git a/src/storage/Makefile.am b/src/storage/Makefile.am index 3e6aeb0..b6ea977 100644 --- a/src/storage/Makefile.am +++ b/src/storage/Makefile.am @@ -3,5 +3,5 @@ AUTOMAKE_OPTIONS = subdir-objects noinst_LIBRARIES = libstorage.a -libstorage_a_SOURCES = storage.c get.c put.c +libstorage_a_SOURCES = storage.c get.c put.c update.c libstorage_a_CFLAGS = $(CFLAGS) -Wall -I ../../include/ diff --git a/src/storage/put.c b/src/storage/put.c index c992e4f..387fa58 100644 --- a/src/storage/put.c +++ b/src/storage/put.c @@ -29,13 +29,6 @@ #include "utils/memory.h" -typedef enum e_StoragePutResults { - SPR_OK = 0, - SPR_READ_ONLY = 1, - SPR_EXISTS = 2, - SPR_UNKNOWN = -1 -} StoragePutResult; - StoragePutResult storagePut(Storage this, char * _key, size_t nkey, char * data, size_t ndata) diff --git a/src/storage/update.c b/src/storage/update.c index a48ef96..3cbaeb2 100644 --- a/src/storage/update.c +++ b/src/storage/update.c @@ -30,7 +30,12 @@ #include "utils/memory.h" StoragePutResult -storagePut(Storage this, char * _key, size_t nkey, char * data, size_t ndata) +storageUpdate( + Storage this, + char * _key, + size_t nkey, + char * data, + size_t ndata) { datum key = {_key, nkey}; datum value = {data, ndata}; From 9cd89f97cf4cb6051aba422c17747433c72967ac Mon Sep 17 00:00:00 2001 From: Georg Hopp Date: Sun, 22 Sep 2013 14:23:40 +0100 Subject: [PATCH 13/17] now signup and login with storage of a hashed password works. --- include/application/application.h | 2 +- include/auth/storage.h | 3 +-- include/{ => storage}/storage.h | 0 include/user.h | 2 +- signuptest.html | 32 +++++++++++++++++++++++++++ src/application/adapter/http/update.c | 6 ++--- src/application/application.c | 24 +++++++++----------- src/application/signup.c | 8 +++++-- src/auth/storage/storage.c | 4 ++-- src/storage/get.c | 2 +- src/storage/put.c | 2 +- src/storage/storage.c | 2 +- src/storage/update.c | 2 +- src/taskrambler.c | 32 ++++++++++++++++++++++----- src/user/load.c | 2 +- src/user/save.c | 2 +- src/user/user.c | 2 +- src/utils/hash.c | 17 -------------- 18 files changed, 91 insertions(+), 53 deletions(-) rename include/{ => storage}/storage.h (100%) create mode 100644 signuptest.html diff --git a/include/application/application.h b/include/application/application.h index 8a89c10..12ea3a2 100644 --- a/include/application/application.h +++ b/include/application/application.h @@ -29,7 +29,7 @@ #include "session.h" #include "queue.h" #include "auth/credential.h" -#include "storage.h" +#include "storage/storage.h" #include "session.h" #include "user.h" diff --git a/include/auth/storage.h b/include/auth/storage.h index 26501da..7fb6d24 100644 --- a/include/auth/storage.h +++ b/include/auth/storage.h @@ -28,8 +28,7 @@ #include #include "class.h" -#include // storage must move to storage/storage.h - // to be loadable with " +#include "storage/storage.h" #define SALT_SIZE 32 diff --git a/include/storage.h b/include/storage/storage.h similarity index 100% rename from include/storage.h rename to include/storage/storage.h diff --git a/include/user.h b/include/user.h index 8aa7c62..147677e 100644 --- a/include/user.h +++ b/include/user.h @@ -26,7 +26,7 @@ #include #include "class.h" -#include "storage.h" +#include "storage/storage.h" CLASS(User) { diff --git a/signuptest.html b/signuptest.html new file mode 100644 index 0000000..2b0ddc5 --- /dev/null +++ b/signuptest.html @@ -0,0 +1,32 @@ + + + + + + Signuptest + + + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ +
+ + + + diff --git a/src/application/adapter/http/update.c b/src/application/adapter/http/update.c index 01eb375..b0c872f 100644 --- a/src/application/adapter/http/update.c +++ b/src/application/adapter/http/update.c @@ -195,14 +195,14 @@ signupAdapter(Application application, HttpWorker worker, Session session) NULL == firstname || NULL == surname) { // maybe this is not a 500...have to check repsonse codes. - worker->current_response = httpResponse500(); + worker->current_response = (HttpMessage)httpResponse500(); return; } if (password->nvalue != pwrepeat->nvalue || 0 != memcmp(password->value, pwrepeat->value, password->nvalue)) { // maybe this is not a 500...have to check repsonse codes. - worker->current_response = httpResponse500(); + worker->current_response = (HttpMessage)httpResponse500(); return; } @@ -217,7 +217,7 @@ signupAdapter(Application application, HttpWorker worker, Session session) (char *)(surname->value), surname->nvalue); if (! applicationSignup(application, credential, user, session)) { - worker->current_response = httpResponse500(); + worker->current_response = (HttpMessage)httpResponse500(); } else { loginAdapter(application, worker, session); } diff --git a/src/application/application.c b/src/application/application.c index d038370..e7c469e 100644 --- a/src/application/application.c +++ b/src/application/application.c @@ -27,7 +27,7 @@ #include "class.h" #include "queue.h" #include "application/application.h" -#include "storage.h" +#include "storage/storage.h" #include "utils/memory.h" @@ -40,6 +40,16 @@ applicationCtor(void * _this, va_list * params) this->val = va_arg(*params, struct randval *); + /* + * @TODO for both of these...each user should be identified + * by a number...that way I could use that number in the + * passwords db and no direct association between email and + * password could be made when someone get the hands on the + * password database. + */ + this->users = va_arg(*params, Storage); + this->passwords = va_arg(*params, Storage); + // initialize authenticators to use. this->nauth = va_arg(*params, size_t); this->auth = memMalloc(this->nauth * sizeof(void*)); @@ -49,16 +59,6 @@ applicationCtor(void * _this, va_list * params) this->active_sessions = new(Queue); - /* - * @TODO for both of these...each user should be identified - * by a number...that way I could use that number in the - * passwords db and no direct association between email and - * password could be made when someone get the hands on the - * password database. - */ - this->users = new(Storage, "./run/users.db"); - this->passwords = new(Storage, "./run/passwords.db"); - return 0; } @@ -69,8 +69,6 @@ applicationDtor(void * _this) Application this = _this; size_t i; - delete(this->passwords); - delete(this->users); delete(this->active_sessions); for (i=0; inauth; i++) { diff --git a/src/application/signup.c b/src/application/signup.c index 8e3afe3..e4347b5 100644 --- a/src/application/signup.c +++ b/src/application/signup.c @@ -41,8 +41,8 @@ applicationSignup( Session session) { unsigned char hash_data[SALT_SIZE+HASH_SIZE]; - unsigned char * salt = hash_data; - unsigned char * hash = hash_data + SALT_SIZE; + unsigned char * salt = NULL; + unsigned char * hash = hash_data+SALT_SIZE; if (NULL != userLoad(user, this->users)) { /* @@ -67,6 +67,10 @@ applicationSignup( return 0; } + memcpy(hash_data, salt, SALT_SIZE); + + MEM_FREE(salt); + storagePut( this->passwords, CRED_PWD(cred).user, diff --git a/src/auth/storage/storage.c b/src/auth/storage/storage.c index 86373d3..f8eef61 100644 --- a/src/auth/storage/storage.c +++ b/src/auth/storage/storage.c @@ -21,7 +21,7 @@ */ #include "class.h" -#include "storage.h" +#include "storage/storage.h" #include "auth.h" #include "commons.h" #include "utils/memory.h" @@ -90,6 +90,6 @@ authStorageAuthenticate(void * _this, Credential cred) INIT_IFACE(Class, authStorageCtor, authStorageDtor, NULL); INIT_IFACE(Auth, authStorageAuthenticate); -CREATE_CLASS(AuthLdap, NULL, IFACE(Class), IFACE(Auth)); +CREATE_CLASS(AuthStorage, NULL, IFACE(Class), IFACE(Auth)); // vim: set ts=4 sw=4: diff --git a/src/storage/get.c b/src/storage/get.c index 39aba82..0053a2e 100644 --- a/src/storage/get.c +++ b/src/storage/get.c @@ -25,8 +25,8 @@ #include #include -#include "storage.h" #include "class.h" +#include "storage/storage.h" #include "utils/memory.h" diff --git a/src/storage/put.c b/src/storage/put.c index 387fa58..d902a51 100644 --- a/src/storage/put.c +++ b/src/storage/put.c @@ -24,8 +24,8 @@ #include #include -#include "storage.h" #include "class.h" +#include "storage/storage.h" #include "utils/memory.h" diff --git a/src/storage/storage.c b/src/storage/storage.c index c275793..efb372e 100644 --- a/src/storage/storage.c +++ b/src/storage/storage.c @@ -24,8 +24,8 @@ #include #include -#include "storage.h" #include "class.h" +#include "storage/storage.h" #include "utils/memory.h" diff --git a/src/storage/update.c b/src/storage/update.c index 3cbaeb2..283171e 100644 --- a/src/storage/update.c +++ b/src/storage/update.c @@ -24,8 +24,8 @@ #include #include -#include "storage.h" #include "class.h" +#include "storage/storage.h" #include "utils/memory.h" diff --git a/src/taskrambler.c b/src/taskrambler.c index c0eada7..27722e5 100644 --- a/src/taskrambler.c +++ b/src/taskrambler.c @@ -140,7 +140,10 @@ main() default: { - AuthLdap ldap; + Storage users; + Storage passwords; + AuthLdap authLdap; + AuthStorage authStorage; Application application; ApplicationAdapterHttp adapterHttp; HttpWorker worker; @@ -154,12 +157,27 @@ main() logger = new(LoggerSyslog, LOGGER_DEBUG); - worker = new(HttpWorker, "testserver"); - ldap = new( - AuthLdap, "ldap://hosted/", CSTRA(LDAP_BASE)); - application = new(Application, value, 1, ldap); + authLdap = new( + AuthLdap, + "ldap://hosted/", + CSTRA(LDAP_BASE)); + + users = new(Storage, "./run/users.db"); + passwords = new(Storage, "./run/passwords.db"); + authStorage = new(AuthStorage, passwords); + + application = new( + Application, + value, + users, + passwords, + 2, + authLdap, + authStorage); adapterHttp = new(ApplicationAdapterHttp, application); + + worker = new(HttpWorker, "testserver"); subjectAttach(worker, adapterHttp); server = new(Server, logger, worker, 11212, SOMAXCONN); @@ -210,6 +228,10 @@ main() delete(worker); delete(adapterHttp); delete(application); + delete(authStorage); + delete(passwords); + delete(users); + delete(authLdap); delete(logger); clearMimeTypes(); diff --git a/src/user/load.c b/src/user/load.c index ed6547f..614dd29 100644 --- a/src/user/load.c +++ b/src/user/load.c @@ -24,7 +24,7 @@ #include #include "user.h" -#include "storage.h" +#include "storage/storage.h" #include "class.h" #include "utils/memory.h" diff --git a/src/user/save.c b/src/user/save.c index acb268f..5f7a505 100644 --- a/src/user/save.c +++ b/src/user/save.c @@ -24,7 +24,7 @@ #include #include "user.h" -#include "storage.h" +#include "storage/storage.h" #include "class.h" #include "utils/memory.h" diff --git a/src/user/user.c b/src/user/user.c index 1dac923..db77a10 100644 --- a/src/user/user.c +++ b/src/user/user.c @@ -21,7 +21,7 @@ */ #include "user.h" -#include "storage.h" +#include "storage/storage.h" #include "class.h" #include "utils/memory.h" diff --git a/src/utils/hash.c b/src/utils/hash.c index aef07bc..448b4fb 100644 --- a/src/utils/hash.c +++ b/src/utils/hash.c @@ -52,21 +52,4 @@ sdbm(const unsigned char * str, size_t len) return hash; } - -/* - * this will use openssl to hash a given password with a given salt. - * If salt is NULL a random salt is generated and returned in salt. - * The memory for this is allocated via memMalloc and has to be freed - * by the caller via MEM_FREE. - * The size of the salt is always SALT_SIZE and that of hash is always - * hash size. Both are defined in auth/storage.h - */ -int -hash_pw( - const char * password, - const size_t npassword, - unsigned char * pw_hash, - unsigned char ** salt) -{ -} // vim: set ts=4 sw=4: From 42f7ad74009e240c89775d8b977b3750fd5d3c30 Mon Sep 17 00:00:00 2001 From: Georg Hopp Date: Sun, 22 Sep 2013 18:57:10 +0100 Subject: [PATCH 14/17] login via ldap and gdbm now works. Signup stores the user account as well as the credentials but still returns a 500 and I have a memory leak most likely within the queue code. To reproduce this one has to start the server and send two requests via telnet to the server...no keep-alive just a single GET. refs #36 --- assets/js/session.js | 9 ++++++++- src/application/adapter/http/update.c | 1 + src/application/application.c | 4 ---- src/application/login.c | 6 +----- src/auth/ldap.c | 3 ++- src/http/response.c | 2 +- src/queue/get.c | 4 ++-- src/session/session.c | 5 ++++- src/storage/storage.c | 5 ++++- 9 files changed, 23 insertions(+), 16 deletions(-) diff --git a/assets/js/session.js b/assets/js/session.js index 9e3e8be..248b047 100644 --- a/assets/js/session.js +++ b/assets/js/session.js @@ -28,8 +28,15 @@ Session.prototype.loadJSON = function(data) this.firstname = data.firstname; this.surname = data.surname; + name = " "; + this.eSid.empty().append(this.id); - $("#main p:eq(1) span:eq(0)").empty().append(" " + this.firstname + " " + this.surname); + if ('(null)' == this.firstname || '(null)' == this.surname) { + name += this.email; + } else { + name += this.firstname + " " + this.surname; + } + $("#main p:eq(1) span:eq(0)").empty().append(name); this.draw(); if (0 < this.timeleft) diff --git a/src/application/adapter/http/update.c b/src/application/adapter/http/update.c index b0c872f..2b6f967 100644 --- a/src/application/adapter/http/update.c +++ b/src/application/adapter/http/update.c @@ -223,6 +223,7 @@ signupAdapter(Application application, HttpWorker worker, Session session) } delete(credential); + delete(user); } diff --git a/src/application/application.c b/src/application/application.c index e7c469e..755210f 100644 --- a/src/application/application.c +++ b/src/application/application.c @@ -71,10 +71,6 @@ applicationDtor(void * _this) delete(this->active_sessions); - for (i=0; inauth; i++) { - delete(this->auth[i]); - } - MEM_FREE(this->auth); } diff --git a/src/application/login.c b/src/application/login.c index 627c2b7..9cc2c28 100644 --- a/src/application/login.c +++ b/src/application/login.c @@ -50,11 +50,7 @@ applicationLogin( session->user->email = CRED_PWD(credential).user; session->user->nemail = &CRED_PWD(credential).nuser; - if (NULL == userLoad(session->user, this->users)) { - session->user->email = NULL; - session->user->nemail = NULL; - } - + userLoad(session->user, this->users); break; default: diff --git a/src/auth/ldap.c b/src/auth/ldap.c index c5975d6..c1e98c4 100644 --- a/src/auth/ldap.c +++ b/src/auth/ldap.c @@ -111,7 +111,8 @@ authLdapAuthenticate(void * _this, Credential cred) return TRUE; } - fprintf(stderr, "%s\n", ldap_err2string(ldap_err)); + //fprintf(stderr, "%s\n", ldap_err2string(ldap_err)); + // @TODO do error logging instead. return FALSE; } diff --git a/src/http/response.c b/src/http/response.c index 9a14315..b950c11 100644 --- a/src/http/response.c +++ b/src/http/response.c @@ -45,7 +45,7 @@ httpResponseCtor(void * _this, va_list * params) this->status = va_arg(* params, unsigned int); reason = va_arg(* params, char *); - this->reason = memCalloc(1, strlen(reason)+1); + this->reason = memCalloc(1, strlen(reason)+1); strcpy(this->reason, reason); return 0; diff --git a/src/queue/get.c b/src/queue/get.c index 20ca7f0..fdbf41e 100644 --- a/src/queue/get.c +++ b/src/queue/get.c @@ -26,8 +26,8 @@ void * queueGet(Queue this) { - Queue first; - void * msg; + Queue first; + void * msg; if (NULL == this->first) { return NULL; diff --git a/src/session/session.c b/src/session/session.c index ff46cc2..aeca7d1 100644 --- a/src/session/session.c +++ b/src/session/session.c @@ -40,7 +40,7 @@ static int sessionCtor(void * _this, va_list * params) { - Session this = _this; + Session this = _this; uuid_t uuid; this->livetime = time(NULL) + SESSION_LIVETIME; @@ -56,6 +56,9 @@ static void sessionDtor(void * _this) { + Session this = _this; + + delete(this->user); } static diff --git a/src/storage/storage.c b/src/storage/storage.c index efb372e..9e8df6a 100644 --- a/src/storage/storage.c +++ b/src/storage/storage.c @@ -60,7 +60,10 @@ storageDtor(void * _this) Storage this = _this; if (NULL != this->db_name) MEM_FREE(this->db_name); - if (NULL != this->gdbm) gdbm_close(this->gdbm); + if (NULL != this->gdbm) { + gdbm_close(this->gdbm); + this->gdbm = NULL; + } } INIT_IFACE(Class, storageCtor, storageDtor, NULL); From 8ddb362e1de9614f3643a42e806979f08a14eb4c Mon Sep 17 00:00:00 2001 From: Georg Hopp Date: Sun, 22 Sep 2013 18:57:59 +0100 Subject: [PATCH 15/17] add some valgrind suppressions for opanldap and gdbm stuff --- tests/Makefile.am | 6 ++++- tests/suppress/external.supp | 45 ++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 tests/suppress/external.supp diff --git a/tests/Makefile.am b/tests/Makefile.am index f3033e7..141b5ed 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,7 +1,11 @@ ACLOCAL_AMFLAGS = -I m4 AUTOMAKE_OPTIONS = subdir-objects -TESTS_ENVIRONMENT = valgrind --error-exitcode=123 --leak-check=full --quiet +TESTS_ENVIRONMENT = valgrind \ + --error-exitcode=123 \ + --leak-check=full \ + --suppressions=./suppress/external.supp \ + --quiet TESTS = classTest loggerTest socketTest serverTest check_PROGRAMS = classTest loggerTest socketTest serverTest diff --git a/tests/suppress/external.supp b/tests/suppress/external.supp new file mode 100644 index 0000000..c27e3e3 --- /dev/null +++ b/tests/suppress/external.supp @@ -0,0 +1,45 @@ +# +# This is a valgrind suppression file that should be used when using valgrind. +# +# See Misc/README.valgrind for more information. +{ + GDBM open on non existent file + Memcheck:Param + write(buf) + fun:__write_nocancel + fun:_gdbm_full_write + fun:gdbm_open + fun:storageCtor + fun:classNew + fun:main +} + +{ + GDBM close - to be honest I don't know what it complains about. + Memcheck:Param + msync(start) + fun:__msync_nocancel + fun:gdbm_close + fun:storageDtor + fun:classDelete + fun:main +} + +{ + Uninitialized bytes in openldap + Memcheck:Param + sendmsg(mmsg[0].msg_hdr) + fun:sendmmsg + fun:__libc_res_nsend + fun:__libc_res_nquery + fun:__libc_res_nquerydomain + fun:__libc_res_nsearch + fun:_nss_dns_gethostbyname4_r + fun:gaih_inet + fun:getaddrinfo + fun:ldap_connect_to_host + fun:ldap_int_open_connection + fun:ldap_new_connection + fun:ldap_open_defconn +} + From 79529475f1c46af1fca7babea202a66d65d627dd Mon Sep 17 00:00:00 2001 From: Georg Hopp Date: Thu, 26 Sep 2013 15:25:21 +0100 Subject: [PATCH 16/17] experiment with attributes --- .gitattributes | 1 + README | 2 ++ 2 files changed, 3 insertions(+) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..0425717 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +README ident diff --git a/README b/README index fa21666..a122cb3 100644 --- a/README +++ b/README @@ -1,3 +1,5 @@ +$Id$ + Actually this is some kind of server toolkit, also containing a class and interface toolkit for C. I use a gcc preprocessor extension to use empty variadoc From db22ebe7a125b6979549da53dbb74b28393707e1 Mon Sep 17 00:00:00 2001 From: Georg Hopp Date: Thu, 26 Sep 2013 23:13:51 +0100 Subject: [PATCH 17/17] fix wrong handling of session queue and thus the memory leak. --- include/queue.h | 2 ++ src/application/adapter/http/update.c | 28 ++++++++++++++++++++------- src/application/application.c | 1 - 3 files changed, 23 insertions(+), 8 deletions(-) diff --git a/include/queue.h b/include/queue.h index 1f16331..586bcc9 100644 --- a/include/queue.h +++ b/include/queue.h @@ -40,6 +40,8 @@ CLASS(Queue) { * first and last are only available in the initial queue * element (the root). This elelment does not contain any message * and exists only for organizational purpose. + * @TODO next and first always have to be the same...so get rid + * of first. */ Queue first; Queue last; diff --git a/src/application/adapter/http/update.c b/src/application/adapter/http/update.c index 2b6f967..47fa55e 100644 --- a/src/application/adapter/http/update.c +++ b/src/application/adapter/http/update.c @@ -62,8 +62,9 @@ static Session getSession(Queue sess_queue, const char * sid) { - Session sess = NULL; - time_t now = time(NULL); + Session sess = NULL; + Queue current = sess_queue; + time_t now = time(NULL); /** * session start or update @@ -95,12 +96,25 @@ getSession(Queue sess_queue, const char * sid) * remove expired sessions and pick out its own.... * this is O(n), but currently I gave no better idea at all. */ - while (NULL != sess_queue->next) { - Session session = (Session)sess_queue->next->msg; + while (NULL != current->next) { + Session session = (Session)current->next->msg; if (now >= session->livetime) { - Queue to_delete = sess_queue->next; - sess_queue->next = sess_queue->next->next; + Queue to_delete = current->next; + + if (to_delete == sess_queue->first) { + sess_queue->first = to_delete->next; + } + if (to_delete == sess_queue->last) { + if (to_delete == sess_queue->next) { + sess_queue->last = NULL; + } else { + sess_queue->last = current; + } + } + + current->next = to_delete->next; + delete(session); delete(to_delete); continue; @@ -111,7 +125,7 @@ getSession(Queue sess_queue, const char * sid) sess = session; } - sess_queue = sess_queue->next; + current = current->next; } if (NULL == sess) { diff --git a/src/application/application.c b/src/application/application.c index 755210f..911687c 100644 --- a/src/application/application.c +++ b/src/application/application.c @@ -67,7 +67,6 @@ void applicationDtor(void * _this) { Application this = _this; - size_t i; delete(this->active_sessions);