Asterisk - The Open Source Telephony Project  18.5.0
app_system.c
Go to the documentation of this file.
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 1999 - 2005, Digium, Inc.
5  *
6  * Mark Spencer <[email protected]>
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 Execute arbitrary system commands
22  *
23  * \author Mark Spencer <[email protected]>
24  *
25  * \ingroup applications
26  */
27 
28 /*** MODULEINFO
29  <support_level>core</support_level>
30  ***/
31 
32 #include "asterisk.h"
33 
34 #include "asterisk/pbx.h"
35 #include "asterisk/module.h"
36 #include "asterisk/app.h"
37 #include "asterisk/channel.h" /* autoservice */
38 #include "asterisk/strings.h"
39 #include "asterisk/threadstorage.h"
40 
41 /*** DOCUMENTATION
42  <application name="System" language="en_US">
43  <synopsis>
44  Execute a system command.
45  </synopsis>
46  <syntax>
47  <parameter name="command" required="true">
48  <para>Command to execute</para>
49  <warning><para>Do not use untrusted strings such as <variable>CALLERID(num)</variable>
50  or <variable>CALLERID(name)</variable> as part of the command parameters. You
51  risk a command injection attack executing arbitrary commands if the untrusted
52  strings aren't filtered to remove dangerous characters. See function
53  <variable>FILTER()</variable>.</para></warning>
54  </parameter>
55  </syntax>
56  <description>
57  <para>Executes a command by using system(). If the command
58  fails, the console should report a fallthrough.</para>
59  <para>Result of execution is returned in the <variable>SYSTEMSTATUS</variable> channel variable:</para>
60  <variablelist>
61  <variable name="SYSTEMSTATUS">
62  <value name="FAILURE">
63  Could not execute the specified command.
64  </value>
65  <value name="SUCCESS">
66  Specified command successfully executed.
67  </value>
68  </variable>
69  </variablelist>
70  </description>
71  </application>
72  <application name="TrySystem" language="en_US">
73  <synopsis>
74  Try executing a system command.
75  </synopsis>
76  <syntax>
77  <parameter name="command" required="true">
78  <para>Command to execute</para>
79  <warning><para>Do not use untrusted strings such as <variable>CALLERID(num)</variable>
80  or <variable>CALLERID(name)</variable> as part of the command parameters. You
81  risk a command injection attack executing arbitrary commands if the untrusted
82  strings aren't filtered to remove dangerous characters. See function
83  <variable>FILTER()</variable>.</para></warning>
84  </parameter>
85  </syntax>
86  <description>
87  <para>Executes a command by using system().</para>
88  <para>Result of execution is returned in the <variable>SYSTEMSTATUS</variable> channel variable:</para>
89  <variablelist>
90  <variable name="SYSTEMSTATUS">
91  <value name="FAILURE">
92  Could not execute the specified command.
93  </value>
94  <value name="SUCCESS">
95  Specified command successfully executed.
96  </value>
97  <value name="APPERROR">
98  Specified command successfully executed, but returned error code.
99  </value>
100  </variable>
101  </variablelist>
102  </description>
103  </application>
104 
105  ***/
106 
108 
109 static char *app = "System";
110 
111 static char *app2 = "TrySystem";
112 
113 static char *chanvar = "SYSTEMSTATUS";
114 
115 static int system_exec_helper(struct ast_channel *chan, const char *data, int failmode)
116 {
117  int res = 0;
118  struct ast_str *buf = ast_str_thread_get(&buf_buf, 16);
119  char *cbuf;
120 
121  if (ast_strlen_zero(data)) {
122  ast_log(LOG_WARNING, "System requires an argument(command)\n");
123  pbx_builtin_setvar_helper(chan, chanvar, "FAILURE");
124  return failmode;
125  }
126 
127  ast_autoservice_start(chan);
128 
129  /* Do our thing here */
130  ast_str_get_encoded_str(&buf, 0, (char *) data);
131  cbuf = ast_str_buffer(buf);
132 
133  if (strchr("\"'", cbuf[0]) && cbuf[ast_str_strlen(buf) - 1] == cbuf[0]) {
134  cbuf[ast_str_strlen(buf) - 1] = '\0';
135  cbuf++;
136  ast_log(LOG_NOTICE, "It is not necessary to quote the argument to the System application.\n");
137  }
138 
139  res = ast_safe_system(cbuf);
140 
141  if ((res < 0) && (errno != ECHILD)) {
142  ast_log(LOG_WARNING, "Unable to execute '%s'\n", (char *)data);
143  pbx_builtin_setvar_helper(chan, chanvar, "FAILURE");
144  res = failmode;
145  } else if (res == 127) {
146  ast_log(LOG_WARNING, "Unable to execute '%s'\n", (char *)data);
147  pbx_builtin_setvar_helper(chan, chanvar, "FAILURE");
148  res = failmode;
149  } else {
150  if (res < 0)
151  res = 0;
152  if (res != 0)
153  pbx_builtin_setvar_helper(chan, chanvar, "APPERROR");
154  else
155  pbx_builtin_setvar_helper(chan, chanvar, "SUCCESS");
156  res = 0;
157  }
158 
159  ast_autoservice_stop(chan);
160 
161  return res;
162 }
163 
164 static int system_exec(struct ast_channel *chan, const char *data)
165 {
166  return system_exec_helper(chan, data, -1);
167 }
168 
169 static int trysystem_exec(struct ast_channel *chan, const char *data)
170 {
171  return system_exec_helper(chan, data, 0);
172 }
173 
174 static int unload_module(void)
175 {
176  int res;
177 
180 
181  return res;
182 }
183 
184 static int load_module(void)
185 {
186  int res;
187 
190 
191  return res;
192 }
193 
194 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Generic System() application");
#define AST_THREADSTORAGE(name)
Define a thread storage variable.
Definition: threadstorage.h:84
Main Channel structure associated with a channel.
#define AST_MODULE_INFO_STANDARD(keystr, desc)
Definition: module.h:567
Asterisk main include file. File version handling, generic pbx functions.
int ast_autoservice_start(struct ast_channel *chan)
Automatically service a channel for us...
Definition: autoservice.c:200
String manipulation functions.
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define LOG_WARNING
Definition: logger.h:274
static int load_module(void)
Definition: app_system.c:184
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
static int unload_module(void)
Definition: app_system.c:174
static int system_exec_helper(struct ast_channel *chan, const char *data, int failmode)
Definition: app_system.c:115
Definitions to aid in the use of thread local storage.
int ast_unregister_application(const char *app)
Unregister an application.
Definition: pbx_app.c:392
int ast_str_get_encoded_str(struct ast_str **str, int maxlen, const char *stream)
Decode a stream of encoded control or extended ASCII characters.
Definition: main/app.c:3015
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42
General Asterisk PBX channel definitions.
Core PBX routines and definitions.
int ast_autoservice_stop(struct ast_channel *chan)
Stop servicing a channel for us...
Definition: autoservice.c:266
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
int ast_safe_system(const char *s)
Safely spawn an OS shell command while closing file descriptors.
Definition: extconf.c:829
int errno
static int system_exec(struct ast_channel *chan, const char *data)
Definition: app_system.c:164
#define LOG_NOTICE
Definition: logger.h:263
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
static char * app
Definition: app_system.c:109
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:688
static int trysystem_exec(struct ast_channel *chan, const char *data)
Definition: app_system.c:169
structure for queuing ARI channel variable setting
Definition: control.c:685
static struct ast_threadstorage buf_buf
Definition: app_system.c:107
struct ast_str * ast_str_thread_get(struct ast_threadstorage *ts, size_t init_len)
Retrieve a thread locally stored dynamic string.
Definition: strings.h:861
#define ASTERISK_GPL_KEY
The text the key() function should return.
Definition: module.h:46
Asterisk module definitions.
static char * app2
Definition: app_system.c:111
Application convenience functions, designed to give consistent look and feel to Asterisk apps...
#define ast_register_application_xml(app, execute)
Register an application using XML documentation.
Definition: module.h:626