GNUnet  0.20.0
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_FS_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 differentiated 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:

  • First, there are URIs that identify a file. They have the format "gnunet://fs/chk/HEX1.HEX2.SIZE". These URIs can be used to download the file. The description, filename, mime-type and other meta-data is NOT part of the file-URI since a URI uniquely identifies a resource (and the contents of the file would be the same even if it had a different description).

  • The second category identifies entries in a namespace. The format is "gnunet://fs/sks/NAMESPACE/IDENTIFIER" where the namespace should be given in HEX. Applications may allow using a nickname for the namespace if the nickname is not ambiguous. The identifier can be either an ASCII sequence or a HEX-encoding. If the identifier is in ASCII but the format is ambiguous and could denote a HEX-string a "/" is appended to indicate ASCII encoding.

  • The third category identifies ordinary searches. The format is "gnunet://fs/ksk/KEYWORD[+KEYWORD]*". Using the "+" syntax it is possible to encode searches with the boolean "AND" operator. "+" is used since it indicates a commutative 'and' operation and is unlikely to be used in a keyword by itself.

  • The last category identifies a datum on a specific machine. The format is "gnunet://fs/loc/HEX1.HEX2.SIZE.PEER.SIG.EXPTIME". PEER is the BinName of the public key of the peer storing the datum. The signature (SIG) certifies that this peer has this content. HEX1, HEX2 and SIZE correspond to a 'chk' URI.

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 262 of file fs_uri.c.

◆ GNUNET_FS_URI_SKS_PREFIX

#define GNUNET_FS_URI_SKS_PREFIX   GNUNET_FS_URI_PREFIX GNUNET_FS_URI_SKS_INFIX

Definition at line 356 of file fs_uri.c.

◆ GNUNET_FS_URI_CHK_PREFIX

#define GNUNET_FS_URI_CHK_PREFIX   GNUNET_FS_URI_PREFIX GNUNET_FS_URI_CHK_INFIX

Definition at line 395 of file fs_uri.c.

◆ GNUNET_FS_URI_LOC_PREFIX

#define GNUNET_FS_URI_LOC_PREFIX   GNUNET_FS_URI_PREFIX GNUNET_FS_URI_LOC_INFIX

Definition at line 483 of file fs_uri.c.

◆ SIGNATURE_ASCII_LENGTH

#define SIGNATURE_ASCII_LENGTH   103

Definition at line 485 of file fs_uri.c.

◆ TOKENS

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

Where to break up keywords.

Definition at line 1614 of file fs_uri.c.

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
decoded string with leading space (or preserved plus)

Definition at line 212 of file fs_uri.c.

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

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

Referenced by uri_ksk_parse().

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 272 of file fs_uri.c.

273 {
274  struct GNUNET_FS_Uri *ret;
275  char **keywords;
276  unsigned int pos;
277  int max;
278  int iret;
279  int i;
280  size_t slen;
281  char *dup;
282  int saw_quote;
283 
284  slen = strlen (s);
285  pos = strlen (GNUNET_FS_URI_KSK_PREFIX);
286  if ((slen <= pos) || (0 != strncmp (s, GNUNET_FS_URI_KSK_PREFIX, pos)))
287  return NULL; /* not KSK URI */
288  if ((s[slen - 1] == '+') || (s[pos] == '+'))
289  {
290  *emsg =
291  GNUNET_strdup (_ ("Malformed KSK URI (must not begin or end with `+')"));
292  return NULL;
293  }
294  max = 1;
295  saw_quote = 0;
296  for (i = pos; i < slen; i++)
297  {
298  if ((s[i] == '%') && (&s[i] == strstr (&s[i], "%22")))
299  {
300  saw_quote = (saw_quote + 1) % 2;
301  i += 3;
302  continue;
303  }
304  if ((s[i] == '+') && (saw_quote == 0))
305  {
306  max++;
307  if (s[i - 1] == '+')
308  {
309  *emsg = GNUNET_strdup (_ ("Malformed KSK URI (`++' not allowed)"));
310  return NULL;
311  }
312  }
313  }
314  if (saw_quote == 1)
315  {
316  *emsg = GNUNET_strdup (_ ("Malformed KSK URI (quotes not balanced)"));
317  return NULL;
318  }
319  iret = max;
320  dup = GNUNET_strdup (s);
321  keywords = GNUNET_new_array (max, char *);
322  for (i = slen - 1; i >= (int) pos; i--)
323  {
324  if ((s[i] == '%') && (&s[i] == strstr (&s[i], "%22")))
325  {
326  saw_quote = (saw_quote + 1) % 2;
327  continue;
328  }
329  if ((dup[i] == '+') && (saw_quote == 0))
330  {
331  keywords[--max] = percent_decode_keyword (&dup[i + 1], emsg);
332  if (NULL == keywords[max])
333  goto CLEANUP;
334  dup[i] = '\0';
335  }
336  }
337  keywords[--max] = percent_decode_keyword (&dup[pos], emsg);
338  if (NULL == keywords[max])
339  goto CLEANUP;
340  GNUNET_assert (0 == max);
341  GNUNET_free (dup);
342  ret = GNUNET_new (struct GNUNET_FS_Uri);
343  ret->type = GNUNET_FS_URI_KSK;
344  ret->data.ksk.keywordCount = iret;
345  ret->data.ksk.keywords = keywords;
346  return ret;
347  CLEANUP:
348  for (i = 0; i < max; i++)
349  GNUNET_free (keywords[i]);
351  GNUNET_free (dup);
352  return NULL;
353 }
@ GNUNET_FS_URI_KSK
Keyword search key (query with keywords).
Definition: fs_api.h:154
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:212
#define GNUNET_FS_URI_KSK_PREFIX
Definition: fs_uri.c:262
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_new_array(n, type)
Allocate a size n array with structs or unions of the given type.
#define max(x, y)
A Universal Resource Identifier (URI), opaque.
Definition: fs_api.h:167
char ** keywords
Keywords start with a '+' if they are mandatory (in which case the '+' is NOT part of the keyword) an...
Definition: fs_api.h:186

