[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[gnunet] 01/27: GNS: Implementation of SBOX records
From: |
gnunet |
Subject: |
[gnunet] 01/27: GNS: Implementation of SBOX records |
Date: |
Thu, 14 Dec 2023 19:22:55 +0100 |
This is an automated email from the git hooks/post-receive script.
sebi pushed a commit to branch master
in repository gnunet.
commit 065ac6e4a865adbf2faa2d1a834f9acfebeca8ad
Author: Sebastian Nadler <sebastian.nadler@tum.de>
AuthorDate: Tue Dec 5 17:37:52 2023 +0100
GNS: Implementation of SBOX records
Fix memory allocation and string handling issues in plugin_gnsrecord_gns.c
and gnunet-service-gns_resolver.c
GNS: sbox records
Add SBox record
---
contrib/gana | 2 +-
src/cli/gns/test_gns_sbox.sh | 40 ++++++++++
src/include/gnu_name_system_record_types.h | 6 ++
src/include/gnunet_gnsrecord_lib.h | 41 +++++++++--
src/lib/util/gnunet_error_codes.c | 1 -
src/plugin/gns/plugin_gnsrecord_gns.c | 101 ++++++++++++++++++++++++++
src/service/gns/gnunet-service-gns_resolver.c | 87 +++++++++++++++++++---
7 files changed, 257 insertions(+), 21 deletions(-)
diff --git a/contrib/gana b/contrib/gana
index 557051695..055954720 160000
--- a/contrib/gana
+++ b/contrib/gana
@@ -1 +1 @@
-Subproject commit 557051695c575b45fb1bfdbacbc69d67c6908425
+Subproject commit 055954720d88d80a98edb11abc232925b7d42758
diff --git a/src/cli/gns/test_gns_sbox.sh b/src/cli/gns/test_gns_sbox.sh
new file mode 100755
index 000000000..b00b813f7
--- /dev/null
+++ b/src/cli/gns/test_gns_sbox.sh
@@ -0,0 +1,40 @@
+#!/bin/sh
+# This file is in the public domain.
+trap "gnunet-arm -e -c test_gns_lookup.conf" INT
+
+LOCATION=$(which gnunet-config)
+if [ -z $LOCATION ]
+then
+ LOCATION="gnunet-config"
+fi
+$LOCATION --version 1> /dev/null
+if test $? != 0
+then
+ echo "GNUnet command line tools cannot be found, check environmental
variables PATH and GNUNET_PREFIX"
+ exit 77
+fi
+
+rm -rf `gnunet-config -c test_gns_lookup.conf -f -s paths -o GNUNET_TEST_HOME`
+which timeout > /dev/null 2>&1 && DO_TIMEOUT="timeout 30"
+TEST_A="139.134.54.9"
+MY_EGO="myego"
+LABEL="testsbox"
+HASH="c93f1e400f26708f98cb19d936620da35eec8f72e57f9eec01c1afd6"
+SERVICE_TEXT="_tcp"
+gnunet-arm -s -c test_gns_lookup.conf
+gnunet-identity -C $MY_EGO -c test_gns_lookup.conf
+gnunet-namestore -p -z $MY_EGO -a -n $LABEL -t SBOX -V "$HASH.$SERVICE_TEXT 1
$TEST_A" -e never -c test_gns_lookup.conf
+sleep 0.5
+RES_A=`$DO_TIMEOUT gnunet-gns --raw -u $HASH.$SERVICE_TEXT.$LABEL.$MY_EGO -t A
-c test_gns_lookup.conf`
+gnunet-namestore -z $MY_EGO -d -n $LABEL -t SBOX -V "$HASH.$SERVICE_TEXT 1
$TEST_A" -e never -c test_gns_lookup.conf
+gnunet-identity -D $MY_EGO -c test_gns_lookup.conf
+gnunet-arm -e -c test_gns_lookup.conf
+rm -rf `gnunet-config -c test_gns_lookup.conf -f -s paths -o GNUNET_TEST_HOME`
+
+if [ "$RES_A" = "$TEST_A" ]
+then
+ exit 0
+else
+ echo "Failed to resolve to proper A, got '$RES_A'."
+ exit 1
+fi
diff --git a/src/include/gnu_name_system_record_types.h
b/src/include/gnu_name_system_record_types.h
index 2cefce589..8ab9c09d5 100644
--- a/src/include/gnu_name_system_record_types.h
+++ b/src/include/gnu_name_system_record_types.h
@@ -97,6 +97,12 @@ extern "C" {
#define GNUNET_GNSRECORD_TYPE_RECLAIM_TICKET 65545
+/**
+ * SBox record
+ */
+#define GNUNET_GNSRECORD_TYPE_SBOX 65547
+
+
/**
* For ABD policies
*/
diff --git a/src/include/gnunet_gnsrecord_lib.h
b/src/include/gnunet_gnsrecord_lib.h
index 813409340..b4e45727b 100644
--- a/src/include/gnunet_gnsrecord_lib.h
+++ b/src/include/gnunet_gnsrecord_lib.h
@@ -331,6 +331,31 @@ struct GNUNET_GNSRECORD_BoxRecord
/* followed by the 'original' record */
};
+
+/**
+ * Record type used to box up SMIMEA records. For example, a
+ * SMIMEA record for "c93f1e400f26708f98cb19d936620da35eec8f72e57
+ * f9eec01c1afd6._smimecert.foo.gnu" will be stored under
+ * "foo.gnu" as a SBOX record with the local-path of the associated
+ * e-mails hash turnicated to 28 octets encoded as hex and protocol _smimecert
+ * and record_type "SMIMEA". When a BOX record is received, GNS
+ * unboxes it if the name contained "hash._PROTO", otherwise GNS
+ * leaves it untouched. This is done to ensure that SMIMEA
+ * records do not require a separate network request, thus making SMIMEA
+ * records inseparable from the "main" A/AAAA/VPN/etc. records.
+ */
+struct GNUNET_GNSRECORD_SBoxRecord
+{
+ /**
+ * GNS record type of the boxed record. In NBO.
+ */
+ uint32_t record_type GNUNET_PACKED;
+
+ /* followed by the zero terminated hostname prefix */
+ /* followed by the 'original' record */
+};
+
+
/**
* Record type used internally to keep track of reverse mappings into a
* namespace.
@@ -836,9 +861,9 @@ GNUNET_GNSRECORD_label_check (const char*label, char
**emsg);
/**
* Maximum length of a revocation
*/
-#define GNUNET_MAX_POW_SIZE sizeof(struct GNUNET_GNSRECORD_PowP) +\
- sizeof(struct
GNUNET_CRYPTO_PublicKey) +\
- 1024 //FIXME max sig_len
+#define GNUNET_MAX_POW_SIZE sizeof(struct GNUNET_GNSRECORD_PowP) \
+ + sizeof(struct GNUNET_CRYPTO_PublicKey) \
+ + 1024 // FIXME max sig_len
/**
* The proof-of-work narrowing factor.
@@ -910,8 +935,8 @@ struct GNUNET_GNSRECORD_PowCalculationHandle;
*/
enum GNUNET_GenericReturnValue
GNUNET_GNSRECORD_check_pow (const struct GNUNET_GNSRECORD_PowP *pow,
- unsigned int matching_bits,
- struct GNUNET_TIME_Relative epoch_duration);
+ unsigned int matching_bits,
+ struct GNUNET_TIME_Relative epoch_duration);
/**
@@ -922,7 +947,7 @@ GNUNET_GNSRECORD_check_pow (const struct
GNUNET_GNSRECORD_PowP *pow,
*/
void
GNUNET_GNSRECORD_pow_init (const struct GNUNET_CRYPTO_PrivateKey *key,
- struct GNUNET_GNSRECORD_PowP *pow);
+ struct GNUNET_GNSRECORD_PowP *pow);
/**
@@ -936,8 +961,8 @@ GNUNET_GNSRECORD_pow_init (const struct
GNUNET_CRYPTO_PrivateKey *key,
*/
struct GNUNET_GNSRECORD_PowCalculationHandle*
GNUNET_GNSRECORD_pow_start (struct GNUNET_GNSRECORD_PowP *pow,
- int epochs,
- unsigned int difficulty);
+ int epochs,
+ unsigned int difficulty);
/**
diff --git a/src/lib/util/gnunet_error_codes.c
b/src/lib/util/gnunet_error_codes.c
index c286f2e52..11ce2d0c8 100644
--- a/src/lib/util/gnunet_error_codes.c
+++ b/src/lib/util/gnunet_error_codes.c
@@ -17,7 +17,6 @@
SPDX-License-Identifier: AGPL3.0-or-later
*/
-#include "platform.h"
#include "gnunet_error_codes.h"
#include <stddef.h>
#include <microhttpd.h>
diff --git a/src/plugin/gns/plugin_gnsrecord_gns.c
b/src/plugin/gns/plugin_gnsrecord_gns.c
index 65587172d..2803d32a4 100644
--- a/src/plugin/gns/plugin_gnsrecord_gns.c
+++ b/src/plugin/gns/plugin_gnsrecord_gns.c
@@ -132,6 +132,36 @@ gns_value_to_string (void *cls,
GNUNET_free (ival);
return box_str;
}
+ case GNUNET_GNSRECORD_TYPE_SBOX: {
+ struct GNUNET_GNSRECORD_SBoxRecord box;
+ uint32_t rt;
+ char *box_str;
+ char *ival;
+ char *prefix;
+
+ cdata = data;
+ if (data_size < sizeof(struct GNUNET_GNSRECORD_SBoxRecord))
+ return NULL; /* malformed */
+ GNUNET_memcpy (&box, data, sizeof(box));
+ rt = ntohl (box.record_type);
+
+ prefix = GNUNET_strdup (&cdata[sizeof(box)]);
+ ival = GNUNET_GNSRECORD_value_to_string (rt, &cdata[sizeof(box)
+ + strlen (prefix)
+ + 1],
+ data_size - sizeof(box)
+ - strlen (prefix) - 1);
+ if (NULL == ival)
+ return NULL; /* malformed */
+ GNUNET_asprintf (&box_str,
+ "%s %u %s",
+ prefix,
+ (unsigned int) rt,
+ ival);
+ GNUNET_free (prefix);
+ GNUNET_free (ival);
+ return box_str;
+ }
case GNUNET_GNSRECORD_TYPE_TOMBSTONE: {
return GNUNET_strdup (_ (
"This is a memento of an older block for
internal maintenance."));
@@ -302,6 +332,76 @@ gns_string_to_value (void *cls,
GNUNET_free (bval);
return GNUNET_OK;
}
+ case GNUNET_GNSRECORD_TYPE_SBOX: {
+ struct GNUNET_GNSRECORD_SBoxRecord *box;
+ size_t rest;
+ char *prefix;
+ unsigned int protocol;
+ unsigned int record_type;
+ void *bval;
+ size_t bval_size;
+ prefix = GNUNET_malloc (strlen (s)); // TODO The allocated memory is
bigger than needed
+ size_t prefix_size;
+ if (2 != sscanf (s, "%s %u ", prefix, &record_type))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ _ ("Unable to parse SBOX record string `%s'\n"),
+ s);
+ return GNUNET_SYSERR;
+ }
+ if (prefix == NULL)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ _ (
+ "Unable to parse SBOX record string `%s', no prefix
found\n"),
+ s);
+ return GNUNET_SYSERR;
+ }
+ char *last_underscore = strrchr (prefix, (int) '_');
+ if (last_underscore == NULL)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ _ (
+ "Unable to parse SBOX record string `%s', no underscore
fund\n"),
+ prefix);
+ return GNUNET_SYSERR;
+ }
+ char *dot_in_last_prefix = strchr (last_underscore, '.');
+ if (dot_in_last_prefix != NULL)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ _ (
+ "Unable to parse SBOX record string `%s', the last label
does not have an underscore\n"),
+ prefix);
+ return GNUNET_SYSERR;
+ }
+ if (prefix < last_underscore && last_underscore[-1] != '.')
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ _ (
+ "Unable to parse SBOX record string `%s', the last label
does not start with an underscore\n"),
+ prefix);
+ return GNUNET_SYSERR;
+ }
+ rest = snprintf (NULL, 0, "%s %u ", prefix, record_type);
+ if (GNUNET_OK != GNUNET_GNSRECORD_string_to_value (record_type,
+ &s[rest],
+ &bval,
+ &bval_size))
+ return GNUNET_SYSERR;
+ prefix_size = strlen (prefix) + 1; // with NULL terminator
+ *data_size = sizeof(struct GNUNET_GNSRECORD_SBoxRecord) + prefix_size
+ + bval_size;
+ void *p = *data = box = GNUNET_malloc (*data_size);
+ box->record_type = htonl (record_type);
+ p += sizeof(struct GNUNET_GNSRECORD_SBoxRecord);
+ GNUNET_memcpy (p, prefix, prefix_size);
+ p += prefix_size;
+ GNUNET_memcpy (p, bval, bval_size);
+ GNUNET_free (bval);
+ GNUNET_free (prefix);
+ return GNUNET_OK;
+ }
case GNUNET_GNSRECORD_TYPE_TOMBSTONE: {
*data_size = 0;
*data = NULL;
@@ -330,6 +430,7 @@ static struct
{ "VPN", GNUNET_GNSRECORD_TYPE_VPN },
{ "GNS2DNS", GNUNET_GNSRECORD_TYPE_GNS2DNS },
{ "BOX", GNUNET_GNSRECORD_TYPE_BOX },
+ { "SBOX", GNUNET_GNSRECORD_TYPE_SBOX },
{ "REDIRECT", GNUNET_GNSRECORD_TYPE_REDIRECT },
/* Tombstones should never be added manually
* so this makes sense, kind of */
diff --git a/src/service/gns/gnunet-service-gns_resolver.c
b/src/service/gns/gnunet-service-gns_resolver.c
index 445ae3346..85a72910a 100644
--- a/src/service/gns/gnunet-service-gns_resolver.c
+++ b/src/service/gns/gnunet-service-gns_resolver.c
@@ -368,6 +368,12 @@ struct GNS_ResolverHandle
*/
int service;
+ /**
+ * For SMIMEA,OPENPGPKEY... records. NULL if no _ prefix was given.
+ */
+ char *prefix;
+
+
/**
* Desired type for the resolution.
*/
@@ -657,14 +663,13 @@ resolver_lookup_get_next_label (struct GNS_ResolverHandle
*rh)
rp = rh->name;
rh->name_resolution_pos = 0;
}
- else if (('_' == dot[1]) &&
- ('_' == rh->name[0]) &&
- (dot == memchr (rh->name, (int) '.', rh->name_resolution_pos)))
+ else if ('_' == dot[1])
{
/**
* Do not advance a label. This seems to be a name only consisting
- * of a BOX indicator (_443,_tcp).
- * Which means, it is a BOX under the empty label.
+ * of a prefix. Indicating a BOX record (_443,_tcp)
+ * Or some version of an SBOX record (HEX,_smimeacert)
+ * Which means, it is a BOX/SBOX under the empty label.
* leaving name_resolution_pos as is and returning empty label.
*/
rp = GNUNET_GNS_EMPTY_LABEL_AT;
@@ -679,8 +684,9 @@ resolver_lookup_get_next_label (struct GNS_ResolverHandle
*rh)
}
rh->protocol = 0;
rh->service = 0;
+ rh->prefix = NULL;
ret = GNUNET_strndup (rp, len);
- /* If we have labels starting with underscore with label on
+ /** If we have labels starting with underscore with label on
* the right (SRV/DANE/BOX case), determine port/protocol;
* The format of `rh->name` must be "_PORT._PROTOCOL".
*/
@@ -703,10 +709,12 @@ resolver_lookup_get_next_label (struct GNS_ResolverHandle
*rh)
if (0 == protocol)
{
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- _ ("Protocol `%s' unknown, skipping labels.\n"),
+ _ (
+ "Protocol `%s' unknown, skipping labels as BOX retain as
SBOX.\n"),
proto_name);
GNUNET_free (proto_name);
GNUNET_free (srv_name);
+ rh->prefix = GNUNET_strndup (rh->name, strlen (rh->name) - len - 1);
return ret;
}
service = resolver_getservbyname (srv_name,
@@ -721,10 +729,12 @@ resolver_lookup_get_next_label (struct GNS_ResolverHandle
*rh)
if (1 != sscanf (srv_name, "%u", &rh->service))
{
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- _ ("Service `%s' not a port, skipping service labels.\n"),
+ _ (
+ "Service `%s' not a port, skipping service labels as BOX
retain as SBOX.\n"),
srv_name);
GNUNET_free (proto_name);
GNUNET_free (srv_name);
+ rh->prefix = GNUNET_strndup (rh->name, strlen (rh->name) - len - 1);
return ret;
}
}
@@ -736,6 +746,20 @@ resolver_lookup_get_next_label (struct GNS_ResolverHandle
*rh)
GNUNET_free (proto_name);
GNUNET_free (srv_name);
}
+ /**
+ * If we have labels starting with underscore with label on
+ * the right, copy prefix to rh->prefix;
+ * The format of `rh->name` must be "*._label",
+ * where label is a string without '.'.
+ */
+ if ((NULL != (dot = memrchr (rh->name,
+ (int) '.',
+ rh->name_resolution_pos)) && '_' == dot[1]) ||
+ '_' == rh->name[0])
+ {
+ rh->name_resolution_pos = 0;
+ rh->prefix = GNUNET_strndup (rh->name, strlen (rh->name) - len - 1);
+ }
return ret;
}
@@ -2040,9 +2064,10 @@ handle_gns_resolution_result (void *cls,
for (unsigned int i = 0; i < rd_count; i++)
{
GNUNET_assert (rd_off <= i);
- if ((0 != rh->protocol) &&
- (0 != rh->service) &&
- (GNUNET_GNSRECORD_TYPE_BOX != rd[i].record_type))
+ if ((((0 != rh->protocol) &&
+ (0 != rh->service)) || (NULL != rh->prefix)) &&
+ (GNUNET_GNSRECORD_TYPE_BOX != rd[i].record_type &&
+ GNUNET_GNSRECORD_TYPE_SBOX != rd[i].record_type))
if (GNUNET_GNSRECORD_TYPE_PKEY != rd[i].record_type &&
GNUNET_GNSRECORD_TYPE_EDKEY != rd[i].record_type)
continue;
@@ -2357,7 +2382,47 @@ handle_gns_resolution_result (void *cls,
}
break;
}
+ case GNUNET_GNSRECORD_TYPE_SBOX:
+ {
+ /* unbox SMIMEA/OPENPGPKEY records if a specific one was requested */
+ if ((rh->prefix != NULL) &&
+ (rd[i].data_size >= sizeof(struct GNUNET_GNSRECORD_SBoxRecord)))
+ {
+ const struct GNUNET_GNSRECORD_SBoxRecord *box;
+ box = rd[i].data;
+ char *prefix = GNUNET_strdup (&box[1]);
+ size_t prefix_len = strlen (prefix) + 1;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Got SBOX record, checking if prefixes match... %s vs
%s\n",
+ prefix, rh->prefix);
+ if (strcmp (rh->prefix, prefix) == 0)
+ {
+ /* Box matches, unbox! */
+ GNUNET_assert (rd_off < rd_count);
+ rd_new[rd_off].record_type = ntohl (box->record_type);
+ rd_new[rd_off].data_size -= sizeof(struct
+ GNUNET_GNSRECORD_SBoxRecord)
+ + prefix_len;
+ rd_new[rd_off].data = &rd[i].data[sizeof(struct
+
GNUNET_GNSRECORD_SBoxRecord)
+ + prefix_len];
+ rd_off++;
+ }
+ GNUNET_free (prefix);
+ }
+ else
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ _ (
+ "GNS no specific protocol/service specified,
preserve all SBOX `%s')\n"),
+ rh->name);
+ /* no specific protocol/service specified, preserve all SBOX
+ records (for modern, GNS-enabled applications) */
+ rd_off++;
+ }
+ break;
+ }
default:
rd_off++;
break;
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.
- [gnunet] branch master updated (55acf39e2 -> b92af915f), gnunet, 2023/12/14
- [gnunet] 04/27: Transport: Added logging in case of UDP errors, and destroy queue in case of errors., gnunet, 2023/12/14
- [gnunet] 02/27: SBOX: Fix memory leaks in gns resovler, gnunet, 2023/12/14
- [gnunet] 01/27: GNS: Implementation of SBOX records,
gnunet <=
- [gnunet] 03/27: GNS: Add test_gns_box_sbox.sh and test_gns_sbox.sh scripts, gnunet, 2023/12/14
- [gnunet] 07/27: Transport: Fixed bugs in core message cache., gnunet, 2023/12/14
- [gnunet] 10/27: Transport: Fixed bug to check each queue for validity separately., gnunet, 2023/12/14
- [gnunet] 06/27: Transport: Removed misplaced removal of QueueEntry., gnunet, 2023/12/14
- [gnunet] 08/27: Transport: We need to check if a message was cached when resuming communicators., gnunet, 2023/12/14
- [gnunet] 09/27: Transport: Fixed bug handling queue length and QueueEntry when queue has no capacity., gnunet, 2023/12/14
- [gnunet] 12/27: build: update sqlite version requirement, gnunet, 2023/12/14
- [gnunet] 11/27: Transport: More useful debug logging für service., gnunet, 2023/12/14
- [gnunet] 05/27: Transport: Fixed bug in handling of AckPending., gnunet, 2023/12/14
- [gnunet] 22/27: meson: add blind signature sources to util - slack coder, gnunet, 2023/12/14