X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Fgns%2Fplugin_gnsrecord_gns.c;h=ebba0db47c6218e7ad7d4066006a4df9e37dc42e;hb=6485325f72b588c838f8b6d9e12c50c642e493b8;hp=87238498a5e4037d1045a81efa8e1ddbb8825aa6;hpb=54d912e8c447f302172bf6dc3b3fe6769f4ac685;p=oweals%2Fgnunet.git diff --git a/src/gns/plugin_gnsrecord_gns.c b/src/gns/plugin_gnsrecord_gns.c index 87238498a..ebba0db47 100644 --- a/src/gns/plugin_gnsrecord_gns.c +++ b/src/gns/plugin_gnsrecord_gns.c @@ -1,21 +1,21 @@ /* This file is part of GNUnet - (C) 2013 Christian Grothoff (and other contributing authors) + Copyright (C) 2013, 2014, 2016 GNUnet e.V. - GNUnet is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3, or (at your - option) any later version. + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. GNUnet is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . - You should have received a copy of the GNU General Public License - along with GNUnet; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. + SPDX-License-Identifier: AGPL3.0-or-later */ /** @@ -26,12 +26,12 @@ * map the result to A/AAAA. * @author Christian Grothoff */ - #include "platform.h" #include "gnunet_util_lib.h" #include "gnunet_gnsrecord_lib.h" #include "gnunet_dnsparser_lib.h" #include "gnunet_gnsrecord_plugin.h" +#include /** @@ -57,48 +57,89 @@ gns_value_to_string (void *cls, if (data_size != sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)) return NULL; return GNUNET_CRYPTO_ecdsa_public_key_to_string (data); - case GNUNET_GNSRECORD_TYPE_PSEU: + case GNUNET_GNSRECORD_TYPE_NICK: return GNUNET_strndup (data, data_size); case GNUNET_GNSRECORD_TYPE_LEHO: return GNUNET_strndup (data, data_size); case GNUNET_GNSRECORD_TYPE_GNS2DNS: { char *ns; + char *ip; size_t off; + char *nstr; off = 0; ns = GNUNET_DNSPARSER_parse_name (data, data_size, &off); + ip = GNUNET_DNSPARSER_parse_name (data, + data_size, + &off); if ( (NULL == ns) || + (NULL == ip) || (off != data_size) ) { GNUNET_break_op (0); GNUNET_free_non_null (ns); + GNUNET_free_non_null (ip); return NULL; } - return ns; + GNUNET_asprintf (&nstr, + "%s@%s", + ns, + ip); + GNUNET_free_non_null (ns); + GNUNET_free_non_null (ip); + return nstr; } case GNUNET_GNSRECORD_TYPE_VPN: { - const struct GNUNET_TUN_GnsVpnRecord *vpn; + struct GNUNET_TUN_GnsVpnRecord vpn; char* vpn_str; cdata = data; - if ( (data_size <= sizeof (struct GNUNET_TUN_GnsVpnRecord)) || + if ( (data_size <= sizeof (vpn)) || ('\0' != cdata[data_size - 1]) ) return NULL; /* malformed */ - vpn = data; - if (0 == GNUNET_asprintf (&vpn_str, "%u %s %s", - (unsigned int) ntohs (vpn->proto), - (const char*) GNUNET_i2s_full (&vpn->peer), - (const char*) &vpn[1])) - { - GNUNET_free (vpn_str); - return NULL; - } + /* need to memcpy for alignment */ + GNUNET_memcpy (&vpn, + data, + sizeof (vpn)); + GNUNET_asprintf (&vpn_str, + "%u %s %s", + (unsigned int) ntohs (vpn.proto), + (const char*) GNUNET_i2s_full (&vpn.peer), + (const char*) &cdata[sizeof (vpn)]); return vpn_str; } + case GNUNET_GNSRECORD_TYPE_BOX: + { + struct GNUNET_GNSRECORD_BoxRecord box; + uint32_t rt; + char *box_str; + char *ival; + + cdata = data; + if (data_size < sizeof (struct GNUNET_GNSRECORD_BoxRecord)) + return NULL; /* malformed */ + GNUNET_memcpy (&box, + data, + sizeof (box)); + rt = ntohl (box.record_type); + ival = GNUNET_GNSRECORD_value_to_string (rt, + &cdata[sizeof (box)], + data_size - sizeof (box)); + if (NULL == ival) + return NULL; /* malformed */ + GNUNET_asprintf (&box_str, + "%u %u %u %s", + (unsigned int) ntohs (box.protocol), + (unsigned int) ntohs (box.service), + (unsigned int) rt, + ival); + GNUNET_free (ival); + return box_str; + } default: return NULL; } @@ -124,84 +165,160 @@ gns_string_to_value (void *cls, size_t *data_size) { struct GNUNET_CRYPTO_EcdsaPublicKey pkey; - struct GNUNET_TUN_GnsVpnRecord *vpn; - char s_peer[103 + 1]; - char s_serv[253 + 1]; - unsigned int proto; if (NULL == s) return GNUNET_SYSERR; switch (type) { - case GNUNET_GNSRECORD_TYPE_PKEY: - if (GNUNET_OK != - GNUNET_CRYPTO_ecdsa_public_key_from_string (s, strlen (s), &pkey)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - _("Unable to parse PKEY record `%s'\n"), - s); - return GNUNET_SYSERR; - } - *data = GNUNET_new (struct GNUNET_CRYPTO_EcdsaPublicKey); - memcpy (*data, &pkey, sizeof (pkey)); - *data_size = sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey); - return GNUNET_OK; - - case GNUNET_GNSRECORD_TYPE_PSEU: - *data = GNUNET_strdup (s); - *data_size = strlen (s); - return GNUNET_OK; - case GNUNET_GNSRECORD_TYPE_LEHO: - *data = GNUNET_strdup (s); - *data_size = strlen (s); - return GNUNET_OK; - case GNUNET_GNSRECORD_TYPE_GNS2DNS: - { - char nsbuf[256]; - size_t off; - - off = 0; + case GNUNET_GNSRECORD_TYPE_PKEY: if (GNUNET_OK != - GNUNET_DNSPARSER_builder_add_name (nsbuf, - sizeof (nsbuf), - &off, - s)) + GNUNET_CRYPTO_ecdsa_public_key_from_string (s, + strlen (s), + &pkey)) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - _("Failed to serialize GNS2DNS record with value `%s'\n"), - s); - return GNUNET_SYSERR; + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Unable to parse PKEY record `%s'\n"), + s); + return GNUNET_SYSERR; } - *data_size = off; - *data = GNUNET_malloc (off); - memcpy (*data, nsbuf, off); + *data = GNUNET_new (struct GNUNET_CRYPTO_EcdsaPublicKey); + GNUNET_memcpy (*data, + &pkey, + sizeof (pkey)); + *data_size = sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey); return GNUNET_OK; - } - case GNUNET_GNSRECORD_TYPE_VPN: - if (3 != SSCANF (s,"%u %103s %253s", - &proto, s_peer, s_serv)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - _("Unable to parse VPN record string `%s'\n"), - s); - return GNUNET_SYSERR; - } - *data_size = sizeof (struct GNUNET_TUN_GnsVpnRecord) + strlen (s_serv) + 1; - *data = vpn = GNUNET_malloc (*data_size); - if (GNUNET_OK != GNUNET_CRYPTO_eddsa_public_key_from_string ((char*) s_peer, - strlen (s_peer), - &vpn->peer.public_key)) - { - GNUNET_free (vpn); - *data_size = 0; + + case GNUNET_GNSRECORD_TYPE_NICK: + *data = GNUNET_strdup (s); + *data_size = strlen (s); + return GNUNET_OK; + case GNUNET_GNSRECORD_TYPE_LEHO: + *data = GNUNET_strdup (s); + *data_size = strlen (s); + return GNUNET_OK; + case GNUNET_GNSRECORD_TYPE_GNS2DNS: + { + char nsbuf[514]; + char *cpy; + char *at; + size_t off; + + cpy = GNUNET_strdup (s); + at = strchr (cpy, '@'); + if (NULL == at) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Unable to parse GNS2DNS record `%s'\n"), + s); + GNUNET_free (cpy); + return GNUNET_SYSERR; + } + *at = '\0'; + at++; + + off = 0; + if ( (GNUNET_OK != + GNUNET_DNSPARSER_builder_add_name (nsbuf, + sizeof (nsbuf), + &off, + cpy)) || + (GNUNET_OK != + GNUNET_DNSPARSER_builder_add_name (nsbuf, + sizeof (nsbuf), + &off, + at)) ) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Failed to serialize GNS2DNS record with value `%s'\n"), + s); + GNUNET_free (cpy); + return GNUNET_SYSERR; + } + GNUNET_free (cpy); + *data_size = off; + *data = GNUNET_malloc (off); + GNUNET_memcpy (*data, + nsbuf, + off); + return GNUNET_OK; + } + case GNUNET_GNSRECORD_TYPE_VPN: + { + struct GNUNET_TUN_GnsVpnRecord *vpn; + char s_peer[103 + 1]; + char s_serv[253 + 1]; + unsigned int proto; + + if (3 != SSCANF (s, + "%u %103s %253s", + &proto, s_peer, s_serv)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Unable to parse VPN record string `%s'\n"), + s); + return GNUNET_SYSERR; + } + *data_size = sizeof (struct GNUNET_TUN_GnsVpnRecord) + strlen (s_serv) + 1; + *data = vpn = GNUNET_malloc (*data_size); + if (GNUNET_OK != + GNUNET_CRYPTO_eddsa_public_key_from_string ((char*) s_peer, + strlen (s_peer), + &vpn->peer.public_key)) + { + GNUNET_free (vpn); + *data_size = 0; + return GNUNET_SYSERR; + } + vpn->proto = htons ((uint16_t) proto); + strcpy ((char*)&vpn[1], s_serv); + return GNUNET_OK; + } + case GNUNET_GNSRECORD_TYPE_BOX: + { + struct GNUNET_GNSRECORD_BoxRecord *box; + size_t rest; + unsigned int protocol; + unsigned int service; + unsigned int record_type; + void *bval; + size_t bval_size; + + if (3 != SSCANF (s, + "%u %u %u ", + &protocol, + &service, + &record_type)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Unable to parse BOX record string `%s'\n"), + s); + return GNUNET_SYSERR; + } + rest = snprintf (NULL, 0, + "%u %u %u ", + protocol, + service, + record_type); + if (GNUNET_OK != + GNUNET_GNSRECORD_string_to_value (record_type, + &s[rest], + &bval, + &bval_size)) + return GNUNET_SYSERR; + *data_size = sizeof (struct GNUNET_GNSRECORD_BoxRecord) + bval_size; + *data = box = GNUNET_malloc (*data_size); + box->protocol = htons (protocol); + box->service = htons (service); + box->record_type = htonl (record_type); + GNUNET_memcpy (&box[1], + bval, + bval_size); + GNUNET_free (bval); + return GNUNET_OK; + } + default: return GNUNET_SYSERR; - } - vpn->proto = htons ((uint16_t) proto); - strcpy ((char*)&vpn[1], s_serv); - return GNUNET_OK; - default: - return GNUNET_SYSERR; } } @@ -213,12 +330,13 @@ gns_string_to_value (void *cls, static struct { const char *name; uint32_t number; -} name_map[] = { +} gns_name_map[] = { { "PKEY", GNUNET_GNSRECORD_TYPE_PKEY }, - { "PSEU", GNUNET_GNSRECORD_TYPE_PSEU }, + { "NICK", GNUNET_GNSRECORD_TYPE_NICK }, { "LEHO", GNUNET_GNSRECORD_TYPE_LEHO }, { "VPN", GNUNET_GNSRECORD_TYPE_VPN }, { "GNS2DNS", GNUNET_GNSRECORD_TYPE_GNS2DNS }, + { "BOX", GNUNET_GNSRECORD_TYPE_BOX }, { NULL, UINT32_MAX } }; @@ -237,10 +355,11 @@ gns_typename_to_number (void *cls, unsigned int i; i=0; - while ( (name_map[i].name != NULL) && - (0 != strcasecmp (gns_typename, name_map[i].name)) ) + while ( (NULL != gns_name_map[i].name) && + (0 != strcasecmp (gns_typename, + gns_name_map[i].name)) ) i++; - return name_map[i].number; + return gns_name_map[i].number; } @@ -258,10 +377,10 @@ gns_number_to_typename (void *cls, unsigned int i; i=0; - while ( (name_map[i].name != NULL) && - (type != name_map[i].number) ) + while ( (NULL != gns_name_map[i].name) && + (type != gns_name_map[i].number) ) i++; - return name_map[i].name; + return gns_name_map[i].name; } @@ -288,7 +407,7 @@ libgnunet_plugin_gnsrecord_gns_init (void *cls) /** * Exit point from the plugin. * - * @param cls the return value from #libgnunet_plugin_block_test_init + * @param cls the return value from #libgnunet_plugin_block_test_init() * @return NULL */ void *