References _, GNUNET_assert, GNUNET_free, GNUNET_FS_URI_KSK, GNUNET_FS_URI_KSK_PREFIX, GNUNET_new, GNUNET_new_array, GNUNET_strdup, consensus-simulation::int, GNUNET_FS_Uri::keywords, max, percent_decode_keyword(), and ret.

Referenced by GNUNET_FS_uri_parse().

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 366 of file fs_uri.c.

367 {
368  struct GNUNET_FS_Uri *ret;
370  size_t pos;
371  char *end;
372 
373  pos = strlen (GNUNET_FS_URI_SKS_PREFIX);
374  if ((strlen (s) <= pos) || (0 != strncmp (s, GNUNET_FS_URI_SKS_PREFIX, pos)))
375  return NULL; /* not an SKS URI */
376  end = strchr (&s[pos], '/');
377  if ((NULL == end) ||
379  end - &s[pos],
380  &ns,
381  sizeof(ns))))
382  {
383  *emsg = GNUNET_strdup (_ ("Malformed SKS URI (wrong syntax)"));
384  return NULL; /* malformed */
385  }
386  end++; /* skip over '/' */
387  ret = GNUNET_new (struct GNUNET_FS_Uri);
388  ret->type = GNUNET_FS_URI_SKS;
389  ret->data.sks.ns = ns;
390  ret->data.sks.identifier = GNUNET_strdup (end);
391  return ret;
392 }
@ GNUNET_FS_URI_SKS
Signed key space (file in namespace).
Definition: fs_api.h:149
#define GNUNET_FS_URI_SKS_PREFIX
Definition: fs_uri.c:356
static struct GNUNET_NAMESTORE_Handle * ns
Handle to the namestore.
Definition: gnunet-abd.c:41
static int end
Set if we are to shutdown all services (including ARM).
Definition: gnunet-arm.c:34
@ GNUNET_OK
enum GNUNET_GenericReturnValue 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:788
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and ECDS...

References _, end, GNUNET_FS_URI_SKS, GNUNET_FS_URI_SKS_PREFIX, GNUNET_new, GNUNET_OK, GNUNET_strdup, GNUNET_STRINGS_string_to_data(), ns, and ret.

Referenced by GNUNET_FS_uri_parse().

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 406 of file fs_uri.c.

