cli.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. /*
  2. * Asterisk -- An open source telephony toolkit.
  3. *
  4. * Copyright (C) 2013, Digium, Inc.
  5. *
  6. * David M. Lee, II <dlee@digium.com>
  7. *
  8. * See http://www.asterisk.org for more information about
  9. * the Asterisk project. Please do not directly contact
  10. * any of the maintainers of this project for assistance;
  11. * the project provides a web site, mailing lists and IRC
  12. * channels for your use.
  13. *
  14. * This program is free software, distributed under the terms of
  15. * the GNU General Public License Version 2. See the LICENSE file
  16. * at the top of the source tree.
  17. */
  18. /*! \file
  19. *
  20. * \brief Command line for ARI.
  21. * \author David M. Lee, II <dlee@digium.com>
  22. */
  23. #include "asterisk.h"
  24. ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
  25. #include "asterisk/astobj2.h"
  26. #include "asterisk/cli.h"
  27. #include "internal.h"
  28. static char *ari_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  29. {
  30. RAII_VAR(struct ast_ari_conf *, conf, NULL, ao2_cleanup);
  31. switch (cmd) {
  32. case CLI_INIT:
  33. e->command = "ari show status";
  34. e->usage =
  35. "Usage: ari show status\n"
  36. " Shows all ARI settings\n";
  37. return NULL;
  38. case CLI_GENERATE:
  39. return NULL;
  40. default:
  41. break;
  42. }
  43. if (a->argc != 3) {
  44. return CLI_SHOWUSAGE;
  45. }
  46. conf = ast_ari_config_get();
  47. if (!conf) {
  48. ast_cli(a->fd, "Error getting ARI configuration\n");
  49. return CLI_FAILURE;
  50. }
  51. ast_cli(a->fd, "ARI Status:\n");
  52. ast_cli(a->fd, "Enabled: %s\n", AST_CLI_YESNO(conf->general->enabled));
  53. ast_cli(a->fd, "Output format: ");
  54. switch (conf->general->format) {
  55. case AST_JSON_COMPACT:
  56. ast_cli(a->fd, "compact");
  57. break;
  58. case AST_JSON_PRETTY:
  59. ast_cli(a->fd, "pretty");
  60. break;
  61. }
  62. ast_cli(a->fd, "\n");
  63. ast_cli(a->fd, "Auth realm: %s\n", conf->general->auth_realm);
  64. ast_cli(a->fd, "Allowed Origins: %s\n", conf->general->allowed_origins);
  65. ast_cli(a->fd, "User count: %d\n", ao2_container_count(conf->users));
  66. return CLI_SUCCESS;
  67. }
  68. static int show_users_cb(void *obj, void *arg, int flags)
  69. {
  70. struct ast_ari_conf_user *user = obj;
  71. struct ast_cli_args *a = arg;
  72. ast_cli(a->fd, "%-4s %s\n",
  73. AST_CLI_YESNO(user->read_only),
  74. user->username);
  75. return 0;
  76. }
  77. static char *ari_show_users(struct ast_cli_entry *e, int cmd,
  78. struct ast_cli_args *a)
  79. {
  80. RAII_VAR(struct ast_ari_conf *, conf, NULL, ao2_cleanup);
  81. switch (cmd) {
  82. case CLI_INIT:
  83. e->command = "ari show users";
  84. e->usage =
  85. "Usage: ari show users\n"
  86. " Shows all ARI users\n";
  87. return NULL;
  88. case CLI_GENERATE:
  89. return NULL;
  90. default:
  91. break;
  92. }
  93. if (a->argc != 3) {
  94. return CLI_SHOWUSAGE;
  95. }
  96. conf = ast_ari_config_get();
  97. if (!conf) {
  98. ast_cli(a->fd, "Error getting ARI configuration\n");
  99. return CLI_FAILURE;
  100. }
  101. ast_cli(a->fd, "r/o? Username\n");
  102. ast_cli(a->fd, "---- --------\n");
  103. ao2_callback(conf->users, OBJ_NODATA, show_users_cb, a);
  104. return CLI_SUCCESS;
  105. }
  106. struct user_complete {
  107. /*! Nth user to search for */
  108. int state;
  109. /*! Which user currently on */
  110. int which;
  111. };
  112. static int complete_ari_user_search(void *obj, void *arg, void *data, int flags)
  113. {
  114. struct user_complete *search = data;
  115. if (++search->which > search->state) {
  116. return CMP_MATCH;
  117. }
  118. return 0;
  119. }
  120. static char *complete_ari_user(struct ast_cli_args *a)
  121. {
  122. RAII_VAR(struct ast_ari_conf *, conf, NULL, ao2_cleanup);
  123. RAII_VAR(struct ast_ari_conf_user *, user, NULL, ao2_cleanup);
  124. struct user_complete search = {
  125. .state = a->n,
  126. };
  127. conf = ast_ari_config_get();
  128. if (!conf) {
  129. ast_cli(a->fd, "Error getting ARI configuration\n");
  130. return CLI_FAILURE;
  131. }
  132. user = ao2_callback_data(conf->users,
  133. ast_strlen_zero(a->word) ? 0 : OBJ_PARTIAL_KEY,
  134. complete_ari_user_search, (char*)a->word, &search);
  135. return user ? ast_strdup(user->username) : NULL;
  136. }
  137. static char *complete_ari_show_user(struct ast_cli_args *a)
  138. {
  139. if (a->pos == 3) {
  140. return complete_ari_user(a);
  141. }
  142. return NULL;
  143. }
  144. static char *ari_show_user(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  145. {
  146. RAII_VAR(struct ast_ari_conf *, conf, NULL, ao2_cleanup);
  147. RAII_VAR(struct ast_ari_conf_user *, user, NULL, ao2_cleanup);
  148. switch (cmd) {
  149. case CLI_INIT:
  150. e->command = "ari show user";
  151. e->usage =
  152. "Usage: ari show user <username>\n"
  153. " Shows a specific ARI user\n";
  154. return NULL;
  155. case CLI_GENERATE:
  156. return complete_ari_show_user(a);
  157. default:
  158. break;
  159. }
  160. if (a->argc != 4) {
  161. return CLI_SHOWUSAGE;
  162. }
  163. conf = ast_ari_config_get();
  164. if (!conf) {
  165. ast_cli(a->fd, "Error getting ARI configuration\n");
  166. return CLI_FAILURE;
  167. }
  168. user = ao2_find(conf->users, a->argv[3], OBJ_KEY);
  169. if (!user) {
  170. ast_cli(a->fd, "User '%s' not found\n", a->argv[3]);
  171. return CLI_SUCCESS;
  172. }
  173. ast_cli(a->fd, "Username: %s\n", user->username);
  174. ast_cli(a->fd, "Read only?: %s\n", AST_CLI_YESNO(user->read_only));
  175. return CLI_SUCCESS;
  176. }
  177. static char *ari_mkpasswd(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  178. {
  179. RAII_VAR(char *, crypted, NULL, ast_free);
  180. switch (cmd) {
  181. case CLI_INIT:
  182. e->command = "ari mkpasswd";
  183. e->usage =
  184. "Usage: ari mkpasswd <password>\n"
  185. " Encrypts a password for use in ari.conf\n"
  186. " Be aware that the password will be shown in the\n"
  187. " command line history. The mkpasswd shell command\n"
  188. " may be preferable.\n"
  189. ;
  190. return NULL;
  191. case CLI_GENERATE:
  192. return NULL;
  193. default:
  194. break;
  195. }
  196. if (a->argc != 3) {
  197. return CLI_SHOWUSAGE;
  198. }
  199. crypted = ast_crypt_encrypt(a->argv[2]);
  200. if (!crypted) {
  201. ast_cli(a->fd, "Failed to encrypt password\n");
  202. return CLI_FAILURE;
  203. }
  204. ast_cli(a->fd,
  205. "; Copy the following two lines into ari.conf\n");
  206. ast_cli(a->fd, "password_format = crypt\n");
  207. ast_cli(a->fd, "password = %s\n", crypted);
  208. return CLI_SUCCESS;
  209. }
  210. static struct ast_cli_entry cli_ari[] = {
  211. AST_CLI_DEFINE(ari_show, "Show ARI settings"),
  212. AST_CLI_DEFINE(ari_show_users, "List ARI users"),
  213. AST_CLI_DEFINE(ari_show_user, "List single ARI user"),
  214. AST_CLI_DEFINE(ari_mkpasswd, "Encrypts a password"),
  215. };
  216. int ast_ari_cli_register(void) {
  217. return ast_cli_register_multiple(cli_ari, ARRAY_LEN(cli_ari));
  218. }
  219. void ast_ari_cli_unregister(void) {
  220. ast_cli_unregister_multiple(cli_ari, ARRAY_LEN(cli_ari));
  221. }