a493af346abbe056ed77401bde1c297a283b2f24
[asterisk/asterisk.git] / main / manager.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 1999 - 2006, Digium, Inc.
5  *
6  * Mark Spencer <markster@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  * \brief The Asterisk Management Interface - AMI
22  *
23  * \author Mark Spencer <markster@digium.com>
24  *
25  * OpenSSL http://www.openssl.org - for AMI/SSL
26  *
27  * At the moment this file contains a number of functions, namely:
28  *
29  * - data structures storing AMI state
30  * - AMI-related API functions, used by internal asterisk components
31  * - handlers for AMI-related CLI functions
32  * - handlers for AMI functions (available through the AMI socket)
33  * - the code for the main AMI listener thread and individual session threads
34  * - the http handlers invoked for AMI-over-HTTP by the threads in main/http.c
35  *
36  * \ref amiconf
37  */
38
39 /*!
40  * \li The core Manager uses the configuration file \ref manager.conf
41  * \addtogroup configuration_file
42  */
43
44 /*! \page manager.conf manager.conf
45  * \verbinclude manager.conf.sample
46  */
47
48 /*** MODULEINFO
49         <support_level>core</support_level>
50  ***/
51
52 #include "asterisk.h"
53
54 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
55
56 #include "asterisk/_private.h"
57 #include "asterisk/paths.h"     /* use various ast_config_AST_* */
58 #include <ctype.h>
59 #include <sys/time.h>
60 #include <signal.h>
61 #include <sys/mman.h>
62 #include <sys/types.h>
63 #include <regex.h>
64
65 #include "asterisk/channel.h"
66 #include "asterisk/file.h"
67 #include "asterisk/manager.h"
68 #include "asterisk/module.h"
69 #include "asterisk/config.h"
70 #include "asterisk/callerid.h"
71 #include "asterisk/lock.h"
72 #include "asterisk/cli.h"
73 #include "asterisk/app.h"
74 #include "asterisk/pbx.h"
75 #include "asterisk/md5.h"
76 #include "asterisk/acl.h"
77 #include "asterisk/utils.h"
78 #include "asterisk/tcptls.h"
79 #include "asterisk/http.h"
80 #include "asterisk/ast_version.h"
81 #include "asterisk/threadstorage.h"
82 #include "asterisk/linkedlists.h"
83 #include "asterisk/term.h"
84 #include "asterisk/astobj2.h"
85 #include "asterisk/features.h"
86 #include "asterisk/security_events.h"
87 #include "asterisk/event.h"
88 #include "asterisk/aoc.h"
89 #include "asterisk/stringfields.h"
90 #include "asterisk/presencestate.h"
91
92 /*** DOCUMENTATION
93         <manager name="Ping" language="en_US">
94                 <synopsis>
95                         Keepalive command.
96                 </synopsis>
97                 <syntax>
98                         <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
99                 </syntax>
100                 <description>
101                         <para>A 'Ping' action will ellicit a 'Pong' response. Used to keep the
102                         manager connection open.</para>
103                 </description>
104         </manager>
105         <manager name="Events" language="en_US">
106                 <synopsis>
107                         Control Event Flow.
108                 </synopsis>
109                 <syntax>
110                         <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
111                         <parameter name="EventMask" required="true">
112                                 <enumlist>
113                                         <enum name="on">
114                                                 <para>If all events should be sent.</para>
115                                         </enum>
116                                         <enum name="off">
117                                                 <para>If no events should be sent.</para>
118                                         </enum>
119                                         <enum name="system,call,log,...">
120                                                 <para>To select which flags events should have to be sent.</para>
121                                         </enum>
122                                 </enumlist>
123                         </parameter>
124                 </syntax>
125                 <description>
126                         <para>Enable/Disable sending of events to this manager client.</para>
127                 </description>
128         </manager>
129         <manager name="Logoff" language="en_US">
130                 <synopsis>
131                         Logoff Manager.
132                 </synopsis>
133                 <syntax>
134                         <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
135                 </syntax>
136                 <description>
137                         <para>Logoff the current manager session.</para>
138                 </description>
139         </manager>
140         <manager name="Login" language="en_US">
141                 <synopsis>
142                         Login Manager.
143                 </synopsis>
144                 <syntax>
145                         <parameter name="ActionID">
146                                 <para>ActionID for this transaction. Will be returned.</para>
147                         </parameter>
148                         <parameter name="Username" required="true">
149                                 <para>Username to login with as specified in manager.conf.</para>
150                         </parameter>
151                         <parameter name="Secret">
152                                 <para>Secret to login with as specified in manager.conf.</para>
153                         </parameter>
154                 </syntax>
155                 <description>
156                         <para>Login Manager.</para>
157                 </description>
158         </manager>
159         <manager name="Challenge" language="en_US">
160                 <synopsis>
161                         Generate Challenge for MD5 Auth.
162                 </synopsis>
163                 <syntax>
164                         <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
165                         <parameter name="AuthType" required="true">
166                                 <para>Digest algorithm to use in the challenge. Valid values are:</para>
167                                 <enumlist>
168                                         <enum name="MD5" />
169                                 </enumlist>
170                         </parameter>
171                 </syntax>
172                 <description>
173                         <para>Generate a challenge for MD5 authentication.</para>
174                 </description>
175         </manager>
176         <manager name="Hangup" language="en_US">
177                 <synopsis>
178                         Hangup channel.
179                 </synopsis>
180                 <syntax>
181                         <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
182                         <parameter name="Channel" required="true">
183                                 <para>The exact channel name to be hungup, or to use a regular expression, set this parameter to: /regex/</para>
184                                 <para>Example exact channel: SIP/provider-0000012a</para>
185                                 <para>Example regular expression: /^SIP/provider-.*$/</para>
186                         </parameter>
187                         <parameter name="Cause">
188                                 <para>Numeric hangup cause.</para>
189                         </parameter>
190                 </syntax>
191                 <description>
192                         <para>Hangup a channel.</para>
193                 </description>
194         </manager>
195         <manager name="Status" language="en_US">
196                 <synopsis>
197                         List channel status.
198                 </synopsis>
199                 <syntax>
200                         <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
201                         <parameter name="Channel" required="true">
202                                 <para>The name of the channel to query for status.</para>
203                         </parameter>
204                         <parameter name="Variables">
205                                 <para>Comma <literal>,</literal> separated list of variable to include.</para>
206                         </parameter>
207                 </syntax>
208                 <description>
209                         <para>Will return the status information of each channel along with the
210                         value for the specified channel variables.</para>
211                 </description>
212         </manager>
213         <manager name="Setvar" language="en_US">
214                 <synopsis>
215                         Set a channel variable.
216                 </synopsis>
217                 <syntax>
218                         <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
219                         <parameter name="Channel">
220                                 <para>Channel to set variable for.</para>
221                         </parameter>
222                         <parameter name="Variable" required="true">
223                                 <para>Variable name.</para>
224                         </parameter>
225                         <parameter name="Value" required="true">
226                                 <para>Variable value.</para>
227                         </parameter>
228                 </syntax>
229                 <description>
230                         <para>Set a global or local channel variable.</para>
231                         <note>
232                                 <para>If a channel name is not provided then the variable is global.</para>
233                         </note>
234                 </description>
235         </manager>
236         <manager name="Getvar" language="en_US">
237                 <synopsis>
238                         Gets a channel variable.
239                 </synopsis>
240                 <syntax>
241                         <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
242                         <parameter name="Channel">
243                                 <para>Channel to read variable from.</para>
244                         </parameter>
245                         <parameter name="Variable" required="true">
246                                 <para>Variable name.</para>
247                         </parameter>
248                 </syntax>
249                 <description>
250                         <para>Get the value of a global or local channel variable.</para>
251                         <note>
252                                 <para>If a channel name is not provided then the variable is global.</para>
253                         </note>
254                 </description>
255         </manager>
256         <manager name="GetConfig" language="en_US">
257                 <synopsis>
258                         Retrieve configuration.
259                 </synopsis>
260                 <syntax>
261                         <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
262                         <parameter name="Filename" required="true">
263                                 <para>Configuration filename (e.g. <filename>foo.conf</filename>).</para>
264                         </parameter>
265                         <parameter name="Category">
266                                 <para>Category in configuration file.</para>
267                         </parameter>
268                 </syntax>
269                 <description>
270                         <para>This action will dump the contents of a configuration
271                         file by category and contents or optionally by specified category only.</para>
272                 </description>
273         </manager>
274         <manager name="GetConfigJSON" language="en_US">
275                 <synopsis>
276                         Retrieve configuration (JSON format).
277                 </synopsis>
278                 <syntax>
279                         <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
280                         <parameter name="Filename" required="true">
281                                 <para>Configuration filename (e.g. <filename>foo.conf</filename>).</para>
282                         </parameter>
283                 </syntax>
284                 <description>
285                         <para>This action will dump the contents of a configuration file by category
286                         and contents in JSON format. This only makes sense to be used using rawman over
287                         the HTTP interface.</para>
288                 </description>
289         </manager>
290         <manager name="UpdateConfig" language="en_US">
291                 <synopsis>
292                         Update basic configuration.
293                 </synopsis>
294                 <syntax>
295                         <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
296                         <parameter name="SrcFilename" required="true">
297                                 <para>Configuration filename to read (e.g. <filename>foo.conf</filename>).</para>
298                         </parameter>
299                         <parameter name="DstFilename" required="true">
300                                 <para>Configuration filename to write (e.g. <filename>foo.conf</filename>)</para>
301                         </parameter>
302                         <parameter name="Reload">
303                                 <para>Whether or not a reload should take place (or name of specific module).</para>
304                         </parameter>
305                         <parameter name="Action-XXXXXX">
306                                 <para>Action to take.</para>
307                                 <para>X's represent 6 digit number beginning with 000000.</para>
308                                 <enumlist>
309                                         <enum name="NewCat" />
310                                         <enum name="RenameCat" />
311                                         <enum name="DelCat" />
312                                         <enum name="EmptyCat" />
313                                         <enum name="Update" />
314                                         <enum name="Delete" />
315                                         <enum name="Append" />
316                                         <enum name="Insert" />
317                                 </enumlist>
318                         </parameter>
319                         <parameter name="Cat-XXXXXX">
320                                 <para>Category to operate on.</para>
321                                 <xi:include xpointer="xpointer(/docs/manager[@name='UpdateConfig']/syntax/parameter[@name='Action-XXXXXX']/para[2])" />
322                         </parameter>
323                         <parameter name="Var-XXXXXX">
324                                 <para>Variable to work on.</para>
325                                 <xi:include xpointer="xpointer(/docs/manager[@name='UpdateConfig']/syntax/parameter[@name='Action-XXXXXX']/para[2])" />
326                         </parameter>
327                         <parameter name="Value-XXXXXX">
328                                 <para>Value to work on.</para>
329                                 <xi:include xpointer="xpointer(/docs/manager[@name='UpdateConfig']/syntax/parameter[@name='Action-XXXXXX']/para[2])" />
330                         </parameter>
331                         <parameter name="Match-XXXXXX">
332                                 <para>Extra match required to match line.</para>
333                                 <xi:include xpointer="xpointer(/docs/manager[@name='UpdateConfig']/syntax/parameter[@name='Action-XXXXXX']/para[2])" />
334                         </parameter>
335                         <parameter name="Line-XXXXXX">
336                                 <para>Line in category to operate on (used with delete and insert actions).</para>
337                                 <xi:include xpointer="xpointer(/docs/manager[@name='UpdateConfig']/syntax/parameter[@name='Action-XXXXXX']/para[2])" />
338                         </parameter>
339                 </syntax>
340                 <description>
341                         <para>This action will modify, create, or delete configuration elements
342                         in Asterisk configuration files.</para>
343                 </description>
344         </manager>
345         <manager name="CreateConfig" language="en_US">
346                 <synopsis>
347                         Creates an empty file in the configuration directory.
348                 </synopsis>
349                 <syntax>
350                         <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
351                         <parameter name="Filename" required="true">
352                                 <para>The configuration filename to create (e.g. <filename>foo.conf</filename>).</para>
353                         </parameter>
354                 </syntax>
355                 <description>
356                         <para>This action will create an empty file in the configuration
357                         directory. This action is intended to be used before an UpdateConfig
358                         action.</para>
359                 </description>
360         </manager>
361         <manager name="ListCategories" language="en_US">
362                 <synopsis>
363                         List categories in configuration file.
364                 </synopsis>
365                 <syntax>
366                         <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
367                         <parameter name="Filename" required="true">
368                                 <para>Configuration filename (e.g. <filename>foo.conf</filename>).</para>
369                         </parameter>
370                 </syntax>
371                 <description>
372                         <para>This action will dump the categories in a given file.</para>
373                 </description>
374         </manager>
375         <manager name="Redirect" language="en_US">
376                 <synopsis>
377                         Redirect (transfer) a call.
378                 </synopsis>
379                 <syntax>
380                         <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
381                         <parameter name="Channel" required="true">
382                                 <para>Channel to redirect.</para>
383                         </parameter>
384                         <parameter name="ExtraChannel">
385                                 <para>Second call leg to transfer (optional).</para>
386                         </parameter>
387                         <parameter name="Exten" required="true">
388                                 <para>Extension to transfer to.</para>
389                         </parameter>
390                         <parameter name="ExtraExten">
391                                 <para>Extension to transfer extrachannel to (optional).</para>
392                         </parameter>
393                         <parameter name="Context" required="true">
394                                 <para>Context to transfer to.</para>
395                         </parameter>
396                         <parameter name="ExtraContext">
397                                 <para>Context to transfer extrachannel to (optional).</para>
398                         </parameter>
399                         <parameter name="Priority" required="true">
400                                 <para>Priority to transfer to.</para>
401                         </parameter>
402                         <parameter name="ExtraPriority">
403                                 <para>Priority to transfer extrachannel to (optional).</para>
404                         </parameter>
405                 </syntax>
406                 <description>
407                         <para>Redirect (transfer) a call.</para>
408                 </description>
409         </manager>
410         <manager name="Atxfer" language="en_US">
411                 <synopsis>
412                         Attended transfer.
413                 </synopsis>
414                 <syntax>
415                         <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
416                         <parameter name="Channel" required="true">
417                                 <para>Transferer's channel.</para>
418                         </parameter>
419                         <parameter name="Exten" required="true">
420                                 <para>Extension to transfer to.</para>
421                         </parameter>
422                         <parameter name="Context" required="true">
423                                 <para>Context to transfer to.</para>
424                         </parameter>
425                         <parameter name="Priority" required="true">
426                                 <para>Priority to transfer to.</para>
427                         </parameter>
428                 </syntax>
429                 <description>
430                         <para>Attended transfer.</para>
431                 </description>
432         </manager>
433         <manager name="Originate" language="en_US">
434                 <synopsis>
435                         Originate a call.
436                 </synopsis>
437                 <syntax>
438                         <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
439                         <parameter name="Channel" required="true">
440                                 <para>Channel name to call.</para>
441                         </parameter>
442                         <parameter name="Exten">
443                                 <para>Extension to use (requires <literal>Context</literal> and
444                                 <literal>Priority</literal>)</para>
445                         </parameter>
446                         <parameter name="Context">
447                                 <para>Context to use (requires <literal>Exten</literal> and
448                                 <literal>Priority</literal>)</para>
449                         </parameter>
450                         <parameter name="Priority">
451                                 <para>Priority to use (requires <literal>Exten</literal> and
452                                 <literal>Context</literal>)</para>
453                         </parameter>
454                         <parameter name="Application">
455                                 <para>Application to execute.</para>
456                         </parameter>
457                         <parameter name="Data">
458                                 <para>Data to use (requires <literal>Application</literal>).</para>
459                         </parameter>
460                         <parameter name="Timeout" default="30000">
461                                 <para>How long to wait for call to be answered (in ms.).</para>
462                         </parameter>
463                         <parameter name="CallerID">
464                                 <para>Caller ID to be set on the outgoing channel.</para>
465                         </parameter>
466                         <parameter name="Variable">
467                                 <para>Channel variable to set, multiple Variable: headers are allowed.</para>
468                         </parameter>
469                         <parameter name="Account">
470                                 <para>Account code.</para>
471                         </parameter>
472                         <parameter name="EarlyMedia">
473                                 <para>Set to <literal>true</literal> to force call bridge on early media..</para>
474                         </parameter>
475                         <parameter name="Async">
476                                 <para>Set to <literal>true</literal> for fast origination.</para>
477                         </parameter>
478                         <parameter name="Codecs">
479                                 <para>Comma-separated list of codecs to use for this call.</para>
480                         </parameter>
481                 </syntax>
482                 <description>
483                         <para>Generates an outgoing call to a
484                         <replaceable>Extension</replaceable>/<replaceable>Context</replaceable>/<replaceable>Priority</replaceable>
485                         or <replaceable>Application</replaceable>/<replaceable>Data</replaceable></para>
486                 </description>
487                 <see-also>
488                         <ref type="managerEvent">OriginateResponse</ref>
489                 </see-also>
490         </manager>
491         <managerEvent language="en_US" name="OriginateResponse">
492                 <managerEventInstance class="EVENT_FLAG_CALL">
493                         <synopsis>Raised in response to an Originate command.</synopsis>
494                         <syntax>
495                                 <parameter name="ActionID" required="false"/>
496                                 <parameter name="Resonse">
497                                         <enumlist>
498                                                 <enum name="Failure"/>
499                                                 <enum name="Success"/>
500                                         </enumlist>
501                                 </parameter>
502                                 <parameter name="Channel"/>
503                                 <parameter name="Context"/>
504                                 <parameter name="Exten"/>
505                                 <parameter name="Reason"/>
506                                 <parameter name="Uniqueid"/>
507                                 <parameter name="CallerIDNum"/>
508                                 <parameter name="CallerIDName"/>
509                         </syntax>
510                         <see-also>
511                                 <ref type="manager">Originate</ref>
512                         </see-also>
513                 </managerEventInstance>
514         </managerEvent>
515         <manager name="Command" language="en_US">
516                 <synopsis>
517                         Execute Asterisk CLI Command.
518                 </synopsis>
519                 <syntax>
520                         <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
521                         <parameter name="Command" required="true">
522                                 <para>Asterisk CLI command to run.</para>
523                         </parameter>
524                 </syntax>
525                 <description>
526                         <para>Run a CLI command.</para>
527                 </description>
528         </manager>
529         <manager name="ExtensionState" language="en_US">
530                 <synopsis>
531                         Check Extension Status.
532                 </synopsis>
533                 <syntax>
534                         <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
535                         <parameter name="Exten" required="true">
536                                 <para>Extension to check state on.</para>
537                         </parameter>
538                         <parameter name="Context" required="true">
539                                 <para>Context for extension.</para>
540                         </parameter>
541                 </syntax>
542                 <description>
543                         <para>Report the extension state for given extension. If the extension has a hint,
544                         will use devicestate to check the status of the device connected to the extension.</para>
545                         <para>Will return an <literal>Extension Status</literal> message. The response will include
546                         the hint for the extension and the status.</para>
547                 </description>
548         </manager>
549         <manager name="PresenceState" language="en_US">
550                 <synopsis>
551                         Check Presence State
552                 </synopsis>
553                 <syntax>
554                         <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
555                         <parameter name="Provider" required="true">
556                                 <para>Presence Provider to check the state of</para>
557                         </parameter>
558                 </syntax>
559                 <description>
560                         <para>Report the presence state for the given presence provider.</para>
561                         <para>Will return a <literal>Presence State</literal> message. The response will include the
562                         presence state and, if set, a presence subtype and custom message.</para>
563                 </description>
564         </manager>
565         <manager name="AbsoluteTimeout" language="en_US">
566                 <synopsis>
567                         Set absolute timeout.
568                 </synopsis>
569                 <syntax>
570                         <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
571                         <parameter name="Channel" required="true">
572                                 <para>Channel name to hangup.</para>
573                         </parameter>
574                         <parameter name="Timeout" required="true">
575                                 <para>Maximum duration of the call (sec).</para>
576                         </parameter>
577                 </syntax>
578                 <description>
579                         <para>Hangup a channel after a certain time. Acknowledges set time with
580                         <literal>Timeout Set</literal> message.</para>
581                 </description>
582         </manager>
583         <manager name="MailboxStatus" language="en_US">
584                 <synopsis>
585                         Check mailbox.
586                 </synopsis>
587                 <syntax>
588                         <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
589                         <parameter name="Mailbox" required="true">
590                                 <para>Full mailbox ID <replaceable>mailbox</replaceable>@<replaceable>vm-context</replaceable>.</para>
591                         </parameter>
592                 </syntax>
593                 <description>
594                         <para>Checks a voicemail account for status.</para>
595                         <para>Returns number of messages.</para>
596                         <para>Message: Mailbox Status.</para>
597                         <para>Mailbox: <replaceable>mailboxid</replaceable>.</para>
598                         <para>Waiting: <literal>0</literal> if messages waiting, <literal>1</literal>
599                         if no messages waiting.</para>
600                 </description>
601         </manager>
602         <manager name="MailboxCount" language="en_US">
603                 <synopsis>
604                         Check Mailbox Message Count.
605                 </synopsis>
606                 <syntax>
607                         <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
608                         <parameter name="Mailbox" required="true">
609                                 <para>Full mailbox ID <replaceable>mailbox</replaceable>@<replaceable>vm-context</replaceable>.</para>
610                         </parameter>
611                 </syntax>
612                 <description>
613                         <para>Checks a voicemail account for new messages.</para>
614                         <para>Returns number of urgent, new and old messages.</para>
615                         <para>Message: Mailbox Message Count</para>
616                         <para>Mailbox: <replaceable>mailboxid</replaceable></para>
617                         <para>UrgentMessages: <replaceable>count</replaceable></para>
618                         <para>NewMessages: <replaceable>count</replaceable></para>
619                         <para>OldMessages: <replaceable>count</replaceable></para>
620                 </description>
621         </manager>
622         <manager name="ListCommands" language="en_US">
623                 <synopsis>
624                         List available manager commands.
625                 </synopsis>
626                 <syntax>
627                         <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
628                 </syntax>
629                 <description>
630                         <para>Returns the action name and synopsis for every action that
631                         is available to the user.</para>
632                 </description>
633         </manager>
634         <manager name="SendText" language="en_US">
635                 <synopsis>
636                         Send text message to channel.
637                 </synopsis>
638                 <syntax>
639                         <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
640                         <parameter name="Channel" required="true">
641                                 <para>Channel to send message to.</para>
642                         </parameter>
643                         <parameter name="Message" required="true">
644                                 <para>Message to send.</para>
645                         </parameter>
646                 </syntax>
647                 <description>
648                         <para>Sends A Text Message to a channel while in a call.</para>
649                 </description>
650         </manager>
651         <manager name="UserEvent" language="en_US">
652                 <synopsis>
653                         Send an arbitrary event.
654                 </synopsis>
655                 <syntax>
656                         <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
657                         <parameter name="UserEvent" required="true">
658                                 <para>Event string to send.</para>
659                         </parameter>
660                         <parameter name="Header1">
661                                 <para>Content1.</para>
662                         </parameter>
663                         <parameter name="HeaderN">
664                                 <para>ContentN.</para>
665                         </parameter>
666                 </syntax>
667                 <description>
668                         <para>Send an event to manager sessions.</para>
669                 </description>
670         </manager>
671         <manager name="WaitEvent" language="en_US">
672                 <synopsis>
673                         Wait for an event to occur.
674                 </synopsis>
675                 <syntax>
676                         <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
677                         <parameter name="Timeout" required="true">
678                                 <para>Maximum time (in seconds) to wait for events, <literal>-1</literal> means forever.</para>
679                         </parameter>
680                 </syntax>
681                 <description>
682                         <para>This action will ellicit a <literal>Success</literal> response. Whenever
683                         a manager event is queued. Once WaitEvent has been called on an HTTP manager
684                         session, events will be generated and queued.</para>
685                 </description>
686         </manager>
687         <manager name="CoreSettings" language="en_US">
688                 <synopsis>
689                         Show PBX core settings (version etc).
690                 </synopsis>
691                 <syntax>
692                         <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
693                 </syntax>
694                 <description>
695                         <para>Query for Core PBX settings.</para>
696                 </description>
697         </manager>
698         <manager name="CoreStatus" language="en_US">
699                 <synopsis>
700                         Show PBX core status variables.
701                 </synopsis>
702                 <syntax>
703                         <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
704                 </syntax>
705                 <description>
706                         <para>Query for Core PBX status.</para>
707                 </description>
708         </manager>
709         <manager name="Reload" language="en_US">
710                 <synopsis>
711                         Send a reload event.
712                 </synopsis>
713                 <syntax>
714                         <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
715                         <parameter name="Module">
716                                 <para>Name of the module to reload.</para>
717                         </parameter>
718                 </syntax>
719                 <description>
720                         <para>Send a reload event.</para>
721                 </description>
722         </manager>
723         <manager name="CoreShowChannels" language="en_US">
724                 <synopsis>
725                         List currently active channels.
726                 </synopsis>
727                 <syntax>
728                         <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
729                 </syntax>
730                 <description>
731                         <para>List currently defined channels and some information about them.</para>
732                 </description>
733         </manager>
734         <manager name="ModuleLoad" language="en_US">
735                 <synopsis>
736                         Module management.
737                 </synopsis>
738                 <syntax>
739                         <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
740                         <parameter name="Module">
741                                 <para>Asterisk module name (including .so extension) or subsystem identifier:</para>
742                                 <enumlist>
743                                         <enum name="cdr" />
744                                         <enum name="dnsmgr" />
745                                         <enum name="extconfig" />
746                                         <enum name="enum" />
747                                         <enum name="acl" />
748                                         <enum name="manager" />
749                                         <enum name="http" />
750                                         <enum name="logger" />
751                                         <enum name="features" />
752                                         <enum name="dsp" />
753                                         <enum name="udptl" />
754                                         <enum name="indications" />
755                                         <enum name="cel" />
756                                         <enum name="plc" />
757                                 </enumlist>
758                         </parameter>
759                         <parameter name="LoadType" required="true">
760                                 <para>The operation to be done on module. Subsystem identifiers may only
761                                 be reloaded.</para>
762                                 <enumlist>
763                                         <enum name="load" />
764                                         <enum name="unload" />
765                                         <enum name="reload" />
766                                 </enumlist>
767                                 <para>If no module is specified for a <literal>reload</literal> loadtype,
768                                 all modules are reloaded.</para>
769                         </parameter>
770                 </syntax>
771                 <description>
772                         <para>Loads, unloads or reloads an Asterisk module in a running system.</para>
773                 </description>
774         </manager>
775         <manager name="ModuleCheck" language="en_US">
776                 <synopsis>
777                         Check if module is loaded.
778                 </synopsis>
779                 <syntax>
780                         <parameter name="Module" required="true">
781                                 <para>Asterisk module name (not including extension).</para>
782                         </parameter>
783                 </syntax>
784                 <description>
785                         <para>Checks if Asterisk module is loaded. Will return Success/Failure.
786                         For success returns, the module revision number is included.</para>
787                 </description>
788         </manager>
789         <manager name="AOCMessage" language="en_US">
790                 <synopsis>
791                         Generate an Advice of Charge message on a channel.
792                 </synopsis>
793                 <syntax>
794                         <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
795                         <parameter name="Channel" required="true">
796                                 <para>Channel name to generate the AOC message on.</para>
797                         </parameter>
798                         <parameter name="ChannelPrefix">
799                                 <para>Partial channel prefix.  By using this option one can match the beginning part
800                                 of a channel name without having to put the entire name in.  For example
801                                 if a channel name is SIP/snom-00000001 and this value is set to SIP/snom, then
802                                 that channel matches and the message will be sent.  Note however that only
803                                 the first matched channel has the message sent on it. </para>
804                         </parameter>
805                         <parameter name="MsgType" required="true">
806                                 <para>Defines what type of AOC message to create, AOC-D or AOC-E</para>
807                                 <enumlist>
808                                         <enum name="D" />
809                                         <enum name="E" />
810                                 </enumlist>
811                         </parameter>
812                         <parameter name="ChargeType" required="true">
813                                 <para>Defines what kind of charge this message represents.</para>
814                                 <enumlist>
815                                         <enum name="NA" />
816                                         <enum name="FREE" />
817                                         <enum name="Currency" />
818                                         <enum name="Unit" />
819                                 </enumlist>
820                         </parameter>
821                         <parameter name="UnitAmount(0)">
822                                 <para>This represents the amount of units charged. The ETSI AOC standard specifies that
823                                 this value along with the optional UnitType value are entries in a list.  To accommodate this
824                                 these values take an index value starting at 0 which can be used to generate this list of
825                                 unit entries.  For Example, If two unit entires were required this could be achieved by setting the
826                                 paramter UnitAmount(0)=1234 and UnitAmount(1)=5678.  Note that UnitAmount at index 0 is
827                                 required when ChargeType=Unit, all other entries in the list are optional.
828                                 </para>
829                         </parameter>
830                         <parameter name="UnitType(0)">
831                                 <para>Defines the type of unit.  ETSI AOC standard specifies this as an integer
832                                 value between 1 and 16, but this value is left open to accept any positive
833                                 integer.  Like the UnitAmount parameter, this value represents a list entry
834                                 and has an index parameter that starts at 0.
835                                 </para>
836                         </parameter>
837                         <parameter name="CurrencyName">
838                                 <para>Specifies the currency's name.  Note that this value is truncated after 10 characters.</para>
839                         </parameter>
840                         <parameter name="CurrencyAmount">
841                                 <para>Specifies the charge unit amount as a positive integer.  This value is required
842                                 when ChargeType==Currency.</para>
843                         </parameter>
844                         <parameter name="CurrencyMultiplier">
845                                 <para>Specifies the currency multiplier.  This value is required when ChargeType==Currency.</para>
846                                 <enumlist>
847                                         <enum name="OneThousandth" />
848                                         <enum name="OneHundredth" />
849                                         <enum name="OneTenth" />
850                                         <enum name="One" />
851                                         <enum name="Ten" />
852                                         <enum name="Hundred" />
853                                         <enum name="Thousand" />
854                                 </enumlist>
855                         </parameter>
856                         <parameter name="TotalType" default="Total">
857                                 <para>Defines what kind of AOC-D total is represented.</para>
858                                 <enumlist>
859                                         <enum name="Total" />
860                                         <enum name="SubTotal" />
861                                 </enumlist>
862                         </parameter>
863                         <parameter name="AOCBillingId">
864                                 <para>Represents a billing ID associated with an AOC-D or AOC-E message. Note
865                                 that only the first 3 items of the enum are valid AOC-D billing IDs</para>
866                                 <enumlist>
867                                         <enum name="Normal" />
868                                         <enum name="ReverseCharge" />
869                                         <enum name="CreditCard" />
870                                         <enum name="CallFwdUnconditional" />
871                                         <enum name="CallFwdBusy" />
872                                         <enum name="CallFwdNoReply" />
873                                         <enum name="CallDeflection" />
874                                         <enum name="CallTransfer" />
875                                 </enumlist>
876                         </parameter>
877                         <parameter name="ChargingAssociationId">
878                                 <para>Charging association identifier.  This is optional for AOC-E and can be
879                                 set to any value between -32768 and 32767</para>
880                         </parameter>
881                         <parameter name="ChargingAssociationNumber">
882                                 <para>Represents the charging association party number.  This value is optional
883                                 for AOC-E.</para>
884                         </parameter>
885                         <parameter name="ChargingAssociationPlan">
886                                 <para>Integer representing the charging plan associated with the ChargingAssociationNumber.
887                                 The value is bits 7 through 1 of the Q.931 octet containing the type-of-number and
888                                 numbering-plan-identification fields.</para>
889                         </parameter>
890                 </syntax>
891                 <description>
892                         <para>Generates an AOC-D or AOC-E message on a channel.</para>
893                 </description>
894         </manager>
895         <function name="AMI_CLIENT" language="en_US">
896                 <synopsis>
897                         Checks attributes of manager accounts
898                 </synopsis>
899                 <syntax>
900                         <parameter name="loginname" required="true">
901                                 <para>Login name, specified in manager.conf</para>
902                         </parameter>
903                         <parameter name="field" required="true">
904                                 <para>The manager account attribute to return</para>
905                                 <enumlist>
906                                         <enum name="sessions"><para>The number of sessions for this AMI account</para></enum>
907                                 </enumlist>
908                         </parameter>
909                 </syntax>
910                 <description>
911                         <para>
912                                 Currently, the only supported  parameter is "sessions" which will return the current number of
913                                 active sessions for this AMI account.
914                         </para>
915                 </description>
916         </function>
917         <manager name="Filter" language="en_US">
918                 <synopsis>
919                         Dynamically add filters for the current manager session.
920                 </synopsis>
921                 <syntax>
922                         <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
923                         <parameter name="Operation">
924                                 <enumlist>
925                                         <enum name="Add">
926                                                 <para>Add a filter.</para>
927                                         </enum>
928                                 </enumlist>
929                         </parameter>
930                         <parameter name="Filter">
931                                 <para>Filters can be whitelist or blacklist</para>
932                                 <para>Example whitelist filter: "Event: Newchannel"</para>
933                                 <para>Example blacklist filter: "!Channel: DAHDI.*"</para>
934                                 <para>This filter option is used to whitelist or blacklist events per user to be
935                                 reported with regular expressions and are allowed if both the regex matches
936                                 and the user has read access as defined in manager.conf. Filters are assumed to be for whitelisting
937                                 unless preceeded by an exclamation point, which marks it as being black.
938                                 Evaluation of the filters is as follows:</para>
939                                 <para>- If no filters are configured all events are reported as normal.</para>
940                                 <para>- If there are white filters only: implied black all filter processed first, then white filters.</para>
941                                 <para>- If there are black filters only: implied white all filter processed first, then black filters.</para>
942                                 <para>- If there are both white and black filters: implied black all filter processed first, then white
943                                 filters, and lastly black filters.</para>
944                         </parameter>
945                 </syntax>
946                 <description>
947                         <para>The filters added are only used for the current session.
948                         Once the connection is closed the filters are removed.</para>
949                         <para>This comand requires the system permission because
950                         this command can be used to create filters that may bypass
951                         filters defined in manager.conf</para>
952                 </description>
953         </manager>
954         <manager name="FilterList" language="en_US">
955                 <synopsis>
956                         Show current event filters for this session
957                 </synopsis>
958                 <description>
959                         <para>The filters displayed are for the current session.  Only those filters defined in
960                         manager.conf will be present upon starting a new session.</para>
961                 </description>
962         </manager>
963  ***/
964
965 /*! \addtogroup Group_AMI AMI functions
966 */
967 /*! @{
968  Doxygen group */
969
970 enum error_type {
971         UNKNOWN_ACTION = 1,
972         UNKNOWN_CATEGORY,
973         UNSPECIFIED_CATEGORY,
974         UNSPECIFIED_ARGUMENT,
975         FAILURE_ALLOCATION,
976         FAILURE_NEWCAT,
977         FAILURE_DELCAT,
978         FAILURE_EMPTYCAT,
979         FAILURE_UPDATE,
980         FAILURE_DELETE,
981         FAILURE_APPEND
982 };
983
984 enum add_filter_result {
985         FILTER_SUCCESS,
986         FILTER_ALLOC_FAILED,
987         FILTER_COMPILE_FAIL,
988 };
989
990 /*!
991  * Linked list of events.
992  * Global events are appended to the list by append_event().
993  * The usecount is the number of stored pointers to the element,
994  * excluding the list pointers. So an element that is only in
995  * the list has a usecount of 0, not 1.
996  *
997  * Clients have a pointer to the last event processed, and for each
998  * of these clients we track the usecount of the elements.
999  * If we have a pointer to an entry in the list, it is safe to navigate
1000  * it forward because elements will not be deleted, but only appended.
1001  * The worst that can happen is seeing the pointer still NULL.
1002  *
1003  * When the usecount of an element drops to 0, and the element is the
1004  * first in the list, we can remove it. Removal is done within the
1005  * main thread, which is woken up for the purpose.
1006  *
1007  * For simplicity of implementation, we make sure the list is never empty.
1008  */
1009 struct eventqent {
1010         int usecount;           /*!< # of clients who still need the event */
1011         int category;
1012         unsigned int seq;       /*!< sequence number */
1013         struct timeval tv;  /*!< When event was allocated */
1014         AST_RWLIST_ENTRY(eventqent) eq_next;
1015         char eventdata[1];      /*!< really variable size, allocated by append_event() */
1016 };
1017
1018 static AST_RWLIST_HEAD_STATIC(all_events, eventqent);
1019
1020 static int displayconnects = 1;
1021 static int allowmultiplelogin = 1;
1022 static int timestampevents;
1023 static int httptimeout = 60;
1024 static int broken_events_action = 0;
1025 static int manager_enabled = 0;
1026 static int webmanager_enabled = 0;
1027 static int manager_debug = 0;   /*!< enable some debugging code in the manager */
1028 static int authtimeout;
1029 static int authlimit;
1030 static char *manager_channelvars;
1031
1032 #define DEFAULT_REALM           "asterisk"
1033 static char global_realm[MAXHOSTNAMELEN];       /*!< Default realm */
1034
1035 static int block_sockets;
1036 static int unauth_sessions = 0;
1037 static struct ast_event_sub *acl_change_event_subscription;
1038
1039 #define MGR_SHOW_TERMINAL_WIDTH 80
1040
1041 /*! \brief
1042  * Descriptor for a manager session, either on the AMI socket or over HTTP.
1043  *
1044  * \note
1045  * AMI session have managerid == 0; the entry is created upon a connect,
1046  * and destroyed with the socket.
1047  * HTTP sessions have managerid != 0, the value is used as a search key
1048  * to lookup sessions (using the mansession_id cookie, or nonce key from
1049  * Digest Authentication http header).
1050  */
1051 #define MAX_BLACKLIST_CMD_LEN 2
1052 static const struct {
1053         const char *words[AST_MAX_CMD_LEN];
1054 } command_blacklist[] = {
1055         {{ "module", "load", NULL }},
1056         {{ "module", "unload", NULL }},
1057         {{ "restart", "gracefully", NULL }},
1058 };
1059
1060 static void acl_change_event_cb(const struct ast_event *event, void *userdata);
1061
1062 static void acl_change_event_subscribe(void)
1063 {
1064         if (!acl_change_event_subscription) {
1065                 acl_change_event_subscription = ast_event_subscribe(AST_EVENT_ACL_CHANGE,
1066                         acl_change_event_cb, "Manager must react to Named ACL changes", NULL, AST_EVENT_IE_END);
1067         }
1068 }
1069
1070 static void acl_change_event_unsubscribe(void)
1071 {
1072         if (acl_change_event_subscription) {
1073                 acl_change_event_subscription = ast_event_unsubscribe(acl_change_event_subscription);
1074         }
1075 }
1076
1077 /* In order to understand what the heck is going on with the
1078  * mansession_session and mansession structs, we need to have a bit of a history
1079  * lesson.
1080  *
1081  * In the beginning, there was the mansession. The mansession contained data that was
1082  * intrinsic to a manager session, such as the time that it started, the name of the logged-in
1083  * user, etc. In addition to these parameters were the f and fd parameters. For typical manager
1084  * sessions, these were used to represent the TCP socket over which the AMI session was taking
1085  * place. It makes perfect sense for these fields to be a part of the session-specific data since
1086  * the session actually defines this information.
1087  *
1088  * Then came the HTTP AMI sessions. With these, the f and fd fields need to be opened and closed
1089  * for every single action that occurs. Thus the f and fd fields aren't really specific to the session
1090  * but rather to the action that is being executed. Because a single session may execute many commands
1091  * at once, some sort of safety needed to be added in order to be sure that we did not end up with fd
1092  * leaks from one action overwriting the f and fd fields used by a previous action before the previous action
1093  * has had a chance to properly close its handles.
1094  *
1095  * The initial idea to solve this was to use thread synchronization, but this prevented multiple actions
1096  * from being run at the same time in a single session. Some manager actions may block for a long time, thus
1097  * creating a large queue of actions to execute. In addition, this fix did not address the basic architectural
1098  * issue that for HTTP manager sessions, the f and fd variables are not really a part of the session, but are
1099  * part of the action instead.
1100  *
1101  * The new idea was to create a structure on the stack for each HTTP Manager action. This structure would
1102  * contain the action-specific information, such as which file to write to. In order to maintain expectations
1103  * of action handlers and not have to change the public API of the manager code, we would need to name this
1104  * new stacked structure 'mansession' and contain within it the old mansession struct that we used to use.
1105  * We renamed the old mansession struct 'mansession_session' to hopefully convey that what is in this structure
1106  * is session-specific data. The structure that it is wrapped in, called a 'mansession' really contains action-specific
1107  * data.
1108  */
1109 struct mansession_session {
1110                                 /*! \todo XXX need to document which fields it is protecting */
1111         struct ast_sockaddr addr;       /*!< address we are connecting from */
1112         FILE *f;                /*!< fdopen() on the underlying fd */
1113         int fd;                 /*!< descriptor used for output. Either the socket (AMI) or a temporary file (HTTP) */
1114         int inuse;              /*!< number of HTTP sessions using this entry */
1115         int needdestroy;        /*!< Whether an HTTP session should be destroyed */
1116         pthread_t waiting_thread;       /*!< Sleeping thread using this descriptor */
1117         uint32_t managerid;     /*!< Unique manager identifier, 0 for AMI sessions */
1118         time_t sessionstart;    /*!< Session start time */
1119         struct timeval sessionstart_tv; /*!< Session start time */
1120         time_t sessiontimeout;  /*!< Session timeout if HTTP */
1121         char username[80];      /*!< Logged in username */
1122         char challenge[10];     /*!< Authentication challenge */
1123         int authenticated;      /*!< Authentication status */
1124         int readperm;           /*!< Authorization for reading */
1125         int writeperm;          /*!< Authorization for writing */
1126         char inbuf[1025];       /*!< Buffer -  we use the extra byte to add a '\\0' and simplify parsing */
1127         int inlen;              /*!< number of buffered bytes */
1128         struct ao2_container *whitefilters;     /*!< Manager event filters - white list */
1129         struct ao2_container *blackfilters;     /*!< Manager event filters - black list */
1130         struct ast_variable *chanvars;  /*!< Channel variables to set for originate */
1131         int send_events;        /*!<  XXX what ? */
1132         struct eventqent *last_ev;      /*!< last event processed. */
1133         int writetimeout;       /*!< Timeout for ast_carefulwrite() */
1134         time_t authstart;
1135         int pending_event;         /*!< Pending events indicator in case when waiting_thread is NULL */
1136         time_t noncetime;       /*!< Timer for nonce value expiration */
1137         unsigned long oldnonce; /*!< Stale nonce value */
1138         unsigned long nc;       /*!< incremental  nonce counter */
1139         AST_LIST_HEAD_NOLOCK(mansession_datastores, ast_datastore) datastores; /*!< Data stores on the session */
1140         AST_LIST_ENTRY(mansession_session) list;
1141 };
1142
1143 enum mansession_message_parsing {
1144         MESSAGE_OKAY,
1145         MESSAGE_LINE_TOO_LONG
1146 };
1147
1148 /*! \brief In case you didn't read that giant block of text above the mansession_session struct, the
1149  * \ref struct mansession is named this solely to keep the API the same in Asterisk. This structure really
1150  * represents data that is different from Manager action to Manager action. The mansession_session pointer
1151  * contained within points to session-specific data.
1152  */
1153 struct mansession {
1154         struct mansession_session *session;
1155         struct ast_tcptls_session_instance *tcptls_session;
1156         FILE *f;
1157         int fd;
1158         enum mansession_message_parsing parsing;
1159         int write_error:1;
1160         struct manager_custom_hook *hook;
1161         ast_mutex_t lock;
1162 };
1163
1164 static struct ao2_container *sessions = NULL;
1165
1166 struct manager_channel_variable {
1167         AST_LIST_ENTRY(manager_channel_variable) entry;
1168         unsigned int isfunc:1;
1169         char name[0]; /* allocate off the end the real size. */
1170 };
1171
1172 static AST_RWLIST_HEAD_STATIC(channelvars, manager_channel_variable);
1173
1174 /*! \brief user descriptor, as read from the config file.
1175  *
1176  * \note It is still missing some fields -- e.g. we can have multiple permit and deny
1177  * lines which are not supported here, and readperm/writeperm/writetimeout
1178  * are not stored.
1179  */
1180 struct ast_manager_user {
1181         char username[80];
1182         char *secret;                   /*!< Secret for logging in */
1183         int readperm;                   /*!< Authorization for reading */
1184         int writeperm;                  /*!< Authorization for writing */
1185         int writetimeout;               /*!< Per user Timeout for ast_carefulwrite() */
1186         int displayconnects;            /*!< XXX unused */
1187         int keep;                       /*!< mark entries created on a reload */
1188         struct ao2_container *whitefilters; /*!< Manager event filters - white list */
1189         struct ao2_container *blackfilters; /*!< Manager event filters - black list */
1190         struct ast_acl_list *acl;       /*!< ACL setting */
1191         char *a1_hash;                  /*!< precalculated A1 for Digest auth */
1192         struct ast_variable *chanvars;  /*!< Channel variables to set for originate */
1193         AST_RWLIST_ENTRY(ast_manager_user) list;
1194 };
1195
1196 /*! \brief list of users found in the config file */
1197 static AST_RWLIST_HEAD_STATIC(users, ast_manager_user);
1198
1199 /*! \brief list of actions registered */
1200 static AST_RWLIST_HEAD_STATIC(actions, manager_action);
1201
1202 /*! \brief list of hooks registered */
1203 static AST_RWLIST_HEAD_STATIC(manager_hooks, manager_custom_hook);
1204
1205 /*! \brief A container of event documentation nodes */
1206 AO2_GLOBAL_OBJ_STATIC(event_docs);
1207
1208 static void free_channelvars(void);
1209
1210 static enum add_filter_result manager_add_filter(const char *filter_pattern, struct ao2_container *whitefilters, struct ao2_container *blackfilters);
1211
1212 /*!
1213  * \internal
1214  * \brief Find a registered action object.
1215  *
1216  * \param name Name of AMI action to find.
1217  *
1218  * \return Reffed action found or NULL
1219  */
1220 static struct manager_action *action_find(const char *name)
1221 {
1222         struct manager_action *act;
1223
1224         AST_RWLIST_RDLOCK(&actions);
1225         AST_RWLIST_TRAVERSE(&actions, act, list) {
1226                 if (!strcasecmp(name, act->action)) {
1227                         ao2_t_ref(act, +1, "found action object");
1228                         break;
1229                 }
1230         }
1231         AST_RWLIST_UNLOCK(&actions);
1232
1233         return act;
1234 }
1235
1236 /*! \brief Add a custom hook to be called when an event is fired */
1237 void ast_manager_register_hook(struct manager_custom_hook *hook)
1238 {
1239         AST_RWLIST_WRLOCK(&manager_hooks);
1240         AST_RWLIST_INSERT_TAIL(&manager_hooks, hook, list);
1241         AST_RWLIST_UNLOCK(&manager_hooks);
1242 }
1243
1244 /*! \brief Delete a custom hook to be called when an event is fired */
1245 void ast_manager_unregister_hook(struct manager_custom_hook *hook)
1246 {
1247         AST_RWLIST_WRLOCK(&manager_hooks);
1248         AST_RWLIST_REMOVE(&manager_hooks, hook, list);
1249         AST_RWLIST_UNLOCK(&manager_hooks);
1250 }
1251
1252 int check_manager_enabled(void)
1253 {
1254         return manager_enabled;
1255 }
1256
1257 int check_webmanager_enabled(void)
1258 {
1259         return (webmanager_enabled && manager_enabled);
1260 }
1261
1262 /*!
1263  * Grab a reference to the last event, update usecount as needed.
1264  * Can handle a NULL pointer.
1265  */
1266 static struct eventqent *grab_last(void)
1267 {
1268         struct eventqent *ret;
1269
1270         AST_RWLIST_WRLOCK(&all_events);
1271         ret = AST_RWLIST_LAST(&all_events);
1272         /* the list is never empty now, but may become so when
1273          * we optimize it in the future, so be prepared.
1274          */
1275         if (ret) {
1276                 ast_atomic_fetchadd_int(&ret->usecount, 1);
1277         }
1278         AST_RWLIST_UNLOCK(&all_events);
1279         return ret;
1280 }
1281
1282 /*!
1283  * Purge unused events. Remove elements from the head
1284  * as long as their usecount is 0 and there is a next element.
1285  */
1286 static void purge_events(void)
1287 {
1288         struct eventqent *ev;
1289         struct timeval now = ast_tvnow();
1290
1291         AST_RWLIST_WRLOCK(&all_events);
1292         while ( (ev = AST_RWLIST_FIRST(&all_events)) &&
1293             ev->usecount == 0 && AST_RWLIST_NEXT(ev, eq_next)) {
1294                 AST_RWLIST_REMOVE_HEAD(&all_events, eq_next);
1295                 ast_free(ev);
1296         }
1297
1298         AST_RWLIST_TRAVERSE_SAFE_BEGIN(&all_events, ev, eq_next) {
1299                 /* Never release the last event */
1300                 if (!AST_RWLIST_NEXT(ev, eq_next)) {
1301                         break;
1302                 }
1303
1304                 /* 2.5 times whatever the HTTP timeout is (maximum 2.5 hours) is the maximum time that we will definitely cache an event */
1305                 if (ev->usecount == 0 && ast_tvdiff_sec(now, ev->tv) > (httptimeout > 3600 ? 3600 : httptimeout) * 2.5) {
1306                         AST_RWLIST_REMOVE_CURRENT(eq_next);
1307                         ast_free(ev);
1308                 }
1309         }
1310         AST_RWLIST_TRAVERSE_SAFE_END;
1311         AST_RWLIST_UNLOCK(&all_events);
1312 }
1313
1314 /*!
1315  * helper functions to convert back and forth between
1316  * string and numeric representation of set of flags
1317  */
1318 static const struct permalias {
1319         int num;
1320         const char *label;
1321 } perms[] = {
1322         { EVENT_FLAG_SYSTEM, "system" },
1323         { EVENT_FLAG_CALL, "call" },
1324         { EVENT_FLAG_LOG, "log" },
1325         { EVENT_FLAG_VERBOSE, "verbose" },
1326         { EVENT_FLAG_COMMAND, "command" },
1327         { EVENT_FLAG_AGENT, "agent" },
1328         { EVENT_FLAG_USER, "user" },
1329         { EVENT_FLAG_CONFIG, "config" },
1330         { EVENT_FLAG_DTMF, "dtmf" },
1331         { EVENT_FLAG_REPORTING, "reporting" },
1332         { EVENT_FLAG_CDR, "cdr" },
1333         { EVENT_FLAG_DIALPLAN, "dialplan" },
1334         { EVENT_FLAG_ORIGINATE, "originate" },
1335         { EVENT_FLAG_AGI, "agi" },
1336         { EVENT_FLAG_CC, "cc" },
1337         { EVENT_FLAG_AOC, "aoc" },
1338         { EVENT_FLAG_TEST, "test" },
1339         { EVENT_FLAG_MESSAGE, "message" },
1340         { INT_MAX, "all" },
1341         { 0, "none" },
1342 };
1343
1344 /*! \brief Checks to see if a string which can be used to evaluate functions should be rejected */
1345 static int function_capable_string_allowed_with_auths(const char *evaluating, int writepermlist)
1346 {
1347         if (!(writepermlist & EVENT_FLAG_SYSTEM)
1348                 && (
1349                         strstr(evaluating, "SHELL") ||       /* NoOp(${SHELL(rm -rf /)})  */
1350                         strstr(evaluating, "EVAL")           /* NoOp(${EVAL(${some_var_containing_SHELL})}) */
1351                 )) {
1352                 return 0;
1353         }
1354         return 1;
1355 }
1356
1357 /*! \brief Convert authority code to a list of options */
1358 static const char *authority_to_str(int authority, struct ast_str **res)
1359 {
1360         int i;
1361         char *sep = "";
1362
1363         ast_str_reset(*res);
1364         for (i = 0; i < ARRAY_LEN(perms) - 1; i++) {
1365                 if (authority & perms[i].num) {
1366                         ast_str_append(res, 0, "%s%s", sep, perms[i].label);
1367                         sep = ",";
1368                 }
1369         }
1370
1371         if (ast_str_strlen(*res) == 0)  /* replace empty string with something sensible */
1372                 ast_str_append(res, 0, "<none>");
1373
1374         return ast_str_buffer(*res);
1375 }
1376
1377 /*! Tells you if smallstr exists inside bigstr
1378    which is delim by delim and uses no buf or stringsep
1379    ast_instring("this|that|more","this",'|') == 1;
1380
1381    feel free to move this to app.c -anthm */
1382 static int ast_instring(const char *bigstr, const char *smallstr, const char delim)
1383 {
1384         const char *val = bigstr, *next;
1385
1386         do {
1387                 if ((next = strchr(val, delim))) {
1388                         if (!strncmp(val, smallstr, (next - val))) {
1389                                 return 1;
1390                         } else {
1391                                 continue;
1392                         }
1393                 } else {
1394                         return !strcmp(smallstr, val);
1395                 }
1396         } while (*(val = (next + 1)));
1397
1398         return 0;
1399 }
1400
1401 static int get_perm(const char *instr)
1402 {
1403         int x = 0, ret = 0;
1404
1405         if (!instr) {
1406                 return 0;
1407         }
1408
1409         for (x = 0; x < ARRAY_LEN(perms); x++) {
1410                 if (ast_instring(instr, perms[x].label, ',')) {
1411                         ret |= perms[x].num;
1412                 }
1413         }
1414
1415         return ret;
1416 }
1417
1418 /*!
1419  * A number returns itself, false returns 0, true returns all flags,
1420  * other strings return the flags that are set.
1421  */
1422 static int strings_to_mask(const char *string)
1423 {
1424         const char *p;
1425
1426         if (ast_strlen_zero(string)) {
1427                 return -1;
1428         }
1429
1430         for (p = string; *p; p++) {
1431                 if (*p < '0' || *p > '9') {
1432                         break;
1433                 }
1434         }
1435         if (!*p) { /* all digits */
1436                 return atoi(string);
1437         }
1438         if (ast_false(string)) {
1439                 return 0;
1440         }
1441         if (ast_true(string)) { /* all permissions */
1442                 int x, ret = 0;
1443                 for (x = 0; x < ARRAY_LEN(perms); x++) {
1444                         ret |= perms[x].num;
1445                 }
1446                 return ret;
1447         }
1448         return get_perm(string);
1449 }
1450
1451 /*! \brief Unreference manager session object.
1452      If no more references, then go ahead and delete it */
1453 static struct mansession_session *unref_mansession(struct mansession_session *s)
1454 {
1455         int refcount = ao2_ref(s, -1);
1456         if (manager_debug) {
1457                 ast_debug(1, "Mansession: %p refcount now %d\n", s, refcount - 1);
1458         }
1459         return s;
1460 }
1461
1462 static void event_filter_destructor(void *obj)
1463 {
1464         regex_t *regex_filter = obj;
1465         regfree(regex_filter);
1466 }
1467
1468 static void session_destructor(void *obj)
1469 {
1470         struct mansession_session *session = obj;
1471         struct eventqent *eqe = session->last_ev;
1472         struct ast_datastore *datastore;
1473
1474         /* Get rid of each of the data stores on the session */
1475         while ((datastore = AST_LIST_REMOVE_HEAD(&session->datastores, entry))) {
1476                 /* Free the data store */
1477                 ast_datastore_free(datastore);
1478         }
1479
1480         if (session->f != NULL) {
1481                 fclose(session->f);
1482         }
1483         if (eqe) {
1484                 ast_atomic_fetchadd_int(&eqe->usecount, -1);
1485         }
1486         if (session->chanvars) {
1487                 ast_variables_destroy(session->chanvars);
1488         }
1489
1490         if (session->whitefilters) {
1491                 ao2_t_callback(session->whitefilters, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, NULL, NULL, "unlink all white filters");
1492                 ao2_t_ref(session->whitefilters, -1 , "decrement ref for white container, should be last one");
1493         }
1494
1495         if (session->blackfilters) {
1496                 ao2_t_callback(session->blackfilters, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, NULL, NULL, "unlink all black filters");
1497                 ao2_t_ref(session->blackfilters, -1 , "decrement ref for black container, should be last one");
1498         }
1499 }
1500
1501 /*! \brief Allocate manager session structure and add it to the list of sessions */
1502 static struct mansession_session *build_mansession(const struct ast_sockaddr *addr)
1503 {
1504         struct mansession_session *newsession;
1505
1506         if (!(newsession = ao2_alloc(sizeof(*newsession), session_destructor))) {
1507                 return NULL;
1508         }
1509
1510         if (!(newsession->whitefilters = ao2_container_alloc(1, NULL, NULL))) {
1511                 ao2_ref(newsession, -1);
1512                 return NULL;
1513         }
1514
1515         if (!(newsession->blackfilters = ao2_container_alloc(1, NULL, NULL))) {
1516                 ao2_ref(newsession, -1); /* session_destructor will cleanup the other filter */
1517                 return NULL;
1518         }
1519
1520         newsession->fd = -1;
1521         newsession->waiting_thread = AST_PTHREADT_NULL;
1522         newsession->writetimeout = 100;
1523         newsession->send_events = -1;
1524         ast_sockaddr_copy(&newsession->addr, addr);
1525
1526         ao2_link(sessions, newsession);
1527
1528         return newsession;
1529 }
1530
1531 static int mansession_cmp_fn(void *obj, void *arg, int flags)
1532 {
1533         struct mansession_session *s = obj;
1534         char *str = arg;
1535         return !strcasecmp(s->username, str) ? CMP_MATCH : 0;
1536 }
1537
1538 static void session_destroy(struct mansession_session *s)
1539 {
1540         unref_mansession(s);
1541         ao2_unlink(sessions, s);
1542 }
1543
1544
1545 static int check_manager_session_inuse(const char *name)
1546 {
1547         struct mansession_session *session = ao2_find(sessions, (char *) name, 0);
1548         int inuse = 0;
1549
1550         if (session) {
1551                 inuse = 1;
1552                 unref_mansession(session);
1553         }
1554         return inuse;
1555 }
1556
1557
1558 /*!
1559  * lookup an entry in the list of registered users.
1560  * must be called with the list lock held.
1561  */
1562 static struct ast_manager_user *get_manager_by_name_locked(const char *name)
1563 {
1564         struct ast_manager_user *user = NULL;
1565
1566         AST_RWLIST_TRAVERSE(&users, user, list) {
1567                 if (!strcasecmp(user->username, name)) {
1568                         break;
1569                 }
1570         }
1571
1572         return user;
1573 }
1574
1575 /*! \brief Get displayconnects config option.
1576  *  \param session manager session to get parameter from.
1577  *  \return displayconnects config option value.
1578  */
1579 static int manager_displayconnects (struct mansession_session *session)
1580 {
1581         struct ast_manager_user *user = NULL;
1582         int ret = 0;
1583
1584         AST_RWLIST_RDLOCK(&users);
1585         if ((user = get_manager_by_name_locked (session->username))) {
1586                 ret = user->displayconnects;
1587         }
1588         AST_RWLIST_UNLOCK(&users);
1589
1590         return ret;
1591 }
1592
1593 static char *handle_showmancmd(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
1594 {
1595         struct manager_action *cur;
1596         struct ast_str *authority;
1597         int num, l, which;
1598         char *ret = NULL;
1599 #ifdef AST_XML_DOCS
1600         char syntax_title[64], description_title[64], synopsis_title[64], seealso_title[64], arguments_title[64], privilege_title[64];
1601 #endif
1602
1603         switch (cmd) {
1604         case CLI_INIT:
1605                 e->command = "manager show command";
1606                 e->usage =
1607                         "Usage: manager show command <actionname> [<actionname> [<actionname> [...]]]\n"
1608                         "       Shows the detailed description for a specific Asterisk manager interface command.\n";
1609                 return NULL;
1610         case CLI_GENERATE:
1611                 l = strlen(a->word);
1612                 which = 0;
1613                 AST_RWLIST_RDLOCK(&actions);
1614                 AST_RWLIST_TRAVERSE(&actions, cur, list) {
1615                         if (!strncasecmp(a->word, cur->action, l) && ++which > a->n) {
1616                                 ret = ast_strdup(cur->action);
1617                                 break;  /* make sure we exit even if ast_strdup() returns NULL */
1618                         }
1619                 }
1620                 AST_RWLIST_UNLOCK(&actions);
1621                 return ret;
1622         }
1623         authority = ast_str_alloca(80);
1624         if (a->argc < 4) {
1625                 return CLI_SHOWUSAGE;
1626         }
1627
1628 #ifdef AST_XML_DOCS
1629         /* setup the titles */
1630         term_color(synopsis_title, "[Synopsis]\n", COLOR_MAGENTA, 0, 40);
1631         term_color(description_title, "[Description]\n", COLOR_MAGENTA, 0, 40);
1632         term_color(syntax_title, "[Syntax]\n", COLOR_MAGENTA, 0, 40);
1633         term_color(seealso_title, "[See Also]\n", COLOR_MAGENTA, 0, 40);
1634         term_color(arguments_title, "[Arguments]\n", COLOR_MAGENTA, 0, 40);
1635         term_color(privilege_title, "[Privilege]\n", COLOR_MAGENTA, 0,40);
1636 #endif
1637
1638         AST_RWLIST_RDLOCK(&actions);
1639         AST_RWLIST_TRAVERSE(&actions, cur, list) {
1640                 for (num = 3; num < a->argc; num++) {
1641                         if (!strcasecmp(cur->action, a->argv[num])) {
1642                                 authority_to_str(cur->authority, &authority);
1643
1644 #ifdef AST_XML_DOCS
1645                                 if (cur->docsrc == AST_XML_DOC) {
1646                                         ast_cli(a->fd, "%s%s\n\n%s%s\n\n%s%s\n\n%s%s\n\n%s%s\n\n%s%s\n\n",
1647                                                 syntax_title,
1648                                                 ast_xmldoc_printable(S_OR(cur->syntax, "Not available"), 1),
1649                                                 synopsis_title,
1650                                                 ast_xmldoc_printable(S_OR(cur->synopsis, "Not available"), 1),
1651                                                 description_title,
1652                                                 ast_xmldoc_printable(S_OR(cur->description, "Not available"), 1),
1653                                                 arguments_title,
1654                                                 ast_xmldoc_printable(S_OR(cur->arguments, "Not available"), 1),
1655                                                 seealso_title,
1656                                                 ast_xmldoc_printable(S_OR(cur->seealso, "Not available"), 1),
1657                                                 privilege_title,
1658                                                 ast_xmldoc_printable(S_OR(authority->str, "Not available"), 1));
1659                                 } else
1660 #endif
1661                                 {
1662                                         ast_cli(a->fd, "Action: %s\nSynopsis: %s\nPrivilege: %s\n%s\n",
1663                                                 cur->action, cur->synopsis,
1664                                                 authority->str,
1665                                                 S_OR(cur->description, ""));
1666                                 }
1667                         }
1668                 }
1669         }
1670         AST_RWLIST_UNLOCK(&actions);
1671
1672         return CLI_SUCCESS;
1673 }
1674
1675 static char *handle_mandebug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
1676 {
1677         switch (cmd) {
1678         case CLI_INIT:
1679                 e->command = "manager set debug [on|off]";
1680                 e->usage = "Usage: manager set debug [on|off]\n Show, enable, disable debugging of the manager code.\n";
1681                 return NULL;
1682         case CLI_GENERATE:
1683                 return NULL;
1684         }
1685
1686         if (a->argc == 3) {
1687                 ast_cli(a->fd, "manager debug is %s\n", manager_debug? "on" : "off");
1688         } else if (a->argc == 4) {
1689                 if (!strcasecmp(a->argv[3], "on")) {
1690                         manager_debug = 1;
1691                 } else if (!strcasecmp(a->argv[3], "off")) {
1692                         manager_debug = 0;
1693                 } else {
1694                         return CLI_SHOWUSAGE;
1695                 }
1696         }
1697         return CLI_SUCCESS;
1698 }
1699
1700 static char *handle_showmanager(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
1701 {
1702         struct ast_manager_user *user = NULL;
1703         int l, which;
1704         char *ret = NULL;
1705         struct ast_str *rauthority = ast_str_alloca(128);
1706         struct ast_str *wauthority = ast_str_alloca(128);
1707         struct ast_variable *v;
1708
1709         switch (cmd) {
1710         case CLI_INIT:
1711                 e->command = "manager show user";
1712                 e->usage =
1713                         " Usage: manager show user <user>\n"
1714                         "        Display all information related to the manager user specified.\n";
1715                 return NULL;
1716         case CLI_GENERATE:
1717                 l = strlen(a->word);
1718                 which = 0;
1719                 if (a->pos != 3) {
1720                         return NULL;
1721                 }
1722                 AST_RWLIST_RDLOCK(&users);
1723                 AST_RWLIST_TRAVERSE(&users, user, list) {
1724                         if ( !strncasecmp(a->word, user->username, l) && ++which > a->n ) {
1725                                 ret = ast_strdup(user->username);
1726                                 break;
1727                         }
1728                 }
1729                 AST_RWLIST_UNLOCK(&users);
1730                 return ret;
1731         }
1732
1733         if (a->argc != 4) {
1734                 return CLI_SHOWUSAGE;
1735         }
1736
1737         AST_RWLIST_RDLOCK(&users);
1738
1739         if (!(user = get_manager_by_name_locked(a->argv[3]))) {
1740                 ast_cli(a->fd, "There is no manager called %s\n", a->argv[3]);
1741                 AST_RWLIST_UNLOCK(&users);
1742                 return CLI_SUCCESS;
1743         }
1744
1745         ast_cli(a->fd, "\n");
1746         ast_cli(a->fd,
1747                 "       username: %s\n"
1748                 "         secret: %s\n"
1749                 "            ACL: %s\n"
1750                 "      read perm: %s\n"
1751                 "     write perm: %s\n"
1752                 "displayconnects: %s\n",
1753                 (user->username ? user->username : "(N/A)"),
1754                 (user->secret ? "<Set>" : "(N/A)"),
1755                 ((user->acl && !ast_acl_list_is_empty(user->acl)) ? "yes" : "no"),
1756                 authority_to_str(user->readperm, &rauthority),
1757                 authority_to_str(user->writeperm, &wauthority),
1758                 (user->displayconnects ? "yes" : "no"));
1759         ast_cli(a->fd, "      Variables: \n");
1760                 for (v = user->chanvars ; v ; v = v->next) {
1761                         ast_cli(a->fd, "                 %s = %s\n", v->name, v->value);
1762                 }
1763
1764         AST_RWLIST_UNLOCK(&users);
1765
1766         return CLI_SUCCESS;
1767 }
1768
1769 static char *handle_showmanagers(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
1770 {
1771         struct ast_manager_user *user = NULL;
1772         int count_amu = 0;
1773         switch (cmd) {
1774         case CLI_INIT:
1775                 e->command = "manager show users";
1776                 e->usage =
1777                         "Usage: manager show users\n"
1778                         "       Prints a listing of all managers that are currently configured on that\n"
1779                         " system.\n";
1780                 return NULL;
1781         case CLI_GENERATE:
1782                 return NULL;
1783         }
1784         if (a->argc != 3) {
1785                 return CLI_SHOWUSAGE;
1786         }
1787
1788         AST_RWLIST_RDLOCK(&users);
1789
1790         /* If there are no users, print out something along those lines */
1791         if (AST_RWLIST_EMPTY(&users)) {
1792                 ast_cli(a->fd, "There are no manager users.\n");
1793                 AST_RWLIST_UNLOCK(&users);
1794                 return CLI_SUCCESS;
1795         }
1796
1797         ast_cli(a->fd, "\nusername\n--------\n");
1798
1799         AST_RWLIST_TRAVERSE(&users, user, list) {
1800                 ast_cli(a->fd, "%s\n", user->username);
1801                 count_amu++;
1802         }
1803
1804         AST_RWLIST_UNLOCK(&users);
1805
1806         ast_cli(a->fd,"-------------------\n"
1807                       "%d manager users configured.\n", count_amu);
1808         return CLI_SUCCESS;
1809 }
1810
1811 /*! \brief  CLI command  manager list commands */
1812 static char *handle_showmancmds(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
1813 {
1814         struct manager_action *cur;
1815         int name_len = 1;
1816         int space_remaining;
1817 #define HSMC_FORMAT "  %-*.*s  %-.*s\n"
1818         switch (cmd) {
1819         case CLI_INIT:
1820                 e->command = "manager show commands";
1821                 e->usage =
1822                         "Usage: manager show commands\n"
1823                         "       Prints a listing of all the available Asterisk manager interface commands.\n";
1824                 return NULL;
1825         case CLI_GENERATE:
1826                 return NULL;
1827         }
1828
1829         AST_RWLIST_RDLOCK(&actions);
1830         AST_RWLIST_TRAVERSE(&actions, cur, list) {
1831                 int incoming_len = strlen(cur->action);
1832                 if (incoming_len > name_len) {
1833                         name_len = incoming_len;
1834                 }
1835         }
1836
1837         space_remaining = MGR_SHOW_TERMINAL_WIDTH - name_len - 4;
1838         if (space_remaining < 0) {
1839                 space_remaining = 0;
1840         }
1841
1842         ast_cli(a->fd, HSMC_FORMAT, name_len, name_len, "Action", space_remaining, "Synopsis");
1843         ast_cli(a->fd, HSMC_FORMAT, name_len, name_len, "------", space_remaining, "--------");
1844
1845         AST_RWLIST_TRAVERSE(&actions, cur, list) {
1846                 ast_cli(a->fd, HSMC_FORMAT, name_len, name_len, cur->action, space_remaining, cur->synopsis);
1847         }
1848         AST_RWLIST_UNLOCK(&actions);
1849
1850         return CLI_SUCCESS;
1851 }
1852
1853 /*! \brief CLI command manager list connected */
1854 static char *handle_showmanconn(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
1855 {
1856         struct mansession_session *session;
1857         time_t now = time(NULL);
1858 #define HSMCONN_FORMAT1 "  %-15.15s  %-55.55s  %-10.10s  %-10.10s  %-8.8s  %-8.8s  %-5.5s  %-5.5s\n"
1859 #define HSMCONN_FORMAT2 "  %-15.15s  %-55.55s  %-10d  %-10d  %-8d  %-8d  %-5.5d  %-5.5d\n"
1860         int count = 0;
1861         struct ao2_iterator i;
1862
1863         switch (cmd) {
1864         case CLI_INIT:
1865                 e->command = "manager show connected";
1866                 e->usage =
1867                         "Usage: manager show connected\n"
1868                         "       Prints a listing of the users that are currently connected to the\n"
1869                         "Asterisk manager interface.\n";
1870                 return NULL;
1871         case CLI_GENERATE:
1872                 return NULL;
1873         }
1874
1875         ast_cli(a->fd, HSMCONN_FORMAT1, "Username", "IP Address", "Start", "Elapsed", "FileDes", "HttpCnt", "Read", "Write");
1876
1877         i = ao2_iterator_init(sessions, 0);
1878         while ((session = ao2_iterator_next(&i))) {
1879                 ao2_lock(session);
1880                 ast_cli(a->fd, HSMCONN_FORMAT2, session->username, ast_sockaddr_stringify_addr(&session->addr), (int)(session->sessionstart), (int)(now - session->sessionstart), session->fd, session->inuse, session->readperm, session->writeperm);
1881                 count++;
1882                 ao2_unlock(session);
1883                 unref_mansession(session);
1884         }
1885         ao2_iterator_destroy(&i);
1886         ast_cli(a->fd, "%d users connected.\n", count);
1887
1888         return CLI_SUCCESS;
1889 }
1890
1891 /*! \brief CLI command manager list eventq */
1892 /* Should change to "manager show connected" */
1893 static char *handle_showmaneventq(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
1894 {
1895         struct eventqent *s;
1896         switch (cmd) {
1897         case CLI_INIT:
1898                 e->command = "manager show eventq";
1899                 e->usage =
1900                         "Usage: manager show eventq\n"
1901                         "       Prints a listing of all events pending in the Asterisk manger\n"
1902                         "event queue.\n";
1903                 return NULL;
1904         case CLI_GENERATE:
1905                 return NULL;
1906         }
1907         AST_RWLIST_RDLOCK(&all_events);
1908         AST_RWLIST_TRAVERSE(&all_events, s, eq_next) {
1909                 ast_cli(a->fd, "Usecount: %d\n", s->usecount);
1910                 ast_cli(a->fd, "Category: %d\n", s->category);
1911                 ast_cli(a->fd, "Event:\n%s", s->eventdata);
1912         }
1913         AST_RWLIST_UNLOCK(&all_events);
1914
1915         return CLI_SUCCESS;
1916 }
1917
1918 /*! \brief CLI command manager reload */
1919 static char *handle_manager_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
1920 {
1921         switch (cmd) {
1922         case CLI_INIT:
1923                 e->command = "manager reload";
1924                 e->usage =
1925                         "Usage: manager reload\n"
1926                         "       Reloads the manager configuration.\n";
1927                 return NULL;
1928         case CLI_GENERATE:
1929                 return NULL;
1930         }
1931         if (a->argc > 2) {
1932                 return CLI_SHOWUSAGE;
1933         }
1934         reload_manager();
1935         return CLI_SUCCESS;
1936 }
1937
1938 static struct eventqent *advance_event(struct eventqent *e)
1939 {
1940         struct eventqent *next;
1941
1942         AST_RWLIST_RDLOCK(&all_events);
1943         if ((next = AST_RWLIST_NEXT(e, eq_next))) {
1944                 ast_atomic_fetchadd_int(&next->usecount, 1);
1945                 ast_atomic_fetchadd_int(&e->usecount, -1);
1946         }
1947         AST_RWLIST_UNLOCK(&all_events);
1948         return next;
1949 }
1950
1951 #define GET_HEADER_FIRST_MATCH  0
1952 #define GET_HEADER_LAST_MATCH   1
1953 #define GET_HEADER_SKIP_EMPTY   2
1954
1955 /*!
1956  * \brief Return a matching header value.
1957  *
1958  * \details
1959  * Generic function to return either the first or the last
1960  * matching header from a list of variables, possibly skipping
1961  * empty strings.
1962  *
1963  * \note At the moment there is only one use of this function in
1964  * this file, so we make it static.
1965  *
1966  * \note Never returns NULL.
1967  */
1968 static const char *__astman_get_header(const struct message *m, char *var, int mode)
1969 {
1970         int x, l = strlen(var);
1971         const char *result = "";
1972
1973         if (!m) {
1974                 return result;
1975         }
1976
1977         for (x = 0; x < m->hdrcount; x++) {
1978                 const char *h = m->headers[x];
1979                 if (!strncasecmp(var, h, l) && h[l] == ':') {
1980                         const char *value = h + l + 1;
1981                         value = ast_skip_blanks(value); /* ignore leading spaces in the value */
1982                         /* found a potential candidate */
1983                         if ((mode & GET_HEADER_SKIP_EMPTY) && ast_strlen_zero(value)) {
1984                                 continue;       /* not interesting */
1985                         }
1986                         if (mode & GET_HEADER_LAST_MATCH) {
1987                                 result = value; /* record the last match so far */
1988                         } else {
1989                                 return value;
1990                         }
1991                 }
1992         }
1993
1994         return result;
1995 }
1996
1997 /*!
1998  * \brief Return the first matching variable from an array.
1999  *
2000  * \note This is the legacy function and is implemented in
2001  * therms of __astman_get_header().
2002  *
2003  * \note Never returns NULL.
2004  */
2005 const char *astman_get_header(const struct message *m, char *var)
2006 {
2007         return __astman_get_header(m, var, GET_HEADER_FIRST_MATCH);
2008 }
2009
2010 /*!
2011  * \internal
2012  * \brief Process one "Variable:" header value string.
2013  *
2014  * \param head Current list of AMI variables to get new values added.
2015  * \param hdr_val Header value string to process.
2016  *
2017  * \return New variable list head.
2018  */
2019 static struct ast_variable *man_do_variable_value(struct ast_variable *head, const char *hdr_val)
2020 {
2021         char *parse;
2022         AST_DECLARE_APP_ARGS(args,
2023                 AST_APP_ARG(vars)[64];
2024         );
2025
2026         hdr_val = ast_skip_blanks(hdr_val); /* ignore leading spaces in the value */
2027         parse = ast_strdupa(hdr_val);
2028
2029         /* Break the header value string into name=val pair items. */
2030         AST_STANDARD_APP_ARGS(args, parse);
2031         if (args.argc) {
2032                 int y;
2033
2034                 /* Process each name=val pair item. */
2035                 for (y = 0; y < args.argc; y++) {
2036                         struct ast_variable *cur;
2037                         char *var;
2038                         char *val;
2039
2040                         if (!args.vars[y]) {
2041                                 continue;
2042                         }
2043                         var = val = args.vars[y];
2044                         strsep(&val, "=");
2045
2046                         /* XXX We may wish to trim whitespace from the strings. */
2047                         if (!val || ast_strlen_zero(var)) {
2048                                 continue;
2049                         }
2050
2051                         /* Create new variable list node and prepend it to the list. */
2052                         cur = ast_variable_new(var, val, "");
2053                         if (cur) {
2054                                 cur->next = head;
2055                                 head = cur;
2056                         }
2057                 }
2058         }
2059
2060         return head;
2061 }
2062
2063 struct ast_variable *astman_get_variables(const struct message *m)
2064 {
2065         int varlen;
2066         int x;
2067         struct ast_variable *head = NULL;
2068
2069         static const char var_hdr[] = "Variable:";
2070
2071         /* Process all "Variable:" headers. */
2072         varlen = strlen(var_hdr);
2073         for (x = 0; x < m->hdrcount; x++) {
2074                 if (strncasecmp(var_hdr, m->headers[x], varlen)) {
2075                         continue;
2076                 }
2077                 head = man_do_variable_value(head, m->headers[x] + varlen);
2078         }
2079
2080         return head;
2081 }
2082
2083 /*! \brief access for hooks to send action messages to ami */
2084 int ast_hook_send_action(struct manager_custom_hook *hook, const char *msg)
2085 {
2086         const char *action;
2087         int ret = 0;
2088         struct manager_action *act_found;
2089         struct mansession s = {.session = NULL, };
2090         struct message m = { 0 };
2091         char *dup_str;
2092         char *src;
2093         int x = 0;
2094         int curlen;
2095
2096         if (hook == NULL) {
2097                 return -1;
2098         }
2099
2100         /* Create our own copy of the AMI action msg string. */
2101         src = dup_str = ast_strdup(msg);
2102         if (!dup_str) {
2103                 return -1;
2104         }
2105
2106         /* convert msg string to message struct */
2107         curlen = strlen(src);
2108         for (x = 0; x < curlen; x++) {
2109                 int cr; /* set if we have \r */
2110                 if (src[x] == '\r' && x+1 < curlen && src[x+1] == '\n')
2111                         cr = 2; /* Found. Update length to include \r\n */
2112                 else if (src[x] == '\n')
2113                         cr = 1; /* also accept \n only */
2114                 else
2115                         continue;
2116                 /* don't keep empty lines */
2117                 if (x && m.hdrcount < ARRAY_LEN(m.headers)) {
2118                         /* ... but trim \r\n and terminate the header string */
2119                         src[x] = '\0';
2120                         m.headers[m.hdrcount++] = src;
2121                 }
2122                 x += cr;
2123                 curlen -= x;            /* remaining size */
2124                 src += x;               /* update pointer */
2125                 x = -1;                 /* reset loop */
2126         }
2127
2128         action = astman_get_header(&m, "Action");
2129         if (strcasecmp(action, "login")) {
2130                 act_found = action_find(action);
2131                 if (act_found) {
2132                         /*
2133                          * we have to simulate a session for this action request
2134                          * to be able to pass it down for processing
2135                          * This is necessary to meet the previous design of manager.c
2136                          */
2137                         s.hook = hook;
2138                         s.f = (void*)1; /* set this to something so our request will make it through all functions that test it*/
2139
2140                         ao2_lock(act_found);
2141                         if (act_found->registered && act_found->func) {
2142                                 if (act_found->module) {
2143                                         ast_module_ref(act_found->module);
2144                                 }
2145                                 ao2_unlock(act_found);
2146                                 ret = act_found->func(&s, &m);
2147                                 ao2_lock(act_found);
2148                                 if (act_found->module) {
2149                                         ast_module_unref(act_found->module);
2150                                 }
2151                         } else {
2152                                 ret = -1;
2153                         }
2154                         ao2_unlock(act_found);
2155                         ao2_t_ref(act_found, -1, "done with found action object");
2156                 }
2157         }
2158         ast_free(dup_str);
2159         return ret;
2160 }
2161
2162
2163 /*!
2164  * helper function to send a string to the socket.
2165  * Return -1 on error (e.g. buffer full).
2166  */
2167 static int send_string(struct mansession *s, char *string)
2168 {
2169         int res;
2170         FILE *f = s->f ? s->f : s->session->f;
2171         int fd = s->f ? s->fd : s->session->fd;
2172
2173         /* It's a result from one of the hook's action invocation */
2174         if (s->hook) {
2175                 /*
2176                  * to send responses, we're using the same function
2177                  * as for receiving events. We call the event "HookResponse"
2178                  */
2179                 s->hook->helper(EVENT_FLAG_HOOKRESPONSE, "HookResponse", string);
2180                 return 0;
2181         }
2182
2183         if ((res = ast_careful_fwrite(f, fd, string, strlen(string), s->session->writetimeout))) {
2184                 s->write_error = 1;
2185         }
2186
2187         return res;
2188 }
2189
2190 /*!
2191  * \brief thread local buffer for astman_append
2192  *
2193  * \note This can not be defined within the astman_append() function
2194  *       because it declares a couple of functions that get used to
2195  *       initialize the thread local storage key.
2196  */
2197 AST_THREADSTORAGE(astman_append_buf);
2198
2199 AST_THREADSTORAGE(userevent_buf);
2200
2201 /*! \brief initial allocated size for the astman_append_buf and astman_send_*_va */
2202 #define ASTMAN_APPEND_BUF_INITSIZE   256
2203
2204 /*!
2205  * utility functions for creating AMI replies
2206  */
2207 void astman_append(struct mansession *s, const char *fmt, ...)
2208 {
2209         va_list ap;
2210         struct ast_str *buf;
2211
2212         if (!(buf = ast_str_thread_get(&astman_append_buf, ASTMAN_APPEND_BUF_INITSIZE))) {
2213                 return;
2214         }
2215
2216         va_start(ap, fmt);
2217         ast_str_set_va(&buf, 0, fmt, ap);
2218         va_end(ap);
2219
2220         if (s->f != NULL || s->session->f != NULL) {
2221                 send_string(s, ast_str_buffer(buf));
2222         } else {
2223                 ast_verbose("fd == -1 in astman_append, should not happen\n");
2224         }
2225 }
2226
2227 /*! \note NOTE: XXX this comment is unclear and possibly wrong.
2228    Callers of astman_send_error(), astman_send_response() or astman_send_ack() must EITHER
2229    hold the session lock _or_ be running in an action callback (in which case s->session->busy will
2230    be non-zero). In either of these cases, there is no need to lock-protect the session's
2231    fd, since no other output will be sent (events will be queued), and no input will
2232    be read until either the current action finishes or get_input() obtains the session
2233    lock.
2234  */
2235
2236 /*! \todo XXX MSG_MOREDATA should go to a header file. */
2237 #define MSG_MOREDATA    ((char *)astman_send_response)
2238
2239 /*! \brief send a response with an optional message,
2240  * and terminate it with an empty line.
2241  * m is used only to grab the 'ActionID' field.
2242  *
2243  * Use the explicit constant MSG_MOREDATA to remove the empty line.
2244  * XXX MSG_MOREDATA should go to a header file.
2245  */
2246 static void astman_send_response_full(struct mansession *s, const struct message *m, char *resp, char *msg, char *listflag)
2247 {
2248         const char *id = astman_get_header(m, "ActionID");
2249
2250         astman_append(s, "Response: %s\r\n", resp);
2251         if (!ast_strlen_zero(id)) {
2252                 astman_append(s, "ActionID: %s\r\n", id);
2253         }
2254         if (listflag) {
2255                 astman_append(s, "EventList: %s\r\n", listflag);        /* Start, complete, cancelled */
2256         }
2257         if (msg == MSG_MOREDATA) {
2258                 return;
2259         } else if (msg) {
2260                 astman_append(s, "Message: %s\r\n\r\n", msg);
2261         } else {
2262                 astman_append(s, "\r\n");
2263         }
2264 }
2265
2266 void astman_send_response(struct mansession *s, const struct message *m, char *resp, char *msg)
2267 {
2268         astman_send_response_full(s, m, resp, msg, NULL);
2269 }
2270
2271 void astman_send_error(struct mansession *s, const struct message *m, char *error)
2272 {
2273         astman_send_response_full(s, m, "Error", error, NULL);
2274 }
2275
2276 void astman_send_error_va(struct mansession *s, const struct message *m, const char *fmt, ...)
2277 {
2278         va_list ap;
2279         struct ast_str *buf;
2280
2281         if (!(buf = ast_str_thread_get(&astman_append_buf, ASTMAN_APPEND_BUF_INITSIZE))) {
2282                 return;
2283         }
2284
2285         va_start(ap, fmt);
2286         ast_str_set_va(&buf, 0, fmt, ap);
2287         va_end(ap);
2288
2289         astman_send_response_full(s, m, "Error", ast_str_buffer(buf), NULL);
2290         ast_free(buf);
2291 }
2292
2293 void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
2294 {
2295         astman_send_response_full(s, m, "Success", msg, NULL);
2296 }
2297
2298 static void astman_start_ack(struct mansession *s, const struct message *m)
2299 {
2300         astman_send_response_full(s, m, "Success", MSG_MOREDATA, NULL);
2301 }
2302
2303 void astman_send_listack(struct mansession *s, const struct message *m, char *msg, char *listflag)
2304 {
2305         astman_send_response_full(s, m, "Success", msg, listflag);
2306 }
2307
2308 /*! \brief Lock the 'mansession' structure. */
2309 static void mansession_lock(struct mansession *s)
2310 {
2311         ast_mutex_lock(&s->lock);
2312 }
2313
2314 /*! \brief Unlock the 'mansession' structure. */
2315 static void mansession_unlock(struct mansession *s)
2316 {
2317         ast_mutex_unlock(&s->lock);
2318 }
2319
2320 /*! \brief
2321    Rather than braindead on,off this now can also accept a specific int mask value
2322    or a ',' delim list of mask strings (the same as manager.conf) -anthm
2323 */
2324 static int set_eventmask(struct mansession *s, const char *eventmask)
2325 {
2326         int maskint = strings_to_mask(eventmask);
2327
2328         ao2_lock(s->session);
2329         if (maskint >= 0) {
2330                 s->session->send_events = maskint;
2331         }
2332         ao2_unlock(s->session);
2333
2334         return maskint;
2335 }
2336
2337 static enum ast_security_event_transport_type mansession_get_transport(const struct mansession *s)
2338 {
2339         return s->tcptls_session->parent->tls_cfg ? AST_SECURITY_EVENT_TRANSPORT_TLS :
2340                         AST_SECURITY_EVENT_TRANSPORT_TCP;
2341 }
2342
2343 static void report_invalid_user(const struct mansession *s, const char *username)
2344 {
2345         char session_id[32];
2346         struct ast_security_event_inval_acct_id inval_acct_id = {
2347                 .common.event_type = AST_SECURITY_EVENT_INVAL_ACCT_ID,
2348                 .common.version    = AST_SECURITY_EVENT_INVAL_ACCT_ID_VERSION,
2349                 .common.service    = "AMI",
2350                 .common.account_id = username,
2351                 .common.session_tv = &s->session->sessionstart_tv,
2352                 .common.local_addr = {
2353                         .addr      = &s->tcptls_session->parent->local_address,
2354                         .transport = mansession_get_transport(s),
2355                 },
2356                 .common.remote_addr = {
2357                         .addr      = &s->session->addr,
2358                         .transport = mansession_get_transport(s),
2359                 },
2360                 .common.session_id = session_id,
2361         };
2362
2363         snprintf(session_id, sizeof(session_id), "%p", s);
2364
2365         ast_security_event_report(AST_SEC_EVT(&inval_acct_id));
2366 }
2367
2368 static void report_failed_acl(const struct mansession *s, const char *username)
2369 {
2370         char session_id[32];
2371         struct ast_security_event_failed_acl failed_acl_event = {
2372                 .common.event_type = AST_SECURITY_EVENT_FAILED_ACL,
2373                 .common.version    = AST_SECURITY_EVENT_FAILED_ACL_VERSION,
2374                 .common.service    = "AMI",
2375                 .common.account_id = username,
2376                 .common.session_tv = &s->session->sessionstart_tv,
2377                 .common.local_addr = {
2378                         .addr      = &s->tcptls_session->parent->local_address,
2379                         .transport = mansession_get_transport(s),
2380                 },
2381                 .common.remote_addr = {
2382                         .addr      = &s->session->addr,
2383                         .transport = mansession_get_transport(s),
2384                 },
2385                 .common.session_id = session_id,
2386         };
2387
2388         snprintf(session_id, sizeof(session_id), "%p", s->session);
2389
2390         ast_security_event_report(AST_SEC_EVT(&failed_acl_event));
2391 }
2392
2393 static void report_inval_password(const struct mansession *s, const char *username)
2394 {
2395         char session_id[32];
2396         struct ast_security_event_inval_password inval_password = {
2397                 .common.event_type = AST_SECURITY_EVENT_INVAL_PASSWORD,
2398                 .common.version    = AST_SECURITY_EVENT_INVAL_PASSWORD_VERSION,
2399                 .common.service    = "AMI",
2400                 .common.account_id = username,
2401                 .common.session_tv = &s->session->sessionstart_tv,
2402                 .common.local_addr = {
2403                         .addr      = &s->tcptls_session->parent->local_address,
2404                         .transport = mansession_get_transport(s),
2405                 },
2406                 .common.remote_addr = {
2407                         .addr      = &s->session->addr,
2408                         .transport = mansession_get_transport(s),
2409                 },
2410                 .common.session_id = session_id,
2411         };
2412
2413         snprintf(session_id, sizeof(session_id), "%p", s->session);
2414
2415         ast_security_event_report(AST_SEC_EVT(&inval_password));
2416 }
2417
2418 static void report_auth_success(const struct mansession *s)
2419 {
2420         char session_id[32];
2421         struct ast_security_event_successful_auth successful_auth = {
2422                 .common.event_type = AST_SECURITY_EVENT_SUCCESSFUL_AUTH,
2423                 .common.version    = AST_SECURITY_EVENT_SUCCESSFUL_AUTH_VERSION,
2424                 .common.service    = "AMI",
2425                 .common.account_id = s->session->username,
2426                 .common.session_tv = &s->session->sessionstart_tv,
2427                 .common.local_addr = {
2428                         .addr      = &s->tcptls_session->parent->local_address,
2429                         .transport = mansession_get_transport(s),
2430                 },
2431                 .common.remote_addr = {
2432                         .addr      = &s->session->addr,
2433                         .transport = mansession_get_transport(s),
2434                 },
2435                 .common.session_id = session_id,
2436         };
2437
2438         snprintf(session_id, sizeof(session_id), "%p", s->session);
2439
2440         ast_security_event_report(AST_SEC_EVT(&successful_auth));
2441 }
2442
2443 static void report_req_not_allowed(const struct mansession *s, const char *action)
2444 {
2445         char session_id[32];
2446         char request_type[64];
2447         struct ast_security_event_req_not_allowed req_not_allowed = {
2448                 .common.event_type = AST_SECURITY_EVENT_REQ_NOT_ALLOWED,
2449                 .common.version    = AST_SECURITY_EVENT_REQ_NOT_ALLOWED_VERSION,
2450                 .common.service    = "AMI",
2451                 .common.account_id = s->session->username,
2452                 .common.session_tv = &s->session->sessionstart_tv,
2453                 .common.local_addr = {
2454                         .addr      = &s->tcptls_session->parent->local_address,
2455                         .transport = mansession_get_transport(s),
2456                 },
2457                 .common.remote_addr = {
2458                         .addr      = &s->session->addr,
2459                         .transport = mansession_get_transport(s),
2460                 },
2461                 .common.session_id = session_id,
2462
2463                 .request_type      = request_type,
2464         };
2465
2466         snprintf(session_id, sizeof(session_id), "%p", s->session);
2467         snprintf(request_type, sizeof(request_type), "Action: %s", action);
2468
2469         ast_security_event_report(AST_SEC_EVT(&req_not_allowed));
2470 }
2471
2472 static void report_req_bad_format(const struct mansession *s, const char *action)
2473 {
2474         char session_id[32];
2475         char request_type[64];
2476         struct ast_security_event_req_bad_format req_bad_format = {
2477                 .common.event_type = AST_SECURITY_EVENT_REQ_BAD_FORMAT,
2478                 .common.version    = AST_SECURITY_EVENT_REQ_BAD_FORMAT_VERSION,
2479                 .common.service    = "AMI",
2480                 .common.account_id = s->session->username,
2481                 .common.session_tv = &s->session->sessionstart_tv,
2482                 .common.local_addr = {
2483                         .addr      = &s->tcptls_session->parent->local_address,
2484                         .transport = mansession_get_transport(s),
2485                 },
2486                 .common.remote_addr = {
2487                         .addr      = &s->session->addr,
2488                         .transport = mansession_get_transport(s),
2489                 },
2490                 .common.session_id = session_id,
2491
2492                 .request_type      = request_type,
2493         };
2494
2495         snprintf(session_id, sizeof(session_id), "%p", s->session);
2496         snprintf(request_type, sizeof(request_type), "Action: %s", action);
2497
2498         ast_security_event_report(AST_SEC_EVT(&req_bad_format));
2499 }
2500
2501 static void report_failed_challenge_response(const struct mansession *s,
2502                 const char *response, const char *expected_response)
2503 {
2504         char session_id[32];
2505         struct ast_security_event_chal_resp_failed chal_resp_failed = {
2506                 .common.event_type = AST_SECURITY_EVENT_CHAL_RESP_FAILED,
2507                 .common.version    = AST_SECURITY_EVENT_CHAL_RESP_FAILED_VERSION,
2508                 .common.service    = "AMI",
2509                 .common.account_id = s->session->username,
2510                 .common.session_tv = &s->session->sessionstart_tv,
2511                 .common.local_addr = {
2512                         .addr      = &s->tcptls_session->parent->local_address,
2513                         .transport = mansession_get_transport(s),
2514                 },
2515                 .common.remote_addr = {
2516                         .addr      = &s->session->addr,
2517                         .transport = mansession_get_transport(s),
2518                 },
2519                 .common.session_id = session_id,
2520
2521                 .challenge         = s->session->challenge,
2522                 .response          = response,
2523                 .expected_response = expected_response,
2524         };
2525
2526         snprintf(session_id, sizeof(session_id), "%p", s->session);
2527
2528         ast_security_event_report(AST_SEC_EVT(&chal_resp_failed));
2529 }
2530
2531 static void report_session_limit(const struct mansession *s)
2532 {
2533         char session_id[32];
2534         struct ast_security_event_session_limit session_limit = {
2535                 .common.event_type = AST_SECURITY_EVENT_SESSION_LIMIT,
2536                 .common.version    = AST_SECURITY_EVENT_SESSION_LIMIT_VERSION,
2537                 .common.service    = "AMI",
2538                 .common.account_id = s->session->username,
2539                 .common.session_tv = &s->session->sessionstart_tv,
2540                 .common.local_addr = {
2541                         .addr      = &s->tcptls_session->parent->local_address,
2542                         .transport = mansession_get_transport(s),
2543                 },
2544                 .common.remote_addr = {
2545                         .addr      = &s->session->addr,
2546                         .transport = mansession_get_transport(s),
2547                 },
2548                 .common.session_id = session_id,
2549         };
2550
2551         snprintf(session_id, sizeof(session_id), "%p", s->session);
2552
2553         ast_security_event_report(AST_SEC_EVT(&session_limit));
2554 }
2555
2556 /*
2557  * Here we start with action_ handlers for AMI actions,
2558  * and the internal functions used by them.
2559  * Generally, the handlers are called action_foo()
2560  */
2561
2562 /* helper function for action_login() */
2563 static int authenticate(struct mansession *s, const struct message *m)
2564 {
2565         const char *username = astman_get_header(m, "Username");
2566         const char *password = astman_get_header(m, "Secret");
2567         int error = -1;
2568         struct ast_manager_user *user = NULL;
2569         regex_t *regex_filter;
2570         struct ao2_iterator filter_iter;
2571
2572         if (ast_strlen_zero(username)) {        /* missing username */
2573                 return -1;
2574         }
2575
2576         /* locate user in locked state */
2577         AST_RWLIST_WRLOCK(&users);
2578
2579         if (!(user = get_manager_by_name_locked(username))) {
2580                 report_invalid_user(s, username);
2581                 ast_log(LOG_NOTICE, "%s tried to authenticate with nonexistent user '%s'\n", ast_sockaddr_stringify_addr(&s->session->addr), username);
2582         } else if (user->acl && (ast_apply_acl(user->acl, &s->session->addr, "Manager User ACL: ") == AST_SENSE_DENY)) {
2583                 report_failed_acl(s, username);
2584                 ast_log(LOG_NOTICE, "%s failed to pass IP ACL as '%s'\n", ast_sockaddr_stringify_addr(&s->session->addr), username);
2585         } else if (!strcasecmp(astman_get_header(m, "AuthType"), "MD5")) {
2586                 const char *key = astman_get_header(m, "Key");
2587                 if (!ast_strlen_zero(key) && !ast_strlen_zero(s->session->challenge) && user->secret) {
2588                         int x;
2589                         int len = 0;
2590                         char md5key[256] = "";
2591                         struct MD5Context md5;
2592                         unsigned char digest[16];
2593
2594                         MD5Init(&md5);
2595                         MD5Update(&md5, (unsigned char *) s->session->challenge, strlen(s->session->challenge));
2596                         MD5Update(&md5, (unsigned char *) user->secret, strlen(user->secret));
2597                         MD5Final(digest, &md5);
2598                         for (x = 0; x < 16; x++)
2599                                 len += sprintf(md5key + len, "%2.2x", digest[x]);
2600                         if (!strcmp(md5key, key)) {
2601                                 error = 0;
2602                         } else {
2603                                 report_failed_challenge_response(s, key, md5key);
2604                         }
2605                 } else {
2606                         ast_debug(1, "MD5 authentication is not possible.  challenge: '%s'\n",
2607                                 S_OR(s->session->challenge, ""));
2608                 }
2609         } else if (user->secret) {
2610                 if (!strcmp(password, user->secret)) {
2611                         error = 0;
2612                 } else {
2613                         report_inval_password(s, username);
2614                 }
2615         }
2616
2617         if (error) {
2618                 ast_log(LOG_NOTICE, "%s failed to authenticate as '%s'\n", ast_sockaddr_stringify_addr(&s->session->addr), username);
2619                 AST_RWLIST_UNLOCK(&users);
2620                 return -1;
2621         }
2622
2623         /* auth complete */
2624
2625         /* All of the user parameters are copied to the session so that in the event
2626         * of a reload and a configuration change, the session parameters are not
2627         * changed. */
2628         ast_copy_string(s->session->username, username, sizeof(s->session->username));
2629         s->session->readperm = user->readperm;
2630         s->session->writeperm = user->writeperm;
2631         s->session->writetimeout = user->writetimeout;
2632         if (user->chanvars) {
2633                 s->session->chanvars = ast_variables_dup(user->chanvars);
2634         }
2635
2636         filter_iter = ao2_iterator_init(user->whitefilters, 0);
2637         while ((regex_filter = ao2_iterator_next(&filter_iter))) {
2638                 ao2_t_link(s->session->whitefilters, regex_filter, "add white user filter to session");
2639                 ao2_t_ref(regex_filter, -1, "remove iterator ref");
2640         }
2641         ao2_iterator_destroy(&filter_iter);
2642
2643         filter_iter = ao2_iterator_init(user->blackfilters, 0);
2644         while ((regex_filter = ao2_iterator_next(&filter_iter))) {
2645                 ao2_t_link(s->session->blackfilters, regex_filter, "add black user filter to session");
2646                 ao2_t_ref(regex_filter, -1, "remove iterator ref");
2647         }
2648         ao2_iterator_destroy(&filter_iter);
2649
2650         s->session->sessionstart = time(NULL);
2651         s->session->sessionstart_tv = ast_tvnow();
2652         set_eventmask(s, astman_get_header(m, "Events"));
2653
2654         report_auth_success(s);
2655
2656         AST_RWLIST_UNLOCK(&users);
2657         return 0;
2658 }
2659
2660 static int action_ping(struct mansession *s, const struct message *m)
2661 {
2662         const char *actionid = astman_get_header(m, "ActionID");
2663         struct timeval now = ast_tvnow();
2664
2665         astman_append(s, "Response: Success\r\n");
2666         if (!ast_strlen_zero(actionid)){
2667                 astman_append(s, "ActionID: %s\r\n", actionid);
2668         }
2669         astman_append(
2670                 s,
2671                 "Ping: Pong\r\n"
2672                 "Timestamp: %ld.%06lu\r\n"
2673                 "\r\n",
2674                 (long) now.tv_sec, (unsigned long) now.tv_usec);
2675         return 0;
2676 }
2677
2678 static int action_getconfig(struct mansession *s, const struct message *m)
2679 {
2680         struct ast_config *cfg;
2681         const char *fn = astman_get_header(m, "Filename");
2682         const char *category = astman_get_header(m, "Category");
2683         int catcount = 0;
2684         int lineno = 0;
2685         char *cur_category = NULL;
2686         struct ast_variable *v;
2687         struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE };
2688
2689         if (ast_strlen_zero(fn)) {
2690                 astman_send_error(s, m, "Filename not specified");
2691                 return 0;
2692         }
2693         cfg = ast_config_load2(fn, "manager", config_flags);
2694         if (cfg == CONFIG_STATUS_FILEMISSING) {
2695                 astman_send_error(s, m, "Config file not found");
2696                 return 0;
2697         } else if (cfg == CONFIG_STATUS_FILEINVALID) {
2698                 astman_send_error(s, m, "Config file has invalid format");
2699                 return 0;
2700         }
2701
2702         astman_start_ack(s, m);
2703         while ((cur_category = ast_category_browse(cfg, cur_category))) {
2704                 if (ast_strlen_zero(category) || (!ast_strlen_zero(category) && !strcmp(category, cur_category))) {
2705                         lineno = 0;
2706                         astman_append(s, "Category-%06d: %s\r\n", catcount, cur_category);
2707                         for (v = ast_variable_browse(cfg, cur_category); v; v = v->next) {
2708                                 astman_append(s, "Line-%06d-%06d: %s=%s\r\n", catcount, lineno++, v->name, v->value);
2709                         }
2710                         catcount++;
2711                 }
2712         }
2713         if (!ast_strlen_zero(category) && catcount == 0) { /* TODO: actually, a config with no categories doesn't even get loaded */
2714                 astman_append(s, "No categories found\r\n");
2715         }
2716         ast_config_destroy(cfg);
2717         astman_append(s, "\r\n");
2718
2719         return 0;
2720 }
2721
2722 static int action_listcategories(struct mansession *s, const struct message *m)
2723 {
2724         struct ast_config *cfg;
2725         const char *fn = astman_get_header(m, "Filename");
2726         char *category = NULL;
2727         struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE };
2728         int catcount = 0;
2729
2730         if (ast_strlen_zero(fn)) {
2731                 astman_send_error(s, m, "Filename not specified");
2732                 return 0;
2733         }
2734         if (!(cfg = ast_config_load2(fn, "manager", config_flags))) {
2735                 astman_send_error(s, m, "Config file not found");
2736                 return 0;
2737         } else if (cfg == CONFIG_STATUS_FILEINVALID) {
2738                 astman_send_error(s, m, "Config file has invalid format");
2739                 return 0;
2740         }
2741         astman_start_ack(s, m);
2742         while ((category = ast_category_browse(cfg, category))) {
2743                 astman_append(s, "Category-%06d: %s\r\n", catcount, category);
2744                 catcount++;
2745         }
2746         if (catcount == 0) { /* TODO: actually, a config with no categories doesn't even get loaded */
2747                 astman_append(s, "Error: no categories found\r\n");
2748         }
2749         ast_config_destroy(cfg);
2750         astman_append(s, "\r\n");
2751
2752         return 0;
2753 }
2754
2755
2756
2757
2758 /*! The amount of space in out must be at least ( 2 * strlen(in) + 1 ) */
2759 static void json_escape(char *out, const char *in)
2760 {
2761         for (; *in; in++) {
2762                 if (*in == '\\' || *in == '\"') {
2763                         *out++ = '\\';
2764                 }
2765                 *out++ = *in;
2766         }
2767         *out = '\0';
2768 }
2769
2770 /*!
2771  * \internal
2772  * \brief Append a JSON escaped string to the manager stream.
2773  *
2774  * \param s AMI stream to append a string.
2775  * \param str String to append to the stream after JSON escaping it.
2776  *
2777  * \return Nothing
2778  */
2779 static void astman_append_json(struct mansession *s, const char *str)
2780 {
2781         char *buf;
2782
2783         buf = ast_alloca(2 * strlen(str) + 1);
2784         json_escape(buf, str);
2785         astman_append(s, "%s", buf);
2786 }
2787
2788 static int action_getconfigjson(struct mansession *s, const struct message *m)
2789 {
2790         struct ast_config *cfg;
2791         const char *fn = astman_get_header(m, "Filename");
2792         char *category = NULL;
2793         struct ast_variable *v;
2794         int comma1 = 0;
2795         struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE };
2796
2797         if (ast_strlen_zero(fn)) {
2798                 astman_send_error(s, m, "Filename not specified");
2799                 return 0;
2800         }
2801
2802         if (!(cfg = ast_config_load2(fn, "manager", config_flags))) {
2803                 astman_send_error(s, m, "Config file not found");
2804                 return 0;
2805         } else if (cfg == CONFIG_STATUS_FILEINVALID) {
2806                 astman_send_error(s, m, "Config file has invalid format");
2807                 return 0;
2808         }
2809
2810         astman_start_ack(s, m);
2811         astman_append(s, "JSON: {");
2812         while ((category = ast_category_browse(cfg, category))) {
2813                 int comma2 = 0;
2814
2815                 astman_append(s, "%s\"", comma1 ? "," : "");
2816                 astman_append_json(s, category);
2817                 astman_append(s, "\":[");
2818                 comma1 = 1;
2819                 for (v = ast_variable_browse(cfg, category); v; v = v->next) {
2820                         astman_append(s, "%s\"", comma2 ? "," : "");
2821                         astman_append_json(s, v->name);
2822                         astman_append(s, "\":\"");
2823                         astman_append_json(s, v->value);
2824                         astman_append(s, "\"");
2825                         comma2 = 1;
2826                 }
2827                 astman_append(s, "]");
2828         }
2829         astman_append(s, "}\r\n\r\n");
2830
2831         ast_config_destroy(cfg);
2832
2833         return 0;
2834 }
2835
2836 /*! \brief helper function for action_updateconfig */
2837 static enum error_type handle_updates(struct mansession *s, const struct message *m, struct ast_config *cfg, const char *dfn)
2838 {
2839         int x;
2840         char hdr[40];
2841         const char *action, *cat, *var, *value, *match, *line;
2842         struct ast_category *category;
2843         struct ast_variable *v;
2844         struct ast_str *str1 = ast_str_create(16), *str2 = ast_str_create(16);
2845         enum error_type result = 0;
2846
2847         for (x = 0; x < 100000; x++) {  /* 100000 = the max number of allowed updates + 1 */
2848                 unsigned int object = 0;
2849
2850                 snprintf(hdr, sizeof(hdr), "Action-%06d", x);
2851                 action = astman_get_header(m, hdr);
2852                 if (ast_strlen_zero(action))            /* breaks the for loop if no action header */
2853                         break;                          /* this could cause problems if actions come in misnumbered */
2854
2855                 snprintf(hdr, sizeof(hdr), "Cat-%06d", x);
2856                 cat = astman_get_header(m, hdr);
2857                 if (ast_strlen_zero(cat)) {             /* every action needs a category */
2858                         result =  UNSPECIFIED_CATEGORY;
2859                         break;
2860                 }
2861
2862                 snprintf(hdr, sizeof(hdr), "Var-%06d", x);
2863                 var = astman_get_header(m, hdr);
2864
2865                 snprintf(hdr, sizeof(hdr), "Value-%06d", x);
2866                 value = astman_get_header(m, hdr);
2867
2868                 if (!ast_strlen_zero(value) && *value == '>') {
2869                         object = 1;
2870                         value++;
2871                 }
2872
2873                 snprintf(hdr, sizeof(hdr), "Match-%06d", x);
2874                 match = astman_get_header(m, hdr);
2875
2876                 snprintf(hdr, sizeof(hdr), "Line-%06d", x);
2877                 line = astman_get_header(m, hdr);
2878
2879                 if (!strcasecmp(action, "newcat")) {
2880                         if (ast_category_get(cfg,cat)) {        /* check to make sure the cat doesn't */
2881                                 result = FAILURE_NEWCAT;        /* already exist */
2882                                 break;
2883                         }
2884                         if (!(category = ast_category_new(cat, dfn, -1))) {
2885                                 result = FAILURE_ALLOCATION;
2886                                 break;
2887                         }
2888                         if (ast_strlen_zero(match)) {
2889                                 ast_category_append(cfg, category);
2890                         } else {
2891                                 ast_category_insert(cfg, category, match);
2892                         }
2893                 } else if (!strcasecmp(action, "renamecat")) {
2894                         if (ast_strlen_zero(value)) {
2895                                 result = UNSPECIFIED_ARGUMENT;
2896                                 break;
2897                         }
2898                         if (!(category = ast_category_get(cfg, cat))) {
2899                                 result = UNKNOWN_CATEGORY;
2900                                 break;
2901                         }
2902                         ast_category_rename(category, value);
2903                 } else if (!strcasecmp(action, "delcat")) {
2904                         if (ast_category_delete(cfg, cat)) {
2905                                 result = FAILURE_DELCAT;
2906                                 break;
2907                         }
2908                 } else if (!strcasecmp(action, "emptycat")) {
2909                         if (ast_category_empty(cfg, cat)) {
2910                                 result = FAILURE_EMPTYCAT;
2911                                 break;
2912                         }
2913                 } else if (!strcasecmp(action, "update")) {
2914                         if (ast_strlen_zero(var)) {
2915                                 result = UNSPECIFIED_ARGUMENT;
2916                                 break;
2917                         }
2918                         if (!(category = ast_category_get(cfg,cat))) {
2919                                 result = UNKNOWN_CATEGORY;
2920                                 break;
2921                         }
2922                         if (ast_variable_update(category, var, value, match, object)) {
2923                                 result = FAILURE_UPDATE;
2924                                 break;
2925                         }
2926                 } else if (!strcasecmp(action, "delete")) {
2927                         if ((ast_strlen_zero(var) && ast_strlen_zero(line))) {
2928                                 result = UNSPECIFIED_ARGUMENT;
2929                                 break;
2930                         }
2931                         if (!(category = ast_category_get(cfg, cat))) {
2932                                 result = UNKNOWN_CATEGORY;
2933                                 break;
2934                         }
2935                         if (ast_variable_delete(category, var, match, line)) {
2936                                 result = FAILURE_DELETE;
2937                                 break;
2938                         }
2939                 } else if (!strcasecmp(action, "append")) {
2940                         if (ast_strlen_zero(var)) {
2941                                 result = UNSPECIFIED_ARGUMENT;
2942                                 break;
2943                         }
2944                         if (!(category = ast_category_get(cfg, cat))) {
2945                                 result = UNKNOWN_CATEGORY;
2946                                 break;
2947                         }
2948                         if (!(v = ast_variable_new(var, value, dfn))) {
2949                                 result = FAILURE_ALLOCATION;
2950                                 break;
2951                         }
2952                         if (object || (match && !strcasecmp(match, "object"))) {
2953                                 v->object = 1;
2954                         }
2955                         ast_variable_append(category, v);
2956                 } else if (!strcasecmp(action, "insert")) {
2957                         if (ast_strlen_zero(var) || ast_strlen_zero(line)) {
2958                                 result = UNSPECIFIED_ARGUMENT;
2959                                 break;
2960                         }
2961                         if (!(category = ast_category_get(cfg, cat))) {
2962                                 result = UNKNOWN_CATEGORY;
2963                                 break;
2964                         }
2965                         if (!(v = ast_variable_new(var, value, dfn))) {
2966                                 result = FAILURE_ALLOCATION;
2967                                 break;
2968                         }
2969                         ast_variable_insert(category, v, line);
2970                 }
2971                 else {
2972                         ast_log(LOG_WARNING, "Action-%06d: %s not handled\n", x, action);
2973                         result = UNKNOWN_ACTION;
2974                         break;
2975                 }
2976         }
2977         ast_free(str1);
2978         ast_free(str2);
2979         return result;
2980 }
2981
2982 static int action_updateconfig(struct mansession *s, const struct message *m)
2983 {
2984         struct ast_config *cfg;
2985         const char *sfn = astman_get_header(m, "SrcFilename");
2986         const char *dfn = astman_get_header(m, "DstFilename");
2987         int res;
2988         const char *rld = astman_get_header(m, "Reload");
2989         struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE };
2990         enum error_type result;
2991
2992         if (ast_strlen_zero(sfn) || ast_strlen_zero(dfn)) {
2993                 astman_send_error(s, m, "Filename not specified");
2994                 return 0;
2995         }
2996         if (!(cfg = ast_config_load2(sfn, "manager", config_flags))) {
2997                 astman_send_error(s, m, "Config file not found");
2998                 return 0;
2999         } else if (cfg == CONFIG_STATUS_FILEINVALID) {
3000                 astman_send_error(s, m, "Config file has invalid format");
3001                 return 0;
3002         }
3003         result = handle_updates(s, m, cfg, dfn);
3004         if (!result) {
3005                 ast_include_rename(cfg, sfn, dfn); /* change the include references from dfn to sfn, so things match up */
3006                 res = ast_config_text_file_save(dfn, cfg, "Manager");
3007                 ast_config_destroy(cfg);
3008                 if (res) {
3009                         astman_send_error(s, m, "Save of config failed");
3010                         return 0;
3011                 }
3012                 astman_send_ack(s, m, NULL);
3013                 if (!ast_strlen_zero(rld)) {
3014                         if (ast_true(rld)) {
3015                                 rld = NULL;
3016                         }
3017                         ast_module_reload(rld);
3018                 }
3019         } else {
3020                 ast_config_destroy(cfg);
3021                 switch(result) {
3022                 case UNKNOWN_ACTION:
3023                         astman_send_error(s, m, "Unknown action command");
3024                         break;
3025                 case UNKNOWN_CATEGORY:
3026                         astman_send_error(s, m, "Given category does not exist");
3027                         break;
3028                 case UNSPECIFIED_CATEGORY:
3029                         astman_send_error(s, m, "Category not specified");
3030                         break;
3031                 case UNSPECIFIED_ARGUMENT:
3032                         astman_send_error(s, m, "Problem with category, value, or line (if required)");
3033                         break;
3034                 case FAILURE_ALLOCATION:
3035                         astman_send_error(s, m, "Memory allocation failure, this should not happen");
3036                         break;
3037                 case FAILURE_NEWCAT:
3038                         astman_send_error(s, m, "Create category did not complete successfully");
3039                         break;
3040                 case FAILURE_DELCAT:
3041                         astman_send_error(s, m, "Delete category did not complete successfully");
3042                         break;
3043                 case FAILURE_EMPTYCAT:
3044                         astman_send_error(s, m, "Empty category did not complete successfully");
3045                         break;
3046                 case FAILURE_UPDATE:
3047                         astman_send_error(s, m, "Update did not complete successfully");
3048                         break;
3049                 case FAILURE_DELETE:
3050                         astman_send_error(s, m, "Delete did not complete successfully");
3051                         break;
3052                 case FAILURE_APPEND:
3053                         astman_send_error(s, m, "Append did not complete successfully");
3054                         break;
3055                 }
3056         }
3057         return 0;
3058 }
3059
3060 static int action_createconfig(struct mansession *s, const struct message *m)
3061 {
3062         int fd;
3063         const char *fn = astman_get_header(m, "Filename");
3064         struct ast_str *filepath = ast_str_alloca(PATH_MAX);
3065         ast_str_set(&filepath, 0, "%s/", ast_config_AST_CONFIG_DIR);
3066         ast_str_append(&filepath, 0, "%s", fn);
3067
3068         if ((fd = open(ast_str_buffer(filepath), O_CREAT | O_EXCL, AST_FILE_MODE)) != -1) {
3069                 close(fd);
3070                 astman_send_ack(s, m, "New configuration file created successfully");
3071         } else {
3072                 astman_send_error(s, m, strerror(errno));
3073         }
3074
3075         return 0;
3076 }
3077
3078 static int action_waitevent(struct mansession *s, const struct message *m)
3079 {
3080         const char *timeouts = astman_get_header(m, "Timeout");
3081         int timeout = -1;
3082         int x;
3083         int needexit = 0;
3084         const char *id = astman_get_header(m, "ActionID");
3085         char idText[256];
3086
3087         if (!ast_strlen_zero(id)) {
3088                 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
3089         } else {
3090                 idText[0] = '\0';
3091         }
3092
3093         if (!ast_strlen_zero(timeouts)) {
3094                 sscanf(timeouts, "%30i", &timeout);
3095                 if (timeout < -1) {
3096                         timeout = -1;
3097                 }
3098                 /* XXX maybe put an upper bound, or prevent the use of 0 ? */
3099         }
3100
3101         ao2_lock(s->session);
3102         if (s->session->waiting_thread != AST_PTHREADT_NULL) {
3103                 pthread_kill(s->session->waiting_thread, SIGURG);
3104         }
3105
3106         if (s->session->managerid) { /* AMI-over-HTTP session */
3107                 /*
3108                  * Make sure the timeout is within the expire time of the session,
3109                  * as the client will likely abort the request if it does not see
3110                  * data coming after some amount of time.
3111                  */
3112                 time_t now = time(NULL);
3113                 int max = s->session->sessiontimeout - now - 10;
3114
3115                 if (max < 0) {  /* We are already late. Strange but possible. */
3116                         max = 0;
3117                 }
3118                 if (timeout < 0 || timeout > max) {
3119                         timeout = max;
3120                 }
3121                 if (!s->session->send_events) { /* make sure we record events */
3122                         s->session->send_events = -1;
3123                 }
3124         }
3125         ao2_unlock(s->session);
3126
3127         /* XXX should this go inside the lock ? */
3128         s->session->waiting_thread = pthread_self();    /* let new events wake up this thread */
3129         ast_debug(1, "Starting waiting for an event!\n");
3130
3131         for (x = 0; x < timeout || timeout < 0; x++) {
3132                 ao2_lock(s->session);
3133                 if (AST_RWLIST_NEXT(s->session->last_ev, eq_next)) {
3134                         needexit = 1;
3135                 }
3136                 /* We can have multiple HTTP session point to the same mansession entry.
3137                  * The way we deal with it is not very nice: newcomers kick out the previous
3138                  * HTTP session. XXX this needs to be improved.
3139                  */
3140                 if (s->session->waiting_thread != pthread_self()) {
3141                         needexit = 1;
3142                 }
3143                 if (s->session->needdestroy) {
3144                         needexit = 1;
3145                 }
3146                 ao2_unlock(s->session);
3147                 if (needexit) {
3148                         break;
3149                 }
3150                 if (s->session->managerid == 0) {       /* AMI session */
3151                         if (ast_wait_for_input(s->session->fd, 1000)) {
3152                                 break;
3153                         }
3154                 } else {        /* HTTP session */
3155                         sleep(1);
3156                 }
3157         }
3158         ast_debug(1, "Finished waiting for an event!\n");
3159
3160         ao2_lock(s->session);
3161         if (s->session->waiting_thread == pthread_self()) {
3162                 struct eventqent *eqe = s->session->last_ev;
3163                 astman_send_response(s, m, "Success", "Waiting for Event completed.");
3164                 while ((eqe = advance_event(eqe))) {
3165                         if (((s->session->readperm & eqe->category) == eqe->category) &&
3166                             ((s->session->send_events & eqe->category) == eqe->category)) {
3167                                 astman_append(s, "%s", eqe->eventdata);
3168                         }
3169                         s->session->last_ev = eqe;
3170                 }
3171                 astman_append(s,
3172                         "Event: WaitEventComplete\r\n"
3173                         "%s"
3174                         "\r\n", idText);
3175                 s->session->waiting_thread = AST_PTHREADT_NULL;
3176         } else {
3177                 ast_debug(1, "Abandoning event request!\n");
3178         }
3179         ao2_unlock(s->session);
3180
3181         return 0;
3182 }
3183
3184 static int action_listcommands(struct mansession *s, const struct message *m)
3185 {
3186         struct manager_action *cur;
3187         struct ast_str *temp = ast_str_alloca(256);
3188
3189         astman_start_ack(s, m);
3190         AST_RWLIST_RDLOCK(&actions);
3191         AST_RWLIST_TRAVERSE(&actions, cur, list) {
3192                 if ((s->session->writeperm & cur->authority) || cur->authority == 0) {
3193                         astman_append(s, "%s: %s (Priv: %s)\r\n",
3194                                 cur->action, cur->synopsis, authority_to_str(cur->authority, &temp));
3195                 }
3196         }
3197         AST_RWLIST_UNLOCK(&actions);
3198         astman_append(s, "\r\n");
3199
3200         return 0;
3201 }
3202
3203 static int action_events(struct mansession *s, const struct message *m)
3204 {
3205         const char *mask = astman_get_header(m, "EventMask");
3206         int res, x;
3207         const char *id = astman_get_header(m, "ActionID");
3208         char id_text[256];
3209
3210         if (!ast_strlen_zero(id)) {
3211                 snprintf(id_text, sizeof(id_text), "ActionID: %s\r\n", id);
3212         } else {
3213                 id_text[0] = '\0';
3214         }
3215
3216         res = set_eventmask(s, mask);
3217         if (broken_events_action) {
3218                 /* if this option is set we should not return a response on
3219                  * error, or when all events are set */
3220
3221                 if (res > 0) {
3222                         for (x = 0; x < ARRAY_LEN(perms); x++) {
3223                                 if (!strcasecmp(perms[x].label, "all") && res == perms[x].num) {
3224                                         return 0;
3225                                 }
3226                         }
3227                         astman_append(s, "Response: Success\r\n%s"
3228                                          "Events: On\r\n\r\n", id_text);
3229                 } else if (res == 0)
3230                         astman_append(s, "Response: Success\r\n%s"
3231                                          "Events: Off\r\n\r\n", id_text);
3232                 return 0;
3233         }
3234
3235         if (res > 0)
3236                 astman_append(s, "Response: Success\r\n%s"
3237                                  "Events: On\r\n\r\n", id_text);
3238         else if (res == 0)
3239                 astman_append(s, "Response: Success\r\n%s"
3240                                  "Events: Off\r\n\r\n", id_text);
3241         else
3242                 astman_send_error(s, m, "Invalid event mask");
3243
3244         return 0;
3245 }
3246
3247 static int action_logoff(struct mansession *s, const struct message *m)
3248 {
3249         astman_send_response(s, m, "Goodbye", "Thanks for all the fish.");
3250         return -1;
3251 }
3252
3253 static int action_login(struct mansession *s, const struct message *m)
3254 {
3255
3256         /* still authenticated - don't process again */
3257         if (s->session->authenticated) {
3258                 astman_send_ack(s, m, "Already authenticated");
3259                 return 0;
3260         }
3261
3262         if (authenticate(s, m)) {
3263                 sleep(1);
3264                 astman_send_error(s, m, "Authentication failed");
3265                 return -1;
3266         }
3267         s->session->authenticated = 1;
3268         ast_atomic_fetchadd_int(&unauth_sessions, -1);
3269         if (manager_displayconnects(s->session)) {
3270                 ast_verb(2, "%sManager '%s' logged on from %s\n", (s->session->managerid ? "HTTP " : ""), s->session->username, ast_sockaddr_stringify_addr(&s->session->addr));
3271         }
3272         astman_send_ack(s, m, "Authentication accepted");
3273         if ((s->session->send_events & EVENT_FLAG_SYSTEM)
3274                 && ast_test_flag(&ast_options, AST_OPT_FLAG_FULLY_BOOTED)) {
3275                 struct ast_str *auth = ast_str_alloca(80);
3276                 const char *cat_str = authority_to_str(EVENT_FLAG_SYSTEM, &auth);
3277                 astman_append(s, "Event: FullyBooted\r\n"
3278                         "Privilege: %s\r\n"
3279                         "Status: Fully Booted\r\n\r\n", cat_str);
3280         }
3281         return 0;
3282 }
3283
3284 static int action_challenge(struct mansession *s, const struct message *m)
3285 {
3286         const char *authtype = astman_get_header(m, "AuthType");
3287
3288         if (!strcasecmp(authtype, "MD5")) {
3289                 if (ast_strlen_zero(s->session->challenge)) {
3290                         snprintf(s->session->challenge, sizeof(s->session->challenge), "%ld", ast_random());
3291                 }
3292                 mansession_lock(s);
3293                 astman_start_ack(s, m);
3294                 astman_append(s, "Challenge: %s\r\n\r\n", s->session->challenge);
3295                 mansession_unlock(s);
3296         } else {
3297                 astman_send_error(s, m, "Must specify AuthType");
3298         }
3299         return 0;
3300 }
3301
3302 static int action_hangup(struct mansession *s, const struct message *m)
3303 {
3304         struct ast_channel *c = NULL;
3305         int causecode = 0; /* all values <= 0 mean 'do not set hangupcause in channel' */
3306         const char *id = astman_get_header(m, "ActionID");
3307         const char *name_or_regex = astman_get_header(m, "Channel");
3308         const char *cause = astman_get_header(m, "Cause");
3309         char idText[256];
3310         regex_t regexbuf;
3311         struct ast_channel_iterator *iter = NULL;
3312         struct ast_str *regex_string;
3313         int channels_matched = 0;
3314
3315         if (ast_strlen_zero(name_or_regex)) {
3316                 astman_send_error(s, m, "No channel specified");
3317                 return 0;
3318         }
3319
3320         if (!ast_strlen_zero(id)) {
3321                 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
3322         } else {
3323                 idText[0] = '\0';
3324         }
3325
3326         if (!ast_strlen_zero(cause)) {
3327                 char *endptr;
3328                 causecode = strtol(cause, &endptr, 10);
3329                 if (causecode < 0 || causecode > 127 || *endptr != '\0') {
3330                         ast_log(LOG_NOTICE, "Invalid 'Cause: %s' in manager action Hangup\n", cause);
3331                         /* keep going, better to hangup without cause than to not hang up at all */
3332                         causecode = 0; /* do not set channel's hangupcause */
3333                 }
3334         }
3335
3336         /************************************************/
3337         /* Regular explicit match channel byname hangup */
3338
3339         if (name_or_regex[0] != '/') {
3340                 if (!(c = ast_channel_get_by_name(name_or_regex))) {
3341                         ast_log(LOG_NOTICE, "!!!!!!!!!! Can't find channel to hang up!\n");
3342                         astman_send_error(s, m, "No such channel");
3343                         return 0;
3344                 }
3345
3346                 ast_verb(3, "%sManager '%s' from %s, hanging up channel: %s\n",
3347                         (s->session->managerid ? "HTTP " : ""),
3348                         s->session->username,
3349                         ast_sockaddr_stringify_addr(&s->session->addr),
3350                         ast_channel_name(c));
3351
3352                 ast_channel_softhangup_withcause_locked(c, causecode);
3353                 c = ast_channel_unref(c);
3354
3355                 astman_send_ack(s, m, "Channel Hungup");
3356
3357                 return 0;
3358         }
3359
3360         /***********************************************/
3361         /* find and hangup any channels matching regex */
3362
3363         regex_string = ast_str_create(strlen(name_or_regex));
3364         if (!regex_string) {
3365                 astman_send_error(s, m, "Memory Allocation Failure");
3366                 return 0;
3367         }
3368
3369         /* Make "/regex/" into "regex" */
3370         if (ast_regex_string_to_regex_pattern(name_or_regex, &regex_string) != 0) {
3371                 astman_send_error(s, m, "Regex format invalid, Channel param should be /regex/");
3372                 ast_free(regex_string);
3373                 return 0;
3374         }
3375
3376         /* if regex compilation fails, hangup fails */
3377         if (regcomp(&regexbuf, ast_str_buffer(regex_string), REG_EXTENDED | REG_NOSUB)) {
3378                 astman_send_error_va(s, m, "Regex compile failed on: %s\n", name_or_regex);
3379                 ast_free(regex_string);
3380                 return 0;
3381         }
3382
3383         astman_send_listack(s, m, "Channels hung up will follow", "start");
3384
3385         iter = ast_channel_iterator_all_new();
3386         if (iter) {
3387                 for (; (c = ast_channel_iterator_next(iter)); ast_channel_unref(c)) {
3388                         if (regexec(&regexbuf, ast_channel_name(c), 0, NULL, 0)) {
3389                                 continue;
3390                         }
3391
3392                         ast_verb(3, "%sManager '%s' from %s, hanging up channel: %s\n",
3393                                 (s->session->managerid ? "HTTP " : ""),
3394                                 s->session->username,
3395                                 ast_sockaddr_stringify_addr(&s->session->addr),
3396                                 ast_channel_name(c));
3397
3398                         ast_channel_softhangup_withcause_locked(c, causecode);
3399                         channels_matched++;
3400
3401                         astman_append(s,
3402                                 "Event: ChannelHungup\r\n"
3403                                 "Channel: %s\r\n"
3404                                 "%s"
3405                                 "\r\n", ast_channel_name(c), idText);
3406                 }
3407                 ast_channel_iterator_destroy(iter);
3408         }
3409
3410         regfree(&regexbuf);
3411         ast_free(regex_string);
3412
3413         astman_append(s,
3414                 "Event: ChannelsHungupListComplete\r\n"
3415                 "EventList: Complete\r\n"
3416                 "ListItems: %d\r\n"
3417                 "%s"
3418                 "\r\n", channels_matched, idText);
3419
3420         return 0;
3421 }
3422
3423 static int action_setvar(struct mansession *s, const struct message *m)
3424 {
3425         struct ast_channel *c = NULL;
3426         const char *name = astman_get_header(m, "Channel");
3427         const char *varname = astman_get_header(m, "Variable");
3428         const char *varval = astman_get_header(m, "Value");
3429         int res = 0;
3430
3431         if (ast_strlen_zero(varname)) {
3432                 astman_send_error(s, m, "No variable specified");
3433                 return 0;
3434         }
3435
3436         if (!ast_strlen_zero(name)) {
3437                 if (!(c = ast_channel_get_by_name(name))) {
3438                         astman_send_error(s, m, "No such channel");
3439                         return 0;
3440                 }
3441         }
3442
3443         res = pbx_builtin_setvar_helper(c, varname, S_OR(varval, ""));
3444
3445         if (c) {
3446                 c = ast_channel_unref(c);
3447         }
3448         if (res == 0) {
3449                 astman_send_ack(s, m, "Variable Set");
3450         } else {
3451                 astman_send_error(s, m, "Variable not set");
3452         }
3453         return 0;
3454 }
3455
3456 static int action_getvar(struct mansession *s, const struct message *m)
3457 {
3458         struct ast_channel *c = NULL;
3459         const char *name = astman_get_header(m, "Channel");
3460         const char *varname = astman_get_header(m, "Variable");
3461         char *varval;
3462         char workspace[1024];
3463
3464         if (ast_strlen_zero(varname)) {
3465                 astman_send_error(s, m, "No variable specified");
3466                 return 0;
3467         }
3468
3469         /* We don't want users with insufficient permissions using certain functions. */
3470         if (!(function_capable_string_allowed_with_auths(varname, s->session->writeperm))) {
3471                 astman_send_error(s, m, "GetVar Access Forbidden: Variable");
3472                 return 0;
3473         }
3474
3475         if (!ast_strlen_zero(name)) {
3476                 if (!(c = ast_channel_get_by_name(name))) {
3477                         astman_send_error(s, m, "No such channel");
3478                         return 0;
3479                 }
3480         }
3481
3482         workspace[0] = '\0';
3483         if (varname[strlen(varname) - 1] == ')') {
3484                 if (!c) {
3485                         c = ast_dummy_channel_alloc();
3486                         if (c) {
3487