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