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