407 {
408  struct GNUNET_FS_Uri *ret;
409  struct FileIdentifier fi;
410  unsigned int pos;
411  unsigned long long flen;
412  size_t slen;
413  char h1[sizeof(struct GNUNET_CRYPTO_HashAsciiEncoded)];
414  char h2[sizeof(struct GNUNET_CRYPTO_HashAsciiEncoded)];
415 
416  slen = strlen (s);
417  pos = strlen (GNUNET_FS_URI_CHK_PREFIX);
418  if ((slen < pos + 2 * sizeof(struct GNUNET_CRYPTO_HashAsciiEncoded) + 1) ||
419  (0 != strncmp (s, GNUNET_FS_URI_CHK_PREFIX, pos)))
420  return NULL; /* not a CHK URI */
421  if ((s[pos + sizeof(struct GNUNET_CRYPTO_HashAsciiEncoded) - 1] != '.') ||
422  (s[pos + sizeof(struct GNUNET_CRYPTO_HashAsciiEncoded) * 2 - 1] != '.'))
423  {
424  *emsg = GNUNET_strdup (_ ("Malformed CHK URI (wrong syntax)"));
425  return NULL;
426  }
427  GNUNET_memcpy (h1, &s[pos], sizeof(struct GNUNET_CRYPTO_HashAsciiEncoded));
428  h1[sizeof(struct GNUNET_CRYPTO_HashAsciiEncoded) - 1] = '\0';
429  GNUNET_memcpy (h2,
430  &s[pos + sizeof(struct GNUNET_CRYPTO_HashAsciiEncoded)],
431  sizeof(struct GNUNET_CRYPTO_HashAsciiEncoded));
432  h2[sizeof(struct GNUNET_CRYPTO_HashAsciiEncoded) - 1] = '\0';
433 
434  if ((GNUNET_OK != GNUNET_CRYPTO_hash_from_string (h1, &fi.chk.key)) ||
435  (GNUNET_OK != GNUNET_CRYPTO_hash_from_string (h2, &fi.chk.query)) ||
436  (1 !=
437  sscanf (&s[pos + sizeof(struct GNUNET_CRYPTO_HashAsciiEncoded) * 2],
438  "%llu",
439  &flen)))
440  {
441  *emsg = GNUNET_strdup (_ ("Malformed CHK URI (failed to decode CHK)"));
442  return NULL;
443  }
444  fi.file_length = GNUNET_htonll (flen);
445  ret = GNUNET_new (struct GNUNET_FS_Uri);
446  ret->type = GNUNET_FS_URI_CHK;
447  ret->data.chk = fi;
448  return ret;
449 }
@ GNUNET_FS_URI_CHK
Content-hash-key (simple file).
Definition: fs_api.h:144
#define GNUNET_FS_URI_CHK_PREFIX
Definition: fs_uri.c:395
#define GNUNET_CRYPTO_hash_from_string(enc, result)
Convert ASCII encoding back to struct GNUNET_HashCode
uint64_t GNUNET_htonll(uint64_t n)
Convert unsigned 64-bit integer to network byte order.
Definition: common_endian.c:37
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
complete information needed to download a file.
Definition: fs_api.h:95
0-terminated ASCII encoding of a struct GNUNET_HashCode.

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

Referenced by GNUNET_FS_uri_parse().

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 496 of file fs_uri.c.

