aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/hello/hello.c358
-rw-r--r--src/include/gnunet_crypto_lib.h2
-rw-r--r--src/include/gnunet_hello_lib.h42
-rw-r--r--src/peerinfo-tool/gnunet-peerinfo.c335
-rw-r--r--src/util/crypto_rsa.c2
5 files changed, 420 insertions, 319 deletions
diff --git a/src/hello/hello.c b/src/hello/hello.c
index 6529c9333..428c4139c 100644
--- a/src/hello/hello.c
+++ b/src/hello/hello.c
@@ -27,6 +27,7 @@
27#include "gnunet_hello_lib.h" 27#include "gnunet_hello_lib.h"
28#include "gnunet_protocols.h" 28#include "gnunet_protocols.h"
29#include "gnunet_util_lib.h" 29#include "gnunet_util_lib.h"
30#include "gnunet_transport_plugin.h"
30 31
31GNUNET_NETWORK_STRUCT_BEGIN 32GNUNET_NETWORK_STRUCT_BEGIN
32 33
@@ -63,6 +64,46 @@ struct GNUNET_HELLO_Message
63}; 64};
64GNUNET_NETWORK_STRUCT_END 65GNUNET_NETWORK_STRUCT_END
65 66
67
68/**
69 * Context used for building our own URI.
70 */
71struct GNUNET_HELLO_ComposeUriContext
72{
73 /**
74 * Final URI.
75 */
76 char *uri;
77
78 /**
79 * Function for finding transport plugins by name.
80 */
81 GNUNET_HELLO_TransportPluginsFind plugins_find;
82};
83
84
85/**
86 * Context for 'add_address_to_hello'.
87 */
88struct GNUNET_HELLO_ParseUriContext
89{
90 /**
91 * Position in the URI with the next address to parse.
92 */
93 const char *pos;
94
95 /**
96 * Set to GNUNET_SYSERR to indicate parse errors.
97 */
98 int ret;
99
100 /**
101 * Function for finding transport plugins by name.
102 */
103 GNUNET_HELLO_TransportPluginsFind plugins_find;
104};
105
106
66/** 107/**
67 * Copy the given address information into 108 * Copy the given address information into
68 * the given buffer using the format of HELLOs. 109 * the given buffer using the format of HELLOs.
@@ -650,10 +691,10 @@ GNUNET_HELLO_get_last_expiration (const struct GNUNET_HELLO_Message *msg)
650 * 691 *
651 * The concrete URI format is: 692 * The concrete URI format is:
652 * 693 *
653 * "gnunet://hello/PEER[!YYYYMMDDHHNNSS!<TYPE>!<ADDRESS>]...". 694 * "gnunet://hello/PEER[!YYYYMMDDHHMMSS!<TYPE>!<ADDRESS>]...".
654 * These URIs can be used to add a peer record to peerinfo service. 695 * These URIs can be used to add a peer record to peerinfo service.
655 * PEER is the string representation of peer's public key. 696 * PEER is the string representation of peer's public key.
656 * YYYYMMDDHHNNSS is the expiration date. 697 * YYYYMMDDHHMMSS is the expiration date.
657 * TYPE is a transport type. 698 * TYPE is a transport type.
658 * ADDRESS is the address, its format depends upon the transport type. 699 * ADDRESS is the address, its format depends upon the transport type.
659 * The concrete transport types and corresponding address formats are: 700 * The concrete transport types and corresponding address formats are:
@@ -683,4 +724,317 @@ GNUNET_HELLO_get_last_expiration (const struct GNUNET_HELLO_Message *msg)
683 * <p> 724 * <p>
684 */ 725 */
685 726
727
728/* ************************* Compose HELLO URI ************************** */
729
730
731/**
732 * Replace all characters in the input 'in' according
733 * to the mapping. The mapping says to map each character
734 * in 'oldchars' to the corresponding character (by offset)
735 * in 'newchars'.
736 *
737 * @param in input string to remap
738 * @param oldchars characters to replace
739 * @param newchars replacement characters, must have same length as 'oldchars'
740 * @return copy of string with replacement applied.
741 */
742static char *
743map_characters (const char *in,
744 const char *oldchars,
745 const char *newchars)
746{
747 char *ret;
748 const char *off;
749 size_t i;
750
751 GNUNET_assert (strlen (oldchars) == strlen (newchars));
752 ret = GNUNET_strdup (in);
753 i = 0;
754 while (ret[i] != '\0')
755 {
756 off = strchr (oldchars, ret[i]);
757 if (NULL != off)
758 ret[i] = newchars[off - oldchars];
759 i++;
760 }
761 return ret;
762}
763
764
765/**
766 * Function that is called on each address of this peer.
767 * Expands the corresponding URI string.
768 *
769 * @param cls the 'GNUNET_HELLO_GetUriContext'
770 * @param address address to add
771 * @param expiration expiration time for the address
772 * @param plugins_find Function to find transport plugins by name
773 * @return GNUNET_OK (continue iteration).
774 */
775static int
776add_address_to_uri (void *cls, const struct GNUNET_HELLO_Address *address,
777 struct GNUNET_TIME_Absolute expiration)
778{
779 struct GNUNET_HELLO_ComposeUriContext *ctx = cls;
780 struct GNUNET_TRANSPORT_PluginFunctions *papi;
781 const char *addr;
782 char *uri_addr;
783 char *ret;
784 char tbuf[16] = "";
785 struct tm *t;
786 time_t seconds;
787
788 papi = ctx->plugins_find (address->transport_name);
789 if (papi == NULL)
790 {
791 /* Not an error - we might just not have the right plugin. */
792 return GNUNET_OK;
793 }
794 if (NULL == papi->address_to_string)
795 {
796 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
797 "URI conversion not implemented for plugin `%s'\n",
798 address->transport_name);
799 return GNUNET_OK;
800 }
801 addr = papi->address_to_string (papi->cls, address->address, address->address_length);
802 if ( (addr == NULL) || (strlen(addr) == 0) )
803 return GNUNET_OK;
804 /* For URIs we use '(' and ')' instead of '[' and ']' as brackets are reserved
805 characters in URIs */
806 uri_addr = map_characters (addr, "[]", "()");
807 seconds = expiration.abs_value / 1000;
808 t = gmtime (&seconds);
809
810 GNUNET_asprintf (&ret,
811 "%s!%s!%s!%s",
812 ctx->uri,
813 strftime (tbuf, sizeof (tbuf), "%Y%m%d%H%M%S", t) ? tbuf : "0",
814 address->transport_name,
815 uri_addr);
816 GNUNET_free (uri_addr);
817 GNUNET_free (ctx->uri);
818 ctx->uri = ret;
819 return GNUNET_OK;
820}
821
822
823/**
824 * Compose a hello URI string from a hello message.
825 *
826 * @param hello Hello message
827 * @param plugins_find Function to find transport plugins by name
828 * @return Hello URI string
829 */
830char *
831GNUNET_HELLO_compose_uri (const struct GNUNET_HELLO_Message *hello,
832 GNUNET_HELLO_TransportPluginsFind plugins_find)
833{
834 struct GNUNET_HELLO_ComposeUriContext ctx;
835 ctx.plugins_find = plugins_find;
836
837 char *pkey = GNUNET_CRYPTO_rsa_public_key_to_string (&(hello->publicKey));
838 GNUNET_asprintf (&(ctx.uri),
839 "%s%s",
840 GNUNET_HELLO_URI_PREFIX,
841 pkey);
842 GNUNET_free (pkey);
843
844 GNUNET_HELLO_iterate_addresses (hello, GNUNET_NO, &add_address_to_uri, &ctx);
845 return ctx.uri;
846}
847
848
849/* ************************* Parse HELLO URI ********************* */
850
851
852/**
853 * We're building a HELLO. Parse the next address from the
854 * parsing context and append it.
855 *
856 * @param cls the 'struct GNUNET_HELLO_AddressParsingContext'
857 * @param max number of bytes available for HELLO construction
858 * @param buffer where to copy the next address (in binary format)
859 * @return number of bytes added to buffer
860 */
861static size_t
862add_address_to_hello (void *cls, size_t max, void *buffer)
863{
864 struct GNUNET_HELLO_ParseUriContext *ctx = cls;
865 const char *tname;
866 const char *address;
867 char *uri_address;
868 char *plugin_address;
869 const char *end;
870 char *plugin_name;
871 struct tm expiration_time;
872 time_t expiration_seconds;
873 struct GNUNET_TIME_Absolute expire;
874 struct GNUNET_TRANSPORT_PluginFunctions *papi;
875 void *addr;
876 size_t addr_len;
877 struct GNUNET_HELLO_Address haddr;
878 size_t ret;
879
880 if (NULL == ctx->pos)
881 return 0;
882 if ('!' != ctx->pos[0])
883 {
884 ctx->ret = GNUNET_SYSERR;
885 GNUNET_break (0);
886 return 0;
887 }
888 ctx->pos++;
889
890 if ('0' == ctx->pos[0] && '!' == ctx->pos[1])
891 {
892 expire = GNUNET_TIME_UNIT_FOREVER_ABS;
893 tname = ctx->pos + 1;
894 }
895 else
896 {
897 memset (&expiration_time, 0, sizeof (expiration_time));
898 tname = strptime (ctx->pos,
899 "%Y%m%d%H%M%S",
900 &expiration_time);
901 if (NULL == tname)
902 {
903 ctx->ret = GNUNET_SYSERR;
904 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
905 _("Failed to parse HELLO message: missing expiration time\n"));
906 GNUNET_break (0);
907 return 0;
908 }
909
910 expiration_seconds = mktime (&expiration_time);
911 if (expiration_seconds == (time_t) -1)
912 {
913 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
914 _("Failed to parse HELLO message: invalid expiration time\n"));
915 ctx->ret = GNUNET_SYSERR;
916 GNUNET_break (0);
917 return 0;
918 }
919 expire.abs_value = expiration_seconds * 1000;
920 }
921 if ('!' != tname[0])
922 {
923 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
924 _("Failed to parse HELLO message: malformed\n"));
925 ctx->ret = GNUNET_SYSERR;
926 GNUNET_break (0);
927 return 0;
928 }
929 tname++;
930 address = strchr (tname, (int) '!');
931 if (NULL == address)
932 {
933 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
934 _("Failed to parse HELLO message: missing transport plugin\n"));
935 ctx->ret = GNUNET_SYSERR;
936 GNUNET_break (0);
937 return 0;
938 }
939 address++;
940 end = strchr (address, (int) '!');
941 ctx->pos = end;
942 plugin_name = GNUNET_strndup (tname, address - (tname+1));
943 papi = ctx->plugins_find (plugin_name);
944 if (NULL == papi)
945 {
946 /* Not an error - we might just not have the right plugin.
947 * Skip this part, advance to the next one and recurse.
948 * But only if this is not the end of string.
949 */
950 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
951 _("Plugin `%s' not found\n"),
952 plugin_name);
953 GNUNET_free (plugin_name);
954 GNUNET_break (0);
955 return 0;
956 }
957 if (NULL == papi->string_to_address)
958 {
959 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
960 _("Plugin `%s' does not support URIs yet\n"),
961 plugin_name);
962 GNUNET_free (plugin_name);
963 GNUNET_break (0);
964 return 0;
965 }
966 uri_address = GNUNET_strndup (address, end - address);
967 /* For URIs we use '(' and ')' instead of '[' and ']' as brackets are reserved
968 characters in URIs; need to convert back to '[]' for the plugin */
969 plugin_address = map_characters (uri_address, "()", "[]");
970 GNUNET_free (uri_address);
971 if (GNUNET_OK !=
972 papi->string_to_address (papi->cls,
973 plugin_address,
974 strlen (plugin_address) + 1,
975 &addr,
976 &addr_len))
977 {
978 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
979 _("Failed to parse `%s' as an address for plugin `%s'\n"),
980 plugin_address,
981 plugin_name);
982 GNUNET_free (plugin_name);
983 GNUNET_free (plugin_address);
984 return 0;
985 }
986 GNUNET_free (plugin_address);
987 /* address.peer is unset - not used by add_address() */
988 haddr.address_length = addr_len;
989 haddr.address = addr;
990 haddr.transport_name = plugin_name;
991 ret = GNUNET_HELLO_add_address (&haddr, expire, buffer, max);
992 GNUNET_free (addr);
993 GNUNET_free (plugin_name);
994 return ret;
995}
996
997
998/**
999 * Parse a hello URI string to a hello message.
1000 *
1001 * @param uri URI string to parse
1002 * @param pubkey Pointer to struct where public key is parsed
1003 * @param hello Pointer to struct where hello message is parsed
1004 * @param plugins_find Function to find transport plugins by name
1005 * @return GNUNET_OK on success, GNUNET_SYSERR if the URI was invalid, GNUNET_NO on other errors
1006 */
1007int
1008GNUNET_HELLO_parse_uri (const char *uri,
1009 struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *pubkey,
1010 struct GNUNET_HELLO_Message **hello,
1011 GNUNET_HELLO_TransportPluginsFind plugins_find)
1012{
1013 const char *pks;
1014 const char *exc;
1015 struct GNUNET_HELLO_ParseUriContext ctx;
1016
1017 if (0 != strncmp (uri,
1018 GNUNET_HELLO_URI_PREFIX,
1019 strlen (GNUNET_HELLO_URI_PREFIX)))
1020 return GNUNET_SYSERR;
1021 pks = &uri[strlen (GNUNET_HELLO_URI_PREFIX)];
1022 exc = strstr (pks, "!");
1023
1024 if (GNUNET_OK !=
1025 GNUNET_STRINGS_string_to_data (pks,
1026 (NULL == exc) ? strlen (pks) : (exc - pks),
1027 (unsigned char *) pubkey,
1028 sizeof (*pubkey)))
1029 return GNUNET_SYSERR;
1030
1031 ctx.pos = exc;
1032 ctx.ret = GNUNET_OK;
1033 ctx.plugins_find = plugins_find;
1034 *hello = GNUNET_HELLO_create (pubkey, &add_address_to_hello, &ctx);
1035
1036 return ctx.ret;
1037}
1038
1039
686/* end of hello.c */ 1040/* end of hello.c */
diff --git a/src/include/gnunet_crypto_lib.h b/src/include/gnunet_crypto_lib.h
index 1e2af8925..90f9d4e45 100644
--- a/src/include/gnunet_crypto_lib.h
+++ b/src/include/gnunet_crypto_lib.h
@@ -949,7 +949,7 @@ GNUNET_CRYPTO_kdf (void *result, size_t out_len, const void *xts,
949 * @return string representing 'pub' 949 * @return string representing 'pub'
950 */ 950 */
951char * 951char *
952GNUNET_CRYPTO_rsa_public_key_to_string (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *pub); 952GNUNET_CRYPTO_rsa_public_key_to_string (const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *pub);
953 953
954 954
955/** 955/**
diff --git a/src/include/gnunet_hello_lib.h b/src/include/gnunet_hello_lib.h
index 244ec3648..6a334a7e5 100644
--- a/src/include/gnunet_hello_lib.h
+++ b/src/include/gnunet_hello_lib.h
@@ -40,6 +40,12 @@ extern "C"
40 40
41 41
42/** 42/**
43 * Prefix that every HELLO URI must start with.
44 */
45#define GNUNET_HELLO_URI_PREFIX "gnunet://hello/"
46
47
48/**
43 * An address for communicating with a peer. We frequently 49 * An address for communicating with a peer. We frequently
44 * need this tuple and the components cannot really be 50 * need this tuple and the components cannot really be
45 * separated. This is NOT the format that would be used 51 * separated. This is NOT the format that would be used
@@ -332,6 +338,42 @@ struct GNUNET_MessageHeader *
332GNUNET_HELLO_get_header (struct GNUNET_HELLO_Message *hello); 338GNUNET_HELLO_get_header (struct GNUNET_HELLO_Message *hello);
333 339
334 340
341
342typedef size_t (*GNUNET_HELLO_GenerateAddressListCallback) (void *cls,
343 size_t max,
344 void *buf);
345
346
347typedef struct GNUNET_TRANSPORT_PluginFunctions *
348(*GNUNET_HELLO_TransportPluginsFind) (const char *name);
349
350
351/**
352 * Compose a hello URI string from a hello message.
353 *
354 * @param hello Hello message
355 * @param plugins_find Function to find transport plugins by name
356 * @return Hello URI string
357 */
358char *
359GNUNET_HELLO_compose_uri (const struct GNUNET_HELLO_Message *hello,
360 GNUNET_HELLO_TransportPluginsFind plugins_find);
361
362/**
363 * Parse a hello URI string to a hello message.
364 *
365 * @param uri URI string to parse
366 * @param pubkey Pointer to struct where public key is parsed
367 * @param hello Pointer to struct where hello message is parsed
368 * @param plugins_find Function to find transport plugins by name
369 * @return GNUNET_OK on success, GNUNET_SYSERR if the URI was invalid, GNUNET_NO on other errors
370 */
371int
372GNUNET_HELLO_parse_uri (const char *uri,
373 struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *pubkey,
374 struct GNUNET_HELLO_Message **hello,
375 GNUNET_HELLO_TransportPluginsFind plugins_find);
376
335#if 0 /* keep Emacsens' auto-indent happy */ 377#if 0 /* keep Emacsens' auto-indent happy */
336{ 378{
337#endif 379#endif
diff --git a/src/peerinfo-tool/gnunet-peerinfo.c b/src/peerinfo-tool/gnunet-peerinfo.c
index c2520fac0..61185bc04 100644
--- a/src/peerinfo-tool/gnunet-peerinfo.c
+++ b/src/peerinfo-tool/gnunet-peerinfo.c
@@ -27,18 +27,13 @@
27#include "gnunet_crypto_lib.h" 27#include "gnunet_crypto_lib.h"
28#include "gnunet_configuration_lib.h" 28#include "gnunet_configuration_lib.h"
29#include "gnunet_getopt_lib.h" 29#include "gnunet_getopt_lib.h"
30#include "gnunet_peerinfo_service.h"
31#include "gnunet_transport_service.h"
32#include "gnunet_program_lib.h" 30#include "gnunet_program_lib.h"
33#include "gnunet_transport_plugin.h" 31#include "gnunet_hello_lib.h"
32#include "gnunet_transport_service.h"
33#include "gnunet_peerinfo_service.h"
34#include "gnunet-peerinfo_plugins.h" 34#include "gnunet-peerinfo_plugins.h"
35 35
36/** 36/**
37 * Prefix that every HELLO URI must start with.
38 */
39#define HELLO_URI_PREFIX "gnunet://hello/"
40
41/**
42 * How long until we time out during peerinfo iterations? 37 * How long until we time out during peerinfo iterations?
43 */ 38 */
44#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5) 39#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5)
@@ -115,37 +110,6 @@ struct PrintContext
115 110
116 111
117/** 112/**
118 * Context used for building our own URI.
119 */
120struct GetUriContext
121{
122 /**
123 * Final URI.
124 */
125 char *uri;
126
127};
128
129
130/**
131 * Context for 'add_address_to_hello'.
132 */
133struct GNUNET_PEERINFO_HelloAddressParsingContext
134{
135 /**
136 * Position in the URI with the next address to parse.
137 */
138 const char *pos;
139
140 /**
141 * Set to GNUNET_SYSERR to indicate parse errors.
142 */
143 int ret;
144
145};
146
147
148/**
149 * Option '-n' 113 * Option '-n'
150 */ 114 */
151static int no_resolve; 115static int no_resolve;
@@ -233,42 +197,6 @@ state_machine (void *cls,
233 const struct GNUNET_SCHEDULER_TaskContext *tc); 197 const struct GNUNET_SCHEDULER_TaskContext *tc);
234 198
235 199
236
237/**
238 * Replace all characters in the input 'in' according
239 * to the mapping. The mapping says to map each character
240 * in 'oldchars' to the corresponding character (by offset)
241 * in 'newchars'.
242 *
243 * @param in input string to remap
244 * @param oldchars characters to replace
245 * @param newchars replacement characters, must have same length as 'oldchars'
246 * @return copy of string with replacement applied.
247 */
248static char *
249map_characters (const char *in,
250 const char *oldchars,
251 const char *newchars)
252{
253 char *ret;
254 const char *off;
255 size_t i;
256
257 GNUNET_assert (strlen (oldchars) == strlen (newchars));
258 ret = GNUNET_strdup (in);
259 i = 0;
260 while (ret[i] != '\0')
261 {
262 off = strchr (oldchars, ret[i]);
263 if (NULL != off)
264 ret[i] = newchars[off - oldchars];
265 i++;
266 }
267 return ret;
268}
269
270
271
272/* ********************* 'get_info' ******************* */ 200/* ********************* 'get_info' ******************* */
273 201
274/** 202/**
@@ -438,65 +366,6 @@ print_peer_info (void *cls, const struct GNUNET_PeerIdentity *peer,
438 366
439 367
440/** 368/**
441 * Function that is called on each address of this peer.
442 * Expands the corresponding URI string.
443 *
444 * @param cls the 'GetUriContext'
445 * @param address address to add
446 * @param expiration expiration time for the address
447 * @return GNUNET_OK (continue iteration).
448 */
449static int
450compose_uri (void *cls, const struct GNUNET_HELLO_Address *address,
451 struct GNUNET_TIME_Absolute expiration)
452{
453 struct GetUriContext *guc = cls;
454 struct GNUNET_TRANSPORT_PluginFunctions *papi;
455 const char *addr;
456 char *uri_addr;
457 char *ret;
458 char tbuf[16];
459 struct tm *t;
460 time_t seconds;
461
462 papi = GPI_plugins_find (address->transport_name);
463 if (papi == NULL)
464 {
465 /* Not an error - we might just not have the right plugin. */
466 return GNUNET_OK;
467 }
468 if (NULL == papi->address_to_string)
469 {
470 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
471 "URI conversion not implemented for plugin `%s'\n",
472 address->transport_name);
473 return GNUNET_OK;
474 }
475 addr = papi->address_to_string (papi->cls, address->address, address->address_length);
476 if ( (addr == NULL) || (strlen(addr) == 0) )
477 return GNUNET_OK;
478 /* For URIs we use '(' and ')' instead of '[' and ']' as brackets are reserved
479 characters in URIs */
480 uri_addr = map_characters (addr, "[]", "()");
481 seconds = expiration.abs_value / 1000;
482 t = gmtime (&seconds);
483 GNUNET_assert (0 != strftime (tbuf, sizeof (tbuf),
484 "%Y%m%d%H%M%S",
485 t));
486 GNUNET_asprintf (&ret,
487 "%s!%s!%s!%s",
488 guc->uri,
489 tbuf,
490 address->transport_name,
491 uri_addr);
492 GNUNET_free (uri_addr);
493 GNUNET_free (guc->uri);
494 guc->uri = ret;
495 return GNUNET_OK;
496}
497
498
499/**
500 * Print URI of the peer. 369 * Print URI of the peer.
501 * 370 *
502 * @param cls the 'struct GetUriContext' 371 * @param cls the 'struct GetUriContext'
@@ -509,8 +378,6 @@ print_my_uri (void *cls, const struct GNUNET_PeerIdentity *peer,
509 const struct GNUNET_HELLO_Message *hello, 378 const struct GNUNET_HELLO_Message *hello,
510 const char *err_msg) 379 const char *err_msg)
511{ 380{
512 struct GetUriContext *guc = cls;
513
514 if (peer == NULL) 381 if (peer == NULL)
515 { 382 {
516 pic = NULL; 383 pic = NULL;
@@ -518,157 +385,24 @@ print_my_uri (void *cls, const struct GNUNET_PeerIdentity *peer,
518 FPRINTF (stderr, 385 FPRINTF (stderr,
519 _("Error in communication with PEERINFO service: %s\n"), 386 _("Error in communication with PEERINFO service: %s\n"),
520 err_msg); 387 err_msg);
521 GNUNET_free_non_null (guc->uri);
522 GNUNET_free (guc);
523 tt = GNUNET_SCHEDULER_add_now (&state_machine, NULL); 388 tt = GNUNET_SCHEDULER_add_now (&state_machine, NULL);
524 return; 389 return;
525 }
526 if (NULL != hello)
527 GNUNET_HELLO_iterate_addresses (hello, GNUNET_NO, &compose_uri, guc);
528 printf ("%s\n", (const char *) guc->uri);
529}
530
531
532/* ************************* import HELLO by URI ********************* */
533
534
535/**
536 * We're building a HELLO. Parse the next address from the
537 * parsing context and append it.
538 *
539 * @param cls the 'struct GNUNET_PEERINFO_HelloAddressParsingContext'
540 * @param max number of bytes available for HELLO construction
541 * @param buffer where to copy the next address (in binary format)
542 * @return number of bytes added to buffer
543 */
544static size_t
545add_address_to_hello (void *cls, size_t max, void *buffer)
546{
547 struct GNUNET_PEERINFO_HelloAddressParsingContext *ctx = cls;
548 const char *tname;
549 const char *address;
550 char *uri_address;
551 char *plugin_address;
552 const char *end;
553 char *plugin_name;
554 struct tm expiration_time;
555 time_t expiration_seconds;
556 struct GNUNET_TIME_Absolute expire;
557 struct GNUNET_TRANSPORT_PluginFunctions *papi;
558 void *addr;
559 size_t addr_len;
560 struct GNUNET_HELLO_Address haddr;
561 size_t ret;
562
563 if (NULL == ctx->pos)
564 return 0;
565 if ('!' != ctx->pos[0])
566 {
567 ctx->ret = GNUNET_SYSERR;
568 GNUNET_break (0);
569 return 0;
570 } 390 }
571 ctx->pos++;
572 memset (&expiration_time, 0, sizeof (expiration_time));
573 tname = strptime (ctx->pos,
574 "%Y%m%d%H%M%S",
575 &expiration_time);
576 391
577 if (NULL == tname) 392 if (NULL == hello)
578 { 393 return;
579 ctx->ret = GNUNET_SYSERR; 394
580 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 395 char *uri = GNUNET_HELLO_compose_uri(hello, &GPI_plugins_find);
581 _("Failed to parse HELLO message: missing expiration time\n")); 396 if (NULL != uri) {
582 GNUNET_break (0); 397 printf ("%s\n", (const char *) uri);
583 return 0; 398 GNUNET_free (uri);
584 }
585 expiration_seconds = mktime (&expiration_time);
586 if (expiration_seconds == (time_t) -1)
587 {
588 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
589 _("Failed to parse HELLO message: invalid expiration time\n"));
590 ctx->ret = GNUNET_SYSERR;
591 GNUNET_break (0);
592 return 0;
593 }
594 expire.abs_value = expiration_seconds * 1000;
595 if ('!' != tname[0])
596 {
597 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
598 _("Failed to parse HELLO message: malformed\n"));
599 ctx->ret = GNUNET_SYSERR;
600 GNUNET_break (0);
601 return 0;
602 }
603 tname++;
604 address = strchr (tname, (int) '!');
605 if (NULL == address)
606 {
607 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
608 _("Failed to parse HELLO message: missing transport plugin\n"));
609 ctx->ret = GNUNET_SYSERR;
610 GNUNET_break (0);
611 return 0;
612 }
613 address++;
614 end = strchr (address, (int) '!');
615 ctx->pos = end;
616 plugin_name = GNUNET_strndup (tname, address - (tname+1));
617 papi = GPI_plugins_find (plugin_name);
618 if (NULL == papi)
619 {
620 /* Not an error - we might just not have the right plugin.
621 * Skip this part, advance to the next one and recurse.
622 * But only if this is not the end of string.
623 */
624 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
625 _("Plugin `%s' not found\n"),
626 plugin_name);
627 GNUNET_free (plugin_name);
628 GNUNET_break (0);
629 return 0;
630 }
631 if (NULL == papi->string_to_address)
632 {
633 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
634 _("Plugin `%s' does not support URIs yet\n"),
635 plugin_name);
636 GNUNET_free (plugin_name);
637 GNUNET_break (0);
638 return 0;
639 }
640 uri_address = GNUNET_strndup (address, end - address);
641 /* For URIs we use '(' and ')' instead of '[' and ']' as brackets are reserved
642 characters in URIs; need to convert back to '[]' for the plugin */
643 plugin_address = map_characters (uri_address, "()", "[]");
644 GNUNET_free (uri_address);
645 if (GNUNET_OK !=
646 papi->string_to_address (papi->cls,
647 plugin_address,
648 strlen (plugin_address) + 1,
649 &addr,
650 &addr_len))
651 {
652 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
653 _("Failed to parse `%s' as an address for plugin `%s'\n"),
654 plugin_address,
655 plugin_name);
656 GNUNET_free (plugin_name);
657 GNUNET_free (plugin_address);
658 return 0;
659 } 399 }
660 GNUNET_free (plugin_address);
661 /* address.peer is unset - not used by add_address() */
662 haddr.address_length = addr_len;
663 haddr.address = addr;
664 haddr.transport_name = plugin_name;
665 ret = GNUNET_HELLO_add_address (&haddr, expire, buffer, max);
666 GNUNET_free (addr);
667 GNUNET_free (plugin_name);
668 return ret;
669} 400}
670 401
671 402
403/* ************************* import HELLO by URI ********************* */
404
405
672/** 406/**
673 * Continuation called from 'GNUNET_PEERINFO_add_peer' 407 * Continuation called from 'GNUNET_PEERINFO_add_peer'
674 * 408 *
@@ -698,31 +432,13 @@ add_continuation (void *cls,
698static int 432static int
699parse_hello_uri (const char *put_uri) 433parse_hello_uri (const char *put_uri)
700{ 434{
701 const char *pks;
702 const char *exc;
703 struct GNUNET_HELLO_Message *hello; 435 struct GNUNET_HELLO_Message *hello;
704 struct GNUNET_PEERINFO_HelloAddressParsingContext ctx; 436
705 437 int ret = GNUNET_HELLO_parse_uri(put_uri, &my_public_key, &hello, &GPI_plugins_find);
706 if (0 != strncmp (put_uri, 438
707 HELLO_URI_PREFIX, 439 if (NULL != hello) {
708 strlen (HELLO_URI_PREFIX)))
709 return GNUNET_SYSERR;
710 pks = &put_uri[strlen (HELLO_URI_PREFIX)];
711 exc = strstr (pks, "!");
712
713 if (GNUNET_OK != GNUNET_STRINGS_string_to_data (pks,
714 (NULL == exc) ? strlen (pks) : (exc - pks),
715 (unsigned char *) &my_public_key,
716 sizeof (my_public_key)))
717 return GNUNET_SYSERR;
718 ctx.pos = exc;
719 ctx.ret = GNUNET_OK;
720 hello = GNUNET_HELLO_create (&my_public_key, &add_address_to_hello, &ctx);
721
722 if (NULL != hello)
723 {
724 /* WARNING: this adds the address from URI WITHOUT verification! */ 440 /* WARNING: this adds the address from URI WITHOUT verification! */
725 if (GNUNET_OK == ctx.ret) 441 if (GNUNET_OK == ret)
726 ac = GNUNET_PEERINFO_add_peer (peerinfo, hello, &add_continuation, NULL); 442 ac = GNUNET_PEERINFO_add_peer (peerinfo, hello, &add_continuation, NULL);
727 else 443 else
728 tt = GNUNET_SCHEDULER_add_now (&state_machine, NULL); 444 tt = GNUNET_SCHEDULER_add_now (&state_machine, NULL);
@@ -732,7 +448,7 @@ parse_hello_uri (const char *put_uri)
732 /* wait 1s to give peerinfo operation a chance to succeed */ 448 /* wait 1s to give peerinfo operation a chance to succeed */
733 /* FIXME: current peerinfo API sucks to require this; not to mention 449 /* FIXME: current peerinfo API sucks to require this; not to mention
734 that we get no feedback to determine if the operation actually succeeded */ 450 that we get no feedback to determine if the operation actually succeeded */
735 return ctx.ret; 451 return ret;
736} 452}
737 453
738 454
@@ -907,20 +623,9 @@ state_machine (void *cls,
907 } 623 }
908 if (GNUNET_YES == get_uri) 624 if (GNUNET_YES == get_uri)
909 { 625 {
910 struct GetUriContext *guc;
911 char *pkey;
912
913 guc = GNUNET_malloc (sizeof (struct GetUriContext));
914 pkey = GNUNET_CRYPTO_rsa_public_key_to_string (&my_public_key);
915 GNUNET_asprintf (&guc->uri,
916 "%s%s",
917 HELLO_URI_PREFIX,
918 pkey);
919 GNUNET_free (pkey);
920 GPI_plugins_load (cfg); 626 GPI_plugins_load (cfg);
921 pic = GNUNET_PEERINFO_iterate (peerinfo, &my_peer_identity, 627 pic = GNUNET_PEERINFO_iterate (peerinfo, &my_peer_identity,
922 TIMEOUT, 628 TIMEOUT, &print_my_uri, NULL);
923 &print_my_uri, guc);
924 get_uri = GNUNET_NO; 629 get_uri = GNUNET_NO;
925 return; 630 return;
926 } 631 }
diff --git a/src/util/crypto_rsa.c b/src/util/crypto_rsa.c
index b5a8c85de..ff99ecf0b 100644
--- a/src/util/crypto_rsa.c
+++ b/src/util/crypto_rsa.c
@@ -201,7 +201,7 @@ GNUNET_CRYPTO_rsa_key_get_public (const struct GNUNET_CRYPTO_RsaPrivateKey
201 * @return string representing 'pub' 201 * @return string representing 'pub'
202 */ 202 */
203char * 203char *
204GNUNET_CRYPTO_rsa_public_key_to_string (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *pub) 204GNUNET_CRYPTO_rsa_public_key_to_string (const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *pub)
205{ 205{
206 char *pubkeybuf; 206 char *pubkeybuf;
207 size_t keylen = (sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded)) * 8; 207 size_t keylen = (sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded)) * 8;