RainflyClient_admin.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. /* vim: set expandtab ts=4 sw=4: */
  2. /*
  3. * You may redistribute this program and/or modify it under the terms of
  4. * the GNU General Public License as published by the Free Software Foundation,
  5. * either version 3 of the License, or (at your option) any later version.
  6. *
  7. * This program is distributed in the hope that it will be useful,
  8. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. * GNU General Public License for more details.
  11. *
  12. * You should have received a copy of the GNU General Public License
  13. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  14. */
  15. #include "admin/Admin.h"
  16. #include "benc/String.h"
  17. #include "benc/Dict.h"
  18. #include "benc/List.h"
  19. #include "benc/Int.h"
  20. #include "crypto/Key.h"
  21. #include "interface/RainflyClient.h"
  22. #include "interface/RainflyClient_admin.h"
  23. #include "util/AddrTools.h"
  24. #include "util/Base32.h"
  25. struct Context
  26. {
  27. struct Allocator* alloc;
  28. struct RainflyClient* rainfly;
  29. struct Admin* admin;
  30. };
  31. static void addKey(Dict* args, void* vcontext, String* txid, struct Allocator* requestAlloc)
  32. {
  33. struct Context* context = vcontext;
  34. struct Allocator* alloc = Allocator_child(context->alloc);
  35. String* identStr = Dict_getString(args, String_CONST("ident"));
  36. int ret;
  37. uint8_t key[32];
  38. char* err = "none";
  39. if (identStr->len < 52) {
  40. err = "too short";
  41. } else if (Base32_decode(key, 32, identStr->bytes, 52) != 32) {
  42. err = "failed to parse";
  43. } else if ((ret = RainflyClient_addKey(context->rainfly, key))) {
  44. if (ret == RainflyClient_addKey_TOO_MANY_KEYS) {
  45. err = "RainflyClient_addKey_TOO_MANY_KEYS";
  46. } else {
  47. err = "unknown error";
  48. }
  49. }
  50. Dict* response = Dict_new(alloc);
  51. Dict_putString(response, String_CONST("error"), String_CONST(err), alloc);
  52. Admin_sendMessage(response, txid, context->admin);
  53. Allocator_free(alloc);
  54. }
  55. static void minSinatures(Dict* args, void* vcontext, String* txid, struct Allocator* requestAlloc)
  56. {
  57. struct Context* context = vcontext;
  58. struct Allocator* alloc = Allocator_child(context->alloc);
  59. int64_t* count = Dict_getInt(args, String_CONST("count"));
  60. char* err = "none";
  61. if (*count < 0 || *count > INT32_MAX) {
  62. err = "count cannot be less than zero or more than INT32_MAX";
  63. } else {
  64. context->rainfly->minSignatures = *count;
  65. }
  66. Dict* response = Dict_new(alloc);
  67. Dict_putString(response, String_CONST("error"), String_CONST(err), alloc);
  68. Admin_sendMessage(response, txid, context->admin);
  69. Allocator_free(alloc);
  70. }
  71. static void addServer(Dict* args, void* vcontext, String* txid, struct Allocator* requestAlloc)
  72. {
  73. struct Context* context = vcontext;
  74. struct Allocator* alloc = Allocator_child(context->alloc);
  75. String* addrStr = Dict_getString(args, String_CONST("addr"));
  76. int ret;
  77. struct Sockaddr_storage ss;
  78. char* err = "none";
  79. if (Sockaddr_parse(addrStr->bytes, &ss)) {
  80. err = "could not parse address";
  81. } else if ((ret = RainflyClient_addServer(context->rainfly, &ss.addr))) {
  82. if (ret == RainflyClient_addServer_WRONG_ADDRESS_TYPE) {
  83. err = "RainflyClient_addServer_WRONG_ADDRESS_TYPE";
  84. } else {
  85. err = "unknown error";
  86. }
  87. }
  88. Dict* response = Dict_new(alloc);
  89. Dict_putString(response, String_CONST("error"), String_CONST(err), alloc);
  90. Admin_sendMessage(response, txid, context->admin);
  91. Allocator_free(alloc);
  92. }
  93. void RainflyClient_admin_register(struct RainflyClient* rainfly,
  94. struct Admin* admin,
  95. struct Allocator* alloc)
  96. {
  97. struct Context* ctx = Allocator_clone(alloc, (&(struct Context) {
  98. .alloc = alloc,
  99. .rainfly = rainfly,
  100. .admin = admin
  101. }));
  102. Admin_registerFunction("RainflyClient_addKey", addKey, ctx, true,
  103. ((struct Admin_FunctionArg[]) {
  104. { .name = "ident", .required = 1, .type = "String" }
  105. }), admin);
  106. Admin_registerFunction("RainflyClient_addServer", addServer, ctx, true,
  107. ((struct Admin_FunctionArg[]) {
  108. { .name = "addr", .required = 1, .type = "String" }
  109. }), admin);
  110. Admin_registerFunction("RainflyClient_minSignatures", minSinatures, ctx, true,
  111. ((struct Admin_FunctionArg[]) {
  112. { .name = "count", .required = 1, .type = "Int" }
  113. }), admin);
  114. }