497 {
498  struct GNUNET_FS_Uri *uri;
499  char h1[sizeof(struct GNUNET_CRYPTO_HashAsciiEncoded)];
500  char h2[sizeof(struct GNUNET_CRYPTO_HashAsciiEncoded)];
501  unsigned int pos;
502  unsigned int npos;
503  unsigned long long exptime;
504  unsigned long long flen;
505  struct GNUNET_TIME_Absolute et;
506  struct GNUNET_CRYPTO_EddsaSignature sig;
507  struct LocUriAssembly ass;
508  size_t slen;
509 
510  slen = strlen (s);
511  pos = strlen (GNUNET_FS_URI_LOC_PREFIX);
512  if ((slen < pos + 2 * sizeof(struct GNUNET_CRYPTO_HashAsciiEncoded) + 1) ||
513  (0 != strncmp (s, GNUNET_FS_URI_LOC_PREFIX, pos)))
514  return NULL; /* not a LOC URI */
515  if ((s[pos + sizeof(struct GNUNET_CRYPTO_HashAsciiEncoded) - 1] != '.') ||
516  (s[pos + sizeof(struct GNUNET_CRYPTO_HashAsciiEncoded) * 2 - 1] != '.'))
517  {
518  *emsg = GNUNET_strdup (_ ("LOC URI malformed (wrong syntax)"));
519  return NULL;
520  }
521  GNUNET_memcpy (h1, &s[pos], sizeof(struct GNUNET_CRYPTO_HashAsciiEncoded));
522  h1[sizeof(struct GNUNET_CRYPTO_HashAsciiEncoded) - 1] = '\0';
523  GNUNET_memcpy (h2,
524  &s[pos + sizeof(struct GNUNET_CRYPTO_HashAsciiEncoded)],
525  sizeof(struct GNUNET_CRYPTO_HashAsciiEncoded));
526  h2[sizeof(struct GNUNET_CRYPTO_HashAsciiEncoded) - 1] = '\0';
527 
528  if ((GNUNET_OK != GNUNET_CRYPTO_hash_from_string (h1, &ass.fi.chk.key)) ||
529  (GNUNET_OK != GNUNET_CRYPTO_hash_from_string (h2, &ass.fi.chk.query)) ||
530  (1 !=
531  sscanf (&s[pos + sizeof(struct GNUNET_CRYPTO_HashAsciiEncoded) * 2],
532  "%llu",
533  &flen)))
534  {
535  *emsg = GNUNET_strdup (_ ("LOC URI malformed (no CHK)"));
536  return NULL;
537  }
538  ass.fi.file_length = GNUNET_htonll (flen);
539 
540  npos = pos + sizeof(struct GNUNET_CRYPTO_HashAsciiEncoded) * 2;
541  while ((s[npos] != '\0') && (s[npos] != '.'))
542  npos++;
543  if (s[npos] == '\0')
544  {
545  *emsg = GNUNET_strdup (_ ("LOC URI malformed (missing LOC)"));
546  goto ERR;
547  }
548  npos++;
549  if ((strlen (&s[npos]) <= GNUNET_CRYPTO_PKEY_ASCII_LENGTH + 1) ||
550  ('.' != s[npos + GNUNET_CRYPTO_PKEY_ASCII_LENGTH]))
551  {
552  *emsg =
553  GNUNET_strdup (_ ("LOC URI malformed (wrong syntax for public key)"));
554  }
555  if (
556  GNUNET_OK !=
559  &ass.peer.public_key))
560  {
561  *emsg =
562  GNUNET_strdup (_ ("LOC URI malformed (could not decode public key)"));
563  goto ERR;
564  }
566  if (s[npos++] != '.')
567  {
568  *emsg = GNUNET_strdup (_ ("LOC URI malformed (could not find signature)"));
569  goto ERR;
570  }
571  if ((strlen (&s[npos]) <= SIGNATURE_ASCII_LENGTH + 1) ||
572  ('.' != s[npos + SIGNATURE_ASCII_LENGTH]))
573  {
574  *emsg =
575  GNUNET_strdup (_ ("LOC URI malformed (wrong syntax for signature)"));
576  goto ERR;
577  }
578  if (GNUNET_OK !=
581  &sig,
582  sizeof(
584  {
585  *emsg =
586  GNUNET_strdup (_ ("LOC URI malformed (could not decode signature)"));
587  goto ERR;
588  }
589  npos += SIGNATURE_ASCII_LENGTH;
590  if (s[npos++] != '.')
591  {
592  *emsg = GNUNET_strdup (
593  _ ("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,
609  &sig,
610  &ass.peer.public_key))
611  {
612  *emsg =
613  GNUNET_strdup (_ ("LOC URI malformed (signature failed validation)"));
614  goto ERR;
615  }
616  uri = GNUNET_new (struct GNUNET_FS_Uri);
618  uri->data.loc.fi = ass.fi;
619  uri->data.loc.peer = ass.peer;
620  uri->data.loc.expirationTime = et;
621  uri->data.loc.contentSignature = sig;
622 
623  return uri;
624  ERR:
625  return NULL;
626 }
#define GNUNET_SIGNATURE_PURPOSE_PEER_PLACEMENT
Signature by which a peer affirms that it is providing a certain bit of content for use in LOCation U...
@ GNUNET_FS_URI_LOC
Location (chk with identity of hosting peer).
Definition: fs_api.h:159
#define GNUNET_FS_URI_LOC_PREFIX
Definition: fs_uri.c:483
#define SIGNATURE_ASCII_LENGTH
Definition: fs_uri.c:485
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_CRYPTO_eddsa_verify(purp, ps, sig, pub)
Verify EdDSA signature.
#define GNUNET_CRYPTO_PKEY_ASCII_LENGTH
How many characters (without 0-terminator) are our ASCII-encoded public keys (ECDSA/EDDSA/ECDHE).
enum GNUNET_GenericReturnValue 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:358
struct GNUNET_TIME_AbsoluteNBO GNUNET_TIME_absolute_hton(struct GNUNET_TIME_Absolute a)
Convert absolute time to network byte order.
Definition: time.c:638
an ECC signature using EdDSA.
union GNUNET_FS_Uri::@13 data
enum GNUNET_FS_UriType type
Type of the URI.
Definition: fs_api.h:171
struct Location loc
Information needed to retrieve a file including signed location (identity of a peer) of the content.
Definition: fs_api.h:218
Time for absolute times used by GNUnet, in microseconds.
Structure that defines how the contents of a location URI must be assembled in memory to create or ve...
Definition: fs_uri.c:459
struct GNUNET_TIME_Absolute expirationTime
Time when this location URI expires.
Definition: fs_api.h:127
struct GNUNET_CRYPTO_EddsaSignature contentSignature
Signature over the GNUNET_EC_FileIdentifier, peer identity and expiration time.
Definition: fs_api.h:133
struct FileIdentifier fi
Information about the shared file.
Definition: fs_api.h:117
struct GNUNET_PeerIdentity peer
Identity of the peer sharing the file.
Definition: fs_api.h:122

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, LocUriAssembly::purpose, GNUNET_CRYPTO_EccSignaturePurpose::purpose, ContentHashKey::query, SIGNATURE_ASCII_LENGTH, GNUNET_CRYPTO_EccSignaturePurpose::size, GNUNET_FS_Uri::type, and uri.

Referenced by GNUNET_FS_uri_parse().

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 1400 of file fs_uri.c.

1401 {
1402  char *nkword;
1403 
1404  GNUNET_asprintf (&nkword,
1405  " %s", /* space to mark as 'non mandatory' */
1406  s);
1407  array[index] = nkword;
1408 }
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.

References GNUNET_asprintf().

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

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 1421 of file fs_uri.c.

1422 {
1423  int j;
1424 
1425  for (j = array_length - 1; j >= 0; j--)
1426  if (0 == strcmp (&array[j][1], s))
1427  return GNUNET_YES;
1428  return GNUNET_NO;
1429 }
@ GNUNET_YES
@ GNUNET_NO

References GNUNET_NO, and GNUNET_YES.

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

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 1436 of file fs_uri.c.

1439 {
1440  uint8_t *free_str = NULL;
1441  uint8_t *str_to_normalize = (uint8_t *) data;
1442  uint8_t *normalized;
1443  size_t r_len;
1444 
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
1454  format = EXTRACTOR_METAFORMAT_C_STRING;
1455  }
1456  if (format == EXTRACTOR_METAFORMAT_C_STRING)
1457  {
1458  free_str = u8_strconv_from_encoding (data,
1459  locale_charset (),
1460  iconveh_escape_sequence);
1461  if (free_str == NULL)
1462  return NULL;
1463  }
1464 
1465  normalized = u8_tolower (str_to_normalize,
1466  strlen ((char *) str_to_normalize),
1467  NULL,
1468  UNINORM_NFD,
1469  NULL,
1470  &r_len);
1471  /* free_str is allocated by libunistring internally, use free() */
1472  if (free_str != NULL)
1473  free (free_str);
1474  if (normalized != NULL)
1475  {
1476  /* u8_tolower allocates a non-NULL-terminated string! */
1477  free_str = GNUNET_malloc (r_len + 1);
1478  GNUNET_memcpy (free_str, normalized, r_len);
1479  free_str[r_len] = '\0';
1480  free (normalized);
1481  normalized = free_str;
1482  }
1483  return (char *) normalized;
1484 }
uint32_t data
The data value.

References data, GNUNET_malloc, and GNUNET_memcpy.

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

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 1492 of file fs_uri.c.

1493 {
1494  size_t count;
1495  ucs4_t c;
1496 
1497  GNUNET_assert (s != NULL);
1498  if (s[0] == 0)
1499  return 0;
1500  for (count = 0; s != NULL; count++)
1501  s = u8_next (&c, s);
1502  return count - 1;
1503 }

References GNUNET_assert.

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

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 1523 of file fs_uri.c.

1524 {
1525  int count = 0;
1526  char *open_paren;
1527  char *close_paren;
1528  char *ss;
1529  char tmp;
1530 
1531  if (NULL == s)
1532  return 0;
1533  ss = GNUNET_strdup (s);
1534  open_paren = ss - 1;
1535  while (NULL != (open_paren = strpbrk (open_paren + 1, "[{(")))
1536  {
1537  int match = 0;
1538 
1539  close_paren = strpbrk (open_paren + 1, "]})");
1540  if (NULL == close_paren)
1541  continue;
1542  switch (open_paren[0])
1543  {
1544  case '[':
1545  if (']' == close_paren[0])
1546  match = 1;
1547  break;
1548 
1549  case '{':
1550  if ('}' == close_paren[0])
1551  match = 1;
1552  break;
1553 
1554  case '(':
1555  if (')' == close_paren[0])
1556  match = 1;
1557  break;
1558 
1559  default:
1560  break;
1561  }
1562  if (match && (close_paren - open_paren > 1))
1563  {
1564  tmp = close_paren[0];
1565  close_paren[0] = '\0';
1566  /* Keywords must be at least 3 characters long */
1567  if (u8_strcount ((const uint8_t *) &open_paren[1]) <= 2)
1568  {
1569  close_paren[0] = tmp;
1570  continue;
1571  }
1572  if (NULL != array)
1573  {
1574  char *normalized;
1575  if (GNUNET_NO == find_duplicate ((const char *) &open_paren[1],
1576  (const char **) array,
1577  index + count))
1578  {
1579  insert_non_mandatory_keyword ((const char *) &open_paren[1],
1580  array,
1581  index + count);
1582  count++;
1583  }
1584  normalized = normalize_metadata (EXTRACTOR_METAFORMAT_UTF8,
1585  &open_paren[1],
1586  close_paren - &open_paren[1]);
1587  if (normalized != NULL)
1588  {
1589  if (GNUNET_NO == find_duplicate ((const char *) normalized,
1590  (const char **) array,
1591  index + count))
1592  {
1593  insert_non_mandatory_keyword ((const char *) normalized,
1594  array,
1595  index + count);
1596  count++;
1597  }
1598  GNUNET_free (normalized);
1599  }
1600  }
1601  else
1602  count++;
1603  close_paren[0] = tmp;
1604  }
1605  }
1606  GNUNET_free (ss);
1607  return count;
1608 }
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'.
Definition: fs_uri.c:1400
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:1492
static char * normalize_metadata(enum EXTRACTOR_MetaFormat format, const char *data, size_t data_len)
FIXME: comment.
Definition: fs_uri.c:1436
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 ...
Definition: fs_uri.c:1421

References 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().

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 1631 of file fs_uri.c.

1632 {
1633  char *p;
1634  char *ss;
1635  int seps = 0;
1636 
1637  ss = GNUNET_strdup (s);
1638  for (p = strtok (ss, TOKENS); p != NULL; p = strtok (NULL, TOKENS))
1639  {
1640  /* Keywords must be at least 3 characters long */
1641  if (u8_strcount ((const uint8_t *) p) <= 2)
1642  continue;
1643  if (NULL != array)
1644  {
1645  char *normalized;
1646  if (GNUNET_NO == find_duplicate (p, (const char **) array, index + seps))
1647  {
1648  insert_non_mandatory_keyword (p, array, index + seps);
1649  seps++;
1650  }
1651  normalized =
1652  normalize_metadata (EXTRACTOR_METAFORMAT_UTF8, p, strlen (p));
1653  if (normalized != NULL)
1654  {
1655  if (GNUNET_NO == find_duplicate ((const char *) normalized,
1656  (const char **) array,
1657  index + seps))
1658  {
1659  insert_non_mandatory_keyword ((const char *) normalized,
1660  array,
1661  index + seps);
1662  seps++;
1663  }
1664  GNUNET_free (normalized);
1665  }
1666  }
1667  else
1668  seps++;
1669  }
1670  GNUNET_free (ss);
1671  return seps;
1672 }
#define TOKENS
Where to break up keywords.
Definition: fs_uri.c:1614
static struct GNUNET_OS_Process * p
Helper process we started.
Definition: gnunet-uri.c:38

References 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().

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 (e.g. '<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 1696 of file fs_uri.c.

1703 {
1704  struct GNUNET_FS_Uri *uri = cls;
1705  char *normalized_data;
1706  const char *sep;
1707 
1708  if ((format != EXTRACTOR_METAFORMAT_UTF8) &&
1709  (format != EXTRACTOR_METAFORMAT_C_STRING))
1710  return 0;
1711  /* Keywords must be at least 3 characters long
1712  * If given non-utf8 string it will, most likely, find it to be invalid,
1713  * and will return the length of its valid part, skipping the keyword.
1714  * If it does - fix the extractor, not this check!
1715  */if (u8_strcount ((const uint8_t *) data) <= 2)
1716  return 0;
1717  if ((EXTRACTOR_METATYPE_MIMETYPE == type) &&
1718  (NULL != (sep = memchr (data, '/', data_len))) && (sep != data))
1719  {
1720  char *xtra;
1721 
1722  GNUNET_asprintf (&xtra, "mimetype:%.*s", (int) (sep - data), data);
1723  if (! find_duplicate (xtra,
1724  (const char **) uri->data.ksk.keywords,
1725  uri->data.ksk.keywordCount))
1726  {
1728  uri->data.ksk.keywords,
1729  uri->data.ksk.keywordCount);
1730  uri->data.ksk.keywordCount++;
1731  }
1732  GNUNET_free (xtra);
1733  }
1734 
1735  normalized_data = normalize_metadata (format, data, data_len);
1736  if (! find_duplicate (data,
1737  (const char **) uri->data.ksk.keywords,
1738  uri->data.ksk.keywordCount))
1739  {
1741  uri->data.ksk.keywords,
1742  uri->data.ksk.keywordCount);
1743  uri->data.ksk.keywordCount++;
1744  }
1745  if (NULL != normalized_data)
1746  {
1747  if (! find_duplicate (normalized_data,
1748  (const char **) uri->data.ksk.keywords,
1749  uri->data.ksk.keywordCount))
1750  {
1751  insert_non_mandatory_keyword (normalized_data,
1752  uri->data.ksk.keywords,
1753  uri->data.ksk.keywordCount);
1754  uri->data.ksk.keywordCount++;
1755  }
1756  GNUNET_free (normalized_data);
1757  }
1758  return 0;
1759 }
struct GNUNET_FS_Uri::@13::@14 ksk
enum GNUNET_TESTBED_UnderlayLinkModelType type
the type of this model

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

