summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2018-10-25 10:57:35 +0200
committerChristian Grothoff <christian@grothoff.org>2018-10-25 10:58:10 +0200
commit9b52c9179b935f3afbf7119e37af2bf6685efa20 (patch)
tree5b79cd65fc0d79e54e7e9a632bb16140edeb6eeb /src
parentf7c6752d8dcda6d73ea9ee93cc8cef1290c45c48 (diff)
add possibility of hijacking any (sub)domain, not just TLDs, via configuration file [gns] section
Diffstat (limited to 'src')
-rw-r--r--src/gns/Makefile.am1
-rw-r--r--src/gns/gns_tld_api.c94
-rwxr-xr-xsrc/gns/test_gns_config_lookup.sh44
3 files changed, 97 insertions, 42 deletions
diff --git a/src/gns/Makefile.am b/src/gns/Makefile.am
index 2659f7e6a..e0497b11e 100644
--- a/src/gns/Makefile.am
+++ b/src/gns/Makefile.am
@@ -235,6 +235,7 @@ libgnunet_plugin_block_gns_la_LDFLAGS = \
check_SCRIPTS = \
test_gns_lookup.sh \
+ test_gns_config_lookup.sh \
test_gns_ipv6_lookup.sh\
test_gns_txt_lookup.sh\
test_gns_mx_lookup.sh \
diff --git a/src/gns/gns_tld_api.c b/src/gns/gns_tld_api.c
index 825b51d06..55ee30bd9 100644
--- a/src/gns/gns_tld_api.c
+++ b/src/gns/gns_tld_api.c
@@ -92,7 +92,7 @@ struct GNUNET_GNS_LookupWithTldRequest
* @return the part of @a name after the last ".",
* or @a name if @a name does not contain a "."
*/
-static char *
+static const char *
get_tld (const char *name)
{
const char *tld;
@@ -103,28 +103,31 @@ get_tld (const char *name)
tld = name;
else
tld++; /* skip the '.' */
- return GNUNET_strdup (tld);
+ return tld;
}
/**
- * Eat the TLD of the given @a name.
+ * Eat the "TLD" (last bit) of the given @a name.
*
* @param[in,out] name a name
+ * @param tld what to eat (can be more than just the tld)
*/
static void
-eat_tld (char *name)
+eat_tld (char *name,
+ const char *tld)
{
- char *tld;
-
GNUNET_assert (0 < strlen (name));
- tld = strrchr (name,
- (unsigned char) '.');
if (NULL == tld)
+ {
strcpy (name,
GNUNET_GNS_EMPTY_LABEL_AT);
+ }
else
- *tld = '\0';
+ {
+ GNUNET_assert (strlen (tld) < strlen (name));
+ name[strlen(name) - strlen(tld) - 1] = '\0';
+ }
}
@@ -227,7 +230,7 @@ GNUNET_GNS_lookup_with_tld (struct GNUNET_GNS_Handle *handle,
void *proc_cls)
{
struct GNUNET_GNS_LookupWithTldRequest *ltr;
- char *tld;
+ const char *tld;
char *dot_tld;
char *zonestr;
struct GNUNET_CRYPTO_EcdsaPublicKey pkey;
@@ -246,51 +249,59 @@ GNUNET_GNS_lookup_with_tld (struct GNUNET_GNS_Handle *handle,
strlen (tld),
&pkey))
{
- eat_tld (ltr->name);
+ eat_tld (ltr->name,
+ tld);
lookup_with_public_key (ltr,
&pkey);
- GNUNET_free (tld);
return ltr;
}
- /* second case: TLD is mapped in our configuration file */
- GNUNET_asprintf (&dot_tld,
- ".%s",
- tld);
- if (GNUNET_OK ==
- GNUNET_CONFIGURATION_get_value_string (handle->cfg,
- "gns",
- dot_tld,
- &zonestr))
+ /* second case: domain is mapped in our configuration file */
+ for (const char *domain = name;
+ NULL != domain;
+ domain = strchr (domain,
+ (unsigned char) '.'))
{
- if (GNUNET_OK !=
- GNUNET_CRYPTO_ecdsa_public_key_from_string (zonestr,
- strlen (zonestr),
- &pkey))
+ if ('.' == domain[0])
+ domain++;
+ GNUNET_asprintf (&dot_tld,
+ ".%s",
+ domain);
+ if (GNUNET_OK ==
+ GNUNET_CONFIGURATION_get_value_string (handle->cfg,
+ "gns",
+ dot_tld,
+ &zonestr))
{
- GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
- "gns",
- dot_tld,
- _("Expected a base32-encoded public zone key\n"));
+ if (GNUNET_OK !=
+ GNUNET_CRYPTO_ecdsa_public_key_from_string (zonestr,
+ strlen (zonestr),
+ &pkey))
+ {
+ GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
+ "gns",
+ dot_tld,
+ _("Expected a base32-encoded public zone key\n"));
+ GNUNET_free (zonestr);
+ GNUNET_free (dot_tld);
+ GNUNET_free (ltr->name);
+ GNUNET_free (ltr);
+ return NULL;
+ }
+ eat_tld (ltr->name,
+ &dot_tld[1]);
GNUNET_free (zonestr);
GNUNET_free (dot_tld);
- GNUNET_free (ltr->name);
- GNUNET_free (ltr);
- GNUNET_free (tld);
- return NULL;
+ lookup_with_public_key (ltr,
+ &pkey);
+ return ltr;
}
GNUNET_free (dot_tld);
- GNUNET_free (zonestr);
- eat_tld (ltr->name);
- lookup_with_public_key (ltr,
- &pkey);
- GNUNET_free (tld);
- return ltr;
}
- GNUNET_free (dot_tld);
/* Final case: TLD matches one of our egos */
- eat_tld (ltr->name);
+ eat_tld (ltr->name,
+ tld);
/* if the name is of the form 'label' (and not 'label.SUBDOMAIN'), never go to the DHT */
if (NULL == strchr (ltr->name,
@@ -302,7 +313,6 @@ GNUNET_GNS_lookup_with_tld (struct GNUNET_GNS_Handle *handle,
tld,
&identity_zone_cb,
ltr);
- GNUNET_free (tld);
if (NULL == ltr->id_op)
{
GNUNET_free (ltr->name);
diff --git a/src/gns/test_gns_config_lookup.sh b/src/gns/test_gns_config_lookup.sh
new file mode 100755
index 000000000..35d7c32d9
--- /dev/null
+++ b/src/gns/test_gns_config_lookup.sh
@@ -0,0 +1,44 @@
+#!/bin/bash
+# This file is in the public domain.
+trap "gnunet-arm -e -c test_gns_lookup.conf" SIGINT
+
+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
+MY_EGO="myego"
+
+rm -rf `gnunet-config -c test_gns_lookup.conf -s PATHS -o GNUNET_HOME -f`
+CFG=`mktemp --tmpdir=$PWD`
+cp test_gns_lookup.conf $CFG || exit 77
+which timeout &> /dev/null && DO_TIMEOUT="timeout 5"
+TEST_IP="dead::beef"
+gnunet-arm -s -c $CFG || exit 77
+gnunet-identity -C $MY_EGO -c $CFG
+EPUB=`gnunet-identity -d -c $CFG | grep $MY_EGO | awk '{print $3}'`
+gnunet-arm -e -c $CFG
+gnunet-config -c $CFG -s "gns" -o ".google.com" -V $EPUB
+gnunet-arm -s -c $CFG
+sleep 1
+gnunet-namestore -p -z $MY_EGO -a -n www -t AAAA -V $TEST_IP -e never -c $CFG
+RES_IP=`$DO_TIMEOUT gnunet-gns --raw -u www.google.com -t AAAA -c $CFG`
+gnunet-namestore -z $MY_EGO -d -n www -t AAAA -V $TEST_IP -e never -c $CFG
+gnunet-identity -D $MY_EGO -c $CFG
+gnunet-arm -e -c $CFG
+rm -rf `gnunet-config -c $CFG -f -s paths -o GNUNET_TEST_HOME`
+rm $CFG
+
+if [ "$RES_IP" == "$TEST_IP" ]
+then
+ exit 0
+else
+ echo "Failed to resolve to proper IP, got $RES_IP."
+ exit 1
+fi