GNUnet  0.10.x
Data Structures | Macros | Functions
fs_uri.c File Reference

Parses and produces uri strings. More...

#include "platform.h"
#include "gnunet_fs_service.h"
#include "gnunet_signatures.h"
#include "fs_api.h"
#include <unitypes.h>
#include <unicase.h>
#include <uniconv.h>
#include <unistr.h>
#include <unistdio.h>
Include dependency graph for fs_uri.c:

Go to the source code of this file.

Data Structures

struct  LocUriAssembly
 Structure that defines how the contents of a location URI must be assembled in memory to create or verify the signature of a location URI. More...
 

Macros

#define GNUNET_FS_URI_KSK_PREFIX   GNUNET_FS_URI_PREFIX GNUNET_FS_URI_KSK_INFIX
 
#define GNUNET_FS_URI_SKS_PREFIX   GNUNET_FS_URI_PREFIX GNUNET_FS_URI_SKS_INFIX
 
#define GNUNET_FS_URI_CHK_PREFIX   GNUNET_FS_URI_PREFIX GNUNET_FS_URI_CHK_INFIX
 
#define GNUNET_FS_URI_LOC_PREFIX   GNUNET_FS_URI_PREFIX GNUNET_FS_URI_LOC_INFIX
 
#define SIGNATURE_ASCII_LENGTH   103
 
#define TOKENS   "_. /-!?#&+@\"\'\\;:,()[]{}$<>|"
 Where to break up keywords. More...
 

Functions

int GNUNET_FS_uri_to_key (const struct GNUNET_FS_Uri *uri, struct GNUNET_HashCode *key)
 Get a unique key from a URI. More...
 