Referenced by GNUNET_FS_uri_ksk_create_from_meta_data().

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 1828 of file fs_uri.c.

1829 {
1830  return(! ((isalnum ((unsigned char) c)) || (c == '-') || (c == '_') ||
1831  (c == '.') || (c == '~')));
1832 }

Referenced by uri_ksk_to_string().

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 1842 of file fs_uri.c.

1843 {
1844  char **keywords;
1845  unsigned int keywordCount;
1846  size_t n;
1847  char *ret;
1848  unsigned int i;
1849  unsigned int j;
1850  unsigned int wpos;
1851  size_t slen;
1852  const char *keyword;
1853 
1854  if (uri->type != GNUNET_FS_URI_KSK)
1855  return NULL;
1856  keywords = uri->data.ksk.keywords;
1857  keywordCount = uri->data.ksk.keywordCount;
1858  n = keywordCount + strlen (GNUNET_FS_URI_PREFIX)
1859  + strlen (GNUNET_FS_URI_KSK_INFIX) + 1;
1860  for (i = 0; i < keywordCount; i++)
1861  {
1862  keyword = keywords[i];
1863  slen = strlen (keyword);
1864  n += slen;
1865  for (j = 0; j < slen; j++)
1866  {
1867  if ((j == 0) && (keyword[j] == ' '))
1868  {
1869  n--;
1870  continue; /* skip leading space */
1871  }
1872  if (needs_percent (keyword[j]))
1873  n += 2; /* will use %-encoding */
1874  }
1875  }
1876  ret = GNUNET_malloc (n);
1877  strcpy (ret, GNUNET_FS_URI_PREFIX);
1878  strcat (ret, GNUNET_FS_URI_KSK_INFIX);
1879  wpos = strlen (ret);
1880  for (i = 0; i < keywordCount; i++)
1881  {
1882  keyword = keywords[i];
1883  slen = strlen (keyword);
1884  for (j = 0; j < slen; j++)
1885  {
1886  if ((j == 0) && (keyword[j] == ' '))
1887  continue; /* skip leading space */
1888  if (needs_percent (keyword[j]))
1889  {
1890  sprintf (&ret[wpos], "%%%02X", (unsigned char) keyword[j]);
1891  wpos += 3;
1892  }
1893  else
1894  {
1895  ret[wpos++] = keyword[j];
1896  }
1897  }
1898  if (i != keywordCount - 1)
1899  ret[wpos++] = '+';
1900  }
1901  return ret;
1902 }
static int needs_percent(char c)
In URI-encoding, does the given character need to be encoded using %-encoding?
Definition: fs_uri.c:1828
#define GNUNET_FS_URI_KSK_INFIX
#define GNUNET_FS_URI_PREFIX

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, GNUNET_FS_Uri::type, and uri.

