- fix coverity 10365
[oweals/gnunet.git] / src / namestore / gnunet-namestore.c
index cc60798955313cc1b8b345442af3132efa1d857d..a79ec5e78d59aa8fc113712e5a35043baafc72a1 100644 (file)
 #include <gnunet_namestore_service.h>
 
 
+/**
+ * Hostkey generation context
+ */
+struct GNUNET_CRYPTO_RsaKeyGenerationContext * keygen;
+
 /**
  * Handle to the namestore.
  */
@@ -139,6 +144,12 @@ static void
 do_shutdown (void *cls,
             const struct GNUNET_SCHEDULER_TaskContext *tc)
 {
+  if (NULL != keygen)
+  {
+    GNUNET_CRYPTO_rsa_key_create_stop (keygen);
+    keygen = NULL;
+  }
+
   if (NULL != list_it)
   {
     GNUNET_NAMESTORE_zone_iteration_stop (list_it);
@@ -266,7 +277,7 @@ display_record (void *cls,
   const char *typestring;
   char *s;
   unsigned int i;
-  char *etime;
+  const char *etime;
   struct GNUNET_TIME_Absolute aex;
   struct GNUNET_TIME_Relative rex;
 
@@ -297,7 +308,7 @@ display_record (void *cls,
     if (0 != (rd[i].flags & GNUNET_NAMESTORE_RF_RELATIVE_EXPIRATION))
     {
       rex.rel_value = rd[i].expiration_time;
-      etime = GNUNET_STRINGS_relative_time_to_string (rex);
+      etime = GNUNET_STRINGS_relative_time_to_string (rex, GNUNET_YES);
     }
     else
     {
@@ -309,26 +320,18 @@ display_record (void *cls,
             ? _(/* what follows is relative expiration */ "for at least")
             : _(/* what follows is absolute expiration */ "until"),
             etime);
-    GNUNET_free (etime);
     GNUNET_free (s);    
   }
   FPRINTF (stdout, "%s", "\n");
   GNUNET_NAMESTORE_zone_iterator_next (list_it);
 }
 
-
-/**
- * Main function that will be run.
- *
- * @param cls closure
- * @param args remaining command-line arguments
- * @param cfgfile name of the configuration file used (for saving, can be NULL!)
- * @param cfg configuration
- */
 static void
-run (void *cls, char *const *args, const char *cfgfile,
-     const struct GNUNET_CONFIGURATION_Handle *cfg)
+key_generation_cb (void *cls,
+                   struct GNUNET_CRYPTO_RsaPrivateKey *pk,
+                   const char *emsg)
 {
+  struct GNUNET_CONFIGURATION_Handle *cfg = cls;
   struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pub;
   uint32_t type;
   void *data = NULL;
@@ -338,25 +341,14 @@ run (void *cls, char *const *args, const char *cfgfile,
   int etime_is_rel = GNUNET_SYSERR;
   struct GNUNET_NAMESTORE_RecordData rd;
 
-  if ( (NULL != args[0]) && (NULL == uri) )
-    uri = GNUNET_strdup (args[0]);
-  if (NULL == keyfile)
+  keygen = NULL;
+  if (NULL == pk)
   {
-    if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, "gns",
-                                                             "ZONEKEY", &keyfile))
-    {
-      fprintf (stderr,
-              _("Option `%s' not given, but I need a zone key file!\n"),
-              "z");
-      return;
-    }
-    fprintf (stderr,
-            _("Using default zone file `%s'\n"),
-            keyfile);
+    GNUNET_SCHEDULER_shutdown ();
+    return;
   }
-  zone_pkey = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile);
-  GNUNET_free (keyfile);
-  keyfile = NULL;
+  zone_pkey = pk;
+
   if (! (add|del|list|(NULL != uri)))
   {
     /* nothing more to be done */  
@@ -369,22 +361,22 @@ run (void *cls, char *const *args, const char *cfgfile,
   if (NULL == zone_pkey)
   {
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-               _("Failed to read or create private zone key\n"));
+                _("Failed to read or create private zone key\n"));
     return;
   }
   GNUNET_CRYPTO_rsa_key_get_public (zone_pkey,
-                                   &pub);
+                                    &pub);
   GNUNET_CRYPTO_short_hash (&pub, sizeof (pub), &zone);
 
   ns = GNUNET_NAMESTORE_connect (cfg);
   if (NULL == ns)
   {
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-               _("Failed to connect to namestore\n"));
+                _("Failed to connect to namestore\n"));
     return;
   }
   GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL,
-                               &do_shutdown, NULL);
+                                &do_shutdown, NULL);
   if (NULL == typestring)
     type = 0;
   else