char * GNUNET_FS_uri_ksk_to_string_fancy (const struct GNUNET_FS_Uri *uri)
 Convert keyword URI to a human readable format (i.e. More...
 
static char * percent_decode_keyword (const char *in, char **emsg)
 Given a keyword with %-encoding (and possibly quotes to protect spaces), return a copy of the keyword without %-encoding and without double-quotes (%22). More...
 
static struct GNUNET_FS_Uriuri_ksk_parse (const char *s, char **emsg)
 Parse a KSK URI. More...
 
static struct GNUNET_FS_Uriuri_sks_parse (const char *s, char **emsg)
 Parse an SKS URI. More...
 
static struct GNUNET_FS_Uriuri_chk_parse (const char *s, char **emsg)
 Parse a CHK URI. More...
 
static struct GNUNET_FS_Uriuri_loc_parse (const char *s, char **emsg)
 Parse a LOC URI. More...
 
struct GNUNET_FS_UriGNUNET_FS_uri_parse (const char *uri, char **emsg)
 Convert a UTF-8 String to a URI. More...
 
void GNUNET_FS_uri_destroy (struct GNUNET_FS_Uri *uri)
 Free URI. More...
 
unsigned int GNUNET_FS_uri_ksk_get_keyword_count (const struct GNUNET_FS_Uri *uri)
 How many keywords are ANDed in this keyword URI? More...
 
int GNUNET_FS_uri_ksk_get_keywords (const struct GNUNET_FS_Uri *uri, GNUNET_FS_KeywordIterator iterator, void *iterator_cls)
 Iterate over all keywords in this keyword URI. More...
 
void GNUNET_FS_uri_ksk_add_keyword (struct GNUNET_FS_Uri *uri, const char *keyword, int is_mandatory)
 Add the given keyword to the set of keywords represented by the URI. More...
 
void GNUNET_FS_uri_ksk_remove_keyword (struct GNUNET_FS_Uri *uri, const char *keyword)
 Remove the given keyword from the set of keywords represented by the URI. More...
 
int GNUNET_FS_uri_loc_get_peer_identity (const struct GNUNET_FS_Uri *uri, struct GNUNET_PeerIdentity *peer)
 Obtain the identity of the peer offering the data. More...
 
struct GNUNET_TIME_Absolute GNUNET_FS_uri_loc_get_expiration (const struct GNUNET_FS_Uri *uri)
 Obtain the expiration of the LOC URI. More...
 
struct GNUNET_FS_UriGNUNET_FS_uri_loc_get_uri (const struct GNUNET_FS_Uri *uri)
 Obtain the URI of the content itself. More...
 
struct GNUNET_FS_UriGNUNET_FS_uri_loc_create (const struct GNUNET_FS_Uri *base_uri, const struct GNUNET_CRYPTO_EddsaPrivateKey *sign_key, struct GNUNET_TIME_Absolute expiration_time)
 Construct a location URI (this peer will be used for the location). More...
 
struct GNUNET_FS_UriGNUNET_FS_uri_sks_create (const struct GNUNET_CRYPTO_EcdsaPublicKey *ns, const char *id)
 Create an SKS URI from a namespace ID and an identifier. More...
 
struct GNUNET_FS_UriGNUNET_FS_uri_ksk_merge (const struct GNUNET_FS_Uri *u1, const struct GNUNET_FS_Uri *u2)
 Merge the sets of keywords from two KSK URIs. More...
 
struct GNUNET_FS_UriGNUNET_FS_uri_dup (const struct GNUNET_FS_Uri *uri)
 Duplicate URI. More...
 
struct GNUNET_FS_UriGNUNET_FS_uri_ksk_create (const char *keywords, char **emsg)
 Create an FS URI from a single user-supplied string of keywords. More...
 
struct GNUNET_FS_UriGNUNET_FS_uri_ksk_create_from_args (unsigned int argc, const char **argv)
 Create an FS URI from a user-supplied command line of keywords. More...
 
int GNUNET_FS_uri_test_equal (const struct GNUNET_FS_Uri *u1, const struct GNUNET_FS_Uri *u2)
 Test if two URIs are equal. More...
 
int GNUNET_FS_uri_test_sks (const struct GNUNET_FS_Uri *uri)
 Is this a namespace URI? More...
 
int GNUNET_FS_uri_sks_get_namespace (const struct GNUNET_FS_Uri *uri, struct GNUNET_CRYPTO_EcdsaPublicKey *pseudonym)
 Get the ID of a namespace from the given namespace URI. More...
 
char * GNUNET_FS_uri_sks_get_content_id (const struct GNUNET_FS_Uri *uri)
 Get the content identifier of an SKS URI. More...
 
int GNUNET_FS_uri_test_ksk (const struct GNUNET_FS_Uri *uri)
 Is this a keyword URI? More...
 
int GNUNET_FS_uri_test_chk (const struct GNUNET_FS_Uri *uri)
 Is this a file (or directory) URI? More...
 
uint64_t GNUNET_FS_uri_chk_get_file_size (const struct GNUNET_FS_Uri *uri)
 What is the size of the file that this URI refers to? More...
 
int GNUNET_FS_uri_test_loc (const struct GNUNET_FS_Uri *uri)
 Is this a location URI? More...
 
static void insert_non_mandatory_keyword (const char *s, char **array, int index)
 Add a keyword as non-mandatory (with ' '-prefix) to the given keyword list at offset 'index'. More...
 
static int find_duplicate (const char *s, const char **array, int array_length)
 Test if the given keyword s is already present in the given array, ignoring the '+'-mandatory prefix in the array. More...
 
static char * normalize_metadata (enum EXTRACTOR_MetaFormat format, const char *data, size_t data_len)
 FIXME: comment. More...
 
static size_t u8_strcount (const uint8_t *s)
 Counts the number of UTF-8 characters (not bytes) in the string, returns that count. More...
 
static int get_keywords_from_parens (const char *s, char **array, int index)
 Break the filename up by matching [], () and {} pairs to make keywords. More...
 
static int get_keywords_from_tokens (const char *s, char **array, int index)
 Break the filename up by TOKENS to make keywords. More...
 
static int gather_uri_data (void *cls, const char *plugin_name, enum EXTRACTOR_MetaType type, enum EXTRACTOR_MetaFormat format, const char *data_mime_type, const char *data, size_t data_len)
 Function called on each value in the meta data. More...
 
struct GNUNET_FS_UriGNUNET_FS_uri_ksk_create_from_meta_data (const struct GNUNET_CONTAINER_MetaData *md)
 Construct a keyword-URI from meta-data (take all entries in the meta-data and construct one large keyword URI that lists all keywords that can be found in the meta-data). More...
 
static int needs_percent (char c)
 In URI-encoding, does the given character need to be encoded using %-encoding? More...
 
static char * uri_ksk_to_string (const struct GNUNET_FS_Uri *uri)
 Convert a KSK URI to a string. More...
 
static char * uri_sks_to_string (const struct GNUNET_FS_Uri *uri)
 Convert SKS URI to a string. More...
 
static char * uri_chk_to_string (const struct GNUNET_FS_Uri *uri)
 Convert a CHK URI to a string. More...
 
static char * uri_loc_to_string (const struct GNUNET_FS_Uri *uri)
 Convert a LOC URI to a string. More...
 
char * GNUNET_FS_uri_to_string (const struct GNUNET_FS_Uri *uri)
 Convert a URI to a UTF-8 String. More...
 

Detailed Description

Parses and produces uri strings.

Author
Igor Wronsky, Christian Grothoff

GNUnet URIs are of the general form "gnunet://MODULE/IDENTIFIER". The specific structure of "IDENTIFIER" depends on the module and maybe differenciated into additional subcategories if applicable. This module only deals with fs identifiers (MODULE = "fs").

This module only parses URIs for the AFS module. The FS URIs fall into four categories, "chk", "sks", "ksk" and "loc". The first three categories were named in analogy (!) to Freenet, but they do NOT work in exactly the same way. They are very similar from the user's point of view (unique file identifier, subspace, keyword), but the implementation is rather different in pretty much every detail. The concrete URI formats are:

The encoding for hexadecimal values is defined in the hashing.c module in the gnunetutil library and discussed there.

Definition in file fs_uri.c.

Macro Definition Documentation

◆ GNUNET_FS_URI_KSK_PREFIX

#define GNUNET_FS_URI_KSK_PREFIX   GNUNET_FS_URI_PREFIX GNUNET_FS_URI_KSK_INFIX

Definition at line 265 of file fs_uri.c.

Referenced by uri_ksk_parse().

◆ GNUNET_FS_URI_SKS_PREFIX

#define GNUNET_FS_URI_SKS_PREFIX   GNUNET_FS_URI_PREFIX GNUNET_FS_URI_SKS_INFIX

Definition at line 361 of file fs_uri.c.

Referenced by uri_sks_parse().

◆ GNUNET_FS_URI_CHK_PREFIX

#define GNUNET_FS_URI_CHK_PREFIX   GNUNET_FS_URI_PREFIX GNUNET_FS_URI_CHK_INFIX

Definition at line 401 of file fs_uri.c.

Referenced by uri_chk_parse().

◆ GNUNET_FS_URI_LOC_PREFIX

#define GNUNET_FS_URI_LOC_PREFIX   GNUNET_FS_URI_PREFIX GNUNET_FS_URI_LOC_INFIX

Definition at line 489 of file fs_uri.c.

Referenced by uri_loc_parse().

◆ SIGNATURE_ASCII_LENGTH

#define SIGNATURE_ASCII_LENGTH   103

Definition at line 491 of file fs_uri.c.

Referenced by uri_loc_parse(), and uri_loc_to_string().

◆ TOKENS

#define TOKENS   "_. /-!?#&+@\"\'\\;:,()[]{}$<>|"

Where to break up keywords.

Definition at line 1600 of file fs_uri.c.

Referenced by get_keywords_from_tokens().

Function Documentation

◆ percent_decode_keyword()

static char* percent_decode_keyword ( const char *  in,
char **  emsg 
)
static

Given a keyword with %-encoding (and possibly quotes to protect spaces), return a copy of the keyword without %-encoding and without double-quotes (%22).

Also, add a space at the beginning if there is not a '+'.

Parameters
instring with %-encoding
emsgwhere to store the parser error message (if any)
Returns
decodded string with leading space (or preserved plus)

Definition at line 216 of file fs_uri.c.

References _, GNUNET_free, GNUNET_malloc, GNUNET_strdup, ret, and SSCANF.

Referenced by uri_ksk_parse().

218 {
219  char *out;
220  char *ret;
221  unsigned int rpos;
222  unsigned int wpos;
223  unsigned int hx;
224 
225  out = GNUNET_strdup (in);
226  rpos = 0;
227  wpos = 0;
228  while (out[rpos] != '\0')
229  {
230  if (out[rpos] == '%')
231  {
232  if (1 != SSCANF (&out[rpos + 1], "%2X", &hx))
233  {
234  GNUNET_free (out);
235  *emsg = GNUNET_strdup (_(/* xgettext:no-c-format */
236  "Malformed KSK URI (`%' must be followed by HEX number)"));
237  return NULL;
238  }
239  rpos += 3;
240  if (hx == '"')
241  continue; /* skip double quote */
242  out[wpos++] = (char) hx;
243  }
244  else
245  {
246  out[wpos++] = out[rpos++];
247  }
248  }
249  out[wpos] = '\0';
250  if (out[0] == '+')
251  {
252  ret = GNUNET_strdup (out);
253  }
254  else
255  {
256  /* need to prefix with space */
257  ret = GNUNET_malloc (strlen (out) + 2);
258  strcpy (ret, " ");
259  strcat (ret, out);
260  }
261  GNUNET_free (out);
262  return ret;
263 }
static int ret
Final status code.
Definition: gnunet-arm.c:89
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define _(String)
GNU gettext support macro.
Definition: platform.h:208
#define SSCANF
Definition: plibc.h:691
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
Here is the caller graph for this function:

◆ uri_ksk_parse()

static struct GNUNET_FS_Uri* uri_ksk_parse ( const char *  s,
char **  emsg 
)
static

Parse a KSK URI.

Parameters
san uri string
emsgwhere to store the parser error message (if any)
Returns
NULL on error, otherwise the KSK URI

Definition at line 275 of file fs_uri.c.

References _, GNUNET_FS_Uri::data, GNUNET_assert, GNUNET_free, GNUNET_free_non_null, GNUNET_FS_URI_KSK, GNUNET_FS_URI_KSK_PREFIX, GNUNET_new, GNUNET_new_array, GNUNET_strdup, GNUNET_FS_Uri::keywords, GNUNET_FS_Uri::ksk, percent_decode_keyword(), ret, and GNUNET_FS_Uri::type.

Referenced by GNUNET_FS_uri_parse().

277 {
278  struct GNUNET_FS_Uri *ret;
279  char **keywords;
280  unsigned int pos;
281  int max;
282  int iret;
283  int i;
284  size_t slen;
285  char *dup;
286  int saw_quote;
287 
288  slen = strlen (s);
289  pos = strlen (GNUNET_FS_URI_KSK_PREFIX);
290  if ((slen <= pos) || (0 != strncmp (s, GNUNET_FS_URI_KSK_PREFIX, pos)))
291  return NULL; /* not KSK URI */
292  if ((s[slen - 1] == '+') || (s[pos] == '+'))
293  {
294  *emsg =
295  GNUNET_strdup (_("Malformed KSK URI (must not begin or end with `+')"));
296  return NULL;
297  }
298  max = 1;
299  saw_quote = 0;
300  for (i = pos; i < slen; i++)
301  {
302  if ((s[i] == '%') && (&s[i] == strstr (&s[i], "%22")))
303  {
304  saw_quote = (saw_quote + 1) % 2;
305  i += 3;
306  continue;
307  }
308  if ((s[i] == '+') && (saw_quote == 0))
309  {
310  max++;
311  if (s[i - 1] == '+')
312  {
313  *emsg = GNUNET_strdup (_("Malformed KSK URI (`++' not allowed)"));
314  return NULL;
315  }
316  }
317  }
318  if (saw_quote == 1)
319  {
320  *emsg = GNUNET_strdup (_("Malformed KSK URI (quotes not balanced)"));
321  return NULL;
322  }
323  iret = max;
324  dup = GNUNET_strdup (s);
325  keywords = GNUNET_new_array (max,
326  char *);
327  for (i = slen - 1; i >= (int) pos; i--)
328  {
329  if ((s[i] == '%') && (&s[i] == strstr (&s[i], "%22")))
330  {
331  saw_quote = (saw_quote + 1) % 2;
332  continue;
333  }
334  if ((dup[i] == '+') && (saw_quote == 0))
335  {
336  keywords[--max] = percent_decode_keyword (&dup[i + 1], emsg);
337  if (NULL == keywords[max])
338  goto CLEANUP;
339  dup[i] = '\0';
340  }
341  }
342  keywords[--max] = percent_decode_keyword (&dup[pos], emsg);
343  if (NULL == keywords[max])
344  goto CLEANUP;
345  GNUNET_assert (0 == max);
346  GNUNET_free (dup);
347  ret = GNUNET_new (struct GNUNET_FS_Uri);
348  ret->type = GNUNET_FS_URI_KSK;
349  ret->data.ksk.keywordCount = iret;
350  ret->data.ksk.keywords = keywords;
351  return ret;
352 CLEANUP:
353  for (i = 0; i < max; i++)
354  GNUNET_free_non_null (keywords[i]);
355  GNUNET_free (keywords);
356  GNUNET_free (dup);
357  return NULL;
358 }
#define GNUNET_FS_URI_KSK_PREFIX
Definition: fs_uri.c:265
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
Keyword search key (query with keywords).
Definition: fs_api.h:156
static char * percent_decode_keyword(const char *in, char **emsg)
Given a keyword with %-encoding (and possibly quotes to protect spaces), return a copy of the keyword...
Definition: fs_uri.c:216
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
static int ret
Final status code.
Definition: gnunet-arm.c:89
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define _(String)
GNU gettext support macro.
Definition: platform.h:208
char ** keywords
Keywords start with a &#39;+&#39; if they are mandatory (in which case the &#39;+&#39; is NOT part of the keyword) an...
Definition: fs_api.h:188
struct GNUNET_FS_Uri::@16::@17 ksk
union GNUNET_FS_Uri::@16 data
#define GNUNET_new_array(n, type)
Allocate a size n array with structs or unions of the given type.
enum GNUNET_FS_UriType type
Type of the URI.
Definition: fs_api.h:173
A Universal Resource Identifier (URI), opaque.
Definition: fs_api.h:168
#define GNUNET_free(ptr)
Wrapper around free.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ uri_sks_parse()

static struct GNUNET_FS_Uri* uri_sks_parse ( const char *  s,
char **  emsg 
)
static

Parse an SKS URI.

Parameters
san uri string
emsgwhere to store the parser error message (if any)
Returns
NULL on error, SKS URI otherwise

Definition at line 371 of file fs_uri.c.

References _, GNUNET_FS_Uri::data, end, GNUNET_FS_URI_SKS, GNUNET_FS_URI_SKS_PREFIX, GNUNET_new, GNUNET_OK, GNUNET_strdup, GNUNET_STRINGS_string_to_data(), ns, ret, GNUNET_FS_Uri::sks, and GNUNET_FS_Uri::type.

Referenced by GNUNET_FS_uri_parse().

373 {
374  struct GNUNET_FS_Uri *ret;
376  size_t pos;
377  char *end;
378 
379  pos = strlen (GNUNET_FS_URI_SKS_PREFIX);
380  if ((strlen (s) <= pos) || (0 != strncmp (s, GNUNET_FS_URI_SKS_PREFIX, pos)))
381  return NULL; /* not an SKS URI */
382  end = strchr (&s[pos], '/');
383  if ( (NULL == end) ||
384  (GNUNET_OK !=
386  end - &s[pos],
387  &ns,
388  sizeof (ns))) )
389  {
390  *emsg = GNUNET_strdup (_("Malformed SKS URI (wrong syntax)"));
391  return NULL; /* malformed */
392  }
393  end++; /* skip over '/' */
394  ret = GNUNET_new (struct GNUNET_FS_Uri);
395  ret->type = GNUNET_FS_URI_SKS;
396  ret->data.sks.ns = ns;
397  ret->data.sks.identifier = GNUNET_strdup (end);
398  return ret;
399 }
static int end
Set if we are to shutdown all services (including ARM).
Definition: gnunet-arm.c:34
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
#define GNUNET_new(type)
Allocate a struct or union of the given type.
static int ret
Final status code.
Definition: gnunet-arm.c:89
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define _(String)
GNU gettext support macro.
Definition: platform.h:208
union GNUNET_FS_Uri::@16 data
#define GNUNET_FS_URI_SKS_PREFIX
Definition: fs_uri.c:361
static struct GNUNET_NAMESTORE_Handle * ns
Handle to the namestore.
enum GNUNET_FS_UriType type
Type of the URI.
Definition: fs_api.h:173
Signed key space (file in namespace).
Definition: fs_api.h:151
struct GNUNET_FS_Uri::@16::@18 sks
A Universal Resource Identifier (URI), opaque.
Definition: fs_api.h:168
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and ECDS...
int GNUNET_STRINGS_string_to_data(const char *enc, size_t enclen, void *out, size_t out_size)
Convert CrockfordBase32 encoding back to data.
Definition: strings.c:1021
Here is the call graph for this function:
Here is the caller graph for this function:

◆ uri_chk_parse()

static struct GNUNET_FS_Uri* uri_chk_parse ( const char *  s,
char **  emsg 
)
static

Parse a CHK URI.

Parameters
san uri string
emsgwhere to store the parser error message (if any)
Returns
NULL on error, CHK URI otherwise

Definition at line 412 of file fs_uri.c.

References _, FileIdentifier::chk, GNUNET_FS_Uri::chk, GNUNET_FS_Uri::data, FileIdentifier::file_length, GNUNET_CRYPTO_hash_from_string, GNUNET_FS_URI_CHK, GNUNET_FS_URI_CHK_PREFIX, GNUNET_htonll(), GNUNET_memcpy, GNUNET_NETWORK_STRUCT_BEGIN, GNUNET_new, GNUNET_OK, GNUNET_strdup, ContentHashKey::key, ContentHashKey::query, ret, SSCANF, and GNUNET_FS_Uri::type.

Referenced by GNUNET_FS_uri_parse().

414 {
415  struct GNUNET_FS_Uri *ret;
416  struct FileIdentifier fi;
417  unsigned int pos;
418  unsigned long long flen;
419  size_t slen;
420  char h1[sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded)];
421  char h2[sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded)];
422 
423  slen = strlen (s);
424  pos = strlen (GNUNET_FS_URI_CHK_PREFIX);
425  if ((slen < pos + 2 * sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) + 1) ||
426  (0 != strncmp (s, GNUNET_FS_URI_CHK_PREFIX, pos)))
427  return NULL; /* not a CHK URI */
428  if ((s[pos + sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) - 1] != '.') ||
429  (s[pos + sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) * 2 - 1] != '.'))
430  {
431  *emsg = GNUNET_strdup (_("Malformed CHK URI (wrong syntax)"));
432  return NULL;
433  }
434  GNUNET_memcpy (h1, &s[pos], sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded));
435  h1[sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) - 1] = '\0';
436  GNUNET_memcpy (h2, &s[pos + sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded)],
437  sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded));
438  h2[sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) - 1] = '\0';
439 
440  if ((GNUNET_OK != GNUNET_CRYPTO_hash_from_string (h1, &fi.chk.key)) ||
441  (GNUNET_OK != GNUNET_CRYPTO_hash_from_string (h2, &fi.chk.query)) ||
442  (1 !=
443  SSCANF (&s[pos + sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) * 2],
444  "%llu", &flen)))
445  {
446  *emsg = GNUNET_strdup (_("Malformed CHK URI (failed to decode CHK)"));
447  return NULL;
448  }
449  fi.file_length = GNUNET_htonll (flen);
450  ret = GNUNET_new (struct GNUNET_FS_Uri);
451  ret->type = GNUNET_FS_URI_CHK;
452  ret->data.chk = fi;
453  return ret;
454 }
struct FileIdentifier chk
Information needed to retrieve a file (content-hash-key plus file size).
Definition: fs_api.h:215
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
#define GNUNET_new(type)
Allocate a struct or union of the given type.
static int ret
Final status code.
Definition: gnunet-arm.c:89
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define _(String)
GNU gettext support macro.
Definition: platform.h:208
#define GNUNET_memcpy(dst, src, n)
union GNUNET_FS_Uri::@16 data
complete information needed to download a file.
Definition: fs_api.h:93
uint64_t GNUNET_htonll(uint64_t n)
Convert unsigned 64-bit integer to network byte order.
Definition: common_endian.c:35
Content-hash-key (simple file).
Definition: fs_api.h:146
enum GNUNET_FS_UriType type
Type of the URI.
Definition: fs_api.h:173
0-terminated ASCII encoding of a struct GNUNET_HashCode.
#define SSCANF
Definition: plibc.h:691
A Universal Resource Identifier (URI), opaque.
Definition: fs_api.h:168
#define GNUNET_FS_URI_CHK_PREFIX
Definition: fs_uri.c:401
#define GNUNET_CRYPTO_hash_from_string(enc, result)
Convert ASCII encoding back to struct GNUNET_HashCode
Here is the call graph for this function:
Here is the caller graph for this function:

◆ uri_loc_parse()

static struct GNUNET_FS_Uri* uri_loc_parse ( const char *  s,
char **  emsg 
)
static

Parse a LOC URI.

Also verifies validity of the location URI.

Parameters
san uri string
emsgwhere to store the parser error message (if any)
Returns
NULL on error, valid LOC URI otherwise

Definition at line 502 of file fs_uri.c.

References _, GNUNET_TIME_Absolute::abs_value_us, FileIdentifier::chk, Location::contentSignature, GNUNET_FS_Uri::data, Location::expirationTime, LocUriAssembly::exptime, Location::fi, LocUriAssembly::fi, FileIdentifier::file_length, GNUNET_CRYPTO_eddsa_public_key_from_string(), GNUNET_CRYPTO_eddsa_verify(), GNUNET_CRYPTO_hash_from_string, GNUNET_CRYPTO_PKEY_ASCII_LENGTH, GNUNET_FS_URI_LOC, GNUNET_FS_URI_LOC_PREFIX, GNUNET_htonll(), GNUNET_memcpy, GNUNET_new, GNUNET_OK, GNUNET_SIGNATURE_PURPOSE_PEER_PLACEMENT, GNUNET_strdup, GNUNET_STRINGS_string_to_data(), GNUNET_TIME_absolute_hton(), ContentHashKey::key, GNUNET_FS_Uri::loc, Location::peer, LocUriAssembly::peer, GNUNET_PeerIdentity::public_key, GNUNET_CRYPTO_EccSignaturePurpose::purpose, LocUriAssembly::purpose, ContentHashKey::query, SIGNATURE_ASCII_LENGTH, GNUNET_CRYPTO_EccSignaturePurpose::size, SSCANF, GNUNET_FS_Uri::type, and uri.

Referenced by GNUNET_FS_uri_parse().