Here is the call 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 1912 of file fs_uri.c.

1913 {
1914  char *ret;
1915  char buf[1024];
1916 
1917  if (GNUNET_FS_URI_SKS != uri->type)
1918  return NULL;
1919  ret =
1921  sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey),
1922  buf,
1923  sizeof(buf));
1924  GNUNET_assert (NULL != ret);
1925  ret[0] = '\0';
1926  GNUNET_asprintf (&ret,
1927  "%s%s%s/%s",
1930  buf,
1931  uri->data.sks.identifier);
1932  return ret;
1933 }
static char buf[2048]
#define GNUNET_FS_URI_SKS_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:708
struct GNUNET_FS_Uri::@13::@15 sks

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, GNUNET_FS_Uri::type, and uri.

Here is the call 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 1943 of file fs_uri.c.

1944 {
1945  const struct FileIdentifier *fi;
1946  char *ret;
1947  struct GNUNET_CRYPTO_HashAsciiEncoded keyhash;
1948  struct GNUNET_CRYPTO_HashAsciiEncoded queryhash;
1949 
1950  if (uri->type != GNUNET_FS_URI_CHK)
1951  return NULL;
1952  fi = &uri->data.chk;
1953  GNUNET_CRYPTO_hash_to_enc (&fi->chk.key, &keyhash);
1954  GNUNET_CRYPTO_hash_to_enc (&fi->chk.query, &queryhash);
1955 
1956  GNUNET_asprintf (&ret,
1957  "%s%s%s.%s.%llu",
1960  (const char *) &keyhash,
1961  (const char *) &queryhash,
1962  (unsigned long long) GNUNET_ntohll (fi->file_length));
1963  return ret;
1964 }
#define GNUNET_FS_URI_CHK_INFIX
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:55
uint64_t GNUNET_ntohll(uint64_t n)
Convert unsigned 64-bit integer to host byte order.
Definition: common_endian.c:54
struct GNUNET_HashCode key
Hash of the original content, used for encryption.
Definition: fs.h:59
struct GNUNET_HashCode query
Hash of the encrypted content, used for querying.
Definition: fs.h:64
struct ContentHashKey chk
Query and key of the top GNUNET_EC_IBlock.
Definition: fs_api.h:104
uint64_t file_length
Total size of the file in bytes.
Definition: fs_api.h:99
struct FileIdentifier chk
Information needed to retrieve a file (content-hash-key plus file size).
Definition: fs_api.h:212

