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