diff options
-rw-r--r-- | src/hello/hello.c | 358 | ||||
-rw-r--r-- | src/include/gnunet_crypto_lib.h | 2 | ||||
-rw-r--r-- | src/include/gnunet_hello_lib.h | 42 | ||||
-rw-r--r-- | src/peerinfo-tool/gnunet-peerinfo.c | 335 | ||||
-rw-r--r-- | src/util/crypto_rsa.c | 2 |
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 | ||
31 | GNUNET_NETWORK_STRUCT_BEGIN | 32 | GNUNET_NETWORK_STRUCT_BEGIN |
32 | 33 | ||
@@ -63,6 +64,46 @@ struct GNUNET_HELLO_Message | |||
63 | }; | 64 | }; |
64 | GNUNET_NETWORK_STRUCT_END | 65 | GNUNET_NETWORK_STRUCT_END |
65 | 66 | ||
67 | |||
68 | /** | ||
69 | * Context used for building our own URI. | ||
70 | */ | ||
71 | struct 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 | */ | ||
88 | struct 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 | */ | ||
742 | static char * | ||
743 | map_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 | */ | ||
775 | static int | ||
776 | add_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 | */ | ||
830 | char * | ||
831 | GNUNET_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 | */ | ||
861 | static size_t | ||
862 | add_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 | */ | ||
1007 | int | ||
1008 | GNUNET_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 | */ |
951 | char * | 951 | char * |
952 | GNUNET_CRYPTO_rsa_public_key_to_string (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *pub); | 952 | GNUNET_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 * | |||
332 | GNUNET_HELLO_get_header (struct GNUNET_HELLO_Message *hello); | 338 | GNUNET_HELLO_get_header (struct GNUNET_HELLO_Message *hello); |
333 | 339 | ||
334 | 340 | ||
341 | |||
342 | typedef size_t (*GNUNET_HELLO_GenerateAddressListCallback) (void *cls, | ||
343 | size_t max, | ||
344 | void *buf); | ||
345 | |||
346 | |||
347 | typedef 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 | */ | ||
358 | char * | ||
359 | GNUNET_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 | */ | ||
371 | int | ||
372 | GNUNET_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 | */ | ||
120 | struct GetUriContext | ||
121 | { | ||
122 | /** | ||
123 | * Final URI. | ||
124 | */ | ||
125 | char *uri; | ||
126 | |||
127 | }; | ||
128 | |||
129 | |||
130 | /** | ||
131 | * Context for 'add_address_to_hello'. | ||
132 | */ | ||
133 | struct 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 | */ |
151 | static int no_resolve; | 115 | static 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 | */ | ||
248 | static char * | ||
249 | map_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 | */ | ||
449 | static int | ||
450 | compose_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 | */ | ||
544 | static size_t | ||
545 | add_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, | |||
698 | static int | 432 | static int |
699 | parse_hello_uri (const char *put_uri) | 433 | parse_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 | */ |
203 | char * | 203 | char * |
204 | GNUNET_CRYPTO_rsa_public_key_to_string (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *pub) | 204 | GNUNET_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; |