References GNUNET_FS_Uri::chk, FileIdentifier::chk, GNUNET_FS_Uri::data, 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, GNUNET_FS_Uri::type, and uri.

Here is the call 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 1974 of file fs_uri.c.

1975 {
1976  char *ret;
1977  struct GNUNET_CRYPTO_HashAsciiEncoded keyhash;
1978  struct GNUNET_CRYPTO_HashAsciiEncoded queryhash;
1979  char *peer_id;
1980  char peer_sig[SIGNATURE_ASCII_LENGTH + 1];
1981 
1982  GNUNET_CRYPTO_hash_to_enc (&uri->data.loc.fi.chk.key, &keyhash);
1983  GNUNET_CRYPTO_hash_to_enc (&uri->data.loc.fi.chk.query, &queryhash);
1984  peer_id =
1986  GNUNET_assert (
1987  NULL !=
1989  sizeof(struct GNUNET_CRYPTO_EddsaSignature),
1990  peer_sig,
1991  sizeof(peer_sig)));
1992  GNUNET_asprintf (&ret,
1993  "%s%s%s.%s.%llu.%s.%s.%llu",
1996  (const char *) &keyhash,
1997  (const char *) &queryhash,
1998  (unsigned long long) GNUNET_ntohll (
2000  peer_id,
2001  peer_sig,
2002  (unsigned long long)
2004  / 1000000LL);
2005  GNUNET_free (peer_id);
2006  return ret;
2007 }
static char * peer_id
Option –peer.
Definition: gnunet-cadet.c:42
#define GNUNET_FS_URI_LOC_INFIX
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:252
struct GNUNET_CRYPTO_EddsaPublicKey public_key
uint64_t abs_value_us
The actual value.

References GNUNET_TIME_Absolute::abs_value_us, FileIdentifier::chk, Location::contentSignature, GNUNET_FS_Uri::data, Location::expirationTime, Location::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, SIGNATURE_ASCII_LENGTH, and uri.

Here is the call graph for this function: