[pisa-src] r824 - in trunk: libpisa pairing

  • From: Jan Marten <jan.marten@xxxxxxxxxxxxxx>
  • To: pisa-src@xxxxxxxxxxxxx
  • Date: Wed, 19 Aug 2009 11:54:30 +0200

Author: marten
Date: Wed Aug 19 11:54:30 2009
New Revision: 824

Log:
Added management-tool to pairing
changed pairing to use libpisa for hitlist, etc.

Added:
   trunk/pairing/management.c   (contents, props changed)
   trunk/pairing/management.h
Modified:
   trunk/libpisa/config.c
   trunk/pairing/Makefile.am
   trunk/pairing/accept.c
   trunk/pairing/accept.h
   trunk/pairing/common.c
   trunk/pairing/common.h
   trunk/pairing/common_headers.c
   trunk/pairing/common_headers.h
   trunk/pairing/libconfig_wrapper.c
   trunk/pairing/libconfig_wrapper.h
   trunk/pairing/packet_handler_accept.c
   trunk/pairing/packet_handler_accept.h

Modified: trunk/libpisa/config.c
==============================================================================
--- trunk/libpisa/config.c      Tue Aug 18 15:21:27 2009        (r823)
+++ trunk/libpisa/config.c      Wed Aug 19 11:54:30 2009        (r824)
@@ -25,11 +25,11 @@
 /**
  * Setup the config module for work. Call this before any other
  * call to the config module happens, and call it only once until a
- * matching call to configCleanup was made.
+ * matching call to pisa_cfg_cleanup was made.
  * @param file Opened file from which the configuration shall be red
  * @return 1 -> Success
  * @return 0 -> Failure
- * @sa configCleanup
+ * @sa pisa_cfg_cleanup
  */
 int pisa_cfg_setup(FILE* file)
 {
@@ -50,13 +50,13 @@
 /**
  * Setup the config module for work. Call this before any other
  * call to the config module happens, and call it only once until a
- * matching call to configCleanup was made.
+ * matching call to pisa_cfg_cleanup was made.
  *
  * @param file full path to the config file which should be used
  * @return 1 -> Success
  * @return 0 -> Failure
  * @sa configSetup
- * @sa configCleanup
+ * @sa pisa_cfg_cleanup
  */
 int pisa_cfg_setup_file(const char* file)
 {
@@ -265,9 +265,9 @@
 
 /**
  * Cleanup config library. This call must always match calls to
- * configAuthorizedHostsSetup or configAuthorizedHostsSetupFile
- * @sa configAuthorizedHostsSetup
- * @sa configAuthorizedHostsSetupFile
+ * pisa_cfg_authorized_hosts_setup or pisa_cfg_authorized_hosts_setup_file
+ * @sa pisa_cfg_authorized_hosts_setup
+ * @sa pisa_cfg_authorized_hosts_setup_file
  */
 void pisa_cfg_authorized_hosts_cleanup(void)
 {
@@ -277,13 +277,13 @@
 /**
  * Setup the authorized hosts config module for work. Call this before any 
other
  * call to the authorized hosts config module happens, and call it only once 
until a
- * matching call to configAuthorizedHostsCleanup was made.
+ * matching call to pisa_cfg_authorized_hosts_cleanup was made.
  *
  * @param file full path to the config file which should be used
  * @return 1 -> Success
  * @return 0 -> Failure
- * @sa configAuthorizedHostsSetup
- * @sa configAuthorizedHostsCleanup
+ * @sa pisa_cfg_authorized_hosts_setup
+ * @sa pisa_cfg_authorized_hosts_cleanup
  */
 int pisa_cfg_authorized_hosts_setup_file(const char* file)
 {
@@ -306,11 +306,11 @@
 /**
  * Setup the authorized hosts config module for work. Call this before any 
other
  * call to the authorized hosts config module happens, and call it only once 
until a
- * matching call to configAuthorizedHostsCleanup was made.
+ * matching call to pisa_cfg_authorized_hosts_cleanup was made.
  * @param file Opened file from which the configuration shall be red
  * @return 1 -> Success
  * @return 0 -> Failure
- * @sa configAuthorizedHostsCleanup
+ * @sa pisa_cfg_authorized_hosts_cleanup
  */
 int pisa_cfg_authorized_hosts_setup(FILE* file)
 {
@@ -330,12 +330,12 @@
 
 /**
  * Save the changes made to the authorized hosts config. The authorized hosts 
- * config has to be set up with configAuthorizedHostsSetup or
- * configAuthorizedHostsSetupFile
+ * config has to be set up with pisa_cfg_authorized_hosts_setup or
+ * pisa_cfg_authorized_hosts_setup_file
  * @return 1 -> Success
  * @return 0 -> Failure
- * @sa configAuthorizedHostsSetup
- * @sa configAuthorizedHostsCleanup
+ * @sa pisa_cfg_authorized_hosts_setup
+ * @sa pisa_cfg_authorized_hosts_cleanup
  */
 int pisa_cfg_write_authorized_hosts_file(void)
 {

Modified: trunk/pairing/Makefile.am
==============================================================================
--- trunk/pairing/Makefile.am   Tue Aug 18 15:21:27 2009        (r823)
+++ trunk/pairing/Makefile.am   Wed Aug 19 11:54:30 2009        (r824)
@@ -11,15 +11,16 @@
 CFLAGS = -Wall -g -I$(top_srcdir)/libpisa/libconfig-1.3.2      # add -pedantic 
if you want it to worry about your commenting style (and other stuff)
 send_CFLAGS = -DSEND
 accept_CFLAGS = -DACCEPT
-bin_PROGRAMS = send accept passgen
+bin_PROGRAMS = send accept passgen management
 
 senddir = .
 acceptdir = .
 passgendir = .
+managementdir = .
 
 include_HEADERS = common_headers.h send.h common.h packet_handler.h hash.h 
libconfig_wrapper.h packet_handler_send.h create_send_headers.h
 include_HEADERS += hash.h accept.h common_headers.h packet_handler.h 
libconfig_wrapper.h common.h packet_handler_accept.h create_accept_headers.h
-include_HEADERS += hash.h
+include_HEADERS += hash.h management.h 
 
 EXTRA_DIST = readme.txt \
        defaults/authorized_hosts.cfg defaults/known_relays.cfg 
defaults/relay_config.cfg \
@@ -34,9 +35,9 @@
   LDFLAGS += -L$(top_srcdir)/libpisa/libconfig-1.3.2
 else
 if PISA_FORCE_SHLIBCONFIG
-  LDADD += -lconfig
+  LDADD += @PISA_LIBPISA_LIB_STATIC@ -lconfig
 else
-  LDADD += @PISA_LIBCONFIG_LIB_STATIC@
+  LDADD += @PISA_LIBPISA_LIB_STATIC@ @PISA_LIBCONFIG_LIB_STATIC@
 endif
 endif
 
@@ -47,3 +48,4 @@
 send_SOURCES = send.c common_headers.c common.c packet_handler.c hash.c 
libconfig_wrapper.c packet_handler_send.c create_send_headers.c
 accept_SOURCES = accept.c hash.c common_headers.c packet_handler.c 
libconfig_wrapper.c common.c packet_handler_accept.c create_accept_headers.c
 passgen_SOURCES = passgen.c hash.c
+management_SOURCES = management.c common.c common_headers.c libconfig_wrapper.c

Modified: trunk/pairing/accept.c
==============================================================================
--- trunk/pairing/accept.c      Tue Aug 18 15:21:27 2009        (r823)
+++ trunk/pairing/accept.c      Wed Aug 19 11:54:30 2009        (r824)
@@ -7,114 +7,186 @@
  * @file accept.c
  * @brief Main program of the pairing application.
  * @author Kate Harrison <harriska@xxxxxxxxxxxxx>
+ * @author Jan Marten <jan.marten@xxxxxxxxxxxxxx>
  * @date Sep. 2008
  */
 
+#include "global.h"    /* it must be included before all other header files */
+#include "config.h"
+#include "hitlist.h"
 #include "accept.h"
 
+extern config_t authorized_cfg;
+
 struct global_accept_variables global_accept = {0};
 
-/** Main program that will be run on the relay. 
+/** Main program that will be run on the relay.
  */
 int main(int argc, char *argv[])
 {
-       struct sockaddr_in6 peer_addr;
-       unsigned int addrlen;
-       header_general *gen_hdr = malloc(sizeof(header_general));
-       int chars_received;     // Number of characters received on the socket
-       char address_string[INET6_ADDRSTRLEN];  // Human-readable address of 
sender
-       int msg_type, return_value;
-
-       if (!open_socket_accept())
-       {
-               DEBUG("Socket could not be created. Leaving program.\n");
-               return 1;
-       }
-
-       addrlen = sizeof(struct sockaddr_in6);
-
-       while (1)
-       {
-               DEBUG_MED(LINE_BREAK LINE_BREAK);
-
-               // Receive message
-               DEBUG_MED("Waiting for incoming message...");
-               chars_received = recvfrom(global_accept.socket_desc, gen_hdr, 
sizeof(header_general), 0, (struct sockaddr *)&peer_addr, &addrlen);
-               DEBUG_MED("Bytes received: %d", chars_received);
-
-               if (chars_received > 0)
-               {
-
-
-                       // Get peer address, determine if it's a HIT
-                       inet_ntop(AF_INET6, &peer_addr.sin6_addr, 
address_string, sizeof(address_string));
-                       DEBUG("Address of sender is %s", address_string);
-                       if (!ipv6_addr_is_hit(&peer_addr.sin6_addr))
-                               DEBUG_HIGH("Address is IPv6.");
-                       else
-                       {
-                               DEBUG_HIGH("Address is a HIT!");
-
-                               // Handle the packet (and react accordingly)
-                               handle_packet(&peer_addr, gen_hdr, &msg_type, 
&return_value);
-
-                               print_msg_info(msg_type, return_value);
-                       }
-
-                       DEBUG_MED(LINE_BREAK LINE_BREAK);
-               }
-               else
-                       perror("receive");
+    struct sockaddr_in6 peer_addr;
+    unsigned int addrlen;
+    header_general *gen_hdr = malloc(sizeof(header_general));
+    int chars_received;        // Number of characters received on the socket
+    char address_string[INET6_ADDRSTRLEN];     // Human-readable address of 
sender
+    int msg_type, return_value;
+
+    if (!open_socket_accept())
+    {
+        DEBUG("Socket could not be created. Leaving program.\n");
+        return 1;
+    }
+
+    pisa_cfg_authorized_hosts_setup_file("authorized_hosts.cfg");
+
+    addrlen = sizeof(struct sockaddr_in6);
+
+    if (signal(SIGALRM, check_expiration_dates) == SIG_ERR)
+    {
+        DEBUG("Cannot register signal handler");
+    }
+    check_expiration_dates(SIGALRM);
+
+
+    while (1)
+    {
+        DEBUG_MED(LINE_BREAK LINE_BREAK);
+
+        // Receive message
+        DEBUG_MED("Waiting for incoming message...");
+        chars_received = recvfrom(global_accept.socket_desc, gen_hdr, 
sizeof(header_general), 0, (struct sockaddr *)&peer_addr, &addrlen);
+        DEBUG_MED("Bytes received: %d", chars_received);
+
+        if (chars_received > 0)
+        {
+
 
-       }
+            // Get peer address, determine if it's a HIT
+            inet_ntop(AF_INET6, &peer_addr.sin6_addr, address_string, 
sizeof(address_string));
+            DEBUG("Address of sender is %s", address_string);
+            if (!ipv6_addr_is_hit(&peer_addr.sin6_addr))
+                DEBUG_HIGH("Address is IPv6.");
+            else
+            {
+                DEBUG_HIGH("Address is a HIT!");
 
-       free(gen_hdr);
+                // Handle the packet (and react accordingly)
+                handle_packet(&peer_addr, gen_hdr, &msg_type, &return_value);
 
-       // Close the socket
-       close(global_accept.socket_desc);
+                print_msg_info(msg_type, return_value);
+            }
 
-       return 0;
+            DEBUG_MED(LINE_BREAK LINE_BREAK);
+        }
+        else
+            perror("receive");
+
+    }
+
+    free(gen_hdr);
+
+    pisa_cfg_authorized_hosts_cleanup();
+
+    // Close the socket
+    close(global_accept.socket_desc);
+
+    return 0;
 }
 
 
 
 int open_socket_accept(void)
 {
-       int optval=1;
-       struct sockaddr_in6 address;
+    int optval=1;
+    struct sockaddr_in6 address;
 
-       // Create socket
-       if ((global_accept.socket_desc=socket(PF_INET6, SOCK_DGRAM, 0))==0)
-       {
-               perror("Create socket");
-               return 0;
-       }
-       else
-               DEBUG_MED("Socket created");
-
-       if (setsockopt(global_accept.socket_desc, SOL_SOCKET, SO_REUSEADDR, 
&optval, sizeof(optval)) == -1)
-               DEBUG_MED("Error with setsockopt\n");
-       else
-               DEBUG_MED("Reusing address.");
-
-
-       // Create an IPv6 socket on which to listen
-       address.sin6_family = AF_INET6;
-       address.sin6_addr = in6addr_any;
-       address.sin6_port = htons(PORT);
-       DEBUG_MED("Parameters set.");
-
-
-       // Bind the socket to the port
-       if (bind(global_accept.socket_desc,(struct sockaddr 
*)&address,sizeof(address))<0)
-       {
-               perror("bind");
-               return 0;
-       }
-       else
-               DEBUG_MED("Bound to port %d", PORT);
+    // Create socket
+    if ((global_accept.socket_desc=socket(PF_INET6, SOCK_DGRAM, 0))==0)
+    {
+        perror("Create socket");
+        return 0;
+    }
+    else
+        DEBUG_MED("Socket created");
+
+    if (setsockopt(global_accept.socket_desc, SOL_SOCKET, SO_REUSEADDR, 
&optval, sizeof(optval)) == -1)
+        DEBUG_MED("Error with setsockopt\n");
+    else
+        DEBUG_MED("Reusing address.");
+
+
+    // Create an IPv6 socket on which to listen
+    address.sin6_family = AF_INET6;
+    address.sin6_addr = in6addr_any;
+    address.sin6_port = htons(PORT);
+    DEBUG_MED("Parameters set.");
+
+
+    // Bind the socket to the port
+    if (bind(global_accept.socket_desc,(struct sockaddr 
*)&address,sizeof(address))<0)
+    {
+        perror("bind");
+        return 0;
+    }
+    else
+        DEBUG_MED("Bound to port %d", PORT);
 
-       return 1;
+    return 1;
 }
 
+void check_expiration_dates(int signr)
+{
+
+    pisa_hitlist *hitlist_allowed_hosts;
+    pisa_hitlist_entry *entry;
+    int i,changes;
+    time_t now;
+    struct tm *ts;
+    char buffer [80];
+    char *name;
+
+    changes = 0;
+    DEBUG("Checking expiration dates...");
+
+    hitlist_allowed_hosts = pisa_hitlist_build("allowed_hosts");
+
+    time(&now);
+
+
+    for(i=0;i< hitlist_allowed_hosts->cur_slots;i++)
+    {
+        entry = &hitlist_allowed_hosts->entries[i];
+        if(difftime(now,entry->expiration)>0)
+        {
+            // Convert expiration date to readable format
+            ts = localtime(&entry->expiration);
+            strftime(buffer, sizeof(buffer), EXPIRATION_DATE_FORMAT, ts);
+
+            // Get HIT
+            config_setting_t *g=entry->group;
+            config_setting_t *parent= config_setting_parent(g);
+            name = (char 
*)config_setting_get_string(config_setting_get_member(g, "hit"));
+
+            DEBUG("HIT: %s",name);
+            DEBUG("With expiration date: %s expired.",buffer);
+            DEBUG("Removing HIT.");
+
+            if(config_setting_remove_elem(parent,config_setting_index(g)) != 
CONFIG_TRUE)
+            {
+                DEBUG("Error removing HIT");
+            }
+            changes = 1;
+        }
+    }
+
+    // Save changes
+    if (changes)
+    {
+        DEBUG("Saving changes to authorized hosts file.");
+        pisa_cfg_write_authorized_hosts_file();
+    }
+
+    pisa_hitlist_destroy(hitlist_allowed_hosts);
+    alarm(TIMER_INTERVAL);
+}
 

Modified: trunk/pairing/accept.h
==============================================================================
--- trunk/pairing/accept.h      Tue Aug 18 15:21:27 2009        (r823)
+++ trunk/pairing/accept.h      Wed Aug 19 11:54:30 2009        (r824)
@@ -7,6 +7,7 @@
  * @file accept.h
  * @brief Header file of the main program of the pairing application.
  * @author Kate Harrison <harriska@xxxxxxxxxxxxx>
+ * @author Jan Marten <jan.marten@xxxxxxxxxxxxxx>
  * @date Sep. 2008
  */
 
@@ -19,6 +20,7 @@
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <string.h>
+#include <signal.h>
 #include <openssl/sha.h>
 #include <openssl/rand.h>
 #include "hash.h"
@@ -40,7 +42,9 @@
 /** Default port is set statically **/
 #define PORT 7000
 
+#define TIMER_INTERVAL 60
+
 // Function prototypes
 int open_socket_accept();
-
+void check_expiration_dates(int signr);
 #endif /* PISA_PAIR_ACCEPT_H */

Modified: trunk/pairing/common.c
==============================================================================
--- trunk/pairing/common.c      Tue Aug 18 15:21:27 2009        (r823)
+++ trunk/pairing/common.c      Wed Aug 19 11:54:30 2009        (r824)
@@ -7,10 +7,21 @@
  * @file common.c
  * @brief Common modules used for the pairing application.
  * @author Kate Harrison <harriska@xxxxxxxxxxxxx>
+ * @author Jan Marten <jan.marten@xxxxxxxxxxxxxx>
  * @date Sep. 2008
  */
 
+
+#include "global.h"    /* it must be included before all other header files */
+
+#define __USE_XOPEN
+#include <time.h>
+
 #include "common.h"
+#include "config.h"
+#include "libconfig_wrapper.h"
+#include "common_headers.h"
+
 
 /** Checks to see if addr has only the characters allowed in an IPv6 address 
(or HIT).
  *
@@ -20,8 +31,8 @@
  */
 int valid_addr(char *addr)
 {
-       assert(addr != NULL);
-        return !(strspn(addr, "0123456789abcdefABCDEF:") < strlen(addr));
+    assert(addr != NULL);
+    return !(strspn(addr, "0123456789abcdefABCDEF:") < strlen(addr));
 }
 
 
@@ -156,3 +167,159 @@
 
 } 
 
+/**
+ * Reads default expiration from FILE_SERVER_CONFIG
+ *
+ * @param buffer Buffer for the expiration string
+ *
+ * @return 0 -> Failure
+ * @return 1 -> Success
+ */
+int get_default_expiration(char *buffer)
+{
+       return get_default_expiration_from_config(buffer,FILE_SERVER_CONFIG);
+}
+
+/**
+ * Reads default expiration from filename
+ *
+ * @param buffer Buffer for the expiration string
+ * @param filename The path to the relay_config file
+ *
+ * @return 0 -> Failure
+ * @return 1 -> Success
+ */
+int get_default_expiration_from_config(char *buffer,const char *filename)
+{
+    long int default_expiration_int;
+    int temp;
+
+    time_t expiration;
+
+    // Obtain the default expiration for a master-password-based connection 
(in minutes)
+    temp = get_config_setting((char *)filename, 
"connection_settings.default_connection_expiration",
+                              CONFIG_TYPE_INT, &default_expiration_int, 0);
+    if (temp == 0)  // Something failed in reading, debug printed by 
get_config_setting
+    {
+        DEBUG("User not remembered.");
+        return 0;
+    }
+    if (default_expiration_int == 0)
+    {
+        DEBUG("Could not read setting 
\'connection_settings.default_connection_expiration\' in file %s", filename);
+        DEBUG("User not remembered.");
+        return 0;
+    }
+
+    default_expiration_int *= 60;   // Convert to seconds
+
+    time(&expiration);
+    expiration += default_expiration_int;  // Add default expiration to 
current time
+
+
+    if(convert_time_t_to_formatted_string(&expiration,buffer)!=0)
+    {
+       return 1;
+    }else {
+       return 0;
+    }
+}
+
+
+/**
+ * Converts time_t time to EXPIRATION_DATE_FORMAT.
+ * @param time Pointer to the time_t time
+ * @param buffer Pointer to the buffer holding the formatted string
+ *
+ * @return 1 -> Success
+ * @return 0 -> Failure
+ */
+int convert_time_t_to_formatted_string(time_t *time,char *buffer)
+{
+       struct tm *ts;
+       size_t temp;
+    // Convert to format: dd-mm-yyyy hh:mm:ss
+    ts = localtime(time);
+    temp = strftime(buffer, LENGTH_TIMEOUT, EXPIRATION_DATE_FORMAT, ts);
+    return temp!=0;
+
+}
+
+int valid_date_string(const char *expiration_date,struct tm *tm_expiration)
+{
+    DEBUG_HIGH("Parsing date.");
+    char *c;
+    // Date format: dd-mm-yyyy hh:mm:ss (24 hour clock)
+    c = strptime(expiration_date, EXPIRATION_DATE_FORMAT, tm_expiration);
+    if ((c == NULL) || (*c != 0))    // If c does not point to the terminating 
character of the string
+    {               // then strptime did not make it all of the way through 
the string.
+        DEBUG("Could not parse time-and-date string.");
+        return 0;
+    }else
+    {
+        return 1;
+    }
+
+}
+
+
+/**
+ * Compares two time strings with the date format EXPIRATION_DATE_FORMAT
+ * and returns the difference in seconds.
+ *
+ * @param time1 The first time string
+ * @param time2 The second time string
+ *
+ * @return time2 - time1
+ */
+int compare_time_strings(const char *time1,const char *time2)
+{
+    struct tm tm_time1,tm_time2;
+    char *c;
+
+    // Date format: yyyy-mm-dd hh:mm:ss (24 hour clock)
+    c = strptime(time1, EXPIRATION_DATE_FORMAT, &tm_time1);
+    if ((c == NULL) || (*c != 0))    // If c does not point to the terminating 
character of the string
+    {               // then strptime did not make it all of the way through 
the string.
+        DEBUG("Could not parse time-and-date string.");
+        return 0;
+    }
+
+    // Date format: dd-mm-yyyy hh:mm:ss (24 hour clock)
+    c = strptime(time2, EXPIRATION_DATE_FORMAT, &tm_time2);
+    if ((c == NULL) || (*c != 0))    // If c does not point to the terminating 
character of the string
+    {               // then strptime did not make it all of the way through 
the string.
+        DEBUG("Could not parse time-and-date string.");
+        return 0;
+    }
+
+    return difftime(mktime(&tm_time1),mktime(&tm_time2));
+
+}
+
+/** Converts a date in human-readable format to its time in seconds.
+ *
+ *  @param expiration_date Pointer to the string containing the human-readable 
version.
+ *  @param expiration_seconds Pointer to the long int where the result should 
be stored.
+ *
+ *  @return 1 if successful; 0 if failed
+ */
+int get_expiration_time(char *expiration_date, long int *expiration_seconds)
+{
+    assert(expiration_date != NULL);
+    assert(expiration_seconds != NULL);
+
+    struct tm time_offset;
+
+    if(!valid_date_string(expiration_date,&time_offset))
+    {
+        return 0;
+    }
+
+    DEBUG_HIGH("You specified: %s",  asctime(&time_offset));
+
+    *expiration_seconds = (long int)mktime(&time_offset);
+    DEBUG_HIGH("Time in seconds: %ld", *expiration_seconds);
+
+    return 1;
+}

Modified: trunk/pairing/common.h
==============================================================================
--- trunk/pairing/common.h      Tue Aug 18 15:21:27 2009        (r823)
+++ trunk/pairing/common.h      Wed Aug 19 11:54:30 2009        (r824)
@@ -7,6 +7,7 @@
  * @file common.h
  * @brief Header file of common modules used for the pairing application.
  * @author Kate Harrison <harriska@xxxxxxxxxxxxx>
+ * @author Jan Marten <jan.marten@xxxxxxxxxxxxxx>
  * @date Sep. 2008
  */
 
@@ -19,6 +20,7 @@
 #include <arpa/inet.h>
 #include <stdio.h>
 #include <sys/types.h>
+#include <time.h>
 
 // For function ipv6_addr_is_hit
 typedef uint32_t hip_closest_prefix_type_t;
@@ -33,6 +35,12 @@
 int identical_hits(char *hit1, char *hit2);
 int ipv6_addr_is_hit(const struct in6_addr *hit);
 void itoa(int n, char s[]);
+int get_default_expiration(char *buffer);
+int get_default_expiration_from_config(char *buffer,const char *filename);
+int valid_date_string(const char *expiration_date,struct tm *tm_expiration);
+int compare_time_strings(const char *time1,const char *time2);
+int convert_time_t_to_formatted_string(time_t *time,char *buffer);
+int get_expiration_time(char *expiration_duration, long int 
*expiration_seconds);
 
 // Global variables
 /*extern int socket_desc;

Modified: trunk/pairing/common_headers.c
==============================================================================
--- trunk/pairing/common_headers.c      Tue Aug 18 15:21:27 2009        (r823)
+++ trunk/pairing/common_headers.c      Wed Aug 19 11:54:30 2009        (r824)
@@ -7,6 +7,7 @@
  * @file common_headers.c
  * @brief Common modules used for the pairing application.
  * @author Kate Harrison <harriska@xxxxxxxxxxxxx>
+ * @author Jan Marten <jan.marten@xxxxxxxxxxxxxx>
  * @date Sep. 2008
  */
 
@@ -54,66 +55,31 @@
  */
 void print_msg_info(int msg_type, int return_value)
 {
-       char msg_string[100];
+    char msg_string[100];
 
-       switch(msg_type)
-       {
-               case MSG_PASSWORD:
-                       strcpy(msg_string, "password");
-                       break;
-               case MSG_ACK_1:
-                       strcpy(msg_string, "ACK 1");
-                       break;
-               case MSG_PWD_REQUEST:
-                       strcpy(msg_string, "password request");
-                       break;
-               case MSG_ACK_2:
-                       strcpy(msg_string, "ACK 2");
-                       break;
-               case MSG_ERROR:
-                       strcpy(msg_string, "error");
-                       break;
-               default:
-                       strcpy(msg_string, "unknown");
-       }
-
-       DEBUG_MED("Message type: %s", msg_string);
-       DEBUG_MED("Return value: %d", return_value);
-
-       return;
-}
-
-
-/** Converts a date in human-readable format to its time in seconds.
- *
- *  @param expiration_date Pointer to the string containing the human-readable 
version.
- *  @param expiration_seconds Pointer to the long int where the result should 
be stored.
- *
- *  @return 1 if successful; 0 if failed
- */
-int get_expiration_time(char *expiration_date, long int *expiration_seconds)
-{
-        assert(expiration_date != NULL);
-        assert(expiration_seconds != NULL);
-
-        DEBUG_HIGH("Parsing date.");
+    switch(msg_type)
+    {
+    case MSG_PASSWORD:
+        strcpy(msg_string, "password");
+        break;
+    case MSG_ACK_1:
+        strcpy(msg_string, "ACK 1");
+        break;
+    case MSG_PWD_REQUEST:
+        strcpy(msg_string, "password request");
+        break;
+    case MSG_ACK_2:
+        strcpy(msg_string, "ACK 2");
+        break;
+    case MSG_ERROR:
+        strcpy(msg_string, "error");
+        break;
+    default:
+        strcpy(msg_string, "unknown");
+    }
 
-        char *c; 
-        struct tm time_offset;
+    DEBUG_MED("Message type: %s", msg_string);
+    DEBUG_MED("Return value: %d", return_value);
 
-        // Date format: dd-mm-yyyy hh:mm:ss (24 hour clock)
-        c = strptime((const char *)expiration_date, "%d-%m-%Y %H:%M:%S", 
&time_offset);
-        if ((c == NULL) || (*c != 0))    // If c does not point to the 
terminating character of the string
-        {               // then strptime did not make it all of the way 
through the string.
-                DEBUG("Could not parse time-and-date string.");
-                return 0;
-        }   
-
-        DEBUG_HIGH("You specified: %s",  asctime(&time_offset));
-
-        *expiration_seconds = (long int)mktime(&time_offset);
-        DEBUG_HIGH("Time in seconds: %ld", *expiration_seconds);
-
-       return 1;
+    return;
 }
-

Modified: trunk/pairing/common_headers.h
==============================================================================
--- trunk/pairing/common_headers.h      Tue Aug 18 15:21:27 2009        (r823)
+++ trunk/pairing/common_headers.h      Wed Aug 19 11:54:30 2009        (r824)
@@ -7,6 +7,7 @@
  * @file common_headers.h
  * @brief Header file of common modules used for the pairing application.
  * @author Kate Harrison <harriska@xxxxxxxxxxxxx>
+ * @author Jan Marten <jan.marten@xxxxxxxxxxxxxx>
  * @date Sep. 2008
  */
 
@@ -89,6 +90,5 @@
 // Function prototypes
 header_general* create_error_struct(int error_type, char *error_string);
 void print_msg_info(int msg_type, int return_value);
-int get_expiration_time(char *expiration_duration, long int 
*expiration_seconds);
 
 #endif /* PISA_PAIR_COMMON_HEADERS_H */

Modified: trunk/pairing/libconfig_wrapper.c
==============================================================================
--- trunk/pairing/libconfig_wrapper.c   Tue Aug 18 15:21:27 2009        (r823)
+++ trunk/pairing/libconfig_wrapper.c   Wed Aug 19 11:54:30 2009        (r824)
@@ -7,10 +7,18 @@
  * @file libconfig_wrapper.c
  * @brief wrapper functions calling libconfig
  * @author Kate Harrison <harriska@xxxxxxxxxxxxx>
+ * @author Jan Marten <jan.marten@xxxxxxxxxxxxxx>
  * @date Sep. 2008
  */
 
 #include "libconfig_wrapper.h"
+#include "config.h"
+#include "hitlist.h"
+#include "packet_handler_accept.h"
+#include "common.h"
+
+extern config_t authorized_cfg;
+extern char *authorized_cfg_file;
 
 /** @todo Add a function which periodically scans files containing expiration 
dates and removes expired entries **/
 
@@ -24,62 +32,44 @@
  */
 int write_config(char *info, char *expiration, configtype type)
 {
-       config_t cfg;
-       config_setting_t *root;
-
-       assert(info != NULL);
-       assert(expiration != NULL);
-
-       config_init(&cfg);
-       if (!config_read_file(&cfg, FILE_AUTHORIZED_HOSTS))
-       {
-               DEBUG("Could not read file \'%s\'.", FILE_AUTHORIZED_HOSTS);
-               return 0;
-       }
-
-       root = config_root_setting(&cfg);
-
-       switch(type)
-       {
-               case CONFIG_TYPE_HIT:
-               {
-                       write_hit(&cfg, root, info, expiration);
-                       break;
-               }
-               case CONFIG_TYPE_PWD:
-               {
-                       config_setting_t *allowed_passwords;
-                       config_setting_t *new_pwd_grp, *new_pwd, *new_expire;
-
-                       allowed_passwords = config_lookup(&cfg, 
"allowed_passwords");
-                       if (!allowed_passwords)
-                       {
-                               DEBUG_HIGH("List allowed_passwords did not 
previously exist. Creating...");
-                               allowed_passwords = config_setting_add(root, 
"allowed_passwords", CONFIG_TYPE_LIST);
-                       }
+    assert(info != NULL);
+    assert(expiration != NULL);
 
-                       // Add a new group
-                       new_pwd_grp = config_setting_add(allowed_passwords, 
NULL, CONFIG_TYPE_GROUP);
-                       // Add the password
-                       new_pwd = config_setting_add(new_pwd_grp, "password", 
CONFIG_TYPE_STRING);
-                       config_setting_set_string(new_pwd, info);
-                       // Add the expiration date
-                       new_expire = config_setting_add(new_pwd_grp, "expires", 
CONFIG_TYPE_STRING);
-                       config_setting_set_string(new_expire, expiration);
-
-                       break;
-               }
-               default:
-               {
-                       DEBUG("Invalid information type.");
-                       return 0;
-               }
-       }
+    switch(type)
+    {
+    case CONFIG_TYPE_HIT:
+        {
+            add_hit(info, expiration);
+            break;
+        }
+    case CONFIG_TYPE_PWD:
+        {
+            config_setting_t *allowed_passwords;
+            config_setting_t *new_pwd_grp, *new_pwd, *new_expire;
+
+            allowed_passwords = check_list("allowed_passwords");
+
+            // Add a new group
+            new_pwd_grp = config_setting_add(allowed_passwords, NULL, 
CONFIG_TYPE_GROUP);
+            // Add the password
+            new_pwd = config_setting_add(new_pwd_grp, "password", 
CONFIG_TYPE_STRING);
+            config_setting_set_string(new_pwd, info);
+            // Add the expiration date
+            new_expire = config_setting_add(new_pwd_grp, "expires", 
CONFIG_TYPE_STRING);
+            config_setting_set_string(new_expire, expiration);
+
+            break;
+        }
+    default:
+        {
+            DEBUG("Invalid information type.");
+            return 0;
+        }
+    }
 
-       config_write_file(&cfg, FILE_AUTHORIZED_HOSTS);
-       config_destroy(&cfg);
+    pisa_cfg_write_authorized_hosts_file();
 
-       return 1;
+    return 1;
 }
 
 
@@ -149,97 +139,159 @@
        return 1;
 }
 
-/** Writes a HIT in the file VALID_HITS_FILE. If an entry already exists, it 
updates
+/** Adds a HIT to the authorized hosts config. If an entry already exists, it 
updates
  *  the expiration date.
- *  
- *  @param cfg The configuration from the config file.
- *  @param root The root config_setting_t for cfg.
+ *
  *  @param info The HIT we wish to write.
  *  @param expiration The expiration date to be written.
  *
  *  @return 1 on success; 0 on failure
  */
-int write_hit(config_t *cfg, config_setting_t *root, char *info, char 
*expiration)
+int add_hit(char *info, char *expiration)
 {
-       int hit_existed = 0;
-       config_setting_t *allowed_hosts;
-       config_setting_t *new_hit_grp, *new_hit, *new_expire;
-       config_setting_t *current_expiration;
+    int hit_existed = 0;
+    config_setting_t *allowed_hosts;
+    config_setting_t *new_hit_grp, *new_hit, *new_expire;
+    config_setting_t *current_expiration;
+
+    pisa_hitlist_entry *con;
+
+    if (!valid_addr(info))
+    {
+        DEBUG("Tried to add invalid HIT \'%s\'. HIT not written. Exiting 
function.", info);
+        return 0;
+    }
+
+
+    con = find_hit_in_hitlist(info);
+
+    if(con!=NULL)
+    {
+        hit_existed = 1;
+        current_expiration = config_setting_get_member(con->group, "expires");
+        DEBUG("HIT found.");
+    }
+
+
+    if (hit_existed == 1)      // Update old entry
+    {
+        DEBUG("Update expiration date for HIT");
+        config_setting_set_string(current_expiration, expiration);
+    }
+    else                       // Create new entry
+    {
+        DEBUG("HIT not found");
+        DEBUG("Adding new entry to config");
+
+        allowed_hosts = check_list("allowed_hosts");
+
+        // Add a new group
+        new_hit_grp = config_setting_add(allowed_hosts, NULL, 
CONFIG_TYPE_GROUP);
+        // Add the HIT
+        new_hit = config_setting_add(new_hit_grp, "hit", CONFIG_TYPE_STRING);
+        config_setting_set_string(new_hit, info);
+        // Add the expiration date
+        new_expire = config_setting_add(new_hit_grp, "expires", 
CONFIG_TYPE_STRING);
+        config_setting_set_string(new_expire, expiration);
 
-       if (!valid_addr(info))
-       {
-               DEBUG("Tried to add invalid HIT \'%s\'. HIT not written. 
Exiting function.", info);
-               return 0;
-       }
+    }
 
-       allowed_hosts = config_lookup(cfg, "allowed_hosts");
-       if (!allowed_hosts)
-       {
-               DEBUG_HIGH("List allowed_hosts did not previously exist. 
Creating...");
-               allowed_hosts = config_setting_add(root, "allowed_hosts", 
CONFIG_TYPE_LIST);
-       }
+    return 1;
+}
 
-       {       // Iterate over the list
-               const char* hit_text = NULL;
-               int length = config_setting_length(allowed_hosts);
-               int i;
-
-               for (i = 0; i < length; i++)
-               {
-                       config_setting_t *group_element = NULL;
-                       group_element = config_setting_get_elem(allowed_hosts, 
i);
+/** Removes a HIT from the authorized hosts config.
+ *
+ *  @param hit The HIT we wish to remove.
+ *
+ *  @return 1 on success; 0 on failure; -1 on write error
+ */
+int remove_hit(char *hit)
+{
+    pisa_hitlist_entry *con;
+    config_setting_t *g,*parent;
+    char *name;
+
+    con = find_hit_in_hitlist(hit);
+
+    if(con!=NULL)
+    {
+        g=con->group;
+        parent= config_setting_parent(g);
+        name = (char *)config_setting_get_string(config_setting_get_member(g, 
"hit"));
+
+        DEBUG("HIT: %s",name);
+        DEBUG("Removing HIT.");
+
+        if(config_setting_remove_elem(parent,config_setting_index(g)) != 
CONFIG_TRUE)
+        {
+            DEBUG("Error removing HIT");
+        }
+
+        if(!pisa_cfg_write_authorized_hosts_file())
+        {
+               return -1;
+        }
 
-                       if (!group_element)
-                       {
-                               DEBUG("Error while parsing config file \'%s\'. 
Exiting function.", FILE_AUTHORIZED_HOSTS);
-                               return 0;
-                       }
+        return 1;
+    }
 
-                       config_setting_t *this_hit = NULL;
-                       this_hit = config_setting_get_member(group_element, 
"hit");
+    return 0;
+}
 
-                       if (!this_hit)
-                       {
-                               DEBUG("Error extracting HIT from group %d in 
file %s. Exiting function.", i, FILE_AUTHORIZED_HOSTS);
-                               return 0;
-                       }
+/**
+ * Searches for a HIT which is given in text format in the HITlist.
+ *
+ * @param hit The HIT we wish to find.
+ *
+ * @return The corresponding pisa_hitlist_entry if the HIT was found. 
Otherwise NULL.
+ */
+pisa_hitlist_entry *find_hit_in_hitlist(char *hit)
+{
 
-                       hit_text = NULL;
-                       hit_text = config_setting_get_string(this_hit);
+    pisa_hitlist_entry *con;
+    pisa_hitlist *hitlist_allowed_hosts;
+    struct sockaddr_in6 clientIp;
+
+    config_setting_t *allowed_hosts;
+    allowed_hosts = check_list("allowed_hosts");
+    hitlist_allowed_hosts = pisa_hitlist_build("allowed_hosts");
+    inet_pton(AF_INET6,hit,&(clientIp.sin6_addr));
 
-                       if (hit_text != NULL && strlen(hit_text)>0)
-                               DEBUG("HIT = %s", hit_text);
-                       else
-                               DEBUG("Error extracting HIT.");
+    // Checks if the HIT already exists to update the expiration date
+    con = pisa_hitlist_find(hitlist_allowed_hosts,&(clientIp.sin6_addr));
 
-                       if (identical_hits((char*)hit_text, info) == 1)
-                       {
-                               DEBUG("hit text = \'%s\'", hit_text);
-                               DEBUG("info = \'%s\'", info);
-                               hit_existed = 1;
-                               current_expiration = 
config_setting_get_member(group_element, "expires");
-                               break;
-                       }
-                               
-               }
+    return con;
+}
 
-       }
+/**
+ * Checks if a list with list_name exists in the authorized hosts config. If 
not, the list will be created.
+ * @param list_name The list name
+ * @return A pointer to the list.
+ */
+config_setting_t *check_list(char * list_name)
+{
+    return check_list_in_config(list_name,&authorized_cfg);
+}
 
-       if (hit_existed == 1)   // Update old entry
-       {
-               config_setting_set_string(current_expiration, expiration);
-       }
-       else                    // Create new entry
-       {
-               // Add a new group
-               new_hit_grp = config_setting_add(allowed_hosts, NULL, 
CONFIG_TYPE_GROUP);
-               // Add the HIT
-               new_hit = config_setting_add(new_hit_grp, "hit", 
CONFIG_TYPE_STRING);
-               config_setting_set_string(new_hit, info);
-               // Add the expiration date
-               new_expire = config_setting_add(new_hit_grp, "expires", 
CONFIG_TYPE_STRING);
-               config_setting_set_string(new_expire, expiration);
-       }
+/**
+ * Checks if a list with list_name exists in the given config. If not, the 
list will be created.
+ * @param list_name The list name
+ * @param config The config to check for the list
+ *
+ * @return A pointer to the list.
+ */
+config_setting_t *check_list_in_config(char * list_name, config_t *config)
+{
+    config_setting_t *root;
+    config_setting_t *list;
 
-       return 1;
+    list = config_lookup(config, list_name);
+    if (!list)
+    {
+        root = config_root_setting(config);
+        DEBUG_HIGH("List %s did not previously exist. Creating...",list_name);
+        list = config_setting_add(root, list_name, CONFIG_TYPE_LIST);
+    }
+    return list;
 }
+

Modified: trunk/pairing/libconfig_wrapper.h
==============================================================================
--- trunk/pairing/libconfig_wrapper.h   Tue Aug 18 15:21:27 2009        (r823)
+++ trunk/pairing/libconfig_wrapper.h   Wed Aug 19 11:54:30 2009        (r824)
@@ -7,6 +7,7 @@
  * @file libconfig_wrapper.h
  * @brief header file of wrapper functions calling libconfig
  * @author Kate Harrison <harriska@xxxxxxxxxxxxx>
+ * @author Jan Marten <jan.marten@xxxxxxxxxxxxxx>
  * @date Sep. 2008
  */
 
@@ -16,6 +17,7 @@
 // This is a wrapper for the libconfig configuration file reader
 #include "common.h"
 #include <libconfig.h>
+#include "hitlist.h"
 
 #define FILE_AUTHORIZED_HOSTS "authorized_hosts.cfg"
 
@@ -26,6 +28,10 @@
 // Function prototypes
 int write_config(char *info, char *expiration, configtype type);
 int get_config_setting(char *filename, char *path, int type, void *return_val, 
int strlen);
-int write_hit(config_t *cfg, config_setting_t *root, char *info, char 
*expiration);
+int add_hit(char *info, char *expiration);
+config_setting_t *check_list(char * list_name);
+config_setting_t *check_list_in_config(char * list_name, config_t *config);
+pisa_hitlist_entry *find_hit_in_hitlist(char *hit);
+int remove_hit(char *hit);
 
 #endif /* PISA_PAIR_LIBCONFIG_WRAPPER_H */

Added: trunk/pairing/management.c
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ trunk/pairing/management.c  Wed Aug 19 11:54:30 2009        (r824)
@@ -0,0 +1,1187 @@
+/*
+ * Copyright (c) 2009, Distributed Systems Group, RWTH Aachen
+ * All rights reserved.
+ */
+
+/**
+ * @file management.c
+ * @brief Management tool for the server daemon.
+ * @author Jan Marten <jan.marten@xxxxxxxxxxxxxx>
+ * @date Aug. 2009
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <time.h>
+#include <netinet/in.h>
+#include <search.h>
+#include <signal.h>
+#include <getopt.h>
+
+#include "global.h" /* it must be included before all other header files */
+#include "config.h"
+#include "debug.h"
+#include "common_headers.h"
+#include "common.h"
+#include "util.h"
+#include "libconfig_wrapper.h"
+#include "hitlist.h"
+#include "management.h"
+
+extern config_t cfg;
+management_conf managementconf;
+
+static const struct option longopts[] =
+    {
+        {"hit", required_argument, NULL, 'h'},
+        {"expiration", required_argument, NULL, 'e'},
+        {"remove", no_argument, NULL, 'r'},
+        {"list", required_argument, NULL, 'l'},
+        {"username", required_argument, NULL, 'u'},
+        {"active", required_argument, NULL, 'a'},
+        {"authorizedcfg", required_argument, NULL, 'f'},
+        {"userscfg", required_argument, NULL, 'c'},
+        {"relaycfg", required_argument, NULL, 's'},
+        {"creditcard", required_argument, NULL, 'p'},
+        {0, 0, 0, 0}
+    };
+
+static int pisa_userlist_entry_compare_hit(const void *p1, const void *p2);
+static int pisa_userlist_entry_compare_name(const void *p1, const void *p2);
+static void pisa_user_hit_list_destroy(pisa_userhitlist *list);
+static void pisa_userlist_destroy(pisa_userlist *list);
+static void pisa_mgmt_conf_init(management_conf *m);
+static pisa_userhitlist * pisa_merge_user_and_hit_list(pisa_userlist *ul, 
pisa_hitlist *hl);
+static void pisa_userlist_parse(const struct cfg_group *g, void *user_data);
+static void remove_leading_zeroes_from_hit(char *hit);
+static int pisa_userlist_entry_remove(pisa_userlist_entry *entry);
+
+/**
+ * Frees the memory allocated for the user_hit_list
+ * @param list The user_hit_list which should be freed
+ */
+static void pisa_user_hit_list_destroy(pisa_userhitlist *list)
+{
+    if (!list)
+    {
+        return ;
+    }
+
+    if (list->entries)
+    {
+        free(list->entries);
+    }
+
+    free(list);
+}
+
+
+/**
+ * Frees the memory allocated for the userlist
+ * @param list The userlist which should be freed
+ */
+static void pisa_userlist_destroy(pisa_userlist *list)
+{
+    if (!list)
+    {
+        return ;
+    }
+
+    if (list->entries)
+    {
+        free(list->entries);
+    }
+
+    free(list);
+}
+
+/**
+ * Comparing userlist_entries means comparing their HITs
+ */
+static int pisa_userlist_entry_compare_hit(const void *p1, const void *p2)
+{
+
+    pisa_userlist_entry *e1 = (pisa_userlist_entry *) p1;
+    pisa_userlist_entry *e2 = (pisa_userlist_entry *) p2;
+    struct in6_addr hit1;
+    struct in6_addr hit2;
+
+    inet_pton(PF_INET6, e1->hit, &hit1);
+    inet_pton(PF_INET6, e2->hit, &hit2);
+
+    return pisa_ipv6_cmp(&hit1, &hit2);
+}
+
+/**
+ * Comparing userlist_entries means comparing the user_names
+ */
+static int pisa_userlist_entry_compare_name(const void *p1, const void *p2)
+{
+
+    pisa_userlist_entry *e1 = (pisa_userlist_entry *) p1;
+    pisa_userlist_entry *e2 = (pisa_userlist_entry *) p2;
+
+    return strcmp((const char *)&e1->user_name, (const char *) &e2->user_name);
+}
+
+/**
+ * Callback for the configIterateOverGroup function.
+ * will build our userlist.
+ * @param g config group in which hit value and other values will be obtained
+ * @param user_data user-defined data
+ */
+static void pisa_userlist_parse(const struct cfg_group *g, void *user_data)
+{
+    char buffer[1000];
+    pisa_userlist *ul = (pisa_userlist *)user_data;
+
+    if (!ul)
+        return ;
+
+    ul->entries[ul->cur_slots].group = (config_setting_t *)g;
+
+    pisa_cfg_get_group_string_value(g, "hit", buffer, sizeof(buffer));
+
+
+    struct in6_addr addr;
+
+    if (pisa_convert_string_to_address(buffer, &addr) != 0)
+    {
+        PISA_ERROR("Invalid network address string:<%s>\n", buffer);
+    }
+    else if (!ipv6_addr_is_hit(&addr))
+    {
+        PISA_ERROR("Invalid network address string:<%s>\n", buffer);
+    }
+    else
+    {
+        strncpy(ul->entries[ul->cur_slots].hit, buffer, INET6_ADDRSTRLEN);
+        pisa_cfg_get_group_string_value(g, "user_name", buffer, 
sizeof(buffer));
+        strncpy(ul->entries[ul->cur_slots].user_name, buffer, 
MAX_USERNAME_LENGTH);
+        ul->entries[ul->cur_slots].active = pisa_cfg_get_group_bool_value(g, 
"active");
+        
pisa_cfg_get_group_string_value(g,"credit_card",ul->entries[ul->cur_slots].creditcard,MAX_CREDIT_CARD_LENGTH);
+        ul->cur_slots++;
+    }
+
+}
+
+/**
+ * Merges the userlist and the hitlist to a pisa_userhitlist which can be 
printed out.
+ * @param ul Userlist which should be merged
+ * @param hl Hitlist which should be merged
+ * @return The merged list as an user_hit_list struct.
+ */
+static pisa_userhitlist * pisa_merge_user_and_hit_list(pisa_userlist *ul, 
pisa_hitlist *hl)
+{
+    if (!ul || !hl)
+        return NULL;
+
+    int i, j;
+    char hit_tmp[INET6_ADDRSTRLEN];
+    char buf_expiration[LENGTH_TIMEOUT];
+    pisa_hitlist_entry *entry;
+    pisa_userlist_entry *ulentry;
+    pisa_userlist_entry ulentry2;
+    pisa_userhitlist *merged_list = malloc(sizeof(pisa_userhitlist));
+
+    merged_list->max_slots = ul->max_slots + hl->max_slots;
+    merged_list->cur_slots = 0;
+    merged_list->entries = calloc(sizeof(pisa_userhitlist_entry), 
merged_list->max_slots);
+
+    i = 0;
+    j = 0;
+
+    // Mergesort
+    while (i < ul->max_slots && j < hl->max_slots)
+    {
+        ulentry = &ul->entries[i];
+        entry = &hl->entries[j];
+        inet_ntop(AF_INET6, &(entry->hit), hit_tmp, INET6_ADDRSTRLEN);
+        memcpy(&ulentry2.hit, hit_tmp, sizeof(ulentry2.hit));
+
+        if (pisa_userlist_entry_compare_hit(ulentry, &ulentry2) <= 0)
+        {
+
+            strncpy(merged_list->entries[merged_list->cur_slots].hit, 
ulentry->hit, INET6_ADDRSTRLEN);
+            strncpy(merged_list->entries[merged_list->cur_slots].user_name, 
ulentry->user_name, MAX_USERNAME_LENGTH);
+            merged_list->entries[merged_list->cur_slots].active = 
ulentry->active;
+            
strncpy(merged_list->entries[merged_list->cur_slots].creditcard,ulentry->creditcard,MAX_CREDIT_CARD_LENGTH);
+            i++;
+        }
+
+        if (pisa_userlist_entry_compare_hit(ulentry, &ulentry2) == 0)
+        {
+            convert_time_t_to_formatted_string(&entry->expiration, 
buf_expiration);
+            strncpy(merged_list->entries[merged_list->cur_slots].expiration, 
buf_expiration, LENGTH_TIMEOUT);
+            j++;
+        }
+
+        if (pisa_userlist_entry_compare_hit(ulentry, &ulentry2) > 0)
+        {
+            strncpy(merged_list->entries[merged_list->cur_slots].hit, 
ulentry2.hit, INET6_ADDRSTRLEN);
+            convert_time_t_to_formatted_string(&entry->expiration, 
buf_expiration);
+            strncpy(merged_list->entries[merged_list->cur_slots].expiration, 
buf_expiration, LENGTH_TIMEOUT);
+            
memset(merged_list->entries[merged_list->cur_slots].creditcard,0,sizeof(merged_list->entries[merged_list->cur_slots].creditcard));
+            merged_list->entries[merged_list->cur_slots].active = 2;
+            j++;
+        }
+
+        merged_list->cur_slots++;
+    }
+
+    while (i < ul->max_slots)
+    {
+        ulentry = &ul->entries[i];
+        strncpy(merged_list->entries[merged_list->cur_slots].hit, 
ulentry->hit, INET6_ADDRSTRLEN);
+        strncpy(merged_list->entries[merged_list->cur_slots].user_name, 
ulentry->user_name, MAX_USERNAME_LENGTH);
+        merged_list->entries[merged_list->cur_slots].active = ulentry->active;
+        
strncpy(merged_list->entries[merged_list->cur_slots].creditcard,ulentry->creditcard,MAX_CREDIT_CARD_LENGTH);
+        i++;
+        merged_list->cur_slots++;
+    }
+
+    while (j < hl->max_slots)
+    {
+        entry = &hl->entries[j];
+        inet_ntop(AF_INET6, &(entry->hit), hit_tmp, INET6_ADDRSTRLEN);
+        strncpy(merged_list->entries[merged_list->cur_slots].hit, hit_tmp, 
INET6_ADDRSTRLEN);
+        convert_time_t_to_formatted_string(&entry->expiration, buf_expiration);
+        strncpy(merged_list->entries[merged_list->cur_slots].expiration, 
buf_expiration, LENGTH_TIMEOUT);
+        merged_list->entries[merged_list->cur_slots].active = 2;
+        
memset(merged_list->entries[merged_list->cur_slots].creditcard,0,sizeof(merged_list->entries[merged_list->cur_slots].creditcard));
+        j++;
+        merged_list->cur_slots++;
+    }
+
+    return merged_list;
+}
+
+/**
+ * Searches for a HIT which is given in text format in the userslist.
+ *
+ * @param ul The userlist where we search for the Hit
+ * @param hit The HIT we wish to find.
+ *
+ * @return The corresponding userlist_entry if the HIT was found. Otherwise 
NULL.
+ */
+pisa_userlist_entry *pisa_userlist_find_hit(const pisa_userlist *ul,
+                    const char *hit)
+{
+
+    pisa_userlist_entry s;
+
+    if (!ul)
+        return 0;
+
+    memcpy(&s.hit, hit, sizeof(s.hit));
+
+    return (pisa_userlist_entry *)bsearch(&s, ul->entries, ul->cur_slots,
+
+                                            sizeof(pisa_userlist_entry),
+                                            pisa_userlist_entry_compare_hit);
+}
+
+
+/**
+ * Searches for a user_name in the userslist.
+ *
+ * @param ul The userlist where we search for the Hit
+ * @param name The user_name we wish to find.
+ *
+ * @return The corresponding userlist_entry if the HIT was found. Otherwise 
NULL.
+ */
+pisa_userlist_entry *pisa_userlist_find_username(const pisa_userlist *ul, 
const char *name)
+{
+
+    pisa_userlist_entry s;
+
+    if (!ul)
+        return 0;
+
+    memcpy(&s.user_name, name, sizeof(s.user_name));
+
+    // lfind because userlist is sorted by HIT
+    return (pisa_userlist_entry *)lfind(&s, ul->entries, (size_t *) 
&ul->cur_slots,
+
+                                          sizeof(pisa_userlist_entry),
+                                          pisa_userlist_entry_compare_name);
+}
+
+
+/**
+ * Builds userlist with userlist_entry from the given section
+ *
+ * @param section The section which is used to build the userslist
+ *
+ * @return The corresponding userlist
+ */
+pisa_userlist *pisa_userlist_build(const char *section)
+{
+    assert(section != NULL);
+
+    pisa_userlist *ul = malloc(sizeof(pisa_userlist));
+    config_setting_t *list;
+    list = check_list_in_config("users", &cfg);
+
+    ul->max_slots = pisa_cfg_get_number_of_section_entries(section, &cfg);
+    ul->cur_slots = 0;
+
+    ul->entries = calloc(sizeof(pisa_userlist_entry), ul->max_slots);
+
+    pisa_cfg_iterate_group(list, pisa_userlist_parse, ul);
+
+    /* sort our array - so we can use bsearch to find a matching hit */
+    qsort(ul->entries, ul->cur_slots, sizeof(pisa_userlist_entry),
+          pisa_userlist_entry_compare_hit);
+
+    return ul;
+}
+
+/** Main program that will be run on the user's computer.
+ */
+int main(int argc, char *argv[])
+{
+    int result;
+
+    struct options options = { 0 };
+    pisa_hitlist *hitlist_allowed_hosts = NULL;
+    pisa_hitlist_entry *entry = NULL;
+    pisa_userlist *userlist = NULL;
+    pisa_userlist_entry *ulentry = NULL;
+    pisa_userhitlist *merged_list = NULL;
+    pisa_userhitlist_entry *uhlentry = NULL;
+    pisa_userhitlist_entry new_entry = {};
+
+    pisa_mgmt_conf_init(&managementconf);
+
+    new_entry.active = NO_CHANGE;
+
+    if (!pisa_mgmt_parse_options(argc, argv, &new_entry, &managementconf, 
&options))
+    {
+        return ERROR_PARSING_COMMANDLINE;
+    }
+
+    // Initialize Configs
+    if 
(!pisa_cfg_authorized_hosts_setup_file(managementconf.authorizedcfgfile))
+    {
+        return ERROR_OPENING_CONFIG;
+    }
+    if (!pisa_cfg_setup_file(managementconf.userscfgfile))
+    {
+        return ERROR_OPENING_CONFIG;
+    }
+
+    switch (options.mode)
+    {
+        // Different list-modes
+        case LIST_SINGLE_ONLY_HIT:
+            entry = find_hit_in_hitlist(new_entry.hit);
+
+            if (!NULL)
+            {
+                pisa_hitlist_entry_print(entry, options.list_mode);
+            }
+
+            break;
+
+        case LIST_ALL:
+            userlist = pisa_userlist_build(USERS_SECTION);
+            hitlist_allowed_hosts = pisa_hitlist_build("allowed_hosts");
+            merged_list = pisa_merge_user_and_hit_list(userlist, 
hitlist_allowed_hosts);
+            int i;
+
+            for (i = 0;i < merged_list->cur_slots;i++)
+            {
+                uhlentry = &merged_list->entries[i];
+                pisa_userhitlist_entry_print(uhlentry, options.list_mode);
+            }
+
+            pisa_user_hit_list_destroy(merged_list);
+            break;
+
+        case LIST_SINGLE:
+            userlist = pisa_userlist_build(USERS_SECTION);
+            ulentry = pisa_userlist_find_username(userlist, 
new_entry.user_name);
+
+            if (ulentry != NULL)
+            {
+                pisa_userlist_entry_print(ulentry, options.list_mode);
+            }
+
+            break;
+
+            // Different remove-modes
+
+        case REMOVE_ONLY_HIT:
+            // Remove Hit
+            result = remove_hit(new_entry.hit);
+
+            if (result <= 0)
+            {
+                if (result == 0)
+                {
+                    result = ERROR_NOT_FOUND;
+                }
+                else
+                {
+                    result = ERROR_WRITING_CONFIG;
+                }
+
+                PISA_ERROR("Error removing HIT.\n");
+            }
+
+            break;
+
+        case REMOVE:
+            // Remove Hit and Users entry
+            // Only Username was given
+
+            if (new_entry.hit[0] == '\0')
+            {
+                userlist = pisa_userlist_build(USERS_SECTION);
+                ulentry = pisa_userlist_find_username(userlist, 
new_entry.user_name);
+
+                if (ulentry != NULL)
+                {
+                    strncpy(new_entry.hit, ulentry->hit, INET6_ADDRSTRLEN);
+                }
+                else
+                {
+                    PISA_ERROR("Username not found!\n");
+                    result = ERROR_NOT_FOUND;
+                    break;
+                }
+            }
+
+            result = pisa_mgmt_remove_userlist_entry_by_hit(new_entry.hit);
+
+            if (result <= 0)
+            {
+                if (result == 0)
+                {
+                    result = ERROR_GENERAL;
+                }
+                else
+                {
+                    result = ERROR_WRITING_CONFIG;
+                }
+            }
+            else
+            {
+                if (ulentry->active)
+                {
+                    result = remove_hit(new_entry.hit);
+
+                    if (result <= 0)
+                    {
+                        if (result == 0)
+                        {
+                            result = ERROR_NOT_FOUND;
+                        }
+                        else
+                        {
+                            result = ERROR_WRITING_CONFIG;
+                        }
+
+                        PISA_ERROR("Error removing HIT.\n");
+                    }
+                }
+            }
+
+            break;
+
+            // Different add-modes
+
+        case ADD_OR_EDIT_ONLY_HIT:
+            // No username was given
+            result = write_config(new_entry.hit, new_entry.expiration, 
CONFIG_TYPE_HIT);
+
+            if (!result)
+            {
+                result = ERROR_WRITING_CONFIG;
+            }
+
+            break;
+
+        case ADD_OR_EDIT:
+            // Find HIT through users config
+            if (new_entry.hit[0] == '\0')
+            {
+                userlist = pisa_userlist_build(USERS_SECTION);
+                ulentry = pisa_userlist_find_username(userlist, 
new_entry.user_name);
+
+                if (ulentry != NULL)
+                {
+                    strncpy(new_entry.hit, ulentry->hit, INET6_ADDRSTRLEN);
+                }
+                else
+                {
+                    PISA_ERROR("Username not found!\n");
+                    result = ERROR_NOT_FOUND;
+                    break;
+                }
+
+            }else
+            {
+               if(new_entry.creditcard[0] == '\0')
+               {
+                       PISA_ERROR("No Creditcard given");
+                       pisa_mgmt_print_usage(argv);
+                       result = ERROR_PARSING_COMMANDLINE;
+                       break;
+               }
+            }
+
+            result = pisa_mgmt_users_config_write(&new_entry);
+
+            if (result <= 0)
+            {
+                if (result == 0)
+                {
+                    result = ERROR_GENERAL;
+                }
+                else
+                {
+                    result = ERROR_WRITING_CONFIG;
+                }
+            }
+
+            break;
+
+        default:
+            PISA_ERROR("Unknown error occurred.\n");
+            return ERROR_GENERAL;
+            break;
+    }
+
+    // Free lists
+    pisa_hitlist_destroy(hitlist_allowed_hosts);
+    pisa_userlist_destroy(userlist);
+
+    // Config cleanup
+    pisa_cfg_cleanup();
+    pisa_cfg_authorized_hosts_cleanup();
+
+    result = (result == 1) ? 0 : result;
+
+    return result;
+}
+
+/**
+ * Initializes the management_conf struct
+ * @param m Pointer to the management_conf struct
+ */
+static void pisa_mgmt_conf_init(management_conf *m)
+{
+    assert(m != NULL);
+
+    memset(m->userscfgfile, 0, sizeof(m->userscfgfile));
+    memset(m->authorizedcfgfile, 0, sizeof(m->authorizedcfgfile));
+}
+
+/**
+ * Print usage instructions of management software.
+ *
+ * @param argv   pointer to the array of command arguments
+ */
+void pisa_mgmt_print_usage(char **argv)
+{
+    PISA_ERROR("\nUSAGE:\n"
+               "%s -l <0|1> [-u <username>|-h <hit>]\n"
+               "%s -r [-u <username>|-h <hit>]\n"
+               "%s -h <hit> -e <1|\"YYYY-MM-DD HH:MM:SS\">\n"
+               "%s -u <username> [-h <hit>] [-e <1|\"YYYY-MM-DD HH:MM:SS\">] 
[-a <0|1>]\n"
+               "\n"
+               "%s -f <authorizedconfig>,\n"
+               "%s -c <usersconfig> and\n"
+               "%s -s <relay_config> can always be used to use specific config 
paths\n"
+                  "%s -p <creditcard> \n"
+               "\n"
+               "Options:\n"
+               "-h|--hit HIT   \t\t\t\t: HIT of the client\n"
+               "-e|--expiration <1|\"Expiration Date\"> \t:\n"
+               "\t\t\t\t\t 1: default expiration date\n"
+               "\t\t\t\t\t Expiration date in format YYYY-MM-DD HH:MM:SS\n"
+               "-r|--remove \t\t\t\t: Remove given HIT or given User\n"
+               "-l|--list <0|1>\t\t\t\t: 0: normal mode, 1: short mode\n"
+               "\t\t\t\t\t: List given HIT or given user or all entries\n"
+                  "-p|--creditcard <creditcard> Credit card which is needed 
for new users\n"
+               "-a|--authorizedcfg <authorizedconfig>\t: Path to 
authorized_hosts configuration file\n"
+               "-f|--userscfg <usersconfig>\t\t: Path to users configuration 
file\n"
+               "-s|--relaycfg <relayconfig>\t\t: Path to relay configuration 
file\n"
+               "\n\n"
+               "Examples: \n"
+               "\t%s -h 2001:1c:539b:fd3:ebd7:de72:7b12:9ba7\n"
+               "Or: \t%s -h 2001:1c:539b:fd3:ebd7:de72:7b12:9ba7 -e 
\"2009-07-12 12:00:00\"\n"
+               "Or: \t%s -h 2001:1c:539b:fd3:ebd7:de72:7b12:9ba7 -e 1\n"
+               "Or: \t%s -h 2001:1c:539b:fd3:ebd7:de72:7b12:9ba7 -r \n"
+               "Or: \t%s -h 2001:1c:539b:fd3:ebd7:de72:7b12:9ba7 -l 0\n"
+               "Or: \t%s -h 2001:1c:539b:fd3:ebd7:de72:7b12:9ba7 -u john -e1\n"
+               "Or: \t%s -u john -a 0 (If user john already exists.)\n"
+               "Or: \t%s -u john -e 1 (If user john already exists.)\n"
+               "Or: \t%s -l 0\n"
+               , argv[0], argv[0], argv[0], argv[0], argv[0], argv[0], argv[0],
+               argv[0], argv[0], argv[0], argv[0], argv[0], argv[0], argv[0],
+               argv[0], argv[0], argv[0]);
+}
+
+/** This function parses the command line input options and stores in the 
information accordingly.
+ *
+ *  @param argc The argument counter.
+ *  @param argv The arguments array.
+ *  @param new_entry Pointer to the user_hit_list_entry for storing the parsed 
details.
+ *  @param mconf Pointer to the management configuration structure.
+ *  @param options Pointer to the options struct.
+ *
+ *  @return 1 if parsing successful and required arguments are present
+ *  @return 0 otherwise (recommend exit program)
+ */
+int pisa_mgmt_parse_options(int argc, char *argv[], pisa_userhitlist_entry 
*new_entry,
+                  management_conf *mconf, struct options *options)
+{
+    int sw;
+    int temp;
+    int hit_given = 0;
+    int expiration_given = 0;
+    int remove = 0;
+    int list = 0;
+    int username_given = 0;
+    int option_index = 0;
+    int relay_cfg_path_given = 0;
+    int usercfg_given = 0;
+    int authorizedcfg_given = 0;
+    int credit_card_given = 0;
+    char relay_cfg_file[MAX_PATH];
+    struct in6_addr addr;
+
+    // Parse options
+    while ((sw = getopt_long(argc, argv, OPTION_STRING, longopts, 
&option_index)) != -1)
+    {
+        switch (sw)
+        {
+            case ':':   /* missing argument of a parameter */
+                PISA_ERROR("Missing argument.");
+                return 0;
+
+            case 'h':
+
+                if (pisa_convert_string_to_address(optarg, &addr) != 0)
+                {
+                    return 0;
+                }
+
+                if (!ipv6_addr_is_hit(&addr))
+                {
+                    PISA_ERROR("Provided address is not a HIT\n");
+                    return 0;
+                }
+
+                strncpy(new_entry->hit, optarg, INET6_ADDRSTRLEN);
+                // :0ba8 will be replaced with :ba8
+                // Thus, no problems will arise because the userlist
+                // just uses strings to save the hit address
+                remove_leading_zeroes_from_hit(new_entry->hit);
+                hit_given = 1;
+                break;
+
+            case 'e':
+                // Use default expiration date
+                if (atoi(optarg) == 1)
+                {
+                    expiration_given = USE_DEFAULT_EXPIRATION;
+                }
+
+                // Use given expiration date
+                else
+                {
+                    struct tm tm;
+
+                    if (!valid_date_string(optarg, &tm))
+                    {
+                        PISA_ERROR("Provided date is not in the format: 
YYYY-MM-DD HH:MM:SS");
+                        return 0;
+                    }
+
+                    strncpy(new_entry->expiration, optarg, LENGTH_TIMEOUT);
+                    expiration_given = 1;
+                }
+
+                break;
+
+            case 'r':
+                remove = 1;
+                break;
+
+            case 'l':
+                list = 1;
+                temp = atoi(optarg);
+
+                if (temp >= 0 && temp <= 1)
+                {
+                    options->list_mode = temp;
+                }
+
+                break;
+
+            case 'a':
+                temp = atoi(optarg);
+
+                if (temp >= 0 && temp <= 1)
+                {
+                    new_entry->active = temp;
+                }
+
+                break;
+
+            case 'p':
+               strncpy(new_entry->creditcard,optarg,MAX_CREDIT_CARD_LENGTH);
+               credit_card_given = 1;
+               break;
+
+            case 'u':
+                strncpy(new_entry->user_name, optarg, MAX_USERNAME_LENGTH);
+                username_given = 1;
+                break;
+
+            case 'f':
+                authorizedcfg_given = 1;
+                strncpy(mconf->authorizedcfgfile, optarg, MAX_PATH);
+                break;
+
+            case 's':
+                relay_cfg_path_given = 1;
+                strncpy(relay_cfg_file, optarg, MAX_PATH);
+                break;
+
+            case 'c':
+                usercfg_given = 1;
+                strncpy(mconf->userscfgfile, optarg, MAX_PATH);
+                break;
+
+            default:   /* unknown */
+                pisa_mgmt_print_usage(argv);
+                return 0;
+        }
+    }
+
+    // Use default value
+    if (!usercfg_given)
+    {
+        strcpy(mconf->userscfgfile, DEFAULT_USERS_CONFIG_FILE);
+    }
+
+    // Use default value
+    if (!authorizedcfg_given)
+    {
+        strcpy(mconf->authorizedcfgfile, DEFAULT_AUTHORIZED_HOSTS_FILE);
+    }
+
+    // No mode was given
+    if (!list && !expiration_given && !remove && new_entry->active == 
NO_CHANGE)
+    {
+        PISA_ERROR("No mode was given.\n");
+        pisa_mgmt_print_usage(argv);
+        return 0;
+    }
+    // Mode was given
+    else
+    {
+        // No HIT or Username given
+        if (!hit_given && !username_given && !list)
+        {
+            PISA_ERROR("No HIT or Username given.\n");
+            pisa_mgmt_print_usage(argv);
+            return 0;
+        }
+
+        // Modes cannot be combined
+        if ((list && (remove || expiration_given || new_entry->active != 
NO_CHANGE)) ||
+                (remove && (expiration_given || new_entry->active != 
NO_CHANGE)) ||
+                (expiration_given && new_entry->active == NO_CHANGE && 
!hit_given && !username_given))
+        {
+            PISA_ERROR("Modes cannot be combined.\n");
+            pisa_mgmt_print_usage(argv);
+            return 0;
+        }
+    }
+
+    // Decide which list-mode to use
+    if (list)
+    {
+        if (username_given)
+        {
+            options->mode = LIST_SINGLE;
+            return 1;
+        }
+        else if (hit_given)
+        {
+            options->mode = LIST_SINGLE_ONLY_HIT;
+            return 1;
+        }
+        else
+        {
+            options->mode = LIST_ALL;
+            return 1;
+        }
+    }
+
+    // Decide which remove-mode to use
+    if (remove)
+    {
+        if (username_given)
+        {
+            options->mode = REMOVE;
+            return 1;
+        }
+        else
+        {
+            options->mode = REMOVE_ONLY_HIT;
+            return 1;
+        }
+    }
+
+    // Use default expiration time
+    if (expiration_given == USE_DEFAULT_EXPIRATION)
+    {
+        PISA_INFO("Using default expiration.\n");
+        // Use default relays_config.cfg in PWD
+        if (!relay_cfg_path_given)
+        {
+            if (!get_default_expiration(new_entry->expiration))
+            {
+                return 0;
+            }
+        }
+        else
+        {
+               // Use given path
+            if (!get_default_expiration_from_config(new_entry->expiration, 
relay_cfg_file))
+            {
+                return 0;
+            }
+        }
+    }
+
+    // No expiration given
+    if (new_entry->active == ACTIVATED && !expiration_given)
+    {
+        PISA_ERROR("Either use -e 1 for default expiration or give a valid 
expiration date.\n");
+        pisa_mgmt_print_usage(argv);
+        return 0;
+    }
+
+
+    // If the username was given the default ADD_OR_EDIT mode is used
+    // otherwise ADD_OR_EDIT_ONLY_HIT is used
+    if (!username_given)
+    {
+        options->mode = ADD_OR_EDIT_ONLY_HIT;
+    }
+
+    // Everything was fine
+    return 1;
+}
+
+/**
+ * Prints an hitlistEntry in normal or short mode
+ * 
+ * @param entry Pointer to the hitlistEntry which should be printed
+ * @param list_mode The mode in which the entry is printed
+ */
+void pisa_hitlist_entry_print(pisa_hitlist_entry *entry, enum list_mode 
list_mode)
+{
+    if (entry != NULL)
+    {
+        char hit[INET6_ADDRSTRLEN];
+        char buf_expiration[LENGTH_TIMEOUT];
+
+        inet_ntop(AF_INET6, &(entry->hit), hit, INET6_ADDRSTRLEN);
+        convert_time_t_to_formatted_string(&entry->expiration, buf_expiration);
+
+        switch (list_mode)
+        {
+            case SHORT:
+                printf("%s\n", hit);
+                printf("%s\n", buf_expiration);
+                break;
+
+            case NORMAL:
+            default:
+                printf("Address: %s\n", hit);
+                printf("Expiration: %s\n", buf_expiration);
+                printf("==================\n");
+                break;
+        }
+    }
+}
+
+/**
+ * Prints an userlist_entry in normal or short mode
+ *
+ * @param entry Pointer to the hitlistEntry which should be printed
+ * @param list_mode The mode in which the entry is printed
+ */
+void pisa_userlist_entry_print(pisa_userlist_entry *entry, enum list_mode 
list_mode)
+{
+    if (entry != NULL)
+    {
+        switch (list_mode)
+        {
+
+            case SHORT:
+                printf("%s\n", (char *)&entry->user_name);
+                printf("%s\n", (char *)&entry->hit);
+                printf("%i\n", entry->active);
+                printf("%s\n",(char *)&entry->creditcard);
+                break;
+
+            case NORMAL:
+            default:
+                printf("Username: %s\n", (char *)&entry->user_name);
+                printf("HIT: %s\n", (char *)&entry->hit);
+                printf("Active: %i\n", entry->active);
+                printf("Credit Card: %s\n",(char *)&entry->creditcard);
+                printf("==================\n");
+                break;
+        }
+    }
+}
+
+/**
+ * Prints an user_hit_list_entry in normal or short mode
+ *
+ * @param entry Pointer to the user_hit_list_entry which should be printed
+ * @param list_mode The mode in which the entry is printed
+ */
+void pisa_userhitlist_entry_print(pisa_userhitlist_entry *entry, enum 
list_mode list_mode)
+{
+    if (entry != NULL)
+    {
+        switch (list_mode)
+        {
+
+            case SHORT:
+                PRINT_ENTRY(1,"%s\n", (char *)&entry->user_name);
+                PRINT_ENTRY(1,"%s\n", (char *)&entry->hit);
+                PRINT_ENTRY(entry->active != 2,"%i\n", entry->active );
+                PRINT_ENTRY(entry->expiration != 0,"%s\n", (char 
*)&entry->expiration);
+                PRINT_ENTRY(entry->creditcard[0] != '\0',"%s\n",(char 
*)&entry->creditcard);
+                break;
+
+            case NORMAL:
+            default:
+                PRINT_ENTRY(1,"Username: %s\n", (char *)&entry->user_name);
+                PRINT_ENTRY(1,"HIT: %s\n", (char *)&entry->hit);
+                PRINT_ENTRY(entry->active != 2,"Active: %i\n", entry->active );
+                PRINT_ENTRY(entry->expiration != 0,"Expiration: %s\n", (char 
*)&entry->expiration);
+                PRINT_ENTRY(entry->creditcard[0] != '\0',"Credit Card: 
%s\n",(char *)&entry->creditcard);
+                printf("==================\n");
+                break;
+        }
+    }
+}
+
+/** Writes the users configuration.
+ *
+ *  @param hit HIT
+ *  @param user_name User_name
+ *  @param expiration Expiration of the Hit
+ *  @param active The active status of the Entry (0: Deactivated, 1:Activated, 
2:No Change)
+ *
+ *  @return 0 on failure; 1 on success; -1 on write error
+ */
+int pisa_mgmt_users_config_write(pisa_userhitlist_entry *new_entry)
+{
+    pisa_userlist *ul;
+    pisa_userlist_entry *entry;
+    int hit_existed = 0;
+    int old_active;
+    int result = 1;
+    config_setting_t *current_username;
+    config_setting_t *current_active;
+    config_setting_t *users_list;
+    config_setting_t *new_grp, *new_hit, *new_username, *new_active, 
*new_creditcard;
+
+    ul = pisa_userlist_build(USERS_SECTION);
+
+    entry = pisa_userlist_find_hit(ul, new_entry->hit);
+
+    if (entry != NULL)
+    {
+        hit_existed = 1;
+        current_username = config_setting_get_member(entry->group, 
"user_name");
+        current_active = config_setting_get_member(entry->group, "active");
+        old_active = config_setting_get_bool(current_active);
+    }
+
+    if (hit_existed)
+    {
+        if (new_entry->active != 2)
+        {
+            DEBUG("Changed active status.");
+            config_setting_set_bool(current_active, new_entry->active);
+
+            // Add or Remove HIT from authorized_hosts.cfg because active 
changed
+            if (old_active != new_entry->active)
+            {
+                if (new_entry->active)
+                {
+                    if (!write_config(new_entry->hit, new_entry->expiration, 
CONFIG_TYPE_HIT))
+                    {
+                        result = -1;
+                    }
+                }
+                else
+                {
+                    result = remove_hit(new_entry->hit);
+                }
+            }
+        }
+        else
+        {
+            // Change expiration date
+            if (new_entry->active)
+            {
+                if (!write_config(new_entry->hit, new_entry->expiration, 
CONFIG_TYPE_HIT))
+                {
+                    result = -1;
+                }
+            }
+        }
+    }
+    else
+    {
+        PISA_INFO("HIT not found");
+        PISA_INFO("Adding new entry to config");
+
+        users_list = check_list_in_config(USERS_SECTION, &cfg);
+        // Add a new group
+        new_grp = config_setting_add(users_list, NULL, CONFIG_TYPE_GROUP);
+        // Add the HIT
+        new_hit = config_setting_add(new_grp, "hit", CONFIG_TYPE_STRING);
+        config_setting_set_string(new_hit, new_entry->hit);
+        // Add the user_name
+        new_username = config_setting_add(new_grp, "user_name", 
CONFIG_TYPE_STRING);
+        config_setting_set_string(new_username, new_entry->user_name);
+        // Add active
+        new_entry->active = (new_entry->active != 0 ) ? 1 : 0;
+        new_active = config_setting_add(new_grp, "active", CONFIG_TYPE_BOOL);
+        config_setting_set_bool(new_active, new_entry->active);
+        // Add creditcard
+        new_creditcard = 
config_setting_add(new_grp,"credit_card",CONFIG_TYPE_STRING);
+        config_setting_set_string(new_creditcard,new_entry->creditcard);
+
+        if (new_entry->active)
+        {
+            if (!write_config(new_entry->hit, new_entry->expiration, 
CONFIG_TYPE_HIT))
+            {
+                result = -1;
+            }
+        }
+    }
+
+    if (config_write_file(&cfg, managementconf.userscfgfile) != CONFIG_TRUE)
+    {
+        result = -1;
+    }
+
+    pisa_userlist_destroy(ul);
+
+    return result;
+}
+
+/**
+ * Removes a user_entry from the users configuration file
+ *
+ * @param hit Search for the entry by the given Hit.
+ *
+ * @return 0-> Error, 1-> Success, -1 -> Write error
+ */
+int pisa_mgmt_remove_userlist_entry_by_hit(char *hit)
+{
+
+    pisa_userlist *ul;
+    pisa_userlist_entry *entry;
+    int result = 0;
+
+    ul = pisa_userlist_build(USERS_SECTION);
+    entry = pisa_userlist_find_hit(ul, hit);
+
+    if (entry != NULL)
+    {
+        result = pisa_userlist_entry_remove(entry);
+    }
+
+    pisa_userlist_destroy(ul);
+    return result;
+}
+
+/**
+ * Removes a user_entry from the users configuration file
+ *
+ * @param name Search for the entry by the given username.
+ *
+ * @return 0-> Error, 1-> Success
+ */
+int pisa_mgmt_remove_userlist_entry_by_name(char *name)
+{
+    pisa_userlist *ul;
+    pisa_userlist_entry *entry;
+    int result = 0;
+
+    ul = pisa_userlist_build(USERS_SECTION);
+    entry = pisa_userlist_find_username(ul, name);
+
+    if (entry != NULL)
+    {
+        result = pisa_userlist_entry_remove(entry);
+    }
+
+    pisa_userlist_destroy(ul);
+    return result;
+}
+
+/**
+ * Removes a user_entry from the users configuration file
+ *
+ * @param entry Remove the given userlist_entry.
+ *
+ * @return 0-> Error, 1-> Success, -1 Write error
+ */
+static int pisa_userlist_entry_remove(pisa_userlist_entry *entry)
+{
+    config_setting_t *group;
+    config_setting_t *parent;
+
+    if (!entry)
+    {
+        return 0;
+    }
+
+    group = entry->group;
+    parent = config_setting_parent(group);
+
+    if (config_setting_remove_elem(parent, config_setting_index(group)) != 
CONFIG_TRUE)
+    {
+        DEBUG("Error removing HIT");
+        return 0;
+    }
+
+    if (config_write_file(&cfg, managementconf.userscfgfile) != CONFIG_TRUE)
+    {
+        return -1;
+    }
+
+    return 1;
+}
+
+/**
+ * Remove zeroes from HITs :0ba8 becomes :ba8
+ * @param hit Pointer to the HIT from which the zeroes should be removed
+ */
+static void remove_leading_zeroes_from_hit(char *hit)
+{
+    struct sockaddr_in6 hit_addr;
+    inet_pton(PF_INET6, hit, &(hit_addr.sin6_addr));
+    inet_ntop(AF_INET6, &(hit_addr.sin6_addr), hit, INET6_ADDRSTRLEN);
+}

Added: trunk/pairing/management.h
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ trunk/pairing/management.h  Wed Aug 19 11:54:30 2009        (r824)
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2009, Distributed Systems Group, RWTH Aachen
+ * All rights reserved.
+ */
+
+/**
+ * @file management.c
+ * @brief Management tool for the server daemon.
+ * @author Jan Marten <jan.marten@xxxxxxxxxxxxxx>
+ * @date Aug. 2009
+ */
+
+#ifndef MANAGEMENT_H_
+#define MANAGEMENT_H_
+
+#define MAX_USERNAME_LENGTH 100
+#define MAX_CREDIT_CARD_LENGTH 20
+
+#define USERS_SECTION "users"
+#define DEFAULT_USERS_CONFIG_FILE "users.conf"
+#define DEFAULT_AUTHORIZED_HOSTS_FILE "authorized_hosts.conf"
+
+#define ERROR_OPENING_CONFIG 2
+#define ERROR_NOT_FOUND 3
+#define ERROR_PARSING_COMMANDLINE 4
+#define ERROR_WRITING_CONFIG 5
+#define ERROR_GENERAL 6
+
+#define DEACTIVATED 0
+#define ACTIVATED 1
+#define NO_CHANGE 2
+
+/** This macro prints the given expression if true
+ * or a new line otherwise
+ */
+#define PRINT_ENTRY(func,fmt,args...) \
+       if(func) {\
+               printf( fmt , ## args);\
+       }else{ \
+               printf("\n"); \
+       }
+
+#define USE_DEFAULT_EXPIRATION 2
+
+#define OPTION_STRING "h:e:rl:u:a:f:c:s:p:"
+
+extern config_t authorized_cfg;
+
+enum mode 
{ADD_OR_EDIT,ADD_OR_EDIT_ONLY_HIT,REMOVE,REMOVE_ONLY_HIT,LIST_SINGLE,LIST_SINGLE_ONLY_HIT,LIST_ALL};
+enum list_mode {NORMAL,SHORT};
+
+typedef struct
+{
+    char hit[INET6_ADDRSTRLEN];
+    char user_name[MAX_USERNAME_LENGTH];
+    int active;
+    char expiration[LENGTH_TIMEOUT];
+    char creditcard[MAX_CREDIT_CARD_LENGTH];
+} pisa_userhitlist_entry;
+
+typedef struct
+{
+    char hit[INET6_ADDRSTRLEN];
+    config_setting_t *group;
+    char user_name[MAX_USERNAME_LENGTH];
+    int active;
+    char creditcard[MAX_CREDIT_CARD_LENGTH];
+} pisa_userlist_entry;
+
+typedef struct
+{
+       pisa_userhitlist_entry *entries;
+    int max_slots;
+    int cur_slots;
+
+} pisa_userhitlist;
+
+typedef struct
+{
+    pisa_userlist_entry *entries;
+    int max_slots;
+    int cur_slots;
+} pisa_userlist;
+
+struct options
+{
+    enum mode mode;
+    enum list_mode list_mode;
+};
+
+typedef struct
+{
+    char userscfgfile[MAX_PATH];
+    char authorizedcfgfile[MAX_PATH];
+} management_conf;
+
+void pisa_mgmt_print_usage(char *argv[]);
+int pisa_mgmt_parse_options(int argc, char *argv[],pisa_userhitlist_entry 
*new_entry,
+                  management_conf *mconf,struct options *options);
+pisa_userlist *pisa_userlist_build(const char *section);
+void pisa_userlist_entry_print(pisa_userlist_entry *entry,enum list_mode 
list_mode);
+void pisa_hitlist_entry_print(pisa_hitlist_entry *entry,enum list_mode 
list_mode);
+void pisa_userhitlist_entry_print(pisa_userhitlist_entry *entry,enum list_mode 
list_mode);
+int pisa_mgmt_users_config_write(pisa_userhitlist_entry *new_entry);
+int pisa_mgmt_remove_userlist_entry_by_hit(char *hit);
+int pisa_mgmt_remove_userlist_entry_by_name(char *name);
+
+#endif /*MANAGEMENT_H_*/

Modified: trunk/pairing/packet_handler_accept.c
==============================================================================
--- trunk/pairing/packet_handler_accept.c       Tue Aug 18 15:21:27 2009        
(r823)
+++ trunk/pairing/packet_handler_accept.c       Wed Aug 19 11:54:30 2009        
(r824)
@@ -7,9 +7,13 @@
  * @file packet_handler_accept.c
  * @brief post-accept process functions for packet handlers
  * @author Kate Harrison <harriska@xxxxxxxxxxxxx>
+ * @author Jan Marten <jan.marten@xxxxxxxxxxxxxx>
  * @date Sep. 2008
  */
 
+#include "global.h"    /* it must be included before all other header files */
+#include "config.h"
+#include "hitlist.h"
 #include "packet_handler_accept.h"
 
 
@@ -22,79 +26,53 @@
  */
 int handle_packet_password(struct sockaddr_in6 *socket_addr, header_password 
*hdr_pwd)
 {
-        int pwd_valid;
-        header_general *gen_hdr;
-        DEBUG_HIGH("Handling a password packet...");
+    int pwd_valid;
+    header_general *gen_hdr;
+    DEBUG_HIGH("Handling a password packet...");
+
+    assert(socket_addr != NULL);
+    assert(hdr_pwd != NULL);
+
+    pwd_valid = check_password((char*)&(hdr_pwd->password));
+
+    if (pwd_valid)
+    {
+        DEBUG_HIGH("Valid password.");
+        // Create ack_1 packet
+        gen_hdr = create_ack_1_struct();
+    }
+    else  // Transmit an error message
+    {
+        DEBUG_HIGH("Invalid password.");
+        gen_hdr = create_error_struct(ERROR_INVALID_PWD, "Invalid password. 
Please try again.");
+    }
+
+    CHECK_FOR_NULL_HDR(gen_hdr);
+
+    // Transmit message
+    SENDTO(global_accept.socket_desc, socket_addr, gen_hdr);
+
+    free(gen_hdr);
+
+    if (pwd_valid)
+        DEBUG_MED("ACK 1 message sent successfully.");
+    else
+        DEBUG_MED("Error message sent successfully.");
 
-        assert(socket_addr != NULL);
-        assert(hdr_pwd != NULL);
-
-        pwd_valid = check_password((char*)&(hdr_pwd->password));
-
-        if (pwd_valid)
-        {
-                DEBUG_HIGH("Valid password.");
-                // Create ack_1 packet
-                gen_hdr = create_ack_1_struct();
-        }
-        else  // Transmit an error message
+    if (pwd_valid)
+    {       // Write the user down in our database
+        char hit[INET6_ADDRSTRLEN];
+        char buf_expiration[LENGTH_TIMEOUT];
+        if(!get_default_expiration(buf_expiration))
         {
-                DEBUG_HIGH("Invalid password.");
-                gen_hdr = create_error_struct(ERROR_INVALID_PWD, "Invalid 
password. Please try again.");
+            return 0;
         }
 
-        CHECK_FOR_NULL_HDR(gen_hdr);
-
-        // Transmit message
-        SENDTO(global_accept.socket_desc, socket_addr, gen_hdr);
-
-        free(gen_hdr);
-
-        if (pwd_valid)
-                DEBUG_MED("ACK 1 message sent successfully.");
-        else
-                DEBUG_MED("Error message sent successfully.");
-
-        if (pwd_valid)
-        {       // Write the user down in our database
-                char hit[INET6_ADDRSTRLEN];
-                long int default_expiration_int;
-                int temp;
-
-                time_t expiration;
-                struct tm *ts;
-                char buf_expiration[LENGTH_TIMEOUT];
-
-                // Obtain the default expiration for a master-password-based 
connection (in minutes)
-                temp = get_config_setting(FILE_SERVER_CONFIG, 
"connection_settings.default_connection_expiration",
-                                          CONFIG_TYPE_INT, 
&default_expiration_int, 0);
-                if (temp == 0)  // Something failed in reading, debug printed 
by get_config_setting
-                {
-                        DEBUG("User not remembered.");
-                        return 0;
-                }
-                if (default_expiration_int == 0)
-                {
-                        DEBUG("Could not read setting 
\'connection_settings.default_connection_expiration\' in file %s", 
FILE_SERVER_CONFIG);
-                        DEBUG("User not remembered.");
-                        return 0;
-                }
-
-                default_expiration_int *= 60;   // Convert to seconds
-
-                time(&expiration);
-                expiration += default_expiration_int;  // Add default 
expiration to current time
-
-                // Convert to format: yyyy-mm-dd_hh:mm:ss
-                ts = localtime(&expiration);
-                strftime(buf_expiration, sizeof(buf_expiration), 
EXPIRATION_DATE_FORMAT, ts);
-                DEBUG_HIGH("Expiration: %s", (char *) &buf_expiration);
+        inet_ntop(AF_INET6, &socket_addr->sin6_addr, hit, sizeof(hit));
+        write_config(hit, buf_expiration, CONFIG_TYPE_HIT);
+    }
 
-                inet_ntop(AF_INET6, &socket_addr->sin6_addr, hit, sizeof(hit));
-                write_config(hit, buf_expiration, CONFIG_TYPE_HIT);
-        }
-
-        return 1;
+    return 1;
 }
 
 
@@ -107,41 +85,47 @@
  */
 int handle_packet_pwd_request(struct sockaddr_in6 *socket_addr, 
header_pwd_request *hdr_pwd_request)
 {
-        assert(socket_addr != NULL);
-        assert(hdr_pwd_request != NULL);
+    pisa_hitlist *allowed_hosts;
+    pisa_hitlist_entry *con;
 
-        header_general *gen_hdr;
-        char password[LENGTH_PASSWORD];
-        char hit[INET6_ADDRSTRLEN];
-        inet_ntop(AF_INET6, &(socket_addr->sin6_addr), hit, sizeof(hit));
+    assert(socket_addr != NULL);
+    assert(hdr_pwd_request != NULL);
 
-        if (!is_allowed_hit(hit))
-        {
-                gen_hdr = create_error_struct(ERROR_NOT_CONNECTED, "Sorry, but 
that HIT is not authenticated on this relay.");
-                CHECK_FOR_NULL_HDR(gen_hdr);
+    header_general *gen_hdr;
+    char password[LENGTH_PASSWORD];
 
-                // Transmit message
-                SENDTO(global_accept.socket_desc, socket_addr, gen_hdr);
+    // Check if HIT is in allowed_hosts list
+    allowed_hosts =  pisa_hitlist_build("allowed_hosts");
+    con = pisa_hitlist_find(allowed_hosts,&socket_addr->sin6_addr);
+
+    if(!con)
+    {
+        gen_hdr = create_error_struct(ERROR_NOT_CONNECTED, "Sorry, but that 
HIT is not authenticated on this relay.");
+        CHECK_FOR_NULL_HDR(gen_hdr);
 
-                free(gen_hdr);
+        // Transmit message
+        SENDTO(global_accept.socket_desc, socket_addr, gen_hdr);
 
-                return 0;
-        }
+        free(gen_hdr);
 
-        if (!store_pwd((char*)hdr_pwd_request->nickname, 
hdr_pwd_request->expiration1, hdr_pwd_request->expiration2, password))
-                return 0;
+        return 0;
+    }
 
-        // Create password ack structure
-        gen_hdr = create_ack_2_struct(password);
-        CHECK_FOR_NULL_HDR(gen_hdr);
+    if (!store_pwd((char*)hdr_pwd_request->nickname, 
hdr_pwd_request->expiration1, hdr_pwd_request->expiration2, password))
+        return 0;
 
-        // Send password ack structure
-        SENDTO(global_accept.socket_desc, socket_addr, gen_hdr);
+    // Create password ack structure
+    gen_hdr = create_ack_2_struct(password);
+    CHECK_FOR_NULL_HDR(gen_hdr);
 
-        free(gen_hdr);
+    // Send password ack structure
+    SENDTO(global_accept.socket_desc, socket_addr, gen_hdr);
 
+    pisa_hitlist_destroy(allowed_hosts);
+    free(gen_hdr);
 
-        return 1;
+
+    return 1;
 }
 
 
@@ -202,203 +186,110 @@
 int store_pwd(char *nickname, long int expr1, long int expr2, char *password)
 {
 
-        assert(nickname != NULL);
-        assert(password != NULL);
-
-        // Write down password
-        config_t cfg;
-        config_setting_t *root;
-        config_setting_t *allowed_passwords;
-        config_setting_t *new_pwd_grp, *new_nick, *new_pwd, *new_expire1, 
*new_expire2;
-        char expiration1[LENGTH_TIMEOUT], expiration2[LENGTH_TIMEOUT];
-
-        struct tm *ts;
-        time_t time_exp1, time_exp2;
-
-        /** @todo Generate password rather than write statically. **/
-        strcpy(password, "aachen2");
-
-        config_init(&cfg);
-        if (!config_read_file(&cfg, FILE_AUTHORIZED_HOSTS))
-        {
-                DEBUG("Could not read file \'%s\'.", FILE_AUTHORIZED_HOSTS);
-                return 0;
-        }
-
-        root = config_root_setting(&cfg);
-
-        allowed_passwords = config_lookup(&cfg, "allowed_passwords");
-        if (!allowed_passwords)
-        {
-                DEBUG_HIGH("List allowed_passwords did not previously exist. 
Creating...");
-                allowed_passwords = config_setting_add(root, 
"allowed_passwords", CONFIG_TYPE_LIST);
-        }
-
-        time(&time_exp1);
-        time(&time_exp2);
+    assert(nickname != NULL);
+    assert(password != NULL);
 
-        time_exp1 += expr1;
-        time_exp2 += expr2;
+    // Write down password
+    config_setting_t *allowed_passwords;
+    config_setting_t *new_pwd_grp, *new_nick, *new_pwd, *new_expire1, 
*new_expire2;
+    char expiration1[LENGTH_TIMEOUT], expiration2[LENGTH_TIMEOUT];
 
-        ts = localtime(&time_exp1);
-        strftime(expiration1, sizeof(expiration1), EXPIRATION_DATE_FORMAT, ts);
-        ts = localtime(&time_exp2);
-        strftime(expiration2, sizeof(expiration2), EXPIRATION_DATE_FORMAT, ts);
-
-        // Add a new group
-        new_pwd_grp = config_setting_add(allowed_passwords, NULL, 
CONFIG_TYPE_GROUP);
-
-        // Add the nickname
-        new_nick = config_setting_add(new_pwd_grp, "nickname", 
CONFIG_TYPE_STRING);
-        if (strlen(nickname) == 0)
-        {
-                DEBUG_HIGH("Reading nickname from config file.");
+    struct tm *ts;
+    time_t time_exp1, time_exp2;
 
-                // Read config file
-                int unknown_user_count_int;
-                char unknown_user_count_string[5];
-
-                config_t cfg;
-                config_setting_t *root;
-                config_setting_t *unknown_user_count_setting;
-                config_init(&cfg);
-
-               if (!config_read_file(&cfg, FILE_SERVER_CONFIG))
-                {
-                        DEBUG("Could not read file \'%s\'.", 
FILE_SERVER_CONFIG);
-                        return 0;
-                }
-
-                root = config_root_setting(&cfg);
-                unknown_user_count_setting = config_lookup(&cfg, 
"pwd_request_settings.unknown_user_count");
-                if (!unknown_user_count_setting)
-                {
-                        DEBUG("Error reading unknown user count setting from 
file %s.", FILE_SERVER_CONFIG);
-                        return 0;
-                }
-
-                // Build the default nickname
-                unknown_user_count_int = 
config_setting_get_int(unknown_user_count_setting);
-                strcpy(nickname, "unknown");
-                itoa(unknown_user_count_int, unknown_user_count_string);
-                strcat(nickname, unknown_user_count_string);
-
-                // Update the unknown user count
-                unknown_user_count_int++;
-                if (config_setting_set_int(unknown_user_count_setting, 
unknown_user_count_int) != CONFIG_TRUE)
-                {
-                        DEBUG("Error setting unknown user count.");
-                        return 0;
-                }
-
-                config_setting_set_string(new_nick, nickname);
-
-                if (config_write_file(&cfg, FILE_SERVER_CONFIG) == 
CONFIG_FALSE)
-                {
-                        DEBUG("Error writing to file %s.", FILE_SERVER_CONFIG);
-                        return 0;
-                }
-                config_destroy(&cfg);
-        }
-        else
-                config_setting_set_string(new_nick, nickname);
+    /** @todo Generate password rather than write statically. **/
+    strcpy(password, "aachen2");
 
-        // Add the password
-        new_pwd = config_setting_add(new_pwd_grp, "password", 
CONFIG_TYPE_STRING);
-        config_setting_set_string(new_pwd, password);
-        // Add the password expiration date
-        new_expire1 = config_setting_add(new_pwd_grp, "pwd_expires", 
CONFIG_TYPE_STRING);
-        config_setting_set_string(new_expire1, expiration1);
-        // Add the access expiration date
-        new_expire2 = config_setting_add(new_pwd_grp, "access_expires", 
CONFIG_TYPE_STRING);
-        config_setting_set_string(new_expire2, expiration2);
-
-        DEBUG_HIGH("Password information written.");
-        DEBUG_HIGH("\tNickname: %s", nickname);
-        DEBUG_HIGH("\tPassword: %s", password);
-        DEBUG_HIGH("\tExpiration 1: %s", expiration1);
-        DEBUG_HIGH("\tExpiration 2: %s", expiration2);
+    allowed_passwords = check_list("allowed_passwords");
 
-        config_write_file(&cfg, FILE_AUTHORIZED_HOSTS);
-        config_destroy(&cfg);
+    time(&time_exp1);
+    time(&time_exp2);
 
+    time_exp1 += expr1;
+    time_exp2 += expr2;
 
-        return 1;
-}
+    ts = localtime(&time_exp1);
+    strftime(expiration1, sizeof(expiration1), EXPIRATION_DATE_FORMAT, ts);
+    ts = localtime(&time_exp2);
+    strftime(expiration2, sizeof(expiration2), EXPIRATION_DATE_FORMAT, ts);
 
+    // Add a new group
+    new_pwd_grp = config_setting_add(allowed_passwords, NULL, 
CONFIG_TYPE_GROUP);
 
+    // Add the nickname
+    new_nick = config_setting_add(new_pwd_grp, "nickname", CONFIG_TYPE_STRING);
+    if (strlen(nickname) == 0)
+    {
+        DEBUG_HIGH("Reading nickname from config file.");
 
-/** Determines if the HIT is written in FILE_AUTHORIZED_HOSTS.
- *
- *  @param hit HIT to be tested.
- *
- *  @return 1 if found; 0 otherwise
- */
-int is_allowed_hit(char *hit)
-{
-        assert(hit != NULL);
+        // Read config file
+        int unknown_user_count_int;
+        char unknown_user_count_string[5];
 
         config_t cfg;
         config_setting_t *root;
-        config_setting_t *allowed_hosts;
-
+        config_setting_t *unknown_user_count_setting;
         config_init(&cfg);
-        if (!config_read_file(&cfg, FILE_AUTHORIZED_HOSTS))
+
+        if (!config_read_file(&cfg, FILE_SERVER_CONFIG))
         {
-                DEBUG("Could not read file \'%s\'.", FILE_AUTHORIZED_HOSTS);
-                return 0;
+            DEBUG("Could not read file \'%s\'.", FILE_SERVER_CONFIG);
+            return 0;
         }
 
         root = config_root_setting(&cfg);
+        unknown_user_count_setting = config_lookup(&cfg, 
"pwd_request_settings.unknown_user_count");
+        if (!unknown_user_count_setting)
+        {
+            DEBUG("Error reading unknown user count setting from file %s.", 
FILE_SERVER_CONFIG);
+            return 0;
+        }
 
-        allowed_hosts = config_lookup(&cfg, "allowed_hosts");
-        if (!allowed_hosts)
+        // Build the default nickname
+        unknown_user_count_int = 
config_setting_get_int(unknown_user_count_setting);
+        strcpy(nickname, "unknown");
+        itoa(unknown_user_count_int, unknown_user_count_string);
+        strcat(nickname, unknown_user_count_string);
+
+        // Update the unknown user count
+        unknown_user_count_int++;
+        if (config_setting_set_int(unknown_user_count_setting, 
unknown_user_count_int) != CONFIG_TRUE)
         {
-                DEBUG_HIGH("No HITs have been stored.");
-                return 0;
+            DEBUG("Error setting unknown user count.");
+            return 0;
         }
 
-        {       // Iterate over the list
-                const char* hit_text = NULL;
-                int length = config_setting_length(allowed_hosts);
-                int i;
-
-                for (i = 0; i < length; i++)
-                {
-                        config_setting_t *group_element = NULL;
-                        group_element = config_setting_get_elem(allowed_hosts, 
i);
-
-                        if (!group_element)
-                        {
-                                DEBUG("Error while parsing config file \'%s\'. 
Exiting function.", FILE_AUTHORIZED_HOSTS);
-                                return 0;
-                        }
-
-                        config_setting_t *this_hit = NULL;
-                        this_hit = config_setting_get_member(group_element, 
"hit");
-
-                        if (!this_hit)
-                        {
-                                DEBUG("Error extracting HIT from group %d in 
file %s. Exiting function.", i, FILE_AUTHORIZED_HOSTS);
-                                return 0;
-                        }
-
-                        hit_text = NULL;
-                        hit_text = config_setting_get_string(this_hit);
-
-                        if (hit_text != NULL && strlen(hit_text)>0)
-                                DEBUG("HIT = %s", hit_text);
-                        else
-                                DEBUG("Error extracting HIT.");
-
-                        if (identical_hits((char*)hit_text, hit) == 1)
-                                return 1;
-                }
+        config_setting_set_string(new_nick, nickname);
+
+        if (config_write_file(&cfg, FILE_SERVER_CONFIG) == CONFIG_FALSE)
+        {
+            DEBUG("Error writing to file %s.", FILE_SERVER_CONFIG);
+            return 0;
         }
+        config_destroy(&cfg);
+    }
+    else
+        config_setting_set_string(new_nick, nickname);
+
+    // Add the password
+    new_pwd = config_setting_add(new_pwd_grp, "password", CONFIG_TYPE_STRING);
+    config_setting_set_string(new_pwd, password);
+    // Add the password expiration date
+    new_expire1 = config_setting_add(new_pwd_grp, "pwd_expires", 
CONFIG_TYPE_STRING);
+    config_setting_set_string(new_expire1, expiration1);
+    // Add the access expiration date
+    new_expire2 = config_setting_add(new_pwd_grp, "access_expires", 
CONFIG_TYPE_STRING);
+    config_setting_set_string(new_expire2, expiration2);
+
+    DEBUG_HIGH("Password information written.");
+    DEBUG_HIGH("\tNickname: %s", nickname);
+    DEBUG_HIGH("\tPassword: %s", password);
+    DEBUG_HIGH("\tExpiration 1: %s", expiration1);
+    DEBUG_HIGH("\tExpiration 2: %s", expiration2);
 
+    pisa_cfg_write_authorized_hosts_file();
 
-        DEBUG_LOW("HIT \'%s\' not allowed. Ignoring request.", hit);
 
-        return 0;
+    return 1;
 }
 

Modified: trunk/pairing/packet_handler_accept.h
==============================================================================
--- trunk/pairing/packet_handler_accept.h       Tue Aug 18 15:21:27 2009        
(r823)
+++ trunk/pairing/packet_handler_accept.h       Wed Aug 19 11:54:30 2009        
(r824)
@@ -7,6 +7,7 @@
  * @file packet_handler_accept.h
  * @brief Header file of post-accept process functions for packet handlers
  * @author Kate Harrison <harriska@xxxxxxxxxxxxx>
+ * @author Jan Marten <jan.marten@xxxxxxxxxxxxxx>
  * @date Sep. 2008
  */
 
@@ -28,6 +29,5 @@
 int check_password(char *password);
 int handle_packet_pwd_request(struct sockaddr_in6 *socket_addr, 
header_pwd_request *hdr_pwd_request);
 int store_pwd(char *nickname, long int expr1, long int expr2, char *password);
-int is_allowed_hit(char *hit);
 
 #endif /* PISA_PAIR_PACKET_HANDLER_ACCEPT_H */

Other related posts:

  • » [pisa-src] r824 - in trunk: libpisa pairing - Jan Marten