@@ -399,8 +391,8 @@ run (void *cls, char *const *args, const char *cfgfile,
   if ((NULL == typestring) && (add | del))
   {
     fprintf (stderr,
-            _("Missing option `%s' for operation `%s'\n"),
-            "-t", _("add/del"));
+             _("Missing option `%s' for operation `%s'\n"),
+             "-t", _("add/del"));
     GNUNET_SCHEDULER_shutdown ();
     ret = 1;
     return;     
@@ -408,23 +400,23 @@ run (void *cls, char *const *args, const char *cfgfile,
   if (NULL != value)
   {
     if (GNUNET_OK !=
-       GNUNET_NAMESTORE_string_to_value (type,
-                                         value,
-                                         &data,
-                                         &data_size))
+        GNUNET_NAMESTORE_string_to_value (type,
+                                          value,
+                                          &data,
+                                          &data_size))
       {
-       fprintf (stderr, _("Value `%s' invalid for record type `%s'\n"), 
-                value,
-                typestring);
-       GNUNET_SCHEDULER_shutdown ();
-       ret = 1;
-       return;
+        fprintf (stderr, _("Value `%s' invalid for record type `%s'\n"),
+                 value,
+                 typestring);
+        GNUNET_SCHEDULER_shutdown ();
+        ret = 1;
+        return;
       }
   } else if (add | del)
   {
     fprintf (stderr,
-            _("Missing option `%s' for operation `%s'\n"),
-            "-V", _("add/del"));
+             _("Missing option `%s' for operation `%s'\n"),
+             "-V", _("add/del"));
     ret = 1;   
     GNUNET_SCHEDULER_shutdown ();
     return;     
@@ -437,43 +429,53 @@ run (void *cls, char *const *args, const char *cfgfile,
       etime_is_rel = GNUNET_NO;
     }
     else if (GNUNET_OK ==
-            GNUNET_STRINGS_fancy_time_to_relative (expirationstring,
-                                                   &etime_rel))
+             GNUNET_STRINGS_fancy_time_to_relative (expirationstring,
+                                                    &etime_rel))
     {
       etime_is_rel = GNUNET_YES;
     }
     else if (GNUNET_OK == 
-            GNUNET_STRINGS_fancy_time_to_absolute (expirationstring,
-                                                   &etime_abs))
+             GNUNET_STRINGS_fancy_time_to_absolute (expirationstring,
+                                                    &etime_abs))
     {
       etime_is_rel = GNUNET_NO;
     }
     else
     {
       fprintf (stderr,
-              _("Invalid time format `%s'\n"),
-              expirationstring);
+               _("Invalid time format `%s'\n"),
+               expirationstring);
       GNUNET_SCHEDULER_shutdown ();
       ret = 1;
       return;     
     }
+    if (etime_is_rel && del)
+    {
+      fprintf (stderr,
+               _("Deletion requires either absolute time, or no time at all. Got relative time `%s' instead.\n"),
+               expirationstring);
+      GNUNET_SCHEDULER_shutdown ();
+      ret = 1;
+      return;
+    }
   } 
   else if (add)
   {
     fprintf (stderr,
-            _("Missing option `%s' for operation `%s'\n"),
-            "-e", _("add"));
+             _("Missing option `%s' for operation `%s'\n"),
+             "-e", _("add"));
     GNUNET_SCHEDULER_shutdown ();
     ret = 1;    
     return;     
   }
