res_security_log.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. /*
  2. * Asterisk -- An open source telephony toolkit.
  3. *
  4. * Copyright (C) 2009, Digium, Inc.
  5. *
  6. * Russell Bryant <russell@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. /*!
  19. * \file
  20. *
  21. * \author Russell Bryant <russell@digium.com>
  22. *
  23. * \brief Security Event Logging
  24. *
  25. * \todo Make informational security events optional
  26. * \todo Escape quotes in string payload IE contents
  27. */
  28. /*** MODULEINFO
  29. <support_level>core</support_level>
  30. ***/
  31. #include "asterisk.h"
  32. ASTERISK_FILE_VERSION(__FILE__, "$Revision$");
  33. #include "asterisk/module.h"
  34. #include "asterisk/logger.h"
  35. #include "asterisk/event.h"
  36. #include "asterisk/threadstorage.h"
  37. #include "asterisk/strings.h"
  38. #include "asterisk/security_events.h"
  39. static const char LOG_SECURITY_NAME[] = "SECURITY";
  40. static int LOG_SECURITY;
  41. static struct ast_event_sub *security_event_sub;
  42. AST_THREADSTORAGE(security_event_buf);
  43. static const size_t SECURITY_EVENT_BUF_INIT_LEN = 256;
  44. enum ie_required {
  45. NOT_REQUIRED,
  46. REQUIRED
  47. };
  48. static int ie_is_present(const struct ast_event *event,
  49. const enum ast_event_ie_type ie_type)
  50. {
  51. return (ast_event_get_ie_raw(event, ie_type) != NULL);
  52. }
  53. static void append_ie(struct ast_str **str, const struct ast_event *event,
  54. const enum ast_event_ie_type ie_type, enum ie_required required)
  55. {
  56. if (!required && !ie_is_present(event, ie_type)) {
  57. /* Optional IE isn't present. Ignore. */
  58. return;
  59. }
  60. /* At this point, it _better_ be there! */
  61. ast_assert(ie_is_present(event, ie_type));
  62. switch (ast_event_get_ie_pltype(ie_type)) {
  63. case AST_EVENT_IE_PLTYPE_UINT:
  64. ast_str_append(str, 0, ",%s=\"%u\"",
  65. ast_event_get_ie_type_name(ie_type),
  66. ast_event_get_ie_uint(event, ie_type));
  67. break;
  68. case AST_EVENT_IE_PLTYPE_STR:
  69. ast_str_append(str, 0, ",%s=\"%s\"",
  70. ast_event_get_ie_type_name(ie_type),
  71. ast_event_get_ie_str(event, ie_type));
  72. break;
  73. case AST_EVENT_IE_PLTYPE_BITFLAGS:
  74. ast_str_append(str, 0, ",%s=\"%u\"",
  75. ast_event_get_ie_type_name(ie_type),
  76. ast_event_get_ie_bitflags(event, ie_type));
  77. break;
  78. case AST_EVENT_IE_PLTYPE_UNKNOWN:
  79. case AST_EVENT_IE_PLTYPE_EXISTS:
  80. case AST_EVENT_IE_PLTYPE_RAW:
  81. ast_log(LOG_WARNING, "Unexpected payload type for IE '%s'\n",
  82. ast_event_get_ie_type_name(ie_type));
  83. break;
  84. }
  85. }
  86. static void append_ies(struct ast_str **str, const struct ast_event *event,
  87. const struct ast_security_event_ie_type *ies, enum ie_required required)
  88. {
  89. unsigned int i;
  90. for (i = 0; ies[i].ie_type != AST_EVENT_IE_END; i++) {
  91. append_ie(str, event, ies[i].ie_type, required);
  92. }
  93. }
  94. static void security_event_cb(const struct ast_event *event, void *data)
  95. {
  96. struct ast_str *str;
  97. enum ast_security_event_type event_type;
  98. if (!(str = ast_str_thread_get(&security_event_buf,
  99. SECURITY_EVENT_BUF_INIT_LEN))) {
  100. return;
  101. }
  102. /* Note that the event type is guaranteed to be valid here. */
  103. event_type = ast_event_get_ie_uint(event, AST_EVENT_IE_SECURITY_EVENT);
  104. ast_assert(event_type >= 0 && event_type < AST_SECURITY_EVENT_NUM_TYPES);
  105. ast_str_set(&str, 0, "%s=\"%s\"",
  106. ast_event_get_ie_type_name(AST_EVENT_IE_SECURITY_EVENT),
  107. ast_security_event_get_name(event_type));
  108. append_ies(&str, event,
  109. ast_security_event_get_required_ies(event_type), REQUIRED);
  110. append_ies(&str, event,
  111. ast_security_event_get_optional_ies(event_type), NOT_REQUIRED);
  112. ast_log_dynamic_level(LOG_SECURITY, "%s\n", ast_str_buffer(str));
  113. }
  114. static int load_module(void)
  115. {
  116. if ((LOG_SECURITY = ast_logger_register_level(LOG_SECURITY_NAME)) == -1) {
  117. return AST_MODULE_LOAD_DECLINE;
  118. }
  119. if (!(security_event_sub = ast_event_subscribe(AST_EVENT_SECURITY,
  120. security_event_cb, "Security Event Logger",
  121. NULL, AST_EVENT_IE_END))) {
  122. ast_logger_unregister_level(LOG_SECURITY_NAME);
  123. LOG_SECURITY = -1;
  124. return AST_MODULE_LOAD_DECLINE;
  125. }
  126. ast_verb(3, "Security Logging Enabled\n");
  127. return AST_MODULE_LOAD_SUCCESS;
  128. }
  129. static int unload_module(void)
  130. {
  131. if (security_event_sub) {
  132. security_event_sub = ast_event_unsubscribe(security_event_sub);
  133. }
  134. ast_verb(3, "Security Logging Disabled\n");
  135. return 0;
  136. }
  137. AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Security Event Logging");