aboutsummaryrefslogtreecommitdiff
path: root/src/identity
diff options
context:
space:
mode:
Diffstat (limited to 'src/identity')
-rw-r--r--src/identity/Makefile.am21
-rw-r--r--src/identity/gnunet-identity.c18
-rw-r--r--src/identity/gnunet-service-identity.c67
-rw-r--r--src/identity/identity.conf.in4
-rw-r--r--src/identity/identity.h18
-rw-r--r--src/identity/identity_api.c18
-rw-r--r--src/identity/identity_api_lookup.c22
-rw-r--r--src/identity/plugin_rest_identity.c993
-rw-r--r--src/identity/test_identity.c18
-rw-r--r--src/identity/test_identity.conf4
-rw-r--r--src/identity/test_identity_defaults.c18
11 files changed, 102 insertions, 1099 deletions
diff --git a/src/identity/Makefile.am b/src/identity/Makefile.am
index b8e70fffb..1f21fc65d 100644
--- a/src/identity/Makefile.am
+++ b/src/identity/Makefile.am
@@ -39,14 +39,6 @@ bin_PROGRAMS = \
39libexec_PROGRAMS = \ 39libexec_PROGRAMS = \
40 gnunet-service-identity 40 gnunet-service-identity
41 41
42if HAVE_MHD
43if HAVE_JSON
44plugin_LTLIBRARIES = \
45 libgnunet_plugin_rest_identity.la
46endif
47endif
48
49
50gnunet_service_identity_SOURCES = \ 42gnunet_service_identity_SOURCES = \
51 gnunet-service-identity.c 43 gnunet-service-identity.c
52gnunet_service_identity_LDADD = \ 44gnunet_service_identity_LDADD = \
@@ -55,19 +47,6 @@ gnunet_service_identity_LDADD = \
55 $(GN_LIBINTL) 47 $(GN_LIBINTL)
56 48
57 49
58libgnunet_plugin_rest_identity_la_SOURCES = \
59 plugin_rest_identity.c
60libgnunet_plugin_rest_identity_la_LIBADD = \
61 libgnunetidentity.la \
62 $(top_builddir)/src/rest/libgnunetrest.la \
63 $(top_builddir)/src/jsonapi/libgnunetjsonapi.la \
64 $(top_builddir)/src/jsonapi/libgnunetjsonapiutils.la \
65 $(top_builddir)/src/util/libgnunetutil.la $(XLIBS) \
66 $(LTLIBINTL) -ljansson -lmicrohttpd
67libgnunet_plugin_rest_identity_la_LDFLAGS = \
68 $(GN_PLUGIN_LDFLAGS)
69
70
71gnunet_identity_SOURCES = \ 50gnunet_identity_SOURCES = \
72 gnunet-identity.c 51 gnunet-identity.c
73gnunet_identity_LDADD = \ 52gnunet_identity_LDADD = \
diff --git a/src/identity/gnunet-identity.c b/src/identity/gnunet-identity.c
index 9b66a1bc7..0c3f9fead 100644
--- a/src/identity/gnunet-identity.c
+++ b/src/identity/gnunet-identity.c
@@ -2,20 +2,18 @@
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2013 GNUnet e.V. 3 Copyright (C) 2013 GNUnet e.V.
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software: you can redistribute it and/or modify it
6 it under the terms of the GNU General Public License as published 6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation; either version 3, or (at your 7 by the Free Software Foundation, either version 3 of the License,
8 option) any later version. 8 or (at your option) any later version.
9 9
10 GNUnet is distributed in the hope that it will be useful, but 10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of 11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details. 13 Affero General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU Affero General Public License
16 along with GNUnet; see the file COPYING. If not, write to the 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/ 17*/
20/** 18/**
21 * @file identity/gnunet-identity.c 19 * @file identity/gnunet-identity.c
diff --git a/src/identity/gnunet-service-identity.c b/src/identity/gnunet-service-identity.c
index fdd7cfdc1..155c49cc5 100644
--- a/src/identity/gnunet-service-identity.c
+++ b/src/identity/gnunet-service-identity.c
@@ -2,20 +2,18 @@
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2013 GNUnet e.V. 3 Copyright (C) 2013 GNUnet e.V.
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software: you can redistribute it and/or modify it
6 it under the terms of the GNU General Public License as published 6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation; either version 3, or (at your 7 by the Free Software Foundation, either version 3 of the License,
8 option) any later version. 8 or (at your option) any later version.
9 9
10 GNUnet is distributed in the hope that it will be useful, but 10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of 11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details. 13 Affero General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU Affero General Public License
16 along with GNUnet; see the file COPYING. If not, write to the 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19 */ 17 */
20 18
21/** 19/**
@@ -373,11 +371,12 @@ handle_get_default_message (void *cls,
373 struct GNUNET_MQ_Envelope *env; 371 struct GNUNET_MQ_Envelope *env;
374 struct GNUNET_SERVICE_Client *client = cls; 372 struct GNUNET_SERVICE_Client *client = cls;
375 struct Ego *ego; 373 struct Ego *ego;
376 const char *name; 374 char *name;
377 char *identifier; 375 char *identifier;
378 376
379 377
380 name = (const char *) &gdm[1]; 378 name = GNUNET_strdup ((const char *) &gdm[1]);
379 GNUNET_STRINGS_utf8_tolower ((const char *) &gdm[1], name);
381 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 380 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
382 "Received GET_DEFAULT for service `%s' from client\n", 381 "Received GET_DEFAULT for service `%s' from client\n",
383 name); 382 name);
@@ -389,6 +388,7 @@ handle_get_default_message (void *cls,
389 { 388 {
390 send_result_code (client, 1, gettext_noop ("no default known")); 389 send_result_code (client, 1, gettext_noop ("no default known"));
391 GNUNET_SERVICE_client_continue (client); 390 GNUNET_SERVICE_client_continue (client);
391 GNUNET_free (name);
392 return; 392 return;
393 } 393 }
394 for (ego = ego_head; NULL != ego; ego = ego->next) 394 for (ego = ego_head; NULL != ego; ego = ego->next)
@@ -401,6 +401,7 @@ handle_get_default_message (void *cls,
401 GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client), env); 401 GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client), env);
402 GNUNET_SERVICE_client_continue (client); 402 GNUNET_SERVICE_client_continue (client);
403 GNUNET_free (identifier); 403 GNUNET_free (identifier);
404 GNUNET_free (name);
404 return; 405 return;
405 } 406 }
406 } 407 }
@@ -408,6 +409,7 @@ handle_get_default_message (void *cls,
408 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 409 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
409 "Failed to find ego `%s'\n", 410 "Failed to find ego `%s'\n",
410 name); 411 name);
412 GNUNET_free (name);
411 send_result_code (client, 1, 413 send_result_code (client, 1,
412 gettext_noop ("default configured, but ego unknown (internal error)")); 414 gettext_noop ("default configured, but ego unknown (internal error)"));
413 GNUNET_SERVICE_client_continue (client); 415 GNUNET_SERVICE_client_continue (client);
@@ -479,9 +481,11 @@ handle_set_default_message (void *cls,
479{ 481{
480 struct Ego *ego; 482 struct Ego *ego;
481 struct GNUNET_SERVICE_Client *client = cls; 483 struct GNUNET_SERVICE_Client *client = cls;
482 const char *str; 484 char *str;
485
486 str = GNUNET_strdup ((const char *) &sdm[1]);
487 GNUNET_STRINGS_utf8_tolower ((const char *) &sdm[1], str);
483 488
484 str = (const char *) &sdm[1];
485 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 489 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
486 "Received SET_DEFAULT for service `%s' from client\n", 490 "Received SET_DEFAULT for service `%s' from client\n",
487 str); 491 str);
@@ -502,10 +506,12 @@ handle_set_default_message (void *cls,
502 subsystem_cfg_file); 506 subsystem_cfg_file);
503 send_result_code (client, 0, NULL); 507 send_result_code (client, 0, NULL);
504 GNUNET_SERVICE_client_continue (client); 508 GNUNET_SERVICE_client_continue (client);
509 GNUNET_free (str);
505 return; 510 return;
506 } 511 }
507 } 512 }
508 send_result_code (client, 1, _("Unknown ego specified for service (internal error)")); 513 send_result_code (client, 1, _("Unknown ego specified for service (internal error)"));
514 GNUNET_free (str);
509 GNUNET_SERVICE_client_continue (client); 515 GNUNET_SERVICE_client_continue (client);
510} 516}
511 517
@@ -587,12 +593,13 @@ handle_create_message (void *cls,
587{ 593{
588 struct GNUNET_SERVICE_Client *client = cls; 594 struct GNUNET_SERVICE_Client *client = cls;
589 struct Ego *ego; 595 struct Ego *ego;
590 const char *str; 596 char *str;
591 char *fn; 597 char *fn;
592 598
593 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 599 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
594 "Received CREATE message from client\n"); 600 "Received CREATE message from client\n");
595 str = (const char *) &crm[1]; 601 str = GNUNET_strdup ((const char *) &crm[1]);
602 GNUNET_STRINGS_utf8_tolower ((const char *) &crm[1], str);
596 for (ego = ego_head; NULL != ego; ego = ego->next) 603 for (ego = ego_head; NULL != ego; ego = ego->next)
597 { 604 {
598 if (0 == strcmp (ego->identifier, 605 if (0 == strcmp (ego->identifier,
@@ -600,6 +607,7 @@ handle_create_message (void *cls,
600 { 607 {
601 send_result_code (client, 1, gettext_noop ("identifier already in use for another ego")); 608 send_result_code (client, 1, gettext_noop ("identifier already in use for another ego"));
602 GNUNET_SERVICE_client_continue (client); 609 GNUNET_SERVICE_client_continue (client);
610 GNUNET_free (str);
603 return; 611 return;
604 } 612 }
605 } 613 }
@@ -622,6 +630,7 @@ handle_create_message (void *cls,
622 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, 630 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
623 "write", fn); 631 "write", fn);
624 GNUNET_free (fn); 632 GNUNET_free (fn);
633 GNUNET_free (str);
625 notify_listeners (ego); 634 notify_listeners (ego);
626 GNUNET_SERVICE_client_continue (client); 635 GNUNET_SERVICE_client_continue (client);
627} 636}
@@ -728,18 +737,22 @@ handle_rename_message (void *cls,
728{ 737{
729 uint16_t old_name_len; 738 uint16_t old_name_len;
730 struct Ego *ego; 739 struct Ego *ego;
731 const char *old_name; 740 char *old_name;
732 const char *new_name; 741 char *new_name;
733 struct RenameContext rename_ctx; 742 struct RenameContext rename_ctx;
734 struct GNUNET_SERVICE_Client *client = cls; 743 struct GNUNET_SERVICE_Client *client = cls;
735 char *fn_old; 744 char *fn_old;
736 char *fn_new; 745 char *fn_new;
746 const char *old_name_tmp;
737 747
738 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 748 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
739 "Received RENAME message from client\n"); 749 "Received RENAME message from client\n");
740 old_name_len = ntohs (rm->old_name_len); 750 old_name_len = ntohs (rm->old_name_len);
741 old_name = (const char *) &rm[1]; 751 old_name_tmp = (const char *) &rm[1];
742 new_name = &old_name[old_name_len]; 752 old_name = GNUNET_strdup (old_name_tmp);
753 GNUNET_STRINGS_utf8_tolower (old_name_tmp, old_name);
754 new_name = GNUNET_strdup (&old_name_tmp[old_name_len]);
755 GNUNET_STRINGS_utf8_tolower (&old_name_tmp[old_name_len], new_name);
743 756
744 /* check if new name is already in use */ 757 /* check if new name is already in use */
745 for (ego = ego_head; NULL != ego; ego = ego->next) 758 for (ego = ego_head; NULL != ego; ego = ego->next)
@@ -749,6 +762,8 @@ handle_rename_message (void *cls,
749 { 762 {
750 send_result_code (client, 1, gettext_noop ("target name already exists")); 763 send_result_code (client, 1, gettext_noop ("target name already exists"));
751 GNUNET_SERVICE_client_continue (client); 764 GNUNET_SERVICE_client_continue (client);
765 GNUNET_free (old_name);
766 GNUNET_free (new_name);
752 return; 767 return;
753 } 768 }
754 } 769 }
@@ -778,6 +793,8 @@ handle_rename_message (void *cls,
778 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "rename", fn_old); 793 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "rename", fn_old);
779 GNUNET_free (fn_old); 794 GNUNET_free (fn_old);
780 GNUNET_free (fn_new); 795 GNUNET_free (fn_new);
796 GNUNET_free (old_name);
797 GNUNET_free (new_name);
781 notify_listeners (ego); 798 notify_listeners (ego);
782 send_result_code (client, 0, NULL); 799 send_result_code (client, 0, NULL);
783 GNUNET_SERVICE_client_continue (client); 800 GNUNET_SERVICE_client_continue (client);
@@ -787,6 +804,8 @@ handle_rename_message (void *cls,
787 804
788 /* failed to locate old name */ 805 /* failed to locate old name */
789 send_result_code (client, 1, gettext_noop ("no matching ego found")); 806 send_result_code (client, 1, gettext_noop ("no matching ego found"));
807 GNUNET_free (old_name);
808 GNUNET_free (new_name);
790 GNUNET_SERVICE_client_continue (client); 809 GNUNET_SERVICE_client_continue (client);
791} 810}
792 811
@@ -870,13 +889,15 @@ handle_delete_message (void *cls,
870 const struct DeleteMessage *dm) 889 const struct DeleteMessage *dm)
871{ 890{
872 struct Ego *ego; 891 struct Ego *ego;
873 const char *name; 892 char *name;
874 char *fn; 893 char *fn;
875 struct GNUNET_SERVICE_Client *client = cls; 894 struct GNUNET_SERVICE_Client *client = cls;
876 895
877 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 896 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
878 "Received DELETE message from client\n"); 897 "Received DELETE message from client\n");
879 name = (const char *) &dm[1]; 898 name = GNUNET_strdup ((const char *) &dm[1]);
899 GNUNET_STRINGS_utf8_tolower ((const char *) &dm[1], name);
900
880 for (ego = ego_head; NULL != ego; ego = ego->next) 901 for (ego = ego_head; NULL != ego; ego = ego->next)
881 { 902 {
882 if (0 == strcmp (ego->identifier, 903 if (0 == strcmp (ego->identifier,
@@ -903,6 +924,7 @@ handle_delete_message (void *cls,
903 notify_listeners (ego); 924 notify_listeners (ego);
904 GNUNET_free (ego->pk); 925 GNUNET_free (ego->pk);
905 GNUNET_free (ego); 926 GNUNET_free (ego);
927 GNUNET_free (name);
906 send_result_code (client, 0, NULL); 928 send_result_code (client, 0, NULL);
907 GNUNET_SERVICE_client_continue (client); 929 GNUNET_SERVICE_client_continue (client);
908 return; 930 return;
@@ -910,6 +932,7 @@ handle_delete_message (void *cls,
910 } 932 }
911 933
912 send_result_code (client, 1, gettext_noop ("no matching ego found")); 934 send_result_code (client, 1, gettext_noop ("no matching ego found"));
935 GNUNET_free (name);
913 GNUNET_SERVICE_client_continue (client); 936 GNUNET_SERVICE_client_continue (client);
914} 937}
915 938
diff --git a/src/identity/identity.conf.in b/src/identity/identity.conf.in
index 4af3a6261..f5d454323 100644
--- a/src/identity/identity.conf.in
+++ b/src/identity/identity.conf.in
@@ -1,6 +1,6 @@
1[identity] 1[identity]
2AUTOSTART = @AUTOSTART@ 2START_ON_DEMAND = @START_ON_DEMAND@
3USER_SERVICE = YES 3RUN_PER_USER = YES
4@JAVAPORT@PORT = 2108 4@JAVAPORT@PORT = 2108
5HOSTNAME = localhost 5HOSTNAME = localhost
6BINARY = gnunet-service-identity 6BINARY = gnunet-service-identity
diff --git a/src/identity/identity.h b/src/identity/identity.h
index aae650a79..45b23066d 100644
--- a/src/identity/identity.h
+++ b/src/identity/identity.h
@@ -2,20 +2,18 @@
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2013 GNUnet e.V. 3 Copyright (C) 2013 GNUnet e.V.
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software: you can redistribute it and/or modify it
6 it under the terms of the GNU General Public Liceidentity as published 6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation; either version 3, or (at your 7 by the Free Software Foundation, either version 3 of the License,
8 option) any later version. 8 or (at your option) any later version.
9 9
10 GNUnet is distributed in the hope that it will be useful, but 10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of 11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public Liceidentity for more details. 13 Affero General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public Liceidentity 15 You should have received a copy of the GNU Affero General Public License
16 along with GNUnet; see the file COPYING. If not, write to the 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/ 17*/
20 18
21/** 19/**
diff --git a/src/identity/identity_api.c b/src/identity/identity_api.c
index 1601ae2fd..30a6fb23d 100644
--- a/src/identity/identity_api.c
+++ b/src/identity/identity_api.c
@@ -2,20 +2,18 @@
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2013, 2016 GNUnet e.V. 3 Copyright (C) 2013, 2016 GNUnet e.V.
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software: you can redistribute it and/or modify it
6 it under the terms of the GNU General Public Liceidentity as published 6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation; either version 3, or (at your 7 by the Free Software Foundation, either version 3 of the License,
8 option) any later version. 8 or (at your option) any later version.
9 9
10 GNUnet is distributed in the hope that it will be useful, but 10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of 11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public Liceidentity for more details. 13 Affero General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public Liceidentity 15 You should have received a copy of the GNU Affero General Public License
16 along with GNUnet; see the file COPYING. If not, write to the 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/ 17*/
20 18
21/** 19/**
diff --git a/src/identity/identity_api_lookup.c b/src/identity/identity_api_lookup.c
index 7d40104fd..25aec8ede 100644
--- a/src/identity/identity_api_lookup.c
+++ b/src/identity/identity_api_lookup.c
@@ -2,20 +2,18 @@
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2013 GNUnet e.V. 3 Copyright (C) 2013 GNUnet e.V.
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software: you can redistribute it and/or modify it
6 it under the terms of the GNU General Public Liceidentity as published 6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation; either version 3, or (at your 7 by the Free Software Foundation, either version 3 of the License,
8 option) any later version. 8 or (at your option) any later version.
9 9
10 GNUnet is distributed in the hope that it will be useful, but 10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of 11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public Liceidentity for more details. 13 Affero General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public Liceidentity 15 You should have received a copy of the GNU Affero General Public License
16 along with GNUnet; see the file COPYING. If not, write to the 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/ 17*/
20 18
21/** 19/**
@@ -133,6 +131,12 @@ GNUNET_IDENTITY_ego_lookup (const struct GNUNET_CONFIGURATION_Handle *cfg,
133 el->identity = GNUNET_IDENTITY_connect (cfg, 131 el->identity = GNUNET_IDENTITY_connect (cfg,
134 &identity_cb, 132 &identity_cb,
135 el); 133 el);
134 if (NULL == el->identity)
135 {
136 GNUNET_free (el->name);
137 GNUNET_free (el);
138 return NULL;
139 }
136 return el; 140 return el;
137} 141}
138 142
diff --git a/src/identity/plugin_rest_identity.c b/src/identity/plugin_rest_identity.c
deleted file mode 100644
index 6044d0641..000000000
--- a/src/identity/plugin_rest_identity.c
+++ /dev/null
@@ -1,993 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2012-2015 GNUnet e.V.
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19 */
20/**
21 * @author Martin Schanzenbach
22 * @file identity/plugin_rest_identity.c
23 * @brief GNUnet Namestore REST plugin
24 *
25 */
26
27#include "platform.h"
28#include "gnunet_rest_plugin.h"
29#include "gnunet_identity_service.h"
30#include "gnunet_rest_lib.h"
31#include "gnunet_jsonapi_lib.h"
32#include "gnunet_jsonapi_util.h"
33#include "microhttpd.h"
34#include <jansson.h>
35#include "gnunet_signatures.h"
36
37/**
38 * REST root namespace
39 */
40#define GNUNET_REST_API_NS_IDENTITY "/identity"
41
42/**
43 * State while collecting all egos
44 */
45#define ID_REST_STATE_INIT 0
46
47/**
48 * Done collecting egos
49 */
50#define ID_REST_STATE_POST_INIT 1
51
52/**
53 * Resource type
54 */
55#define GNUNET_REST_JSONAPI_IDENTITY_EGO "ego"
56
57/**
58 * Name attribute
59 */
60#define GNUNET_REST_JSONAPI_IDENTITY_NAME "name"
61
62/**
63 * Attribute to rename "name" TODO we changed id to the pubkey
64 * so this can be unified with "name"
65 */
66#define GNUNET_REST_JSONAPI_IDENTITY_NEWNAME "newname"
67
68/**
69 * URL parameter to change the subsytem for ego
70 */
71#define GNUNET_REST_JSONAPI_IDENTITY_SUBSYSTEM "subsystem"
72
73
74/**
75 * Error messages
76 */
77#define GNUNET_REST_ERROR_RESOURCE_INVALID "Resource location invalid"
78#define GNUNET_REST_ERROR_NO_DATA "No data"
79
80/**
81 * GNUid token lifetime
82 */
83#define GNUNET_GNUID_TOKEN_EXPIRATION_MICROSECONDS 300000000
84
85/**
86 * The configuration handle
87 */
88const struct GNUNET_CONFIGURATION_Handle *cfg;
89
90/**
91 * HTTP methods allows for this plugin
92 */
93static char* allow_methods;
94
95/**
96 * @brief struct returned by the initialization function of the plugin
97 */
98struct Plugin
99{
100 const struct GNUNET_CONFIGURATION_Handle *cfg;
101};
102
103/**
104 * The ego list
105 */
106struct EgoEntry
107{
108 /**
109 * DLL
110 */
111 struct EgoEntry *next;
112
113 /**
114 * DLL
115 */
116 struct EgoEntry *prev;
117
118 /**
119 * Ego Identifier
120 */
121 char *identifier;
122
123 /**
124 * Public key string
125 */
126 char *keystring;
127
128 /**
129 * The Ego
130 */
131 struct GNUNET_IDENTITY_Ego *ego;
132};
133
134
135struct RequestHandle
136{
137 /**
138 * Ego list
139 */
140 struct EgoEntry *ego_head;
141
142 /**
143 * Ego list
144 */
145 struct EgoEntry *ego_tail;
146
147 /**
148 * Handle to the rest connection
149 */
150 struct GNUNET_REST_RequestHandle *conndata_handle;
151
152 /**
153 * response code
154 */
155 int response_code;
156
157 /**
158 * The processing state
159 */
160 int state;
161
162 /**
163 * Handle to GNS service.
164 */
165 struct GNUNET_IDENTITY_Handle *identity_handle;
166
167 /**
168 * IDENTITY Operation
169 */
170 struct GNUNET_IDENTITY_Operation *op;
171
172 /**
173 * Desired timeout for the lookup (default is no timeout).
174 */
175 struct GNUNET_TIME_Relative timeout;
176
177 /**
178 * ID of a task associated with the resolution process.
179 */
180 struct GNUNET_SCHEDULER_Task * timeout_task;
181
182 /**
183 * The plugin result processor
184 */
185 GNUNET_REST_ResultProcessor proc;
186
187 /**
188 * The closure of the result processor
189 */
190 void *proc_cls;
191
192 /**
193 * The name to look up
194 */
195 char *name;
196
197 /**
198 * The subsystem set from REST
199 */
200 char *subsys;
201
202 /**
203 * The url
204 */
205 char *url;
206
207 /**
208 * The data from the REST request
209 */
210 const char* data;
211
212 /**
213 * the length of the REST data
214 */
215 size_t data_size;
216
217 /**
218 * HTTP method
219 */
220 const char* method;
221
222 /**
223 * Error response message
224 */
225 char *emsg;
226
227};
228
229
230/**
231 * Cleanup lookup handle
232 * @param handle Handle to clean up
233 */
234static void
235cleanup_handle (struct RequestHandle *handle)
236{
237 struct EgoEntry *ego_entry;
238 struct EgoEntry *ego_tmp;
239 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
240 "Cleaning up\n");
241 if (NULL != handle->name)
242 GNUNET_free (handle->name);
243 if (NULL != handle->timeout_task)
244 {
245 GNUNET_SCHEDULER_cancel (handle->timeout_task);
246 handle->timeout_task = NULL;
247 }
248 if (NULL != handle->identity_handle)
249 GNUNET_IDENTITY_disconnect (handle->identity_handle);
250 if (NULL != handle->subsys)
251 GNUNET_free (handle->subsys);
252 if (NULL != handle->url)
253 GNUNET_free (handle->url);
254 if (NULL != handle->emsg)
255 GNUNET_free (handle->emsg);
256 for (ego_entry = handle->ego_head;
257 NULL != ego_entry;)
258 {
259 ego_tmp = ego_entry;
260 ego_entry = ego_entry->next;
261 GNUNET_free (ego_tmp->identifier);
262 GNUNET_free (ego_tmp->keystring);
263 GNUNET_free (ego_tmp);
264 }
265 GNUNET_free (handle);
266}
267
268
269/**
270 * Task run on errors. Reports an error and cleans up everything.
271 *
272 * @param cls the `struct RequestHandle`
273 */
274static void
275do_error (void *cls)
276{
277 struct RequestHandle *handle = cls;
278 struct MHD_Response *resp;
279 char *json_error;
280
281 GNUNET_asprintf (&json_error,
282 "{Error while processing request: %s}",
283 &handle->emsg);
284
285 resp = GNUNET_REST_create_response (json_error);
286 handle->proc (handle->proc_cls,
287 resp,
288 handle->response_code);
289 cleanup_handle (handle);
290 GNUNET_free (json_error);
291}
292
293
294/**
295 * Callback for IDENTITY_get()
296 *
297 * @param cls the RequestHandle
298 * @param ego the Ego found
299 * @param ctx the context
300 * @param name the id of the ego
301 */
302static void
303get_ego_for_subsys (void *cls,
304 struct GNUNET_IDENTITY_Ego *ego,
305 void **ctx,
306 const char *name)
307{
308 struct RequestHandle *handle = cls;
309 struct GNUNET_JSONAPI_Document *json_document;
310 struct GNUNET_JSONAPI_Resource *json_resource;
311 struct EgoEntry *ego_entry;
312 struct MHD_Response *resp;
313 json_t *name_json;
314 char *result_str;
315
316 json_document = GNUNET_JSONAPI_document_new ();
317
318 for (ego_entry = handle->ego_head;
319 NULL != ego_entry;
320 ego_entry = ego_entry->next)
321 {
322 if ( (NULL != name) && (0 != strcmp (name, ego_entry->identifier)) )
323 continue;
324 if (NULL == name)
325 continue;
326 json_resource = GNUNET_JSONAPI_resource_new
327 (GNUNET_REST_JSONAPI_IDENTITY_EGO, ego_entry->keystring);
328 name_json = json_string (ego_entry->identifier);
329 GNUNET_JSONAPI_resource_add_attr (json_resource,
330 GNUNET_REST_JSONAPI_IDENTITY_NAME,
331 name_json);
332 json_decref (name_json);
333 GNUNET_JSONAPI_document_resource_add (json_document, json_resource);
334 break;
335 }
336 if (0 == GNUNET_JSONAPI_document_resource_count (json_document))
337 {
338 GNUNET_JSONAPI_document_delete (json_document);
339 handle->emsg = GNUNET_strdup("No identity matches results!");
340 GNUNET_SCHEDULER_add_now (&do_error, handle);
341 return;
342 }
343 GNUNET_JSONAPI_document_serialize (json_document, &result_str);
344 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", result_str);
345 resp = GNUNET_REST_create_response (result_str);
346 GNUNET_JSONAPI_document_delete (json_document);
347 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
348 GNUNET_free (result_str);
349 cleanup_handle (handle);
350}
351
352/**
353 * Create a response with requested ego(s)
354 *
355 * @param con the Rest handle
356 * @param url the requested url
357 * @param cls the request handle
358 */
359static void
360ego_info_response (struct GNUNET_REST_RequestHandle *con,
361 const char *url,
362 void *cls)
363{
364 const char *egoname;
365 char *result_str;
366 char *subsys_val;
367 char *keystring;
368 struct RequestHandle *handle = cls;
369 struct EgoEntry *ego_entry;
370 struct GNUNET_HashCode key;
371 struct MHD_Response *resp;
372 struct GNUNET_JSONAPI_Document *json_document;
373 struct GNUNET_JSONAPI_Resource *json_resource;
374 json_t *name_str;
375
376 if (GNUNET_NO == GNUNET_REST_namespace_match (handle->url, GNUNET_REST_API_NS_IDENTITY))
377 {
378 resp = GNUNET_REST_create_response (NULL);
379 handle->proc (handle->proc_cls, resp, MHD_HTTP_BAD_REQUEST);
380 cleanup_handle (handle);
381 return;
382 }
383 egoname = NULL;
384 keystring = NULL;
385 if (strlen (GNUNET_REST_API_NS_IDENTITY) < strlen (handle->url))
386 {
387 keystring = &handle->url[strlen (GNUNET_REST_API_NS_IDENTITY)+1];
388 //Return all egos
389 for (ego_entry = handle->ego_head;
390 NULL != ego_entry;
391 ego_entry = ego_entry->next)
392 {
393 if ( (NULL != keystring) && (0 != strcmp (keystring, ego_entry->keystring)) )
394 continue;
395 egoname = ego_entry->identifier;
396 }
397 }
398
399 if ( NULL == egoname ) {
400 GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_IDENTITY_SUBSYSTEM,
401 strlen (GNUNET_REST_JSONAPI_IDENTITY_SUBSYSTEM),
402 &key);
403 if ( GNUNET_YES ==
404 GNUNET_CONTAINER_multihashmap_contains (handle->conndata_handle->url_param_map,
405 &key) )
406 {
407 subsys_val = GNUNET_CONTAINER_multihashmap_get (handle->conndata_handle->url_param_map,
408 &key);
409 if (NULL != subsys_val)
410 {
411 GNUNET_asprintf (&handle->subsys, "%s", subsys_val);
412 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Looking for %s's ego\n", subsys_val);
413 handle->op = GNUNET_IDENTITY_get (handle->identity_handle,
414 handle->subsys,
415 &get_ego_for_subsys,
416 handle);
417 return;
418 }
419 }
420 }
421
422 json_document = GNUNET_JSONAPI_document_new ();
423
424 //Return all egos
425 for (ego_entry = handle->ego_head;
426 NULL != ego_entry;
427 ego_entry = ego_entry->next)
428 {
429 if ( (NULL != egoname) && (0 != strcmp (egoname, ego_entry->identifier)) )
430 continue;
431 json_resource = GNUNET_JSONAPI_resource_new (GNUNET_REST_JSONAPI_IDENTITY_EGO,
432 ego_entry->keystring);
433 name_str = json_string (ego_entry->identifier);
434 GNUNET_JSONAPI_resource_add_attr (
435 json_resource,
436 GNUNET_REST_JSONAPI_IDENTITY_NAME,
437 name_str);
438 json_decref (name_str);
439 GNUNET_JSONAPI_document_resource_add (json_document, json_resource);
440 }
441 if (0 == GNUNET_JSONAPI_document_resource_count (json_document))
442 {
443 GNUNET_JSONAPI_document_delete (json_document);
444 handle->emsg = GNUNET_strdup ("No identities found!");
445 GNUNET_SCHEDULER_add_now (&do_error, handle);
446 return;
447 }
448 GNUNET_JSONAPI_document_serialize (json_document, &result_str);
449 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", result_str);
450 resp = GNUNET_REST_create_response (result_str);
451 GNUNET_JSONAPI_document_delete (json_document);
452 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
453 GNUNET_free (result_str);
454 cleanup_handle (handle);
455}
456
457/**
458 * Processing finished
459 *
460 * @param cls request handle
461 * @param emsg error message
462 */
463static void
464do_finished (void *cls, const char *emsg)
465{
466 struct RequestHandle *handle = cls;
467 struct MHD_Response *resp;
468
469 handle->op = NULL;
470 if (NULL != emsg)
471 {
472 handle->emsg = GNUNET_strdup (emsg);
473 GNUNET_SCHEDULER_add_now (&do_error, handle);
474 return;
475 }
476 resp = GNUNET_REST_create_response (NULL);
477 handle->proc (handle->proc_cls, resp, MHD_HTTP_NO_CONTENT);
478 cleanup_handle (handle);
479}
480
481/**
482 * Create a new ego
483 *
484 * @param con rest handle
485 * @param url url
486 * @param cls request handle
487 */
488static void
489ego_create_cont (struct GNUNET_REST_RequestHandle *con,
490 const char *url,
491 void *cls)
492{
493 struct RequestHandle *handle = cls;
494 struct EgoEntry *ego_entry;
495 struct MHD_Response *resp;
496 struct GNUNET_JSONAPI_Document *json_obj;
497 struct GNUNET_JSONAPI_Resource *json_res;
498 json_t *egoname_json;
499 json_t *data_js;
500 json_error_t err;
501 const char* egoname;
502 char term_data[handle->data_size+1];
503 struct GNUNET_JSON_Specification docspec[] = {
504 GNUNET_JSON_spec_jsonapi_document (&json_obj),
505 GNUNET_JSON_spec_end()
506 };
507 if (strlen (GNUNET_REST_API_NS_IDENTITY) != strlen (handle->url))
508 {
509 handle->emsg = GNUNET_strdup (GNUNET_REST_ERROR_RESOURCE_INVALID);
510 GNUNET_SCHEDULER_add_now (&do_error, handle);
511 return;
512 }
513 if (0 >= handle->data_size)
514 {
515 handle->emsg = GNUNET_strdup (GNUNET_REST_ERROR_NO_DATA);
516 GNUNET_SCHEDULER_add_now (&do_error, handle);
517 return;
518 }
519 term_data[handle->data_size] = '\0';
520 GNUNET_memcpy (term_data, handle->data, handle->data_size);
521 data_js = json_loads (term_data,
522 JSON_DECODE_ANY,
523 &err);
524 GNUNET_assert (NULL != data_js);
525 GNUNET_assert (GNUNET_OK ==
526 GNUNET_JSON_parse (data_js, docspec,
527 NULL, NULL));
528
529 json_decref (data_js);
530
531 if (NULL == json_obj)
532 {
533 GNUNET_SCHEDULER_add_now (&do_error, handle);
534 return;
535 }
536 if (1 != GNUNET_JSONAPI_document_resource_count (json_obj))
537 {
538 GNUNET_JSONAPI_document_delete (json_obj);
539 handle->emsg = GNUNET_strdup ("Provided resource count invalid");
540 GNUNET_SCHEDULER_add_now (&do_error, handle);
541 return;
542 }
543 json_res = GNUNET_JSONAPI_document_get_resource (json_obj, 0);
544 if (GNUNET_NO == GNUNET_JSONAPI_resource_check_type (json_res, GNUNET_REST_JSONAPI_IDENTITY_EGO))
545 {
546 GNUNET_JSONAPI_document_delete (json_obj);
547 resp = GNUNET_REST_create_response (NULL);
548 handle->proc (handle->proc_cls, resp, MHD_HTTP_CONFLICT);
549 cleanup_handle (handle);
550 return;
551 }
552 egoname_json = GNUNET_JSONAPI_resource_read_attr (json_res, GNUNET_REST_JSONAPI_IDENTITY_NAME);
553 if (!json_is_string (egoname_json))
554 {
555 GNUNET_JSONAPI_document_delete (json_obj);
556 handle->emsg = GNUNET_strdup ("No name provided");
557 GNUNET_SCHEDULER_add_now (&do_error, handle);
558 return;
559 }
560 egoname = json_string_value (egoname_json);
561 for (ego_entry = handle->ego_head;
562 NULL != ego_entry;
563 ego_entry = ego_entry->next)
564 {
565 if (0 == strcasecmp (egoname, ego_entry->identifier))
566 {
567 GNUNET_JSONAPI_document_delete (json_obj);
568 resp = GNUNET_REST_create_response (NULL);
569 handle->proc (handle->proc_cls, resp, MHD_HTTP_CONFLICT);
570 cleanup_handle (handle);
571 return;
572 }
573 }
574 GNUNET_asprintf (&handle->name, "%s", egoname);
575 GNUNET_JSONAPI_document_delete (json_obj);
576 handle->op = GNUNET_IDENTITY_create (handle->identity_handle,
577 handle->name,
578 &do_finished,
579 handle);
580}
581
582
583/**
584 * Handle ego edit request
585 *
586 * @param con rest connection handle
587 * @param url the url that is requested
588 * @param cls the RequestHandle
589 */
590static void
591ego_edit_cont (struct GNUNET_REST_RequestHandle *con,
592 const char *url,
593 void *cls)
594{
595 struct GNUNET_JSONAPI_Document *json_obj;
596 struct GNUNET_JSONAPI_Resource *json_res;
597 struct RequestHandle *handle = cls;
598 struct EgoEntry *ego_entry;
599 struct EgoEntry *ego_entry_tmp;
600 struct MHD_Response *resp;
601 json_t *subsys_json;
602 json_t *name_json;
603 json_t *data_js;
604 json_error_t err;
605 const char *keystring;
606 const char *subsys;
607 const char *newname;
608 char term_data[handle->data_size+1];
609 int ego_exists = GNUNET_NO;
610 struct GNUNET_JSON_Specification docspec[] = {
611 GNUNET_JSON_spec_jsonapi_document (&json_obj),
612 GNUNET_JSON_spec_end()
613 };
614
615 if (strlen (GNUNET_REST_API_NS_IDENTITY) > strlen (handle->url))
616 {
617 handle->emsg = GNUNET_strdup (GNUNET_REST_ERROR_RESOURCE_INVALID);
618 GNUNET_SCHEDULER_add_now (&do_error, handle);
619 return;
620 }
621
622 keystring = &handle->url[strlen(GNUNET_REST_API_NS_IDENTITY)+1];
623
624 for (ego_entry = handle->ego_head;
625 NULL != ego_entry;
626 ego_entry = ego_entry->next)
627 {
628 if (0 != strcasecmp (keystring, ego_entry->keystring))
629 continue;
630 ego_exists = GNUNET_YES;
631 break;
632 }
633
634 if (GNUNET_NO == ego_exists)
635 {
636 resp = GNUNET_REST_create_response (NULL);
637 handle->proc (handle->proc_cls, resp, MHD_HTTP_NOT_FOUND);
638 cleanup_handle (handle);
639 return;
640 }
641
642 if (0 >= handle->data_size)
643 {
644 handle->emsg = GNUNET_strdup (GNUNET_REST_ERROR_NO_DATA);
645 GNUNET_SCHEDULER_add_now (&do_error, handle);
646 return;
647 }
648
649 term_data[handle->data_size] = '\0';
650 GNUNET_memcpy (term_data, handle->data, handle->data_size);
651 data_js = json_loads (term_data,
652 JSON_DECODE_ANY,
653 &err);
654 GNUNET_assert (NULL != data_js);
655 GNUNET_assert (GNUNET_OK ==
656 GNUNET_JSON_parse (data_js, docspec,
657 NULL, NULL));
658
659 json_decref (data_js);
660
661 if (NULL == json_obj)
662 {
663 handle->emsg = GNUNET_strdup ("Data invalid");
664 GNUNET_SCHEDULER_add_now (&do_error, handle);
665 return;
666 }
667
668 if (1 != GNUNET_JSONAPI_document_resource_count (json_obj))
669 {
670 GNUNET_JSONAPI_document_delete (json_obj);
671 handle->emsg = GNUNET_strdup ("Resource amount invalid");
672 GNUNET_SCHEDULER_add_now (&do_error, handle);
673 return;
674 }
675 json_res = GNUNET_JSONAPI_document_get_resource (json_obj, 0);
676
677 if (GNUNET_NO == GNUNET_JSONAPI_resource_check_type (json_res, GNUNET_REST_JSONAPI_IDENTITY_EGO))
678 {
679 GNUNET_JSONAPI_document_delete (json_obj);
680 handle->emsg = GNUNET_strdup ("Resource type invalid");
681 GNUNET_SCHEDULER_add_now (&do_error, handle);
682 return;
683 }
684
685 //This is a rename
686 name_json = GNUNET_JSONAPI_resource_read_attr (json_res,
687 GNUNET_REST_JSONAPI_IDENTITY_NEWNAME);
688 if ((NULL != name_json) && json_is_string (name_json))
689 {
690 newname = json_string_value (name_json);
691 for (ego_entry_tmp = handle->ego_head;
692 NULL != ego_entry_tmp;
693 ego_entry_tmp = ego_entry_tmp->next)
694 {
695 if (0 == strcasecmp (newname, ego_entry_tmp->identifier) &&
696 0 != strcasecmp (keystring, ego_entry_tmp->keystring))
697 {
698 //Ego with same name not allowed
699 GNUNET_JSONAPI_document_delete (json_obj);
700 resp = GNUNET_REST_create_response (NULL);
701 handle->proc (handle->proc_cls, resp, MHD_HTTP_CONFLICT);
702 cleanup_handle (handle);
703 return;
704 }
705 }
706 handle->op = GNUNET_IDENTITY_rename (handle->identity_handle,
707 ego_entry->identifier,
708 newname,
709 &do_finished,
710 handle);
711 GNUNET_JSONAPI_document_delete (json_obj);
712 return;
713 }
714
715 //Set subsystem
716 subsys_json = GNUNET_JSONAPI_resource_read_attr (json_res, GNUNET_REST_JSONAPI_IDENTITY_SUBSYSTEM);
717 if ( (NULL != subsys_json) && json_is_string (subsys_json))
718 {
719 subsys = json_string_value (subsys_json);
720 GNUNET_asprintf (&handle->subsys, "%s", subsys);
721 GNUNET_JSONAPI_document_delete (json_obj);
722 handle->op = GNUNET_IDENTITY_set (handle->identity_handle,
723 handle->subsys,
724 ego_entry->ego,
725 &do_finished,
726 handle);
727 return;
728 }
729 GNUNET_JSONAPI_document_delete (json_obj);
730 handle->emsg = GNUNET_strdup ("Subsystem not provided");
731 GNUNET_SCHEDULER_add_now (&do_error, handle);
732}
733
734void
735ego_delete_cont (struct GNUNET_REST_RequestHandle *con_handle,
736 const char* url,
737 void *cls)
738{
739 const char *keystring;
740 struct EgoEntry *ego_entry;
741 struct MHD_Response *resp;
742 struct RequestHandle *handle = cls;
743 int ego_exists = GNUNET_NO;
744
745 if (strlen (GNUNET_REST_API_NS_IDENTITY) >= strlen (handle->url))
746 {
747 handle->emsg = GNUNET_strdup (GNUNET_REST_ERROR_RESOURCE_INVALID);
748 GNUNET_SCHEDULER_add_now (&do_error, handle);
749 return;
750 }
751
752 keystring = &handle->url[strlen(GNUNET_REST_API_NS_IDENTITY)+1];
753 for (ego_entry = handle->ego_head;
754 NULL != ego_entry;
755 ego_entry = ego_entry->next)
756 {
757 if (0 != strcasecmp (keystring, ego_entry->keystring))
758 continue;
759 ego_exists = GNUNET_YES;
760 break;
761 }
762 if (GNUNET_NO == ego_exists)
763 {
764 resp = GNUNET_REST_create_response (NULL);
765 handle->proc (handle->proc_cls, resp, MHD_HTTP_NOT_FOUND);
766 cleanup_handle (handle);
767 return;
768 }
769 handle->op = GNUNET_IDENTITY_delete (handle->identity_handle,
770 ego_entry->identifier,
771 &do_finished,
772 handle);
773
774}
775
776
777/**
778 * Respond to OPTIONS request
779 *
780 * @param con_handle the connection handle
781 * @param url the url
782 * @param cls the RequestHandle
783 */
784static void
785options_cont (struct GNUNET_REST_RequestHandle *con_handle,
786 const char* url,
787 void *cls)
788{
789 struct MHD_Response *resp;
790 struct RequestHandle *handle = cls;
791
792 //For now, independent of path return all options
793 resp = GNUNET_REST_create_response (NULL);
794 MHD_add_response_header (resp,
795 "Access-Control-Allow-Methods",
796 allow_methods);
797 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
798 cleanup_handle (handle);
799 return;
800}
801
802/**
803 * Handle rest request
804 *
805 * @param handle the request handle
806 */
807static void
808init_cont (struct RequestHandle *handle)
809{
810 struct GNUNET_REST_RequestHandlerError err;
811 static const struct GNUNET_REST_RequestHandler handlers[] = {
812 {MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_IDENTITY, &ego_info_response},
813 {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_IDENTITY, &ego_create_cont},
814 {MHD_HTTP_METHOD_PUT, GNUNET_REST_API_NS_IDENTITY, &ego_edit_cont},
815 {MHD_HTTP_METHOD_DELETE, GNUNET_REST_API_NS_IDENTITY, &ego_delete_cont},
816 {MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_IDENTITY, &options_cont},
817 GNUNET_REST_HANDLER_END
818 };
819
820 if (GNUNET_NO == GNUNET_JSONAPI_handle_request (handle->conndata_handle,
821 handlers,
822 &err,
823 handle))
824 {
825 handle->response_code = err.error_code;
826 GNUNET_SCHEDULER_add_now (&do_error, handle);
827 }
828}
829
830/**
831 * If listing is enabled, prints information about the egos.
832 *
833 * This function is initially called for all egos and then again
834 * whenever a ego's identifier changes or if it is deleted. At the
835 * end of the initial pass over all egos, the function is once called
836 * with 'NULL' for 'ego'. That does NOT mean that the callback won't
837 * be invoked in the future or that there was an error.
838 *
839 * When used with 'GNUNET_IDENTITY_create' or 'GNUNET_IDENTITY_get',
840 * this function is only called ONCE, and 'NULL' being passed in
841 * 'ego' does indicate an error (i.e. name is taken or no default
842 * value is known). If 'ego' is non-NULL and if '*ctx'
843 * is set in those callbacks, the value WILL be passed to a subsequent
844 * call to the identity callback of 'GNUNET_IDENTITY_connect' (if
845 * that one was not NULL).
846 *
847 * When an identity is renamed, this function is called with the
848 * (known) ego but the NEW identifier.
849 *
850 * When an identity is deleted, this function is called with the
851 * (known) ego and "NULL" for the 'identifier'. In this case,
852 * the 'ego' is henceforth invalid (and the 'ctx' should also be
853 * cleaned up).
854 *
855 * @param cls closure
856 * @param ego ego handle
857 * @param ctx context for application to store data for this ego
858 * (during the lifetime of this process, initially NULL)
859 * @param identifier identifier assigned by the user for this ego,
860 * NULL if the user just deleted the ego and it
861 * must thus no longer be used
862 */
863static void
864list_ego (void *cls,
865 struct GNUNET_IDENTITY_Ego *ego,
866 void **ctx,
867 const char *identifier)
868{
869 struct RequestHandle *handle = cls;
870 struct EgoEntry *ego_entry;
871 struct GNUNET_CRYPTO_EcdsaPublicKey pk;
872
873 if ((NULL == ego) && (ID_REST_STATE_INIT == handle->state))
874 {
875 handle->state = ID_REST_STATE_POST_INIT;
876 init_cont (handle);
877 return;
878 }
879 if (ID_REST_STATE_INIT == handle->state) {
880 ego_entry = GNUNET_new (struct EgoEntry);
881 GNUNET_IDENTITY_ego_get_public_key (ego, &pk);
882 ego_entry->keystring =
883 GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk);
884 ego_entry->ego = ego;
885 GNUNET_asprintf (&ego_entry->identifier, "%s", identifier);
886 GNUNET_CONTAINER_DLL_insert_tail(handle->ego_head,handle->ego_tail, ego_entry);
887 }
888
889}
890
891/**
892 * Function processing the REST call
893 *
894 * @param method HTTP method
895 * @param url URL of the HTTP request
896 * @param data body of the HTTP request (optional)
897 * @param data_size length of the body
898 * @param proc callback function for the result
899 * @param proc_cls closure for callback function
900 * @return GNUNET_OK if request accepted
901 */
902static void
903rest_identity_process_request(struct GNUNET_REST_RequestHandle *conndata_handle,
904 GNUNET_REST_ResultProcessor proc,
905 void *proc_cls)
906{
907 struct RequestHandle *handle = GNUNET_new (struct RequestHandle);
908
909
910
911 handle->timeout = GNUNET_TIME_UNIT_FOREVER_REL;
912
913 handle->proc_cls = proc_cls;
914 handle->proc = proc;
915 handle->state = ID_REST_STATE_INIT;
916 handle->conndata_handle = conndata_handle;
917 handle->data = conndata_handle->data;
918 handle->data_size = conndata_handle->data_size;
919 handle->method = conndata_handle->method;
920 GNUNET_asprintf (&handle->url, "%s", conndata_handle->url);
921 if (handle->url[strlen (handle->url)-1] == '/')
922 handle->url[strlen (handle->url)-1] = '\0';
923 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
924 "Connecting...\n");
925 handle->identity_handle = GNUNET_IDENTITY_connect (cfg,
926 &list_ego,
927 handle);
928 handle->timeout_task =
929 GNUNET_SCHEDULER_add_delayed (handle->timeout,
930 &do_error,
931 handle);
932
933
934 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
935 "Connected\n");
936}
937
938/**
939 * Entry point for the plugin.
940 *
941 * @param cls Config info
942 * @return NULL on error, otherwise the plugin context
943 */
944void *
945libgnunet_plugin_rest_identity_init (void *cls)
946{
947 static struct Plugin plugin;
948 struct GNUNET_REST_Plugin *api;
949
950 cfg = cls;
951 if (NULL != plugin.cfg)
952 return NULL; /* can only initialize once! */
953 memset (&plugin, 0, sizeof (struct Plugin));
954 plugin.cfg = cfg;
955 api = GNUNET_new (struct GNUNET_REST_Plugin);
956 api->cls = &plugin;
957 api->name = GNUNET_REST_API_NS_IDENTITY;
958 api->process_request = &rest_identity_process_request;
959 GNUNET_asprintf (&allow_methods,
960 "%s, %s, %s, %s, %s",
961 MHD_HTTP_METHOD_GET,
962 MHD_HTTP_METHOD_POST,
963 MHD_HTTP_METHOD_PUT,
964 MHD_HTTP_METHOD_DELETE,
965 MHD_HTTP_METHOD_OPTIONS);
966
967 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
968 _("Identity REST API initialized\n"));
969 return api;
970}
971
972
973/**
974 * Exit point from the plugin.
975 *
976 * @param cls the plugin context (as returned by "init")
977 * @return always NULL
978 */
979void *
980libgnunet_plugin_rest_identity_done (void *cls)
981{
982 struct GNUNET_REST_Plugin *api = cls;
983 struct Plugin *plugin = api->cls;
984
985 plugin->cfg = NULL;
986 GNUNET_free_non_null (allow_methods);
987 GNUNET_free (api);
988 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
989 "Identity REST plugin is finished\n");
990 return NULL;
991}
992
993/* end of plugin_rest_gns.c */
diff --git a/src/identity/test_identity.c b/src/identity/test_identity.c
index 7c88e0ace..a1cb1dc6d 100644
--- a/src/identity/test_identity.c
+++ b/src/identity/test_identity.c
@@ -2,20 +2,18 @@
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2013, 2016 GNUnet e.V. 3 Copyright (C) 2013, 2016 GNUnet e.V.
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software: you can redistribute it and/or modify it
6 it under the terms of the GNU General Public License as published 6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation; either version 3, or (at your 7 by the Free Software Foundation, either version 3 of the License,
8 option) any later version. 8 or (at your option) any later version.
9 9
10 GNUnet is distributed in the hope that it will be useful, but 10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of 11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details. 13 Affero General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU Affero General Public License
16 along with GNUnet; see the file COPYING. If not, write to the 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/ 17*/
20 18
21/** 19/**
diff --git a/src/identity/test_identity.conf b/src/identity/test_identity.conf
index 1653a88f8..9c433da77 100644
--- a/src/identity/test_identity.conf
+++ b/src/identity/test_identity.conf
@@ -4,5 +4,5 @@ UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-p1-service-arm.sock
4 4
5[identity] 5[identity]
6# need to overwrite paths to ensure they stay the same between runs... 6# need to overwrite paths to ensure they stay the same between runs...
7EGODIR = /tmp/test-identity-service/egos/ 7EGODIR = $GNUNET_TMP/test-identity-service/egos/
8SUBSYSTEM_CFG = /tmp/test-identity-service/s.conf 8SUBSYSTEM_CFG = $GNUNET_TMP/test-identity-service/s.conf
diff --git a/src/identity/test_identity_defaults.c b/src/identity/test_identity_defaults.c
index 207db321f..1e91f139e 100644
--- a/src/identity/test_identity_defaults.c
+++ b/src/identity/test_identity_defaults.c
@@ -2,20 +2,18 @@
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2013 GNUnet e.V. 3 Copyright (C) 2013 GNUnet e.V.
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software: you can redistribute it and/or modify it
6 it under the terms of the GNU General Public License as published 6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation; either version 3, or (at your 7 by the Free Software Foundation, either version 3 of the License,
8 option) any later version. 8 or (at your option) any later version.
9 9
10 GNUnet is distributed in the hope that it will be useful, but 10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of 11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details. 13 Affero General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU Affero General Public License
16 along with GNUnet; see the file COPYING. If not, write to the 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/ 17*/
20 18
21/** 19/**