+  memset (&rd, 0, sizeof (rd));
   if (add)
   {
     if (NULL == name)
     {
       fprintf (stderr,
-              _("Missing option `%s' for operation `%s'\n"),
-              "-n", _("add"));
+               _("Missing option `%s' for operation `%s'\n"),
+               "-n", _("add"));
       GNUNET_SCHEDULER_shutdown ();
       ret = 1;    
       return;     
@@ -491,8 +493,8 @@ run (void *cls, char *const *args, const char *cfgfile,
     else
     {
       fprintf (stderr,
-              _("No valid expiration time for operation `%s'\n"),
-              _("add"));
+               _("No valid expiration time for operation `%s'\n"),
+               _("add"));
       GNUNET_SCHEDULER_shutdown ();
       ret = 1;
       return;
@@ -502,19 +504,19 @@ run (void *cls, char *const *args, const char *cfgfile,
     if (1 != public)
       rd.flags |= GNUNET_NAMESTORE_RF_PRIVATE;
     add_qe = GNUNET_NAMESTORE_record_create (ns,
-                                            zone_pkey,
-                                            name,
-                                            &rd,
-                                            &add_continuation,
-                                            &add_qe);
+                                             zone_pkey,
+                                             name,
+                                             &rd,
+                                             &add_continuation,
+                                             &add_qe);
   }
   if (del)
   {
     if (NULL == name)
     {
       fprintf (stderr,
-              _("Missing option `%s' for operation `%s'\n"),
-              "-n", _("del"));
+               _("Missing option `%s' for operation `%s'\n"),
+               "-n", _("del"));
       GNUNET_SCHEDULER_shutdown ();
       ret = 1;
       return;     
@@ -523,13 +525,15 @@ run (void *cls, char *const *args, const char *cfgfile,
     rd.data_size = data_size;
     rd.record_type = type;
     rd.expiration_time = 0;
+    if (!etime_is_rel)
+      rd.expiration_time = etime_abs.abs_value;
     rd.flags = GNUNET_NAMESTORE_RF_AUTHORITY;
     del_qe = GNUNET_NAMESTORE_record_remove (ns,
-                                            zone_pkey,
-                                            name,
-                                            &rd,
-                                            &del_continuation,
-                                            NULL);
+                                             zone_pkey,
+                                             name,
+                                             &rd,
+                                             &del_continuation,
+                                             NULL);
   }
   if (list)
   {
@@ -542,11 +546,11 @@ run (void *cls, char *const *args, const char *cfgfile,
       must_not_flags |= GNUNET_NAMESTORE_RF_PRIVATE;
 
     list_it = GNUNET_NAMESTORE_zone_iteration_start (ns,
-                                                    &zone,
-                                                    GNUNET_NAMESTORE_RF_RELATIVE_EXPIRATION,
-                                                    must_not_flags,
-                                                    &display_record,
-                                                    NULL);
+                                                     &zone,
+                                                     GNUNET_NAMESTORE_RF_RELATIVE_EXPIRATION,
+                                                     must_not_flags,
+                                                     &display_record,
+                                                     NULL);
   }
   if (NULL != uri)
   {
@@ -555,15 +559,15 @@ run (void *cls, char *const *args, const char *cfgfile,
     struct GNUNET_CRYPTO_ShortHashCode sc;
 
     if ( (2 != (sscanf (uri,
-                       "gnunet://gns/%52s/%63s",
-                       sh,
-                       name)) ) ||
-        (GNUNET_OK !=
-         GNUNET_CRYPTO_short_hash_from_string (sh, &sc)) )
+                        "gnunet://gns/%52s/%63s",
+                        sh,
+                        name)) ) ||
+         (GNUNET_OK !=
+          GNUNET_CRYPTO_short_hash_from_string (sh, &sc)) )
     {
       fprintf (stderr, 
-              _("Invalid URI `%s'\n"),
-              uri);
+               _("Invalid URI `%s'\n"),
+               uri);
       GNUNET_SCHEDULER_shutdown ();
       ret = 1;
       return;
@@ -584,13 +588,74 @@ run (void *cls, char *const *args, const char *cfgfile,
       rd.flags |= GNUNET_NAMESTORE_RF_AUTHORITY;
 
     add_qe_uri = GNUNET_NAMESTORE_record_create (ns,
-                                                zone_pkey,
-                                                name,
-                                                &rd,
-                                                &add_continuation,
-                                                &add_qe_uri);
+                                                 zone_pkey,
+                                                 name,
+                                                 &rd,
+                                                 &add_continuation,
+                                                 &add_qe_uri);
   }
   GNUNET_free_non_null (data);
+
+}
+
+
+static void
+testservice_task (void *cls,
+                  const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+  struct GNUNET_CONFIGURATION_Handle *cfg = cls;
+
+  if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_TIMEOUT))
+  {
+      FPRINTF (stderr, _("Service `%s' is not running\n"), "namestore");
+      return;
+  }
+
+
+  if (NULL == keyfile)
+  {
+    if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, "gns",
+                                                              "ZONEKEY", &keyfile))
+    {
+      GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
+                                "gns", "ZONEKEY");
+      return;
+    }
+    fprintf (stderr,
+             _("Using default zone file `%s'\n"),
+             keyfile);
+  }
+  keygen = GNUNET_CRYPTO_rsa_key_create_start (keyfile, key_generation_cb, cfg);
+  GNUNET_free (keyfile);
+  keyfile = NULL;
+  if (NULL == keygen)
+  {
+    GNUNET_SCHEDULER_shutdown ();
+    ret = 1;
+  }
+}
+
+
+/**
+ * Main function that will be run.
+ *
+ * @param cls closure
+ * @param args remaining command-line arguments
+ * @param cfgfile name of the configuration file used (for saving, can be NULL!)
+ * @param cfg configuration
+ */
+static void
+run (void *cls, char *const *args, const char *cfgfile,
+     const struct GNUNET_CONFIGURATION_Handle *cfg)
+{
+
+  if ( (NULL != args[0]) && (NULL == uri) )
+    uri = GNUNET_strdup (args[0]);
+
+  GNUNET_CLIENT_service_test ("namestore", cfg,
+      GNUNET_TIME_UNIT_SECONDS,
+      &testservice_task,
+      (void *) cfg);
 }
 
 
@@ -653,8 +718,11 @@ main (int argc, char *const *argv)
                          _("GNUnet zone manipulation tool"), 
                          options,
                          &run, NULL))
+  {
+    GNUNET_free ((void*) argv);
     return 1;
-
+  }
+  GNUNET_free ((void*) argv);
   return ret;
 }