[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] r25222 - in gnunet/src: dns include namestore
From: |
gnunet |
Subject: |
[GNUnet-SVN] r25222 - in gnunet/src: dns include namestore |
Date: |
Tue, 4 Dec 2012 14:12:42 +0100 |
Author: grothoff
Date: 2012-12-04 14:12:42 +0100 (Tue, 04 Dec 2012)
New Revision: 25222
Modified:
gnunet/src/dns/dnsparser.c
gnunet/src/dns/dnsparser.h
gnunet/src/include/gnunet_dnsparser_lib.h
gnunet/src/namestore/namestore_common.c
Log:
-ensure labels are less than 64 chars, add test for full DNS names
Modified: gnunet/src/dns/dnsparser.c
===================================================================
--- gnunet/src/dns/dnsparser.c 2012-12-04 12:39:47 UTC (rev 25221)
+++ gnunet/src/dns/dnsparser.c 2012-12-04 13:12:42 UTC (rev 25222)
@@ -46,20 +46,62 @@
GNUNET_DNSPARSER_check_label (const char *label)
{
char *output;
+ size_t slen;
+ if (NULL != strchr (label, "."))
+ return GNUNET_SYSERR; /* not a label! Did you mean
GNUNET_DNSPARSER_check_name? */
if (IDNA_SUCCESS !=
idna_to_ascii_8z (label, &output, IDNA_USE_STD3_ASCII_RULES))
return GNUNET_SYSERR;
+ slen = strlen (output);
#if WINDOWS
idn_free (output);
#else
free (output);
#endif
- return GNUNET_OK;
+ return (slen > 63) ? GNUNET_SYSERR : GNUNET_OK;
}
/**
+ * Check if a label in UTF-8 format can be coded into valid IDNA.
+ * This can fail if the ASCII-conversion becomes longer than 253 characters.
+ *
+ * @param name name to check (UTF-8 string)
+ * @return GNUNET_OK if the label can be converted to IDNA,
+ * GNUNET_SYSERR if the label is not valid for DNS names
+ */
+int
+GNUNET_DNSPARSER_check_name (const char *label)
+{
+ char *ldup;
+ char *output;
+ size_t slen;
+ char *tok;
+
+ ldup = GNUNET_strdup (label);
+ for (tok = strtok (ldup, "."); NULL != tok; tok = strtok (NULL, "."))
+ if (GNUNET_OK !=
+ GNUNET_DNSPARSER_check_label (tok))
+ {
+ GNUNET_free (ldup);
+ return GNUNET_SYSERR;
+ }
+ GNUNET_free (ldup);
+ if (IDNA_SUCCESS !=
+ idna_to_ascii_8z (label, &output, IDNA_USE_STD3_ASCII_RULES))
+ return GNUNET_SYSERR;
+ slen = strlen (output);
+#if WINDOWS
+ idn_free (output);
+#else
+ free (output);
+#endif
+ return (slen > 253) ? GNUNET_SYSERR : GNUNET_OK;
+}
+
+
+/**
* Parse name inside of a DNS query or record.
*
* @param udp_payload entire UDP payload
Modified: gnunet/src/dns/dnsparser.h
===================================================================
--- gnunet/src/dns/dnsparser.h 2012-12-04 12:39:47 UTC (rev 25221)
+++ gnunet/src/dns/dnsparser.h 2012-12-04 13:12:42 UTC (rev 25222)
@@ -187,7 +187,7 @@
*/
struct GNUNET_HashCode peer;
- /* followed by the servicename */
+ /* followed by the servicename / identifier / password (0-terminated) */
};
GNUNET_NETWORK_STRUCT_END
Modified: gnunet/src/include/gnunet_dnsparser_lib.h
===================================================================
--- gnunet/src/include/gnunet_dnsparser_lib.h 2012-12-04 12:39:47 UTC (rev
25221)
+++ gnunet/src/include/gnunet_dnsparser_lib.h 2012-12-04 13:12:42 UTC (rev
25222)
@@ -538,6 +538,19 @@
/**
+ * Check if a hostname in UTF-8 format can be coded into valid IDNA.
+ * This can fail if a label becomes longer than 63 characters or if
+ * the entire name exceeds 253 characters.
+ *
+ * @param name name to check (UTF-8 string)
+ * @return GNUNET_OK if the label can be converted to IDNA,
+ * GNUNET_SYSERR if the label is not valid for DNS names
+ */
+int
+GNUNET_DNSPARSER_check_name (const char *name);
+
+
+/**
* Parse a UDP payload of a DNS packet in to a nice struct for further
* processing and manipulation.
*
Modified: gnunet/src/namestore/namestore_common.c
===================================================================
--- gnunet/src/namestore/namestore_common.c 2012-12-04 12:39:47 UTC (rev
25221)
+++ gnunet/src/namestore/namestore_common.c 2012-12-04 13:12:42 UTC (rev
25222)
@@ -348,18 +348,19 @@
size_t data_size)
{
uint16_t mx_pref;
- struct soa_data *soa;
- struct vpn_data *vpn;
- struct srv_data *srv;
- struct tlsa_data *tlsa;
+ const struct soa_data *soa;
+ const struct vpn_data *vpn;
+ const struct srv_data *srv;
+ const struct tlsa_data *tlsa;
struct GNUNET_CRYPTO_ShortHashAsciiEncoded enc;
struct GNUNET_CRYPTO_HashAsciiEncoded s_peer;
+ const char *cdata;
char* vpn_str;
char* srv_str;
char* tlsa_str;
char* result;
- char* soa_rname;
- char* soa_mname;
+ const char* soa_rname;
+ const char* soa_mname;
char tmp[INET6_ADDRSTRLEN];
switch (type)
@@ -373,20 +374,32 @@
return NULL;
return GNUNET_strdup (tmp);
case GNUNET_DNSPARSER_TYPE_NS:
- return GNUNET_strdup (data);
+ return GNUNET_strndup (data, data_size);
case GNUNET_DNSPARSER_TYPE_CNAME:
- return GNUNET_strdup (data);
+ return GNUNET_strndup (data, data_size);
case GNUNET_DNSPARSER_TYPE_SOA:
- soa = (struct soa_data*)data;
- soa_rname = (char*)&soa[1];
- soa_mname = (char*)&soa[1]+strlen(soa_rname)+1;
- if (0 == GNUNET_asprintf(&result, "rname=%s mname=%s %lu,%lu,%lu,%lu,%lu",
- soa_rname, soa_mname,
- ntohl (soa->serial), ntohl (soa->refresh),
- ntohl (soa->retry), ntohl (soa->expire), ntohl
(soa->minimum)))
+ if (data_size <= sizeof (struct soa_data))
+ return NULL;
+ soa = data;
+ soa_rname = (const char*) &soa[1];
+ soa_mname = memchr (soa_rname, 0, data_size - sizeof (struct soa_data) -
1);
+ if (NULL == soa_mname)
+ return NULL;
+ soa_mname++;
+ if (NULL == memchr (soa_mname, 0,
+ data_size - (sizeof (struct soa_data) + strlen
(soa_rname) + 1)))
+ return NULL;
+ if (0 == GNUNET_asprintf (&result,
+ "rname=%s mname=%s %lu,%lu,%lu,%lu,%lu",
+ soa_rname, soa_mname,
+ ntohl (soa->serial),
+ ntohl (soa->refresh),
+ ntohl (soa->retry),
+ ntohl (soa->expire),
+ ntohl (soa->minimum)))
{
- GNUNET_free (result);
- return NULL;
+ GNUNET_free (result);
+ return NULL;
}
return result;
case GNUNET_DNSPARSER_TYPE_PTR:
@@ -420,42 +433,54 @@
case GNUNET_NAMESTORE_TYPE_LEHO:
return GNUNET_strndup (data, data_size);
case GNUNET_NAMESTORE_TYPE_VPN:
- vpn = (struct vpn_data*)data;
-
+ cdata = data;
+ if ( (data_size <= sizeof (struct vpn_data)) ||
+ ('\0' != cdata[data_size - 1]) )
+ return NULL; /* malformed */
+ vpn = data;
GNUNET_CRYPTO_hash_to_enc (&vpn->peer, &s_peer);
if (0 == GNUNET_asprintf (&vpn_str, "%hu %s %s",
- vpn->proto,
- (char*)&s_peer,
- (char*)&vpn[1]))
+ vpn->proto,
+ (const char*) &s_peer,
+ (const char*) &vpn[1]))
{
GNUNET_free (vpn_str);
return NULL;
}
return vpn_str;
case GNUNET_DNSPARSER_TYPE_SRV:
- srv = (struct srv_data*)data;
+ cdata = data;
+ if ( (data_size <= sizeof (struct srv_data)) ||
+ ('\0' != cdata[data_size - 1]) )
+ return NULL; /* malformed */
+ srv = data;
- if (0 == GNUNET_asprintf (&srv_str, "%d %d %d %s",
- ntohs (srv->prio),
- ntohs (srv->weight),
- ntohs (srv->port),
- (char*)&srv[1]))
+ if (0 == GNUNET_asprintf (&srv_str,
+ "%d %d %d %s",
+ ntohs (srv->prio),
+ ntohs (srv->weight),
+ ntohs (srv->port),
+ (const char *)&srv[1]))
{
GNUNET_free (srv_str);
return NULL;
}
return srv_str;
case GNUNET_DNSPARSER_TYPE_TLSA:
- tlsa = (struct tlsa_data*)data;
-
- if (0 == GNUNET_asprintf (&tlsa_str, "%c %c %c %s",
- tlsa->usage,
- tlsa->selector,
- tlsa->matching_type,
- tlsa[1]))
+ cdata = data;
+ if ( (data_size <= sizeof (struct tlsa_data)) ||
+ ('\0' != cdata[data_size - 1]) )
+ return NULL; /* malformed */
+ tlsa = data;
+ if (0 == GNUNET_asprintf (&tlsa_str,
+ "%c %c %c %s",
+ tlsa->usage,
+ tlsa->selector,
+ tlsa->matching_type,
+ (const char *) &tlsa[1]))
{
- GNUNET_free (tlsa_str);
- return NULL;
+ GNUNET_free (tlsa_str);
+ return NULL;
}
return tlsa_str;
default:
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r25222 - in gnunet/src: dns include namestore,
gnunet <=