res_pjsip_t38: Don't crash on authenticated reinvite after originated T.38 FAX.
[asterisk/asterisk.git] / main / security_events.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2012, 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 /*!
20  * \file
21  *
22  * \brief Security Event Reporting Helpers
23  *
24  * \author Russell Bryant <russell@digium.com>
25  */
26
27 /*** MODULEINFO
28         <support_level>core</support_level>
29  ***/
30
31 /*** DOCUMENTATION
32         <managerEvent language="en_US" name="FailedACL">
33                 <managerEventInstance class="EVENT_FLAG_SECURITY">
34                         <synopsis>Raised when a request violates an ACL check.</synopsis>
35                         <syntax>
36                                 <parameter name="EventTV">
37                                         <para>The time the event was detected.</para>
38                                 </parameter>
39                                 <parameter name="Severity">
40                                         <para>A relative severity of the security event.</para>
41                                         <enumlist>
42                                                 <enum name="Informational"/>
43                                                 <enum name="Error"/>
44                                         </enumlist>
45                                 </parameter>
46                                 <parameter name="Service">
47                                         <para>The Asterisk service that raised the security event.</para>
48                                 </parameter>
49                                 <parameter name="EventVersion">
50                                         <para>The version of this event.</para>
51                                 </parameter>
52                                 <parameter name="AccountID">
53                                         <para>The Service account associated with the security event
54                                         notification.</para>
55                                 </parameter>
56                                 <parameter name="SessionID">
57                                         <para>A unique identifier for the session in the service
58                                         that raised the event.</para>
59                                 </parameter>
60                                 <parameter name="LocalAddress">
61                                         <para>The address of the Asterisk service that raised the
62                                         security event.</para>
63                                 </parameter>
64                                 <parameter name="RemoteAddress">
65                                         <para>The remote address of the entity that caused the
66                                         security event to be raised.</para>
67                                 </parameter>
68                                 <parameter name="Module" required="false">
69                                         <para>If available, the name of the module that raised the event.</para>
70                                 </parameter>
71                                 <parameter name="ACLName" required="false">
72                                         <para>If available, the name of the ACL that failed.</para>
73                                 </parameter>
74                                 <parameter name="SessionTV" required="false">
75                                         <para>The timestamp reported by the session.</para>
76                                 </parameter>
77                         </syntax>
78                 </managerEventInstance>
79         </managerEvent>
80         <managerEvent language="en_US" name="InvalidAccountID">
81                 <managerEventInstance class="EVENT_FLAG_SECURITY">
82                         <synopsis>Raised when a request fails an authentication check due to an invalid account ID.</synopsis>
83                         <syntax>
84                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='EventTV'])" />
85                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='Severity'])" />
86                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='Service'])" />
87                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='EventVersion'])" />
88                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='AccountID'])" />
89                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='SessionID'])" />
90                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='LocalAddress'])" />
91                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='RemoteAddress'])" />
92                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='Module'])" />
93                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='SessionTV'])" />
94                         </syntax>
95                 </managerEventInstance>
96         </managerEvent>
97         <managerEvent language="en_US" name="SessionLimit">
98                 <managerEventInstance class="EVENT_FLAG_SECURITY">
99                         <synopsis>Raised when a request fails due to exceeding the number of allowed concurrent sessions for that service.</synopsis>
100                         <syntax>
101                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='EventTV'])" />
102                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='Severity'])" />
103                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='Service'])" />
104                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='EventVersion'])" />
105                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='AccountID'])" />
106                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='SessionID'])" />
107                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='LocalAddress'])" />
108                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='RemoteAddress'])" />
109                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='Module'])" />
110                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='SessionTV'])" />
111                         </syntax>
112                 </managerEventInstance>
113         </managerEvent>
114         <managerEvent language="en_US" name="MemoryLimit">
115                 <managerEventInstance class="EVENT_FLAG_SECURITY">
116                         <synopsis>Raised when a request fails due to an internal memory allocation failure.</synopsis>
117                         <syntax>
118                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='EventTV'])" />
119                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='Severity'])" />
120                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='Service'])" />
121                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='EventVersion'])" />
122                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='AccountID'])" />
123                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='SessionID'])" />
124                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='LocalAddress'])" />
125                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='RemoteAddress'])" />
126                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='Module'])" />
127                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='SessionTV'])" />
128                         </syntax>
129                 </managerEventInstance>
130         </managerEvent>
131         <managerEvent language="en_US" name="LoadAverageLimit">
132                 <managerEventInstance class="EVENT_FLAG_SECURITY">
133                         <synopsis>Raised when a request fails because a configured load average limit has been reached.</synopsis>
134                         <syntax>
135                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='EventTV'])" />
136                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='Severity'])" />
137                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='Service'])" />
138                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='EventVersion'])" />
139                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='AccountID'])" />
140                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='SessionID'])" />
141                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='LocalAddress'])" />
142                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='RemoteAddress'])" />
143                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='Module'])" />
144                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='SessionTV'])" />
145                         </syntax>
146                 </managerEventInstance>
147         </managerEvent>
148         <managerEvent language="en_US" name="RequestNotSupported">
149                 <managerEventInstance class="EVENT_FLAG_SECURITY">
150                         <synopsis>Raised when a request fails due to some aspect of the requested item not being supported by the service.</synopsis>
151                         <syntax>
152                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='EventTV'])" />
153                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='Severity'])" />
154                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='Service'])" />
155                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='EventVersion'])" />
156                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='AccountID'])" />
157                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='SessionID'])" />
158                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='LocalAddress'])" />
159                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='RemoteAddress'])" />
160                                 <parameter name="RequestType">
161                                         <para>The type of request attempted.</para>
162                                 </parameter>
163                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='Module'])" />
164                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='SessionTV'])" />
165                         </syntax>
166                 </managerEventInstance>
167         </managerEvent>
168         <managerEvent language="en_US" name="RequestNotAllowed">
169                 <managerEventInstance class="EVENT_FLAG_SECURITY">
170                         <synopsis>Raised when a request is not allowed by the service.</synopsis>
171                         <syntax>
172                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='EventTV'])" />
173                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='Severity'])" />
174                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='Service'])" />
175                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='EventVersion'])" />
176                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='AccountID'])" />
177                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='SessionID'])" />
178                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='LocalAddress'])" />
179                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='RemoteAddress'])" />
180                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='RequestNotSupported']/managerEventInstance/syntax/parameter[@name='RequestType'])" />
181                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='Module'])" />
182                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='SessionTV'])" />
183                                 <parameter name="RequestParams" required="false">
184                                         <para>Parameters provided to the rejected request.</para>
185                                 </parameter>
186                         </syntax>
187                 </managerEventInstance>
188         </managerEvent>
189         <managerEvent language="en_US" name="AuthMethodNotAllowed">
190                 <managerEventInstance class="EVENT_FLAG_SECURITY">
191                         <synopsis>Raised when a request used an authentication method not allowed by the service.</synopsis>
192                         <syntax>
193                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='EventTV'])" />
194                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='Severity'])" />
195                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='Service'])" />
196                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='EventVersion'])" />
197                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='AccountID'])" />
198                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='SessionID'])" />
199                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='LocalAddress'])" />
200                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='RemoteAddress'])" />
201                                 <parameter name="AuthMethod">
202                                         <para>The authentication method attempted.</para>
203                                 </parameter>
204                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='Module'])" />
205                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='SessionTV'])" />
206                         </syntax>
207                 </managerEventInstance>
208         </managerEvent>
209         <managerEvent language="en_US" name="RequestBadFormat">
210                 <managerEventInstance class="EVENT_FLAG_SECURITY">
211                         <synopsis>Raised when a request is received with bad formatting.</synopsis>
212                         <syntax>
213                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='EventTV'])" />
214                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='Severity'])" />
215                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='Service'])" />
216                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='EventVersion'])" />
217                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='AccountID'])" />
218                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='SessionID'])" />
219                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='LocalAddress'])" />
220                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='RemoteAddress'])" />
221                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='RequestNotSupported']/managerEventInstance/syntax/parameter[@name='RequestType'])" />
222                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='Module'])" />
223                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='SessionTV'])" />
224                                 <parameter name="AccountID" required="false">
225                                         <para>The account ID associated with the rejected request.</para>
226                                 </parameter>
227                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='RequestNotAllowed']/managerEventInstance/syntax/parameter[@name='RequestParams'])" />
228                         </syntax>
229                 </managerEventInstance>
230         </managerEvent>
231         <managerEvent language="en_US" name="SuccessfulAuth">
232                 <managerEventInstance class="EVENT_FLAG_SECURITY">
233                         <synopsis>Raised when a request successfully authenticates with a service.</synopsis>
234                         <syntax>
235                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='EventTV'])" />
236                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='Severity'])" />
237                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='Service'])" />
238                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='EventVersion'])" />
239                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='AccountID'])" />
240                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='SessionID'])" />
241                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='LocalAddress'])" />
242                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='RemoteAddress'])" />
243                                 <parameter name="UsingPassword">
244                                         <para>Whether or not the authentication attempt included a password.</para>
245                                 </parameter>
246                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='Module'])" />
247                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='SessionTV'])" />
248                         </syntax>
249                 </managerEventInstance>
250         </managerEvent>
251         <managerEvent language="en_US" name="UnexpectedAddress">
252                 <managerEventInstance class="EVENT_FLAG_SECURITY">
253                         <synopsis>Raised when a request has a different source address then what is expected for a session already in progress with a service.</synopsis>
254                         <syntax>
255                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='EventTV'])" />
256                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='Severity'])" />
257                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='Service'])" />
258                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='EventVersion'])" />
259                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='AccountID'])" />
260                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='SessionID'])" />
261                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='LocalAddress'])" />
262                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='RemoteAddress'])" />
263                                 <parameter name="ExpectedAddress">
264                                         <para>The address that the request was expected to use.</para>
265                                 </parameter>
266                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='Module'])" />
267                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='SessionTV'])" />
268                         </syntax>
269                 </managerEventInstance>
270         </managerEvent>
271         <managerEvent language="en_US" name="ChallengeResponseFailed">
272                 <managerEventInstance class="EVENT_FLAG_SECURITY">
273                         <synopsis>Raised when a request's attempt to authenticate has been challenged, and the request failed the authentication challenge.</synopsis>
274                         <syntax>
275                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='EventTV'])" />
276                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='Severity'])" />
277                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='Service'])" />
278                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='EventVersion'])" />
279                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='AccountID'])" />
280                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='SessionID'])" />
281                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='LocalAddress'])" />
282                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='RemoteAddress'])" />
283                                 <parameter name="Challenge">
284                                         <para>The challenge that was sent.</para>
285                                 </parameter>
286                                 <parameter name="Response">
287                                         <para>The response that was received.</para>
288                                 </parameter>
289                                 <parameter name="ExpectedResponse">
290                                         <para>The expected response to the challenge.</para>
291                                 </parameter>
292                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='Module'])" />
293                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='SessionTV'])" />
294                         </syntax>
295                 </managerEventInstance>
296         </managerEvent>
297         <managerEvent language="en_US" name="InvalidPassword">
298                 <managerEventInstance class="EVENT_FLAG_SECURITY">
299                         <synopsis>Raised when a request provides an invalid password during an authentication attempt.</synopsis>
300                         <syntax>
301                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='EventTV'])" />
302                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='Severity'])" />
303                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='Service'])" />
304                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='EventVersion'])" />
305                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='AccountID'])" />
306                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='SessionID'])" />
307                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='LocalAddress'])" />
308                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='RemoteAddress'])" />
309                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='Module'])" />
310                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='SessionTV'])" />
311                                 <parameter name="Challenge" required="false">
312                                         <para>The challenge that was sent.</para>
313                                 </parameter>
314                                 <parameter name="ReceivedChallenge" required="false">
315                                         <para>The challenge that was received.</para>
316                                 </parameter>
317                                 <parameter name="RecievedHash" required="false">
318                                         <para>The hash that was received.</para>
319                                 </parameter>
320                         </syntax>
321                 </managerEventInstance>
322         </managerEvent>
323         <managerEvent language="en_US" name="ChallengeSent">
324                 <managerEventInstance class="EVENT_FLAG_SECURITY">
325                         <synopsis>Raised when an Asterisk service sends an authentication challenge to a request.</synopsis>
326                         <syntax>
327                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='EventTV'])" />
328                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='Severity'])" />
329                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='Service'])" />
330                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='EventVersion'])" />
331                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='AccountID'])" />
332                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='SessionID'])" />
333                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='LocalAddress'])" />
334                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='RemoteAddress'])" />
335                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='ChallengeResponseFailed']/managerEventInstance/syntax/parameter[@name='Challenge'])" />
336                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='Module'])" />
337                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='SessionTV'])" />
338                         </syntax>
339                 </managerEventInstance>
340         </managerEvent>
341         <managerEvent language="en_US" name="InvalidTransport">
342                 <managerEventInstance class="EVENT_FLAG_SECURITY">
343                         <synopsis>Raised when a request attempts to use a transport not allowed by the Asterisk service.</synopsis>
344                         <syntax>
345                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='EventTV'])" />
346                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='Severity'])" />
347                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='Service'])" />
348                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='EventVersion'])" />
349                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='AccountID'])" />
350                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='SessionID'])" />
351                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='LocalAddress'])" />
352                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='RemoteAddress'])" />
353                                 <parameter name="AttemptedTransport">
354                                         <para>The transport type that the request attempted to use.</para>
355                                 </parameter>
356                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='Module'])" />
357                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='FailedACL']/managerEventInstance/syntax/parameter[@name='SessionTV'])" />
358                         </syntax>
359                 </managerEventInstance>
360         </managerEvent>
361  ***/
362
363 #include "asterisk.h"
364
365 ASTERISK_REGISTER_FILE()
366
367 #include "asterisk/utils.h"
368 #include "asterisk/strings.h"
369 #include "asterisk/network.h"
370 #include "asterisk/event.h"
371 #include "asterisk/security_events.h"
372 #include "asterisk/netsock2.h"
373 #include "asterisk/stasis.h"
374 #include "asterisk/json.h"
375 #include "asterisk/astobj2.h"
376
377 static const size_t SECURITY_EVENT_BUF_INIT_LEN = 256;
378
379 /*! \brief Security Topic */
380 static struct stasis_topic *security_topic;
381
382 struct stasis_topic *ast_security_topic(void)
383 {
384         return security_topic;
385 }
386
387 static int append_event_str_single(struct ast_str **str, struct ast_json *json,
388                 const enum ast_event_ie_type ie_type)
389 {
390         const char *ie_type_key = ast_event_get_ie_type_name(ie_type);
391         struct ast_json *json_string = ast_json_object_get(json, ie_type_key);
392
393         if (!json_string) {
394                 return 0;
395         }
396
397         if (ast_str_append(str, 0, "%s: %s\r\n", ie_type_key, S_OR(ast_json_string_get(json_string), "")) == -1) {
398                 return -1;
399         }
400
401         return 0;
402 }
403
404 static int append_event_str_from_json(struct ast_str **str, struct ast_json *json,
405                 const struct ast_security_event_ie_type *ies)
406 {
407         unsigned int i;
408
409         if (!ies) {
410                 return 0;
411         }
412
413         for (i = 0; ies[i].ie_type != AST_EVENT_IE_END; i++) {
414                 if (append_event_str_single(str, json, ies[i].ie_type)) {
415                         return -1;
416                 }
417         }
418
419         return 0;
420 }
421
422 static struct ast_manager_event_blob *security_event_to_ami_blob(struct ast_json *json)
423 {
424         RAII_VAR(struct ast_str *, str, NULL, ast_free);
425         struct ast_json *event_type_json;
426         enum ast_security_event_type event_type;
427
428         event_type_json = ast_json_object_get(json, "SecurityEvent");
429         event_type = ast_json_integer_get(event_type_json);
430
431         ast_assert(event_type >= 0 && event_type < AST_SECURITY_EVENT_NUM_TYPES);
432
433         if (!(str = ast_str_create(SECURITY_EVENT_BUF_INIT_LEN))) {
434                 return NULL;
435         }
436
437         if (append_event_str_from_json(&str, json,
438                         ast_security_event_get_required_ies(event_type))) {
439                 ast_log(AST_LOG_ERROR, "Failed to issue a security event to AMI: "
440                         "error occurred when adding required event fields.\n");
441                 return NULL;
442         }
443
444         if (append_event_str_from_json(&str, json,
445                         ast_security_event_get_optional_ies(event_type))) {
446                 ast_log(AST_LOG_ERROR, "Failed to issue a security event to AMI: "
447                         "error occurred when adding optional event fields.\n");
448                 return NULL;
449         }
450
451         return ast_manager_event_blob_create(EVENT_FLAG_SECURITY,
452                 ast_security_event_get_name(event_type),
453                 "%s",
454                 ast_str_buffer(str));
455 }
456
457 static struct ast_manager_event_blob *security_event_to_ami(struct stasis_message *message)
458 {
459         struct ast_json_payload *payload = stasis_message_data(message);
460
461         if (stasis_message_type(message) != ast_security_event_type()) {
462                 return NULL;
463         }
464
465         if (!payload) {
466                 return NULL;
467         }
468
469         return security_event_to_ami_blob(payload->json);
470 }
471
472 /*! \brief Message type for security events */
473 STASIS_MESSAGE_TYPE_DEFN(ast_security_event_type,
474         .to_ami = security_event_to_ami,
475         );
476
477 static void security_stasis_cleanup(void)
478 {
479         ao2_cleanup(security_topic);
480         security_topic = NULL;
481
482         STASIS_MESSAGE_TYPE_CLEANUP(ast_security_event_type);
483 }
484
485 int ast_security_stasis_init(void)
486 {
487         ast_register_cleanup(security_stasis_cleanup);
488
489         security_topic = stasis_topic_create("ast_security");
490         if (!security_topic) {
491                 return -1;
492         }
493
494         if (STASIS_MESSAGE_TYPE_INIT(ast_security_event_type)) {
495                 return -1;
496         }
497
498
499         return 0;
500 }
501
502 static const struct {
503         const char *name;
504         uint32_t version;
505         enum ast_security_event_severity severity;
506 #define MAX_SECURITY_IES 12
507         struct ast_security_event_ie_type required_ies[MAX_SECURITY_IES];
508         struct ast_security_event_ie_type optional_ies[MAX_SECURITY_IES];
509 #undef MAX_SECURITY_IES
510 } sec_events[AST_SECURITY_EVENT_NUM_TYPES] = {
511
512 #define SEC_EVT_FIELD(e, field) (offsetof(struct ast_security_event_##e, field))
513
514 [AST_SECURITY_EVENT_FAILED_ACL] = {
515         .name     = "FailedACL",
516         .version  = AST_SECURITY_EVENT_FAILED_ACL_VERSION,
517         .severity = AST_SECURITY_EVENT_SEVERITY_ERROR,
518         .required_ies = {
519                 { AST_EVENT_IE_EVENT_TV, 0 },
520                 { AST_EVENT_IE_SEVERITY, 0 },
521                 { AST_EVENT_IE_SERVICE, SEC_EVT_FIELD(common, service) },
522                 { AST_EVENT_IE_EVENT_VERSION, SEC_EVT_FIELD(common, version) },
523                 { AST_EVENT_IE_ACCOUNT_ID, SEC_EVT_FIELD(common, account_id) },
524                 { AST_EVENT_IE_SESSION_ID, SEC_EVT_FIELD(common, session_id) },
525                 { AST_EVENT_IE_LOCAL_ADDR, SEC_EVT_FIELD(common, local_addr) },
526                 { AST_EVENT_IE_REMOTE_ADDR, SEC_EVT_FIELD(common, remote_addr) },
527                 { AST_EVENT_IE_END, 0 }
528         },
529         .optional_ies = {
530                 { AST_EVENT_IE_MODULE, SEC_EVT_FIELD(common, module) },
531                 { AST_EVENT_IE_ACL_NAME, SEC_EVT_FIELD(failed_acl, acl_name) },
532                 { AST_EVENT_IE_SESSION_TV, SEC_EVT_FIELD(common, session_tv) },
533                 { AST_EVENT_IE_END, 0 }
534         },
535 },
536
537 [AST_SECURITY_EVENT_INVAL_ACCT_ID] = {
538         .name     = "InvalidAccountID",
539         .version  = AST_SECURITY_EVENT_INVAL_ACCT_ID_VERSION,
540         .severity = AST_SECURITY_EVENT_SEVERITY_ERROR,
541         .required_ies = {
542                 { AST_EVENT_IE_EVENT_TV, 0 },
543                 { AST_EVENT_IE_SEVERITY, 0 },
544                 { AST_EVENT_IE_SERVICE, SEC_EVT_FIELD(common, service) },
545                 { AST_EVENT_IE_EVENT_VERSION, SEC_EVT_FIELD(common, version) },
546                 { AST_EVENT_IE_ACCOUNT_ID, SEC_EVT_FIELD(common, account_id) },
547                 { AST_EVENT_IE_SESSION_ID, SEC_EVT_FIELD(common, session_id) },
548                 { AST_EVENT_IE_LOCAL_ADDR, SEC_EVT_FIELD(common, local_addr) },
549                 { AST_EVENT_IE_REMOTE_ADDR, SEC_EVT_FIELD(common, remote_addr) },
550                 { AST_EVENT_IE_END, 0 }
551         },
552         .optional_ies = {
553                 { AST_EVENT_IE_MODULE, SEC_EVT_FIELD(common, module) },
554                 { AST_EVENT_IE_SESSION_TV, SEC_EVT_FIELD(common, session_tv) },
555                 { AST_EVENT_IE_END, 0 }
556         },
557 },
558
559 [AST_SECURITY_EVENT_SESSION_LIMIT] = {
560         .name     = "SessionLimit",
561         .version  = AST_SECURITY_EVENT_SESSION_LIMIT_VERSION,
562         .severity = AST_SECURITY_EVENT_SEVERITY_ERROR,
563         .required_ies = {
564                 { AST_EVENT_IE_EVENT_TV, 0 },
565                 { AST_EVENT_IE_SEVERITY, 0 },
566                 { AST_EVENT_IE_SERVICE, SEC_EVT_FIELD(common, service) },
567                 { AST_EVENT_IE_EVENT_VERSION, SEC_EVT_FIELD(common, version) },
568                 { AST_EVENT_IE_ACCOUNT_ID, SEC_EVT_FIELD(common, account_id) },
569                 { AST_EVENT_IE_SESSION_ID, SEC_EVT_FIELD(common, session_id) },
570                 { AST_EVENT_IE_LOCAL_ADDR, SEC_EVT_FIELD(common, local_addr) },
571                 { AST_EVENT_IE_REMOTE_ADDR, SEC_EVT_FIELD(common, remote_addr) },
572                 { AST_EVENT_IE_END, 0 }
573         },
574         .optional_ies = {
575                 { AST_EVENT_IE_MODULE, SEC_EVT_FIELD(common, module) },
576                 { AST_EVENT_IE_SESSION_TV, SEC_EVT_FIELD(common, session_tv) },
577                 { AST_EVENT_IE_END, 0 }
578         },
579 },
580
581 [AST_SECURITY_EVENT_MEM_LIMIT] = {
582         .name     = "MemoryLimit",
583         .version  = AST_SECURITY_EVENT_MEM_LIMIT_VERSION,
584         .severity = AST_SECURITY_EVENT_SEVERITY_ERROR,
585         .required_ies = {
586                 { AST_EVENT_IE_EVENT_TV, 0 },
587                 { AST_EVENT_IE_SEVERITY, 0 },
588                 { AST_EVENT_IE_SERVICE, SEC_EVT_FIELD(common, service) },
589                 { AST_EVENT_IE_EVENT_VERSION, SEC_EVT_FIELD(common, version) },
590                 { AST_EVENT_IE_ACCOUNT_ID, SEC_EVT_FIELD(common, account_id) },
591                 { AST_EVENT_IE_SESSION_ID, SEC_EVT_FIELD(common, session_id) },
592                 { AST_EVENT_IE_LOCAL_ADDR, SEC_EVT_FIELD(common, local_addr) },
593                 { AST_EVENT_IE_REMOTE_ADDR, SEC_EVT_FIELD(common, remote_addr) },
594                 { AST_EVENT_IE_END, 0 }
595         },
596         .optional_ies = {
597                 { AST_EVENT_IE_MODULE, SEC_EVT_FIELD(common, module) },
598                 { AST_EVENT_IE_SESSION_TV, SEC_EVT_FIELD(common, session_tv) },
599                 { AST_EVENT_IE_END, 0 }
600         },
601 },
602
603 [AST_SECURITY_EVENT_LOAD_AVG] = {
604         .name     = "LoadAverageLimit",
605         .version  = AST_SECURITY_EVENT_LOAD_AVG_VERSION,
606         .severity = AST_SECURITY_EVENT_SEVERITY_ERROR,
607         .required_ies = {
608                 { AST_EVENT_IE_EVENT_TV, 0 },
609                 { AST_EVENT_IE_SEVERITY, 0 },
610                 { AST_EVENT_IE_SERVICE, SEC_EVT_FIELD(common, service) },
611                 { AST_EVENT_IE_EVENT_VERSION, SEC_EVT_FIELD(common, version) },
612                 { AST_EVENT_IE_ACCOUNT_ID, SEC_EVT_FIELD(common, account_id) },
613                 { AST_EVENT_IE_SESSION_ID, SEC_EVT_FIELD(common, session_id) },
614                 { AST_EVENT_IE_LOCAL_ADDR, SEC_EVT_FIELD(common, local_addr) },
615                 { AST_EVENT_IE_REMOTE_ADDR, SEC_EVT_FIELD(common, remote_addr) },
616                 { AST_EVENT_IE_END, 0 }
617         },
618         .optional_ies = {
619                 { AST_EVENT_IE_MODULE, SEC_EVT_FIELD(common, module) },
620                 { AST_EVENT_IE_SESSION_TV, SEC_EVT_FIELD(common, session_tv) },
621                 { AST_EVENT_IE_END, 0 }
622         },
623 },
624
625 [AST_SECURITY_EVENT_REQ_NO_SUPPORT] = {
626         .name     = "RequestNotSupported",
627         .version  = AST_SECURITY_EVENT_REQ_NO_SUPPORT_VERSION,
628         .severity = AST_SECURITY_EVENT_SEVERITY_ERROR,
629         .required_ies = {
630                 { AST_EVENT_IE_EVENT_TV, 0 },
631                 { AST_EVENT_IE_SEVERITY, 0 },
632                 { AST_EVENT_IE_SERVICE, SEC_EVT_FIELD(common, service) },
633                 { AST_EVENT_IE_EVENT_VERSION, SEC_EVT_FIELD(common, version) },
634                 { AST_EVENT_IE_ACCOUNT_ID, SEC_EVT_FIELD(common, account_id) },
635                 { AST_EVENT_IE_SESSION_ID, SEC_EVT_FIELD(common, session_id) },
636                 { AST_EVENT_IE_LOCAL_ADDR, SEC_EVT_FIELD(common, local_addr) },
637                 { AST_EVENT_IE_REMOTE_ADDR, SEC_EVT_FIELD(common, remote_addr) },
638                 { AST_EVENT_IE_REQUEST_TYPE, SEC_EVT_FIELD(req_no_support, request_type) },
639                 { AST_EVENT_IE_END, 0 }
640         },
641         .optional_ies = {
642                 { AST_EVENT_IE_MODULE, SEC_EVT_FIELD(common, module) },
643                 { AST_EVENT_IE_SESSION_TV, SEC_EVT_FIELD(common, session_tv) },
644                 { AST_EVENT_IE_END, 0 }
645         },
646 },
647
648 [AST_SECURITY_EVENT_REQ_NOT_ALLOWED] = {
649         .name     = "RequestNotAllowed",
650         .version  = AST_SECURITY_EVENT_REQ_NOT_ALLOWED_VERSION,
651         .severity = AST_SECURITY_EVENT_SEVERITY_ERROR,
652         .required_ies = {
653                 { AST_EVENT_IE_EVENT_TV, 0 },
654                 { AST_EVENT_IE_SEVERITY, 0 },
655                 { AST_EVENT_IE_SERVICE, SEC_EVT_FIELD(common, service) },
656                 { AST_EVENT_IE_EVENT_VERSION, SEC_EVT_FIELD(common, version) },
657                 { AST_EVENT_IE_ACCOUNT_ID, SEC_EVT_FIELD(common, account_id) },
658                 { AST_EVENT_IE_SESSION_ID, SEC_EVT_FIELD(common, session_id) },
659                 { AST_EVENT_IE_LOCAL_ADDR, SEC_EVT_FIELD(common, local_addr) },
660                 { AST_EVENT_IE_REMOTE_ADDR, SEC_EVT_FIELD(common, remote_addr) },
661                 { AST_EVENT_IE_REQUEST_TYPE, SEC_EVT_FIELD(req_not_allowed, request_type) },
662                 { AST_EVENT_IE_END, 0 }
663         },
664         .optional_ies = {
665                 { AST_EVENT_IE_MODULE, SEC_EVT_FIELD(common, module) },
666                 { AST_EVENT_IE_SESSION_TV, SEC_EVT_FIELD(common, session_tv) },
667                 { AST_EVENT_IE_REQUEST_PARAMS, SEC_EVT_FIELD(req_not_allowed, request_params) },
668                 { AST_EVENT_IE_END, 0 }
669         },
670 },
671
672 [AST_SECURITY_EVENT_AUTH_METHOD_NOT_ALLOWED] = {
673         .name     = "AuthMethodNotAllowed",
674         .version  = AST_SECURITY_EVENT_AUTH_METHOD_NOT_ALLOWED_VERSION,
675         .severity = AST_SECURITY_EVENT_SEVERITY_ERROR,
676         .required_ies = {
677                 { AST_EVENT_IE_EVENT_TV, 0 },
678                 { AST_EVENT_IE_SEVERITY, 0 },
679                 { AST_EVENT_IE_SERVICE, SEC_EVT_FIELD(common, service) },
680                 { AST_EVENT_IE_EVENT_VERSION, SEC_EVT_FIELD(common, version) },
681                 { AST_EVENT_IE_ACCOUNT_ID, SEC_EVT_FIELD(common, account_id) },
682                 { AST_EVENT_IE_SESSION_ID, SEC_EVT_FIELD(common, session_id) },
683                 { AST_EVENT_IE_LOCAL_ADDR, SEC_EVT_FIELD(common, local_addr) },
684                 { AST_EVENT_IE_REMOTE_ADDR, SEC_EVT_FIELD(common, remote_addr) },
685                 { AST_EVENT_IE_AUTH_METHOD, SEC_EVT_FIELD(auth_method_not_allowed, auth_method) },
686                 { AST_EVENT_IE_END, 0 }
687         },
688         .optional_ies = {
689                 { AST_EVENT_IE_MODULE, SEC_EVT_FIELD(common, module) },
690                 { AST_EVENT_IE_SESSION_TV, SEC_EVT_FIELD(common, session_tv) },
691                 { AST_EVENT_IE_END, 0 }
692         },
693 },
694
695 [AST_SECURITY_EVENT_REQ_BAD_FORMAT] = {
696         .name     = "RequestBadFormat",
697         .version  = AST_SECURITY_EVENT_REQ_BAD_FORMAT_VERSION,
698         .severity = AST_SECURITY_EVENT_SEVERITY_ERROR,
699         .required_ies = {
700                 { AST_EVENT_IE_EVENT_TV, 0 },
701                 { AST_EVENT_IE_SEVERITY, 0 },
702                 { AST_EVENT_IE_SERVICE, SEC_EVT_FIELD(common, service) },
703                 { AST_EVENT_IE_EVENT_VERSION, SEC_EVT_FIELD(common, version) },
704                 { AST_EVENT_IE_SESSION_ID, SEC_EVT_FIELD(common, session_id) },
705                 { AST_EVENT_IE_LOCAL_ADDR, SEC_EVT_FIELD(common, local_addr) },
706                 { AST_EVENT_IE_REMOTE_ADDR, SEC_EVT_FIELD(common, remote_addr) },
707                 { AST_EVENT_IE_REQUEST_TYPE, SEC_EVT_FIELD(req_bad_format, request_type) },
708                 { AST_EVENT_IE_END, 0 }
709         },
710         .optional_ies = {
711                 { AST_EVENT_IE_MODULE, SEC_EVT_FIELD(common, module) },
712                 { AST_EVENT_IE_SESSION_TV, SEC_EVT_FIELD(common, session_tv) },
713                 { AST_EVENT_IE_ACCOUNT_ID, SEC_EVT_FIELD(common, account_id) },
714                 { AST_EVENT_IE_REQUEST_PARAMS, SEC_EVT_FIELD(req_bad_format, request_params) },
715                 { AST_EVENT_IE_END, 0 }
716         },
717 },
718
719 [AST_SECURITY_EVENT_SUCCESSFUL_AUTH] = {
720         .name     = "SuccessfulAuth",
721         .version  = AST_SECURITY_EVENT_SUCCESSFUL_AUTH_VERSION,
722         .severity = AST_SECURITY_EVENT_SEVERITY_INFO,
723         .required_ies = {
724                 { AST_EVENT_IE_EVENT_TV, 0 },
725                 { AST_EVENT_IE_SEVERITY, 0 },
726                 { AST_EVENT_IE_SERVICE, SEC_EVT_FIELD(common, service) },
727                 { AST_EVENT_IE_EVENT_VERSION, SEC_EVT_FIELD(common, version) },
728                 { AST_EVENT_IE_ACCOUNT_ID, SEC_EVT_FIELD(common, account_id) },
729                 { AST_EVENT_IE_SESSION_ID, SEC_EVT_FIELD(common, session_id) },
730                 { AST_EVENT_IE_LOCAL_ADDR, SEC_EVT_FIELD(common, local_addr) },
731                 { AST_EVENT_IE_REMOTE_ADDR, SEC_EVT_FIELD(common, remote_addr) },
732                 { AST_EVENT_IE_USING_PASSWORD, SEC_EVT_FIELD(successful_auth, using_password) },
733                 { AST_EVENT_IE_END, 0 }
734         },
735         .optional_ies = {
736                 { AST_EVENT_IE_MODULE, SEC_EVT_FIELD(common, module) },
737                 { AST_EVENT_IE_SESSION_TV, SEC_EVT_FIELD(common, session_tv) },
738                 { AST_EVENT_IE_END, 0 }
739         },
740 },
741
742 [AST_SECURITY_EVENT_UNEXPECTED_ADDR] = {
743         .name     = "UnexpectedAddress",
744         .version  = AST_SECURITY_EVENT_UNEXPECTED_ADDR_VERSION,
745         .severity = AST_SECURITY_EVENT_SEVERITY_ERROR,
746         .required_ies = {
747                 { AST_EVENT_IE_EVENT_TV, 0 },
748                 { AST_EVENT_IE_SEVERITY, 0 },
749                 { AST_EVENT_IE_SERVICE, SEC_EVT_FIELD(common, service) },
750                 { AST_EVENT_IE_EVENT_VERSION, SEC_EVT_FIELD(common, version) },
751                 { AST_EVENT_IE_ACCOUNT_ID, SEC_EVT_FIELD(common, account_id) },
752                 { AST_EVENT_IE_SESSION_ID, SEC_EVT_FIELD(common, session_id) },
753                 { AST_EVENT_IE_LOCAL_ADDR, SEC_EVT_FIELD(common, local_addr) },
754                 { AST_EVENT_IE_REMOTE_ADDR, SEC_EVT_FIELD(common, remote_addr) },
755                 { AST_EVENT_IE_EXPECTED_ADDR, SEC_EVT_FIELD(unexpected_addr, expected_addr) },
756                 { AST_EVENT_IE_END, 0 }
757         },
758         .optional_ies = {
759                 { AST_EVENT_IE_MODULE, SEC_EVT_FIELD(common, module) },
760                 { AST_EVENT_IE_SESSION_TV, SEC_EVT_FIELD(common, session_tv) },
761                 { AST_EVENT_IE_END, 0 }
762         },
763 },
764
765 [AST_SECURITY_EVENT_CHAL_RESP_FAILED] = {
766         .name     = "ChallengeResponseFailed",
767         .version  = AST_SECURITY_EVENT_CHAL_RESP_FAILED_VERSION,
768         .severity = AST_SECURITY_EVENT_SEVERITY_ERROR,
769         .required_ies = {
770                 { AST_EVENT_IE_EVENT_TV, 0 },
771                 { AST_EVENT_IE_SEVERITY, 0 },
772                 { AST_EVENT_IE_SERVICE, SEC_EVT_FIELD(common, service) },
773                 { AST_EVENT_IE_EVENT_VERSION, SEC_EVT_FIELD(common, version) },
774                 { AST_EVENT_IE_ACCOUNT_ID, SEC_EVT_FIELD(common, account_id) },
775                 { AST_EVENT_IE_SESSION_ID, SEC_EVT_FIELD(common, session_id) },
776                 { AST_EVENT_IE_LOCAL_ADDR, SEC_EVT_FIELD(common, local_addr) },
777                 { AST_EVENT_IE_REMOTE_ADDR, SEC_EVT_FIELD(common, remote_addr) },
778                 { AST_EVENT_IE_CHALLENGE, SEC_EVT_FIELD(chal_resp_failed, challenge) },
779                 { AST_EVENT_IE_RESPONSE, SEC_EVT_FIELD(chal_resp_failed, response) },
780                 { AST_EVENT_IE_EXPECTED_RESPONSE, SEC_EVT_FIELD(chal_resp_failed, expected_response) },
781                 { AST_EVENT_IE_END, 0 }
782         },
783         .optional_ies = {
784                 { AST_EVENT_IE_MODULE, SEC_EVT_FIELD(common, module) },
785                 { AST_EVENT_IE_SESSION_TV, SEC_EVT_FIELD(common, session_tv) },
786                 { AST_EVENT_IE_END, 0 }
787         },
788 },
789
790 [AST_SECURITY_EVENT_INVAL_PASSWORD] = {
791         .name     = "InvalidPassword",
792         .version  = AST_SECURITY_EVENT_INVAL_PASSWORD_VERSION,
793         .severity = AST_SECURITY_EVENT_SEVERITY_ERROR,
794         .required_ies = {
795                 { AST_EVENT_IE_EVENT_TV, 0 },
796                 { AST_EVENT_IE_SEVERITY, 0 },
797                 { AST_EVENT_IE_SERVICE, SEC_EVT_FIELD(common, service) },
798                 { AST_EVENT_IE_EVENT_VERSION, SEC_EVT_FIELD(common, version) },
799                 { AST_EVENT_IE_ACCOUNT_ID, SEC_EVT_FIELD(common, account_id) },
800                 { AST_EVENT_IE_SESSION_ID, SEC_EVT_FIELD(common, session_id) },
801                 { AST_EVENT_IE_LOCAL_ADDR, SEC_EVT_FIELD(common, local_addr) },
802                 { AST_EVENT_IE_REMOTE_ADDR, SEC_EVT_FIELD(common, remote_addr) },
803                 { AST_EVENT_IE_END, 0 }
804         },
805         .optional_ies = {
806                 { AST_EVENT_IE_MODULE, SEC_EVT_FIELD(common, module) },
807                 { AST_EVENT_IE_SESSION_TV, SEC_EVT_FIELD(common, session_tv) },
808                 { AST_EVENT_IE_CHALLENGE, SEC_EVT_FIELD(inval_password, challenge) },
809                 { AST_EVENT_IE_RECEIVED_CHALLENGE, SEC_EVT_FIELD(inval_password, received_challenge) },
810                 { AST_EVENT_IE_RECEIVED_HASH, SEC_EVT_FIELD(inval_password, received_hash) },
811                 { AST_EVENT_IE_END, 0 }
812         },
813 },
814
815 [AST_SECURITY_EVENT_CHAL_SENT] = {
816         .name     = "ChallengeSent",
817         .version  = AST_SECURITY_EVENT_CHAL_SENT_VERSION,
818         .severity = AST_SECURITY_EVENT_SEVERITY_INFO,
819         .required_ies = {
820                 { AST_EVENT_IE_EVENT_TV, 0 },
821                 { AST_EVENT_IE_SEVERITY, 0 },
822                 { AST_EVENT_IE_SERVICE, SEC_EVT_FIELD(common, service) },
823                 { AST_EVENT_IE_EVENT_VERSION, SEC_EVT_FIELD(common, version) },
824                 { AST_EVENT_IE_ACCOUNT_ID, SEC_EVT_FIELD(common, account_id) },
825                 { AST_EVENT_IE_SESSION_ID, SEC_EVT_FIELD(common, session_id) },
826                 { AST_EVENT_IE_LOCAL_ADDR, SEC_EVT_FIELD(common, local_addr) },
827                 { AST_EVENT_IE_REMOTE_ADDR, SEC_EVT_FIELD(common, remote_addr) },
828                 { AST_EVENT_IE_CHALLENGE, SEC_EVT_FIELD(chal_sent, challenge) },
829                 { AST_EVENT_IE_END, 0 }
830         },
831         .optional_ies = {
832                 { AST_EVENT_IE_MODULE, SEC_EVT_FIELD(common, module) },
833                 { AST_EVENT_IE_SESSION_TV, SEC_EVT_FIELD(common, session_tv) },
834                 { AST_EVENT_IE_END, 0 }
835         },
836 },
837
838 [AST_SECURITY_EVENT_INVAL_TRANSPORT] = {
839         .name     = "InvalidTransport",
840         .version  = AST_SECURITY_EVENT_INVAL_TRANSPORT_VERSION,
841         .severity = AST_SECURITY_EVENT_SEVERITY_ERROR,
842         .required_ies = {
843                 { AST_EVENT_IE_EVENT_TV, 0 },
844                 { AST_EVENT_IE_SEVERITY, 0 },
845                 { AST_EVENT_IE_SERVICE, SEC_EVT_FIELD(common, service) },
846                 { AST_EVENT_IE_EVENT_VERSION, SEC_EVT_FIELD(common, version) },
847                 { AST_EVENT_IE_ACCOUNT_ID, SEC_EVT_FIELD(common, account_id) },
848                 { AST_EVENT_IE_SESSION_ID, SEC_EVT_FIELD(common, session_id) },
849                 { AST_EVENT_IE_LOCAL_ADDR, SEC_EVT_FIELD(common, local_addr) },
850                 { AST_EVENT_IE_REMOTE_ADDR, SEC_EVT_FIELD(common, remote_addr) },
851                 { AST_EVENT_IE_ATTEMPTED_TRANSPORT, SEC_EVT_FIELD(inval_transport, transport) },
852                 { AST_EVENT_IE_END, 0 }
853         },
854         .optional_ies = {
855                 { AST_EVENT_IE_MODULE, SEC_EVT_FIELD(common, module) },
856                 { AST_EVENT_IE_SESSION_TV, SEC_EVT_FIELD(common, session_tv) },
857                 { AST_EVENT_IE_END, 0 }
858         },
859 },
860
861 #undef SEC_EVT_FIELD
862
863 };
864
865 static const struct {
866         enum ast_security_event_severity severity;
867         const char *str;
868 } severities[] = {
869         { AST_SECURITY_EVENT_SEVERITY_INFO,  "Informational" },
870         { AST_SECURITY_EVENT_SEVERITY_ERROR, "Error" },
871 };
872
873 const char *ast_security_event_severity_get_name(
874                 const enum ast_security_event_severity severity)
875 {
876         unsigned int i;
877
878         for (i = 0; i < ARRAY_LEN(severities); i++) {
879                 if (severities[i].severity == severity) {
880                         return severities[i].str;
881                 }
882         }
883
884         return NULL;
885 }
886
887 static int check_event_type(const enum ast_security_event_type event_type)
888 {
889         if (event_type >= AST_SECURITY_EVENT_NUM_TYPES) {
890                 ast_log(LOG_ERROR, "Invalid security event type %u\n", event_type);
891                 return -1;
892         }
893
894         return 0;
895 }
896
897 const char *ast_security_event_get_name(const enum ast_security_event_type event_type)
898 {
899         if (check_event_type(event_type)) {
900                 return NULL;
901         }
902
903         return sec_events[event_type].name;
904 }
905
906 const struct ast_security_event_ie_type *ast_security_event_get_required_ies(
907                 const enum ast_security_event_type event_type)
908 {
909         if (check_event_type(event_type)) {
910                 return NULL;
911         }
912
913         return sec_events[event_type].required_ies;
914 }
915
916 const struct ast_security_event_ie_type *ast_security_event_get_optional_ies(
917                 const enum ast_security_event_type event_type)
918 {
919         if (check_event_type(event_type)) {
920                 return NULL;
921         }
922
923         return sec_events[event_type].optional_ies;
924 }
925
926 static int add_ip_json_object(struct ast_json *json, enum ast_event_ie_type ie_type,
927                 const struct ast_security_event_ip_addr *addr)
928 {
929         struct ast_json *json_ip;
930
931         json_ip = ast_json_ipaddr(addr->addr, addr->transport);
932         if (!json_ip) {
933                 return -1;
934         }
935
936         return ast_json_object_set(json, ast_event_get_ie_type_name(ie_type), json_ip);
937 }
938
939 enum ie_required {
940         NOT_REQUIRED,
941         REQUIRED
942 };
943
944 static int add_json_object(struct ast_json *json, const struct ast_security_event_common *sec,
945                 const struct ast_security_event_ie_type *ie_type, enum ie_required req)
946 {
947         int res = 0;
948
949         switch (ie_type->ie_type) {
950         case AST_EVENT_IE_SERVICE:
951         case AST_EVENT_IE_ACCOUNT_ID:
952         case AST_EVENT_IE_SESSION_ID:
953         case AST_EVENT_IE_MODULE:
954         case AST_EVENT_IE_ACL_NAME:
955         case AST_EVENT_IE_REQUEST_TYPE:
956         case AST_EVENT_IE_REQUEST_PARAMS:
957         case AST_EVENT_IE_AUTH_METHOD:
958         case AST_EVENT_IE_CHALLENGE:
959         case AST_EVENT_IE_RESPONSE:
960         case AST_EVENT_IE_EXPECTED_RESPONSE:
961         case AST_EVENT_IE_RECEIVED_CHALLENGE:
962         case AST_EVENT_IE_RECEIVED_HASH:
963         case AST_EVENT_IE_ATTEMPTED_TRANSPORT:
964         {
965                 const char *str;
966                 struct ast_json *json_string;
967
968                 str = *((const char **)(((const char *) sec) + ie_type->offset));
969
970                 if (req && !str) {
971                         ast_log(LOG_WARNING, "Required IE '%d' (%s) for security event "
972                                         "type '%u' (%s) not present\n", ie_type->ie_type,
973                                         ast_event_get_ie_type_name(ie_type->ie_type),
974                                         sec->event_type, ast_security_event_get_name(sec->event_type));
975                         res = -1;
976                         break;
977                 }
978
979                 if (!str) {
980                         break;
981                 }
982
983                 json_string = ast_json_string_create(str);
984                 if (!json_string) {
985                         res = -1;
986                         break;
987                 }
988
989                 res = ast_json_object_set(json, ast_event_get_ie_type_name(ie_type->ie_type), json_string);
990                 break;
991         }
992         case AST_EVENT_IE_EVENT_VERSION:
993         case AST_EVENT_IE_USING_PASSWORD:
994         {
995                 struct ast_json *json_string;
996                 uint32_t val;
997                 val = *((const uint32_t *)(((const char *) sec) + ie_type->offset));
998
999                 json_string = ast_json_stringf("%u", val);
1000                 if (!json_string) {
1001                         res = -1;
1002                         break;
1003                 }
1004
1005                 res = ast_json_object_set(json, ast_event_get_ie_type_name(ie_type->ie_type), json_string);
1006                 break;
1007         }
1008         case AST_EVENT_IE_LOCAL_ADDR:
1009         case AST_EVENT_IE_REMOTE_ADDR:
1010         case AST_EVENT_IE_EXPECTED_ADDR:
1011         {
1012                 const struct ast_security_event_ip_addr *addr;
1013
1014                 addr = (const struct ast_security_event_ip_addr *)(((const char *) sec) + ie_type->offset);
1015
1016                 if (req && !addr->addr) {
1017                         ast_log(LOG_WARNING, "Required IE '%d' (%s) for security event "
1018                                         "type '%u' (%s) not present\n", ie_type->ie_type,
1019                                         ast_event_get_ie_type_name(ie_type->ie_type),
1020                                         sec->event_type, ast_security_event_get_name(sec->event_type));
1021                         res = -1;
1022                 }
1023
1024                 if (addr->addr) {
1025                         res = add_ip_json_object(json, ie_type->ie_type, addr);
1026                 }
1027
1028                 break;
1029         }
1030         case AST_EVENT_IE_SESSION_TV:
1031         {
1032                 const struct timeval *tval;
1033
1034                 tval = *((const struct timeval **)(((const char *) sec) + ie_type->offset));
1035
1036                 if (req && !tval) {
1037                         ast_log(LOG_WARNING, "Required IE '%d' (%s) for security event "
1038                                         "type '%u' (%s) not present\n", ie_type->ie_type,
1039                                         ast_event_get_ie_type_name(ie_type->ie_type),
1040                                         sec->event_type, ast_security_event_get_name(sec->event_type));
1041                         res = -1;
1042                 }
1043
1044                 if (tval) {
1045                         struct ast_json *json_tval = ast_json_timeval(*tval, NULL);
1046                         if (!json_tval) {
1047                                 res = -1;
1048                                 break;
1049                         }
1050                         res = ast_json_object_set(json, ast_event_get_ie_type_name(ie_type->ie_type), json_tval);
1051                 }
1052
1053                 break;
1054         }
1055         case AST_EVENT_IE_EVENT_TV:
1056         case AST_EVENT_IE_SEVERITY:
1057                 /* Added automatically, nothing to do here. */
1058                 break;
1059         default:
1060                 ast_log(LOG_WARNING, "Unhandled IE type '%d' (%s), this security event "
1061                                 "will be missing data.\n", ie_type->ie_type,
1062                                 ast_event_get_ie_type_name(ie_type->ie_type));
1063                 break;
1064         }
1065
1066         return res;
1067 }
1068
1069 static struct ast_json *alloc_security_event_json_object(const struct ast_security_event_common *sec)
1070 {
1071         struct timeval tv = ast_tvnow();
1072         const char *severity_str;
1073         struct ast_json *json_temp;
1074         RAII_VAR(struct ast_json *, json_object, ast_json_object_create(), ast_json_unref);
1075
1076         if (!json_object) {
1077                 return NULL;
1078         }
1079
1080         /* NOTE: Every time ast_json_object_set is used, json_temp becomes a stale pointer since the reference is taken.
1081          *       This is true even if ast_json_object_set fails.
1082          */
1083
1084         json_temp = ast_json_integer_create(sec->event_type);
1085         if (!json_temp || ast_json_object_set(json_object, "SecurityEvent", json_temp)) {
1086                 return NULL;
1087         }
1088
1089         json_temp = ast_json_stringf("%u", sec->version);
1090         if (!json_temp || ast_json_object_set(json_object, ast_event_get_ie_type_name(AST_EVENT_IE_EVENT_VERSION), json_temp)) {
1091                 return NULL;
1092         }
1093
1094         /* AST_EVENT_IE_EVENT_TV */
1095         json_temp  = ast_json_timeval(tv, NULL);
1096         if (!json_temp || ast_json_object_set(json_object, ast_event_get_ie_type_name(AST_EVENT_IE_EVENT_TV), json_temp)) {
1097                 return NULL;
1098         }
1099
1100         /* AST_EVENT_IE_SERVICE */
1101         json_temp = ast_json_string_create(sec->service);
1102         if (!json_temp || ast_json_object_set(json_object, ast_event_get_ie_type_name(AST_EVENT_IE_SERVICE), json_temp)) {
1103                 return NULL;
1104         }
1105
1106         /* AST_EVENT_IE_SEVERITY */
1107         severity_str = S_OR(
1108                 ast_security_event_severity_get_name(sec_events[sec->event_type].severity),
1109                 "Unknown"
1110         );
1111
1112         json_temp = ast_json_string_create(severity_str);
1113         if (!json_temp || ast_json_object_set(json_object, ast_event_get_ie_type_name(AST_EVENT_IE_SEVERITY), json_temp)) {
1114                 return NULL;
1115         }
1116
1117         return ast_json_ref(json_object);
1118 }
1119
1120 static int handle_security_event(const struct ast_security_event_common *sec)
1121 {
1122         RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
1123         RAII_VAR(struct ast_json_payload *, json_payload, NULL, ao2_cleanup);
1124         RAII_VAR(struct ast_json *, json_object, NULL, ast_json_unref);
1125
1126         const struct ast_security_event_ie_type *ies;
1127         unsigned int i;
1128
1129         if (!ast_security_event_type()) {
1130                 return -1;
1131         }
1132
1133         json_object = alloc_security_event_json_object(sec);
1134         if (!json_object) {
1135                 return -1;
1136         }
1137
1138         for (ies = ast_security_event_get_required_ies(sec->event_type), i = 0;
1139                         ies[i].ie_type != AST_EVENT_IE_END;
1140                         i++) {
1141                 if (add_json_object(json_object, sec, ies + i, REQUIRED)) {
1142                         goto return_error;
1143                 }
1144         }
1145
1146         for (ies = ast_security_event_get_optional_ies(sec->event_type), i = 0;
1147                         ies[i].ie_type != AST_EVENT_IE_END;
1148                         i++) {
1149                 if (add_json_object(json_object, sec, ies + i, NOT_REQUIRED)) {
1150                         goto return_error;
1151                 }
1152         }
1153
1154         /* The json blob is ready.  Throw it in the payload and send it out over stasis. */
1155         if (!(json_payload = ast_json_payload_create(json_object))) {
1156                 goto return_error;
1157         }
1158
1159         msg = stasis_message_create(ast_security_event_type(), json_payload);
1160
1161         if (!msg) {
1162                 goto return_error;
1163         }
1164
1165         stasis_publish(ast_security_topic(), msg);
1166
1167         return 0;
1168
1169 return_error:
1170         return -1;
1171 }
1172
1173 int ast_security_event_report(const struct ast_security_event_common *sec)
1174 {
1175         if (sec->event_type >= AST_SECURITY_EVENT_NUM_TYPES) {
1176                 ast_log(LOG_ERROR, "Invalid security event type\n");
1177                 return -1;
1178         }
1179
1180         if (!sec_events[sec->event_type].name) {
1181                 ast_log(LOG_WARNING, "Security event type %u not handled\n",
1182                                 sec->event_type);
1183                 return -1;
1184         }
1185
1186         if (sec->version != sec_events[sec->event_type].version) {
1187                 ast_log(LOG_WARNING, "Security event %u version mismatch\n",
1188                                 sec->event_type);
1189                 return -1;
1190         }
1191
1192         if (handle_security_event(sec)) {
1193                 ast_log(LOG_ERROR, "Failed to issue security event of type %s.\n",
1194                                 ast_security_event_get_name(sec->event_type));
1195         }
1196
1197         return 0;
1198 }
1199
1200