504 {
505  struct GNUNET_FS_Uri *uri;
506  char h1[sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded)];
507  char h2[sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded)];
508  unsigned int pos;
509  unsigned int npos;
510  unsigned long long exptime;
511  unsigned long long flen;
512  struct GNUNET_TIME_Absolute et;
513  struct GNUNET_CRYPTO_EddsaSignature sig;
514  struct LocUriAssembly ass;
515  size_t slen;
516 
517  slen = strlen (s);
518  pos = strlen (GNUNET_FS_URI_LOC_PREFIX);
519  if ((slen < pos + 2 * sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) + 1) ||
520  (0 != strncmp (s, GNUNET_FS_URI_LOC_PREFIX, pos)))
521  return NULL; /* not a LOC URI */
522  if ((s[pos + sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) - 1] != '.') ||
523  (s[pos + sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) * 2 - 1] != '.'))
524  {
525  *emsg = GNUNET_strdup (_("LOC URI malformed (wrong syntax)"));
526  return NULL;
527  }
528  GNUNET_memcpy (h1, &s[pos], sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded));
529  h1[sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) - 1] = '\0';
530  GNUNET_memcpy (h2, &s[pos + sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded)],
531  sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded));
532  h2[sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) - 1] = '\0';
533 
534  if ((GNUNET_OK != GNUNET_CRYPTO_hash_from_string (h1, &ass.fi.chk.key)) ||
535  (GNUNET_OK != GNUNET_CRYPTO_hash_from_string (h2, &ass.fi.chk.query)) ||
536  (1 !=
537  SSCANF (&s[pos + sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) * 2],
538  "%llu", &flen)))
539  {
540  *emsg = GNUNET_strdup (_("LOC URI malformed (no CHK)"));
541  return NULL;
542  }
543  ass.fi.file_length = GNUNET_htonll (flen);
544 
545  npos = pos + sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) * 2;
546  while ((s[npos] != '\0') && (s[npos] != '.'))
547  npos++;
548  if (s[npos] == '\0')
549  {
550  *emsg = GNUNET_strdup (_("LOC URI malformed (missing LOC)"));
551  goto ERR;
552  }
553  npos++;
554  if ( (strlen (&s[npos]) <= GNUNET_CRYPTO_PKEY_ASCII_LENGTH + 1) ||
555  ('.' != s[npos+GNUNET_CRYPTO_PKEY_ASCII_LENGTH]) )
556  {
557  *emsg =
558  GNUNET_strdup (_("LOC URI malformed (wrong syntax for public key)"));
559  }
560  if (GNUNET_OK !=
563  &ass.peer.public_key))
564  {
565  *emsg =
566  GNUNET_strdup (_("LOC URI malformed (could not decode public key)"));
567  goto ERR;
568  }
570  if (s[npos++] != '.')
571  {
572  *emsg = GNUNET_strdup (_("LOC URI malformed (could not find signature)"));
573  goto ERR;
574  }
575  if ( (strlen (&s[npos]) <= SIGNATURE_ASCII_LENGTH + 1) ||
576  ('.' != s[npos + SIGNATURE_ASCII_LENGTH]) )
577  {
578  *emsg = GNUNET_strdup (_("LOC URI malformed (wrong syntax for signature)"));
579  goto ERR;
580  }
581  if (GNUNET_OK !=
584  &sig,
585  sizeof (struct GNUNET_CRYPTO_EddsaSignature)))
586  {
587  *emsg = GNUNET_strdup (_("LOC URI malformed (could not decode signature)"));
588  goto ERR;
589  }
590  npos += SIGNATURE_ASCII_LENGTH;
591  if (s[npos++] != '.')
592  {
593  *emsg = GNUNET_strdup (_("LOC URI malformed (wrong syntax for expiration time)"));
594  goto ERR;
595  }
596  if (1 != SSCANF (&s[npos], "%llu", &exptime))
597  {
598  *emsg =
599  GNUNET_strdup (_("LOC URI malformed (could not parse expiration time)"));
600  goto ERR;
601  }
602  ass.purpose.size = htonl (sizeof (struct LocUriAssembly));
603  ass.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_PEER_PLACEMENT);
604  et.abs_value_us = exptime * 1000LL * 1000LL;
605  ass.exptime = GNUNET_TIME_absolute_hton (et);
606  if (GNUNET_OK !=
608  &ass.purpose, &sig, &ass.peer.public_key))
609  {
610  *emsg =
611  GNUNET_strdup (_("LOC URI malformed (signature failed validation)"));
612  goto ERR;
613  }
614  uri = GNUNET_new (struct GNUNET_FS_Uri);
615  uri->type = GNUNET_FS_URI_LOC;
616  uri->data.loc.fi = ass.fi;
617  uri->data.loc.peer = ass.peer;
618  uri->data.loc.expirationTime = et;
619  uri->data.loc.contentSignature = sig;
620 
621  return uri;
622 ERR:
623  return NULL;
624 }
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
#define GNUNET_new(type)
Allocate a struct or union of the given type.
struct GNUNET_PeerIdentity peer
Identity of the peer sharing the file.
Definition: fs_api.h:123
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define _(String)
GNU gettext support macro.
Definition: platform.h:208
#define GNUNET_CRYPTO_PKEY_ASCII_LENGTH
How many characters (without 0-terminator) are our ASCII-encoded public keys (ECDSA/EDDSA/ECDHE).
static struct GNUNET_FS_Uri * uri
Value of URI provided on command-line (when not publishing a file but just creating UBlocks to refer ...
#define GNUNET_SIGNATURE_PURPOSE_PEER_PLACEMENT
Signature by which a peer affirms that it is providing a certain bit of content (used in LOCation URI...
#define GNUNET_memcpy(dst, src, n)
int GNUNET_CRYPTO_eddsa_verify(uint32_t purpose, const struct GNUNET_CRYPTO_EccSignaturePurpose *validate, const struct GNUNET_CRYPTO_EddsaSignature *sig, const struct GNUNET_CRYPTO_EddsaPublicKey *pub)
Verify EdDSA signature.
Definition: crypto_ecc.c:1116
union GNUNET_FS_Uri::@16 data
uint64_t GNUNET_htonll(uint64_t n)
Convert unsigned 64-bit integer to network byte order.
Definition: common_endian.c:35
struct GNUNET_TIME_Absolute expirationTime
Time when this location URI expires.
Definition: fs_api.h:128
enum GNUNET_FS_UriType type
Type of the URI.
Definition: fs_api.h:173
an ECC signature using EdDSA.
0-terminated ASCII encoding of a struct GNUNET_HashCode.
int GNUNET_CRYPTO_eddsa_public_key_from_string(const char *enc, size_t enclen, struct GNUNET_CRYPTO_EddsaPublicKey *pub)
Convert a string representing a public key to a public key.
Definition: crypto_ecc.c:501
#define SSCANF
Definition: plibc.h:691
A Universal Resource Identifier (URI), opaque.
Definition: fs_api.h:168
struct GNUNET_CRYPTO_EddsaSignature contentSignature
Signature over the GNUNET_EC_FileIdentifier, peer identity and expiration time.
Definition: fs_api.h:134
struct FileIdentifier fi
Information about the shared file.
Definition: fs_api.h:118
Location (chk with identity of hosting peer).
Definition: fs_api.h:161
struct Location loc
Information needed to retrieve a file including signed location (identity of a peer) of the content...
Definition: fs_api.h:221
Time for absolute times used by GNUnet, in microseconds.
#define SIGNATURE_ASCII_LENGTH
Definition: fs_uri.c:491
#define GNUNET_FS_URI_LOC_PREFIX
Definition: fs_uri.c:489
struct GNUNET_TIME_AbsoluteNBO GNUNET_TIME_absolute_hton(struct GNUNET_TIME_Absolute a)
Convert absolute time to network byte order.
Definition: time.c:654
#define GNUNET_CRYPTO_hash_from_string(enc, result)
Convert ASCII encoding back to struct GNUNET_HashCode
int GNUNET_STRINGS_string_to_data(const char *enc, size_t enclen, void *out, size_t out_size)
Convert CrockfordBase32 encoding back to data.
Definition: strings.c:1021
Structure that defines how the contents of a location URI must be assembled in memory to create or ve...
Definition: fs_uri.c:463
Here is the call graph for this function:
Here is the caller graph for this function:

◆ insert_non_mandatory_keyword()

static void insert_non_mandatory_keyword ( const char *  s,
char **  array,
int  index 
)
static

Add a keyword as non-mandatory (with ' '-prefix) to the given keyword list at offset 'index'.

The array is guaranteed to be long enough.

Parameters
skeyword to add
arrayarray to add the keyword to
indexoffset where to add the keyword

Definition at line 1397 of file fs_uri.c.

References GNUNET_asprintf().

Referenced by gather_uri_data(), get_keywords_from_parens(), and get_keywords_from_tokens().

1400 {
1401  char *nkword;
1402 
1403  GNUNET_asprintf (&nkword,
1404  " %s", /* space to mark as 'non mandatory' */
1405  s);
1406  array[index] = nkword;
1407 }
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ find_duplicate()

static int find_duplicate ( const char *  s,
const char **  array,
int  array_length 
)
static

Test if the given keyword s is already present in the given array, ignoring the '+'-mandatory prefix in the array.

Parameters
skeyword to test
arraykeywords to test against, with ' ' or '+' prefix to ignore
array_lengthlength of the array
Returns
GNUNET_YES if the keyword exists, GNUNET_NO if not

Definition at line 1420 of file fs_uri.c.

References GNUNET_NO, and GNUNET_YES.

Referenced by gather_uri_data(), get_keywords_from_parens(), and get_keywords_from_tokens().

1423 {
1424  int j;
1425 
1426  for (j = array_length - 1; j >= 0; j--)
1427  if (0 == strcmp (&array[j][1], s))
1428  return GNUNET_YES;
1429  return GNUNET_NO;
1430 }
#define GNUNET_NO
Definition: gnunet_common.h:81
#define GNUNET_YES
Definition: gnunet_common.h:80
Here is the caller graph for this function:

◆ normalize_metadata()

static char* normalize_metadata ( enum EXTRACTOR_MetaFormat  format,
const char *  data,
size_t  data_len 
)
static

FIXME: comment.

Definition at line 1437 of file fs_uri.c.

References data, EXTRACTOR_METAFORMAT_C_STRING, EXTRACTOR_METAFORMAT_UTF8, GNUNET_malloc, and GNUNET_memcpy.

Referenced by gather_uri_data(), get_keywords_from_parens(), and get_keywords_from_tokens().

1440 {
1441  uint8_t *free_str = NULL;
1442  uint8_t *str_to_normalize = (uint8_t *) data;
1443  uint8_t *normalized;
1444  size_t r_len;
1445  if (str_to_normalize == NULL)
1446  return NULL;
1447  /* Don't trust libextractor */
1448  if (format == EXTRACTOR_METAFORMAT_UTF8)
1449  {
1450  free_str = (uint8_t *) u8_check ((const uint8_t *) data, data_len);
1451  if (free_str == NULL)
1452  free_str = NULL;
1453  else
1455  }
1456  if (format == EXTRACTOR_METAFORMAT_C_STRING)
1457  {
1458  free_str = u8_strconv_from_encoding (data, locale_charset (), iconveh_escape_sequence);
1459  if (free_str == NULL)
1460  return NULL;
1461  }
1462 
1463  normalized = u8_tolower (str_to_normalize, strlen ((char *) str_to_normalize), NULL, UNINORM_NFD, NULL, &r_len);
1464  /* free_str is allocated by libunistring internally, use free() */
1465  if (free_str != NULL)
1466  free (free_str);
1467  if (normalized != NULL)
1468  {
1469  /* u8_tolower allocates a non-NULL-terminated string! */
1470  free_str = GNUNET_malloc (r_len + 1);
1471  GNUNET_memcpy (free_str, normalized, r_len);
1472  free_str[r_len] = '\0';
1473  free (normalized);
1474  normalized = free_str;
1475  }
1476  return (char *) normalized;
1477 }
0-terminated, UTF-8 encoded string.
#define GNUNET_memcpy(dst, src, n)
uint32_t data
The data value.
#define GNUNET_malloc(size)
Wrapper around malloc.
Here is the caller graph for this function:

◆ u8_strcount()

static size_t u8_strcount ( const uint8_t *  s)
static

Counts the number of UTF-8 characters (not bytes) in the string, returns that count.

Definition at line 1485 of file fs_uri.c.

References GNUNET_assert.

Referenced by gather_uri_data(), get_keywords_from_parens(), and get_keywords_from_tokens().

1486 {
1487  size_t count;
1488  ucs4_t c;
1489  GNUNET_assert (s != NULL);
1490  if (s[0] == 0)
1491  return 0;
1492  for (count = 0; s != NULL; count++)
1493  s = u8_next (&c, s);
1494  return count - 1;
1495 }
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
Here is the caller graph for this function:

◆ get_keywords_from_parens()

static int get_keywords_from_parens ( const char *  s,
char **  array,
int  index 
)
static

Break the filename up by matching [], () and {} pairs to make keywords.

In case of nesting parentheses only the inner pair counts. You can't escape parentheses to scan something like "[blah\{foo]" to make a "blah{foo" keyword, this function is only a heuristic!

Parameters
sstring to break down.
arrayarray to fill with enclosed tokens. If NULL, then tokens are only counted.
indexindex at which to start filling the array (entries prior to it are used to check for duplicates). ignored if array == NULL.
Returns
number of tokens counted (including duplicates), or number of tokens extracted (excluding duplicates). 0 if there are no matching parens in the string (when counting), or when all tokens were duplicates (when extracting).

Definition at line 1515 of file fs_uri.c.

References EXTRACTOR_METAFORMAT_UTF8, find_duplicate(), GNUNET_free, GNUNET_NO, GNUNET_strdup, insert_non_mandatory_keyword(), normalize_metadata(), and u8_strcount().

Referenced by GNUNET_FS_uri_ksk_create_from_meta_data().

1518 {
1519  int count = 0;
1520  char *open_paren;
1521  char *close_paren;
1522  char *ss;
1523  char tmp;
1524 
1525  if (NULL == s)
1526  return 0;
1527  ss = GNUNET_strdup (s);
1528  open_paren = ss - 1;
1529  while (NULL != (open_paren = strpbrk (open_paren + 1, "[{(")))
1530  {
1531  int match = 0;
1532 
1533  close_paren = strpbrk (open_paren + 1, "]})");
1534  if (NULL == close_paren)
1535  continue;
1536  switch (open_paren[0])
1537  {
1538  case '[':
1539  if (']' == close_paren[0])
1540  match = 1;
1541  break;
1542  case '{':
1543  if ('}' == close_paren[0])
1544  match = 1;
1545  break;
1546  case '(':
1547  if (')' == close_paren[0])
1548  match = 1;
1549  break;
1550  default:
1551  break;
1552  }
1553  if (match && (close_paren - open_paren > 1))
1554  {
1555  tmp = close_paren[0];
1556  close_paren[0] = '\0';
1557  /* Keywords must be at least 3 characters long */
1558  if (u8_strcount ((const uint8_t *) &open_paren[1]) <= 2)
1559  {
1560  close_paren[0] = tmp;
1561  continue;
1562  }
1563  if (NULL != array)
1564  {
1565  char *normalized;
1566  if (GNUNET_NO == find_duplicate ((const char *) &open_paren[1],
1567  (const char **) array, index + count))
1568  {
1569  insert_non_mandatory_keyword ((const char *) &open_paren[1], array,
1570  index + count);
1571  count++;
1572  }
1574  &open_paren[1], close_paren - &open_paren[1]);
1575  if (normalized != NULL)
1576  {
1577  if (GNUNET_NO == find_duplicate ((const char *) normalized,
1578  (const char **) array, index + count))
1579  {
1580  insert_non_mandatory_keyword ((const char *) normalized, array,
1581  index + count);
1582  count++;
1583  }
1584  GNUNET_free (normalized);
1585  }
1586  }
1587  else
1588  count++;
1589  close_paren[0] = tmp;
1590  }
1591  }
1592  GNUNET_free (ss);
1593  return count;
1594 }
static size_t u8_strcount(const uint8_t *s)
Counts the number of UTF-8 characters (not bytes) in the string, returns that count.
Definition: fs_uri.c:1485
static void insert_non_mandatory_keyword(const char *s, char **array, int index)
Add a keyword as non-mandatory (with &#39; &#39;-prefix) to the given keyword list at offset &#39;index&#39;...
Definition: fs_uri.c:1397
0-terminated, UTF-8 encoded string.
#define GNUNET_NO
Definition: gnunet_common.h:81
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
static int find_duplicate(const char *s, const char **array, int array_length)
Test if the given keyword s is already present in the given array, ignoring the &#39;+&#39;-mandatory prefix ...
Definition: fs_uri.c:1420
static char * normalize_metadata(enum EXTRACTOR_MetaFormat format, const char *data, size_t data_len)
FIXME: comment.
Definition: fs_uri.c:1437
#define GNUNET_free(ptr)
Wrapper around free.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_keywords_from_tokens()

static int get_keywords_from_tokens ( const char *  s,
char **  array,
int  index 
)
static

Break the filename up by TOKENS to make keywords.

Parameters
sstring to break down.
arrayarray to fill with tokens. If NULL, then tokens are only counted.
indexindex at which to start filling the array (entries prior to it are used to check for duplicates). ignored if array == NULL.
Returns
number of tokens (>1) counted (including duplicates), or number of tokens extracted (excluding duplicates). 0 if there are no separators in the string (when counting), or when all tokens were duplicates (when extracting).

Definition at line 1617 of file fs_uri.c.

References EXTRACTOR_METAFORMAT_UTF8, find_duplicate(), GNUNET_free, GNUNET_NO, GNUNET_strdup, insert_non_mandatory_keyword(), normalize_metadata(), p, TOKENS, and u8_strcount().

Referenced by GNUNET_FS_uri_ksk_create_from_meta_data().

1620 {
1621  char *p;
1622  char *ss;
1623  int seps = 0;
1624 
1625  ss = GNUNET_strdup (s);
1626  for (p = strtok (ss, TOKENS); p != NULL; p = strtok (NULL, TOKENS))
1627  {
1628  /* Keywords must be at least 3 characters long */
1629  if (u8_strcount ((const uint8_t *) p) <= 2)
1630  continue;
1631  if (NULL != array)
1632  {
1633  char *normalized;
1634  if (GNUNET_NO == find_duplicate (p, (const char **) array, index + seps))
1635  {
1636  insert_non_mandatory_keyword (p, array,
1637  index + seps);
1638  seps++;
1639  }
1641  p, strlen (p));
1642  if (normalized != NULL)
1643  {
1644  if (GNUNET_NO == find_duplicate ((const char *) normalized,
1645  (const char **) array, index + seps))
1646  {
1647  insert_non_mandatory_keyword ((const char *) normalized, array,
1648  index + seps);
1649  seps++;
1650  }
1651  GNUNET_free (normalized);
1652  }
1653  }
1654  else
1655  seps++;
1656  }
1657  GNUNET_free (ss);
1658  return seps;
1659 }
static size_t u8_strcount(const uint8_t *s)
Counts the number of UTF-8 characters (not bytes) in the string, returns that count.
Definition: fs_uri.c:1485
static void insert_non_mandatory_keyword(const char *s, char **array, int index)
Add a keyword as non-mandatory (with &#39; &#39;-prefix) to the given keyword list at offset &#39;index&#39;...
Definition: fs_uri.c:1397
0-terminated, UTF-8 encoded string.
#define GNUNET_NO
Definition: gnunet_common.h:81
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
static int find_duplicate(const char *s, const char **array, int array_length)
Test if the given keyword s is already present in the given array, ignoring the &#39;+&#39;-mandatory prefix ...
Definition: fs_uri.c:1420
static struct GNUNET_OS_Process * p
Helper process we started.
Definition: gnunet-qr.c:59
#define TOKENS
Where to break up keywords.
Definition: fs_uri.c:1600
static char * normalize_metadata(enum EXTRACTOR_MetaFormat format, const char *data, size_t data_len)
FIXME: comment.
Definition: fs_uri.c:1437
#define GNUNET_free(ptr)
Wrapper around free.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ gather_uri_data()

static int gather_uri_data ( void *  cls,
const char *  plugin_name,
enum EXTRACTOR_MetaType  type,
enum EXTRACTOR_MetaFormat  format,
const char *  data_mime_type,
const char *  data,
size_t  data_len 
)
static

Function called on each value in the meta data.

Adds it to the URI.

Parameters
clsURI to update
plugin_namename of the plugin that produced this value; special values can be used (i.e. '<zlib>' for zlib being used in the main libextractor library and yielding meta data).
typelibextractor-type describing the meta data
formatbasic format information about data
data_mime_typemime-type of data (not of the original file); can be NULL (if mime-type is not known)
dataactual meta-data found
data_lennumber of bytes in data
Returns
0 (always)

Definition at line 1681 of file fs_uri.c.

References GNUNET_FS_Uri::data, EXTRACTOR_METAFORMAT_C_STRING, EXTRACTOR_METAFORMAT_UTF8, EXTRACTOR_METATYPE_MIMETYPE, find_duplicate(), GNUNET_asprintf(), GNUNET_free, insert_non_mandatory_keyword(), GNUNET_FS_Uri::ksk, normalize_metadata(), u8_strcount(), and uri.

Referenced by GNUNET_FS_uri_ksk_create_from_meta_data().

1687 {
1688  struct GNUNET_FS_Uri *uri = cls;
1689  char *normalized_data;
1690  const char *sep;
1691 
1692  if ((format != EXTRACTOR_METAFORMAT_UTF8) &&
1693  (format != EXTRACTOR_METAFORMAT_C_STRING))
1694  return 0;
1695  /* Keywords must be at least 3 characters long
1696  * If given non-utf8 string it will, most likely, find it to be invalid,
1697  * and will return the length of its valid part, skipping the keyword.
1698  * If it does - fix the extractor, not this check!
1699  */
1700  if (u8_strcount ((const uint8_t *) data) <= 2)
1701  return 0;
1702  if ( (EXTRACTOR_METATYPE_MIMETYPE == type) &&
1703  (NULL != (sep = memchr (data, '/', data_len))) &&
1704  (sep != data) )
1705  {
1706  char *xtra;
1707 
1708  GNUNET_asprintf (&xtra,
1709  "mimetype:%.*s",
1710  (int) (sep - data),
1711  data);
1712  if (! find_duplicate (xtra,
1713  (const char **) uri->data.ksk.keywords,
1714  uri->data.ksk.keywordCount))
1715  {
1717  uri->data.ksk.keywords,
1718  uri->data.ksk.keywordCount);
1719  uri->data.ksk.keywordCount++;
1720  }
1721  GNUNET_free (xtra);
1722  }
1723 
1724  normalized_data = normalize_metadata (format, data, data_len);
1725  if (! find_duplicate (data,
1726  (const char **) uri->data.ksk.keywords,
1727  uri->data.ksk.keywordCount))
1728  {
1730  uri->data.ksk.keywords, uri->data.ksk.keywordCount);
1731  uri->data.ksk.keywordCount++;
1732  }
1733  if (NULL != normalized_data)
1734  {
1735  if (! find_duplicate (normalized_data,
1736  (const char **) uri->data.ksk.keywords,
1737  uri->data.ksk.keywordCount))
1738  {
1739  insert_non_mandatory_keyword (normalized_data,
1740  uri->data.ksk.keywords, uri->data.ksk.keywordCount);
1741  uri->data.ksk.keywordCount++;
1742  }
1743  GNUNET_free (normalized_data);
1744  }
1745  return 0;
1746 }
static size_t u8_strcount(const uint8_t *s)
Counts the number of UTF-8 characters (not bytes) in the string, returns that count.
Definition: fs_uri.c:1485
static void insert_non_mandatory_keyword(const char *s, char **array, int index)
Add a keyword as non-mandatory (with &#39; &#39;-prefix) to the given keyword list at offset &#39;index&#39;...
Definition: fs_uri.c:1397
0-terminated, UTF-8 encoded string.
static int find_duplicate(const char *s, const char **array, int array_length)
Test if the given keyword s is already present in the given array, ignoring the &#39;+&#39;-mandatory prefix ...
Definition: fs_uri.c:1420
static struct GNUNET_FS_Uri * uri
Value of URI provided on command-line (when not publishing a file but just creating UBlocks to refer ...
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
struct GNUNET_FS_Uri::@16::@17 ksk
union GNUNET_FS_Uri::@16 data
A Universal Resource Identifier (URI), opaque.
Definition: fs_api.h:168
enum GNUNET_TESTBED_UnderlayLinkModelType type
the type of this model
static char * normalize_metadata(enum EXTRACTOR_MetaFormat format, const char *data, size_t data_len)
FIXME: comment.
Definition: fs_uri.c:1437
uint32_t data
The data value.
#define GNUNET_free(ptr)
Wrapper around free.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ needs_percent()

static int needs_percent ( char  c)
static

In URI-encoding, does the given character need to be encoded using %-encoding?

Definition at line 1811 of file fs_uri.c.

Referenced by uri_ksk_to_string().

1812 {
1813  return (!
1814  ((isalnum ((unsigned char) c)) || (c == '-') || (c == '_') ||
1815  (c == '.') || (c == '~')));
1816 }
Here is the caller graph for this function:

◆ uri_ksk_to_string()

static char* uri_ksk_to_string ( const struct GNUNET_FS_Uri uri)
static

Convert a KSK URI to a string.

Parameters
urithe URI to convert
Returns
NULL on error (i.e. keywordCount == 0)

Definition at line 1826 of file fs_uri.c.

References GNUNET_FS_Uri::data, GNUNET_FS_URI_KSK, GNUNET_FS_URI_KSK_INFIX, GNUNET_FS_URI_PREFIX, GNUNET_malloc, GNUNET_FS_Uri::keywordCount, GNUNET_FS_Uri::keywords, GNUNET_FS_Uri::ksk, needs_percent(), ret, and GNUNET_FS_Uri::type.

Referenced by GNUNET_FS_uri_to_string().

1827 {
1828  char **keywords;
1829  unsigned int keywordCount;
1830  size_t n;
1831  char *ret;
1832  unsigned int i;
1833  unsigned int j;
1834  unsigned int wpos;
1835  size_t slen;
1836  const char *keyword;
1837 
1838  if (uri->type != GNUNET_FS_URI_KSK)
1839  return NULL;
1840  keywords = uri->data.ksk.keywords;
1841  keywordCount = uri->data.ksk.keywordCount;
1842  n = keywordCount + strlen (GNUNET_FS_URI_PREFIX) +
1843  strlen (GNUNET_FS_URI_KSK_INFIX) + 1;
1844  for (i = 0; i < keywordCount; i++)
1845  {
1846  keyword = keywords[i];
1847  slen = strlen (keyword);
1848  n += slen;
1849  for (j = 0; j < slen; j++)
1850  {
1851  if ((j == 0) && (keyword[j] == ' '))
1852  {
1853  n--;
1854  continue; /* skip leading space */
1855  }
1856  if (needs_percent (keyword[j]))
1857  n += 2; /* will use %-encoding */
1858  }
1859  }
1860  ret = GNUNET_malloc (n);
1861  strcpy (ret, GNUNET_FS_URI_PREFIX);
1862  strcat (ret, GNUNET_FS_URI_KSK_INFIX);
1863  wpos = strlen (ret);
1864  for (i = 0; i < keywordCount; i++)
1865  {
1866  keyword = keywords[i];
1867  slen = strlen (keyword);
1868  for (j = 0; j < slen; j++)
1869  {
1870  if ((j == 0) && (keyword[j] == ' '))
1871  continue; /* skip leading space */
1872  if (needs_percent (keyword[j]))
1873  {
1874  sprintf (&ret[wpos], "%%%02X", (unsigned char) keyword[j]);
1875  wpos += 3;
1876  }
1877  else
1878  {
1879  ret[wpos++] = keyword[j];
1880  }
1881  }
1882  if (i != keywordCount - 1)
1883  ret[wpos++] = '+';
1884  }
1885  return ret;
1886 }
Keyword search key (query with keywords).
Definition: fs_api.h:156
static int ret
Final status code.
Definition: gnunet-arm.c:89
char ** keywords
Keywords start with a &#39;+&#39; if they are mandatory (in which case the &#39;+&#39; is NOT part of the keyword) an...
Definition: fs_api.h:188
struct GNUNET_FS_Uri::@16::@17 ksk
union GNUNET_FS_Uri::@16 data
unsigned int keywordCount
Size of the keywords array.
Definition: fs_api.h:193
enum GNUNET_FS_UriType type
Type of the URI.
Definition: fs_api.h:173
#define GNUNET_FS_URI_KSK_INFIX
#define GNUNET_FS_URI_PREFIX
static int needs_percent(char c)
In URI-encoding, does the given character need to be encoded using %-encoding?
Definition: fs_uri.c:1811
#define GNUNET_malloc(size)
Wrapper around malloc.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ uri_sks_to_string()

static char* uri_sks_to_string ( const struct GNUNET_FS_Uri uri)
static

Convert SKS URI to a string.

Parameters
urisks uri to convert
Returns
NULL on error

Definition at line 1896 of file fs_uri.c.

References buf, GNUNET_FS_Uri::data, GNUNET_asprintf(), GNUNET_assert, GNUNET_FS_URI_PREFIX, GNUNET_FS_URI_SKS, GNUNET_FS_URI_SKS_INFIX, GNUNET_STRINGS_data_to_string(), ret, GNUNET_FS_Uri::sks, and GNUNET_FS_Uri::type.

Referenced by GNUNET_FS_uri_to_string().

1897 {
1898  char *ret;
1899  char buf[1024];
1900 
1901  if (GNUNET_FS_URI_SKS != uri->type)
1902  return NULL;
1903  ret = GNUNET_STRINGS_data_to_string (&uri->data.sks.ns,
1904  sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey),
1905  buf,
1906  sizeof (buf));
1907  GNUNET_assert (NULL != ret);
1908  ret[0] = '\0';
1909  GNUNET_asprintf (&ret, "%s%s%s/%s", GNUNET_FS_URI_PREFIX,
1911  uri->data.sks.identifier);
1912  return ret;
1913 }
#define GNUNET_FS_URI_SKS_INFIX
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
static int ret
Final status code.
Definition: gnunet-arm.c:89
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
union GNUNET_FS_Uri::@16 data
static char buf[2048]
enum GNUNET_FS_UriType type
Type of the URI.
Definition: fs_api.h:173
Signed key space (file in namespace).
Definition: fs_api.h:151
struct GNUNET_FS_Uri::@16::@18 sks
#define GNUNET_FS_URI_PREFIX
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and ECDS...
char * GNUNET_STRINGS_data_to_string(const void *data, size_t size, char *out, size_t out_size)
Convert binary data to ASCII encoding using CrockfordBase32.
Definition: strings.c:924
Here is the call graph for this function:
Here is the caller graph for this function:

◆ uri_chk_to_string()

static char* uri_chk_to_string ( const struct GNUNET_FS_Uri uri)
static

Convert a CHK URI to a string.

Parameters
urichk uri to convert
Returns
NULL on error

Definition at line 1923 of file fs_uri.c.

References GNUNET_FS_Uri::chk, FileIdentifier::chk, GNUNET_FS_Uri::data, LocUriAssembly::fi, FileIdentifier::file_length, GNUNET_asprintf(), GNUNET_CRYPTO_hash_to_enc(), GNUNET_FS_URI_CHK, GNUNET_FS_URI_CHK_INFIX, GNUNET_FS_URI_PREFIX, GNUNET_ntohll(), ContentHashKey::key, ContentHashKey::query, ret, and GNUNET_FS_Uri::type.

Referenced by GNUNET_FS_uri_to_string().

1924 {
1925  const struct FileIdentifier *fi;
1926  char *ret;
1927  struct GNUNET_CRYPTO_HashAsciiEncoded keyhash;
1928  struct GNUNET_CRYPTO_HashAsciiEncoded queryhash;
1929 
1930  if (uri->type != GNUNET_FS_URI_CHK)
1931  return NULL;
1932  fi = &uri->data.chk;
1933  GNUNET_CRYPTO_hash_to_enc (&fi->chk.key, &keyhash);
1934  GNUNET_CRYPTO_hash_to_enc (&fi->chk.query, &queryhash);
1935 
1936  GNUNET_asprintf (&ret, "%s%s%s.%s.%llu", GNUNET_FS_URI_PREFIX,
1937  GNUNET_FS_URI_CHK_INFIX, (const char *) &keyhash,
1938  (const char *) &queryhash, GNUNET_ntohll (fi->file_length));
1939  return ret;
1940 }
struct ContentHashKey chk
Query and key of the top GNUNET_EC_IBlock.
Definition: fs_api.h:104
struct FileIdentifier chk
Information needed to retrieve a file (content-hash-key plus file size).
Definition: fs_api.h:215
static int ret
Final status code.
Definition: gnunet-arm.c:89
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
struct GNUNET_HashCode query
Hash of the encrypted content, used for querying.
Definition: fs.h:63
union GNUNET_FS_Uri::@16 data
#define GNUNET_FS_URI_CHK_INFIX
complete information needed to download a file.
Definition: fs_api.h:93
Content-hash-key (simple file).
Definition: fs_api.h:146
void GNUNET_CRYPTO_hash_to_enc(const struct GNUNET_HashCode *block, struct GNUNET_CRYPTO_HashAsciiEncoded *result)
Convert hash to ASCII encoding.
Definition: crypto_hash.c:69
enum GNUNET_FS_UriType type
Type of the URI.
Definition: fs_api.h:173
0-terminated ASCII encoding of a struct GNUNET_HashCode.
struct GNUNET_HashCode key
Hash of the original content, used for encryption.
Definition: fs.h:58
#define GNUNET_FS_URI_PREFIX
uint64_t file_length
Total size of the file in bytes.
Definition: fs_api.h:99
uint64_t GNUNET_ntohll(uint64_t n)
Convert unsigned 64-bit integer to host byte order.
Definition: common_endian.c:48
Here is the call graph for this function:
Here is the caller graph for this function:

◆ uri_loc_to_string()

static char* uri_loc_to_string ( const struct GNUNET_FS_Uri uri)
static

Convert a LOC URI to a string.

Parameters
uriloc uri to convert
Returns
NULL on error

Definition at line 1950 of file fs_uri.c.

References GNUNET_TIME_Absolute::abs_value_us, FileIdentifier::chk, Location::contentSignature, GNUNET_FS_Uri::data, Location::expirationTime, Location::fi, LocUriAssembly::fi, FileIdentifier::file_length, GNUNET_asprintf(), GNUNET_assert, GNUNET_CRYPTO_eddsa_public_key_to_string(), GNUNET_CRYPTO_hash_to_enc(), GNUNET_free, GNUNET_FS_URI_LOC_INFIX, GNUNET_FS_URI_PREFIX, GNUNET_ntohll(), GNUNET_STRINGS_data_to_string(), ContentHashKey::key, GNUNET_FS_Uri::loc, Location::peer, peer_id, GNUNET_PeerIdentity::public_key, ContentHashKey::query, ret, and SIGNATURE_ASCII_LENGTH.

Referenced by GNUNET_FS_uri_to_string().

1951 {
1952  char *ret;
1953  struct GNUNET_CRYPTO_HashAsciiEncoded keyhash;
1954  struct GNUNET_CRYPTO_HashAsciiEncoded queryhash;
1955  char *peer_id;
1956  char peer_sig[SIGNATURE_ASCII_LENGTH + 1];
1957 
1958  GNUNET_CRYPTO_hash_to_enc (&uri->data.loc.fi.chk.key, &keyhash);
1959  GNUNET_CRYPTO_hash_to_enc (&uri->data.loc.fi.chk.query, &queryhash);
1960  peer_id =
1962  GNUNET_assert (NULL !=
1964  sizeof (struct GNUNET_CRYPTO_EddsaSignature),
1965  peer_sig,
1966  sizeof (peer_sig)));
1967  GNUNET_asprintf (&ret,
1968  "%s%s%s.%s.%llu.%s.%s.%llu", GNUNET_FS_URI_PREFIX,
1969  GNUNET_FS_URI_LOC_INFIX, (const char *) &keyhash,
1970  (const char *) &queryhash,
1971  (unsigned long long) GNUNET_ntohll (uri->data.loc.
1972  fi.file_length),
1973  peer_id,
1974  peer_sig,
1975  (unsigned long long) uri->data.loc.expirationTime.abs_value_us / 1000000LL);
1976  GNUNET_free (peer_id);
1977  return ret;
1978 }
struct ContentHashKey chk
Query and key of the top GNUNET_EC_IBlock.
Definition: fs_api.h:104
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
static char * peer_id
Option –peer.
Definition: gnunet-cadet.c:42
struct GNUNET_PeerIdentity peer
Identity of the peer sharing the file.
Definition: fs_api.h:123
static int ret
Final status code.
Definition: gnunet-arm.c:89
uint64_t abs_value_us
The actual value.
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
char * GNUNET_CRYPTO_eddsa_public_key_to_string(const struct GNUNET_CRYPTO_EddsaPublicKey *pub)
Convert a public key to a string.
Definition: crypto_ecc.c:367
struct GNUNET_HashCode query
Hash of the encrypted content, used for querying.
Definition: fs.h:63
union GNUNET_FS_Uri::@16 data
void GNUNET_CRYPTO_hash_to_enc(const struct GNUNET_HashCode *block, struct GNUNET_CRYPTO_HashAsciiEncoded *result)
Convert hash to ASCII encoding.
Definition: crypto_hash.c:69
struct GNUNET_TIME_Absolute expirationTime
Time when this location URI expires.
Definition: fs_api.h:128
an ECC signature using EdDSA.
0-terminated ASCII encoding of a struct GNUNET_HashCode.
struct GNUNET_HashCode key
Hash of the original content, used for encryption.
Definition: fs.h:58
#define GNUNET_FS_URI_PREFIX
struct GNUNET_CRYPTO_EddsaSignature contentSignature
Signature over the GNUNET_EC_FileIdentifier, peer identity and expiration time.
Definition: fs_api.h:134
struct FileIdentifier fi
Information about the shared file.
Definition: fs_api.h:118
struct Location loc
Information needed to retrieve a file including signed location (identity of a peer) of the content...
Definition: fs_api.h:221
#define SIGNATURE_ASCII_LENGTH
Definition: fs_uri.c:491
#define GNUNET_FS_URI_LOC_INFIX
char * GNUNET_STRINGS_data_to_string(const void *data, size_t size, char *out, size_t out_size)
Convert binary data to ASCII encoding using CrockfordBase32.
Definition: strings.c:924
uint64_t GNUNET_ntohll(uint64_t n)
Convert unsigned 64-bit integer to host byte order.
Definition: common_endian.c:48
#define GNUNET_free(ptr)
Wrapper around free.
struct GNUNET_CRYPTO_EddsaPublicKey public_key
Here is the call graph for this function:
Here is the caller graph for this function: