aboutsummaryrefslogtreecommitdiff
path: root/src/fs/fs_uri.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2009-08-22 17:57:31 +0000
committerChristian Grothoff <christian@grothoff.org>2009-08-22 17:57:31 +0000
commit2ae973618f3b51fa9bbf5532eaa1352cafc24ecc (patch)
treeea8bb13a4c7d390f88318b61bc6caf50ea6cf400 /src/fs/fs_uri.c
parent9a10e9c06a3b08c8ab73edb7d2093a6d452ecc05 (diff)
downloadgnunet-2ae973618f3b51fa9bbf5532eaa1352cafc24ecc.tar.gz
gnunet-2ae973618f3b51fa9bbf5532eaa1352cafc24ecc.zip
stuff
Diffstat (limited to 'src/fs/fs_uri.c')
-rw-r--r--src/fs/fs_uri.c133
1 files changed, 94 insertions, 39 deletions
diff --git a/src/fs/fs_uri.c b/src/fs/fs_uri.c
index f2351af1b..8e69a8425 100644
--- a/src/fs/fs_uri.c
+++ b/src/fs/fs_uri.c
@@ -26,10 +26,10 @@
26 * GNUnet URIs are of the general form "gnunet://MODULE/IDENTIFIER". 26 * GNUnet URIs are of the general form "gnunet://MODULE/IDENTIFIER".
27 * The specific structure of "IDENTIFIER" depends on the module and 27 * The specific structure of "IDENTIFIER" depends on the module and
28 * maybe differenciated into additional subcategories if applicable. 28 * maybe differenciated into additional subcategories if applicable.
29 * This module only deals with ecrs identifiers (MODULE = "ecrs"). 29 * This module only deals with fs identifiers (MODULE = "fs").
30 * <p> 30 * <p>
31 * 31 *
32 * This module only parses URIs for the AFS module. The ECRS URIs fall 32 * This module only parses URIs for the AFS module. The FS URIs fall
33 * into four categories, "chk", "sks", "ksk" and "loc". The first three 33 * into four categories, "chk", "sks", "ksk" and "loc". The first three
34 * categories were named in analogy (!) to Freenet, but they do NOT 34 * categories were named in analogy (!) to Freenet, but they do NOT
35 * work in exactly the same way. They are very similar from the user's 35 * work in exactly the same way. They are very similar from the user's
@@ -40,7 +40,7 @@
40 * <ul><li> 40 * <ul><li>
41 * 41 *
42 * First, there are URIs that identify a file. They have the format 42 * First, there are URIs that identify a file. They have the format
43 * "gnunet://ecrs/chk/HEX1.HEX2.SIZE". These URIs can be used to 43 * "gnunet://fs/chk/HEX1.HEX2.SIZE". These URIs can be used to
44 * download the file. The description, filename, mime-type and other 44 * download the file. The description, filename, mime-type and other
45 * meta-data is NOT part of the file-URI since a URI uniquely 45 * meta-data is NOT part of the file-URI since a URI uniquely
46 * identifies a resource (and the contents of the file would be the 46 * identifies a resource (and the contents of the file would be the
@@ -49,7 +49,7 @@
49 * </li><li> 49 * </li><li>
50 * 50 *
51 * The second category identifies entries in a namespace. The format 51 * The second category identifies entries in a namespace. The format
52 * is "gnunet://ecrs/sks/NAMESPACE/IDENTIFIER" where the namespace 52 * is "gnunet://fs/sks/NAMESPACE/IDENTIFIER" where the namespace
53 * should be given in HEX. Applications may allow using a nickname 53 * should be given in HEX. Applications may allow using a nickname
54 * for the namespace if the nickname is not ambiguous. The identifier 54 * for the namespace if the nickname is not ambiguous. The identifier
55 * can be either an ASCII sequence or a HEX-encoding. If the 55 * can be either an ASCII sequence or a HEX-encoding. If the
@@ -59,7 +59,7 @@
59 * </li> <li> 59 * </li> <li>
60 * 60 *
61 * The third category identifies ordinary searches. The format is 61 * The third category identifies ordinary searches. The format is
62 * "gnunet://ecrs/ksk/KEYWORD[+KEYWORD]*". Using the "+" syntax 62 * "gnunet://fs/ksk/KEYWORD[+KEYWORD]*". Using the "+" syntax
63 * it is possible to encode searches with the boolean "AND" operator. 63 * it is possible to encode searches with the boolean "AND" operator.
64 * "+" is used since it indicates a commutative 'and' operation and 64 * "+" is used since it indicates a commutative 'and' operation and
65 * is unlikely to be used in a keyword by itself. 65 * is unlikely to be used in a keyword by itself.
@@ -67,7 +67,7 @@
67 * </li><li> 67 * </li><li>
68 * 68 *
69 * The last category identifies a datum on a specific machine. The 69 * The last category identifies a datum on a specific machine. The
70 * format is "gnunet://ecrs/loc/HEX1.HEX2.SIZE.PEER.SIG.EXPTIME". PEER is 70 * format is "gnunet://fs/loc/HEX1.HEX2.SIZE.PEER.SIG.EXPTIME". PEER is
71 * the BinName of the public key of the peer storing the datum. The 71 * the BinName of the public key of the peer storing the datum. The
72 * signature (SIG) certifies that this peer has this content. 72 * signature (SIG) certifies that this peer has this content.
73 * HEX1, HEX2 and SIZE correspond to a 'chk' URI. 73 * HEX1, HEX2 and SIZE correspond to a 'chk' URI.
@@ -211,6 +211,7 @@ percent_decode_keyword (const char *in, char **emsg)
211 if (1 != sscanf (&out[rpos + 1], "%2X", &hx)) 211 if (1 != sscanf (&out[rpos + 1], "%2X", &hx))
212 { 212 {
213 GNUNET_free (out); 213 GNUNET_free (out);
214 *emsg = GNUNET_strdup (_("`%' must be followed by HEX number"));
214 return NULL; 215 return NULL;
215 } 216 }
216 rpos += 3; 217 rpos += 3;
@@ -265,11 +266,14 @@ uri_ksk_parse (const char *s, char **emsg)
265 pos = strlen (GNUNET_FS_URI_PREFIX GNUNET_FS_URI_KSK_INFIX); 266 pos = strlen (GNUNET_FS_URI_PREFIX GNUNET_FS_URI_KSK_INFIX);
266 if ( (slen <= pos) || 267 if ( (slen <= pos) ||
267 (0 != strncmp (s, GNUNET_FS_URI_PREFIX GNUNET_FS_URI_KSK_INFIX, 268 (0 != strncmp (s, GNUNET_FS_URI_PREFIX GNUNET_FS_URI_KSK_INFIX,
268 pos) ) || 269 pos) ) )
269 (s[slen - 1] == '+') || 270 return NULL; /* not KSK URI */
271 if ( (s[slen - 1] == '+') ||
270 (s[pos] == '+') ) 272 (s[pos] == '+') )
271 return NULL; /* no keywords / malformed */ 273 {
272 274 *emsg = GNUNET_strdup (_("Malformed KSK URI (must not begin or end with `+')"));
275 return NULL;
276 }
273 max = 1; 277 max = 1;
274 saw_quote = 0; 278 saw_quote = 0;
275 for (i = pos; i < slen; i++) 279 for (i = pos; i < slen; i++)
@@ -284,11 +288,17 @@ uri_ksk_parse (const char *s, char **emsg)
284 { 288 {
285 max++; 289 max++;
286 if (s[i - 1] == '+') 290 if (s[i - 1] == '+')
287 return NULL; /* "++" not allowed */ 291 {
292 *emsg = GNUNET_strdup (_("`++' not allowed in KSK URI"));
293 return NULL;
294 }
288 } 295 }
289 } 296 }
290 if (saw_quote == 1) 297 if (saw_quote == 1)
291 return NULL; /* quotes not balanced */ 298 {
299 *emsg = GNUNET_strdup (_("Quotes not balanced in KSK URI"));
300 return NULL;
301 }
292 iret = max; 302 iret = max;
293 dup = GNUNET_strdup (s); 303 dup = GNUNET_strdup (s);
294 keywords = GNUNET_malloc (max * sizeof (char *)); 304 keywords = GNUNET_malloc (max * sizeof (char *));
@@ -304,7 +314,7 @@ uri_ksk_parse (const char *s, char **emsg)
304 { 314 {
305 keywords[--max] = percent_decode_keyword (&dup[i + 1], emsg); 315 keywords[--max] = percent_decode_keyword (&dup[i + 1], emsg);
306 if (NULL == keywords[max]) 316 if (NULL == keywords[max])
307 goto CLEANUP; 317 goto CLEANUP;
308 dup[i] = '\0'; 318 dup[i] = '\0';
309 } 319 }
310 } 320 }
@@ -349,14 +359,21 @@ uri_sks_parse (const char *s, char **emsg)
349 pos = strlen (GNUNET_FS_URI_PREFIX GNUNET_FS_URI_SKS_INFIX); 359 pos = strlen (GNUNET_FS_URI_PREFIX GNUNET_FS_URI_SKS_INFIX);
350 if ( (slen <= pos) || 360 if ( (slen <= pos) ||
351 (0 != strncmp (s, GNUNET_FS_URI_PREFIX GNUNET_FS_URI_SKS_INFIX, 361 (0 != strncmp (s, GNUNET_FS_URI_PREFIX GNUNET_FS_URI_SKS_INFIX,
352 pos) ) || 362 pos) ) )
353 (slen < pos + sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) + 1) || 363 return NULL; /* not an SKS URI */
364 if ( (slen < pos + sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) + 1) ||
354 (s[pos + sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) - 1] != '/') ) 365 (s[pos + sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) - 1] != '/') )
355 return NULL; 366 {
367 *emsg = GNUNET_strdup (_("Malformed SKS URI"));
368 return NULL;
369 }
356 memcpy (enc, &s[pos], sizeof(struct GNUNET_CRYPTO_HashAsciiEncoded)); 370 memcpy (enc, &s[pos], sizeof(struct GNUNET_CRYPTO_HashAsciiEncoded));
357 enc[sizeof(struct GNUNET_CRYPTO_HashAsciiEncoded)-1] = '\0'; 371 enc[sizeof(struct GNUNET_CRYPTO_HashAsciiEncoded)-1] = '\0';
358 if (GNUNET_OK != GNUNET_CRYPTO_hash_from_string (enc, &namespace)) 372 if (GNUNET_OK != GNUNET_CRYPTO_hash_from_string (enc, &namespace))
359 return NULL; 373 {
374 *emsg = GNUNET_strdup (_("Malformed SKS URI"));
375 return NULL;
376 }
360 identifier = GNUNET_strdup (&s[pos + sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded)]); 377 identifier = GNUNET_strdup (&s[pos + sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded)]);
361 ret = GNUNET_malloc (sizeof(struct GNUNET_FS_Uri)); 378 ret = GNUNET_malloc (sizeof(struct GNUNET_FS_Uri));
362 ret->type = sks; 379 ret->type = sks;
@@ -389,11 +406,14 @@ uri_chk_parse (const char *s, char **emsg)
389 pos = strlen (GNUNET_FS_URI_PREFIX GNUNET_FS_URI_CHK_INFIX); 406 pos = strlen (GNUNET_FS_URI_PREFIX GNUNET_FS_URI_CHK_INFIX);
390 if ( (slen < pos + 2 * sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) + 1) || 407 if ( (slen < pos + 2 * sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) + 1) ||
391 (0 != strncmp (s, GNUNET_FS_URI_PREFIX GNUNET_FS_URI_CHK_INFIX, 408 (0 != strncmp (s, GNUNET_FS_URI_PREFIX GNUNET_FS_URI_CHK_INFIX,
392 pos) ) || 409 pos) ) )
393 (s[pos + sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) - 1] != '.') || 410 return NULL; /* not a CHK URI */
411 if ( (s[pos + sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) - 1] != '.') ||
394 (s[pos + sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) * 2 - 1] != '.') ) 412 (s[pos + sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) * 2 - 1] != '.') )
395 return NULL; 413 {
396 414 *emsg = GNUNET_strdup (_("Malformed CHK URI"));
415 return NULL;
416 }
397 memcpy (h1, 417 memcpy (h1,
398 &s[pos], 418 &s[pos],
399 sizeof(struct GNUNET_CRYPTO_HashAsciiEncoded)); 419 sizeof(struct GNUNET_CRYPTO_HashAsciiEncoded));
@@ -410,9 +430,11 @@ uri_chk_parse (const char *s, char **emsg)
410 (1 != SSCANF (&s[pos + sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) * 2], 430 (1 != SSCANF (&s[pos + sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) * 2],
411 "%llu", 431 "%llu",
412 &fi.file_length))) 432 &fi.file_length)))
413 return NULL; 433 {
434 *emsg = GNUNET_strdup (_("Malformed CHK URI"));
435 return NULL;
436 }
414 fi.file_length = GNUNET_htonll (fi.file_length); 437 fi.file_length = GNUNET_htonll (fi.file_length);
415
416 ret = GNUNET_malloc (sizeof(struct GNUNET_FS_Uri)); 438 ret = GNUNET_malloc (sizeof(struct GNUNET_FS_Uri));
417 ret->type = chk; 439 ret->type = chk;
418 ret->data.chk = fi; 440 ret->data.chk = fi;
@@ -527,18 +549,20 @@ uri_loc_parse (const char *s, char **emsg)
527 struct LocUriAssembly ass; 549 struct LocUriAssembly ass;
528 int ret; 550 int ret;
529 size_t slen; 551 size_t slen;
530 char *addr;
531 552
532 GNUNET_assert (s != NULL); 553 GNUNET_assert (s != NULL);
533 slen = strlen (s); 554 slen = strlen (s);
534 pos = strlen (GNUNET_FS_URI_PREFIX GNUNET_FS_URI_LOC_INFIX); 555 pos = strlen (GNUNET_FS_URI_PREFIX GNUNET_FS_URI_LOC_INFIX);
535 if ( (slen < pos + 2 * sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) + 1) || 556 if ( (slen < pos + 2 * sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) + 1) ||
536 (0 != strncmp (s, GNUNET_FS_URI_PREFIX GNUNET_FS_URI_LOC_INFIX, 557 (0 != strncmp (s, GNUNET_FS_URI_PREFIX GNUNET_FS_URI_LOC_INFIX,
537 pos) ) || 558 pos) ) )
538 (s[pos + sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) - 1] != '.') || 559 return NULL; /* not an SKS URI */
560 if ( (s[pos + sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) - 1] != '.') ||
539 (s[pos + sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) * 2 - 1] != '.') ) 561 (s[pos + sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) * 2 - 1] != '.') )
540 return NULL; 562 {
541 563 *emsg = GNUNET_strdup (_("SKS URI malformed"));
564 return NULL;
565 }
542 memcpy (h1, 566 memcpy (h1,
543 &s[pos], 567 &s[pos],
544 sizeof(struct GNUNET_CRYPTO_HashAsciiEncoded)); 568 sizeof(struct GNUNET_CRYPTO_HashAsciiEncoded));
@@ -555,32 +579,54 @@ uri_loc_parse (const char *s, char **emsg)
555 (1 != SSCANF (&s[pos + sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) * 2], 579 (1 != SSCANF (&s[pos + sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) * 2],
556 "%llu", 580 "%llu",
557 &ass.fi.file_length)) ) 581 &ass.fi.file_length)) )
558 return NULL; 582 {
583 *emsg = GNUNET_strdup (_("SKS URI malformed"));
584 return NULL;
585 }
559 ass.fi.file_length = GNUNET_htonll (ass.fi.file_length); 586 ass.fi.file_length = GNUNET_htonll (ass.fi.file_length);
560 587
561 npos = pos + sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) * 2; 588 npos = pos + sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) * 2;
562 while ((s[npos] != '\0') && (s[npos] != '.')) 589 while ((s[npos] != '\0') && (s[npos] != '.'))
563 npos++; 590 npos++;
564 if (s[npos] == '\0') 591 if (s[npos] == '\0')
565 goto ERR; 592 {
593 *emsg = GNUNET_strdup (_("SKS URI malformed"));
594 goto ERR;
595 }
596 npos++;
566 ret = enc2bin (&s[npos], 597 ret = enc2bin (&s[npos],
567 &ass.peer, 598 &ass.peer,
568 sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded)); 599 sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded));
569 if (ret == -1) 600 if (ret == -1)
570 goto ERR; 601 {
602 *emsg = GNUNET_strdup (_("SKS URI malformed (could not decode public key)"));
603 goto ERR;
604 }
571 npos += ret; 605 npos += ret;
572 if (s[npos++] != '.') 606 if (s[npos++] != '.')
573 goto ERR; 607 {
608 *emsg = GNUNET_strdup (_("SKS URI malformed (could not find signature)"));
609 goto ERR;
610 }
574 ret = enc2bin (&s[npos], 611 ret = enc2bin (&s[npos],
575 &sig, 612 &sig,
576 sizeof (struct GNUNET_CRYPTO_RsaSignature)); 613 sizeof (struct GNUNET_CRYPTO_RsaSignature));
577 if (ret == -1) 614 if (ret == -1)
578 goto ERR; 615 {
579 npos += ret; 616 *emsg = GNUNET_strdup (_("SKS URI malformed (could not decode signature)"));
617 goto ERR;
618 }
619 npos += ret;
580 if (s[npos++] != '.') 620 if (s[npos++] != '.')
581 goto ERR; 621 {
622 *emsg = GNUNET_strdup (_("SKS URI malformed"));
623 goto ERR;
624 }
582 if (1 != SSCANF (&s[npos], "%llu", &exptime)) 625 if (1 != SSCANF (&s[npos], "%llu", &exptime))
583 goto ERR; 626 {
627 *emsg = GNUNET_strdup (_("SKS URI malformed (could not parse expiration time)"));
628 goto ERR;
629 }
584 ass.purpose.size = htonl(sizeof(struct LocUriAssembly)); 630 ass.purpose.size = htonl(sizeof(struct LocUriAssembly));
585 ass.purpose.purpose = htonl(GNUNET_SIGNATURE_PURPOSE_NAMESPACE_PLACEMENT); 631 ass.purpose.purpose = htonl(GNUNET_SIGNATURE_PURPOSE_NAMESPACE_PLACEMENT);
586 et.value = exptime; 632 et.value = exptime;
@@ -590,8 +636,10 @@ uri_loc_parse (const char *s, char **emsg)
590 &ass.purpose, 636 &ass.purpose,
591 &sig, 637 &sig,
592 &ass.peer)) 638 &ass.peer))
593 goto ERR; 639 {
594 640 *emsg = GNUNET_strdup (_("SKS URI malformed (signature failed validation)"));
641 goto ERR;
642 }
595 uri = GNUNET_malloc (sizeof(struct GNUNET_FS_Uri)); 643 uri = GNUNET_malloc (sizeof(struct GNUNET_FS_Uri));
596 uri->type = loc; 644 uri->type = loc;
597 uri->data.loc.fi = ass.fi; 645 uri->data.loc.fi = ass.fi;
@@ -601,7 +649,6 @@ uri_loc_parse (const char *s, char **emsg)
601 649
602 return uri; 650 return uri;
603ERR: 651ERR:
604 GNUNET_free_non_null (addr);
605 return NULL; 652 return NULL;
606} 653}
607 654
@@ -618,12 +665,20 @@ GNUNET_FS_uri_parse (const char *uri,
618 char **emsg) 665 char **emsg)
619{ 666{
620 struct GNUNET_FS_Uri *ret; 667 struct GNUNET_FS_Uri *ret;
668 char *msg;
621 669
670 if (NULL == emsg)
671 emsg = &msg;
672 *emsg = NULL;
622 if ( (NULL != (ret = uri_chk_parse (uri, emsg))) || 673 if ( (NULL != (ret = uri_chk_parse (uri, emsg))) ||
623 (NULL != (ret = uri_ksk_parse (uri, emsg))) || 674 (NULL != (ret = uri_ksk_parse (uri, emsg))) ||
624 (NULL != (ret = uri_sks_parse (uri, emsg))) || 675 (NULL != (ret = uri_sks_parse (uri, emsg))) ||
625 (NULL != (ret = uri_loc_parse (uri, emsg))) ) 676 (NULL != (ret = uri_loc_parse (uri, emsg))) )
626 return ret; 677 return ret;
678 if (NULL == *emsg)
679 *emsg = GNUNET_strdup (_("Unrecognized URI type"));
680 if (emsg == &msg)
681 GNUNET_free (msg);
627 return NULL; 682 return NULL;
628} 683}
629 684