dect
/
asterisk
Archived
13
0
Fork 0

Merged revisions 314628 via svnmerge from

https://origsvn.digium.com/svn/asterisk/branches/1.8

................
  r314628 | mnicholson | 2011-04-21 13:24:05 -0500 (Thu, 21 Apr 2011) | 27 lines
  
  Merged revisions 314620 via svnmerge from 
  https://origsvn.digium.com/svn/asterisk/branches/1.6.2
  
  ................
    r314620 | mnicholson | 2011-04-21 13:22:19 -0500 (Thu, 21 Apr 2011) | 20 lines
    
    Merged revisions 314607 via svnmerge from 
    https://origsvn.digium.com/svn/asterisk/branches/1.4
    
    ........
      r314607 | mnicholson | 2011-04-21 13:19:21 -0500 (Thu, 21 Apr 2011) | 14 lines
      
      Added limits to the number of unauthenticated sessions TCP based protocols are allowed to have open simultaneously.  Also added timeouts for unauthenticated sessions where it made sense to do so.
      
      Unrelated, the manager interface now properly checks if the user has the "system" privilege before executing shell commands via the Originate action. 
      
      AST-2011-005
      AST-2011-006
      
      (closes issue #18787)
      Reported by: kobaz
      
      (related to issue #18996)
      Reported by: tzafrir
    ........
  ................
................


git-svn-id: http://svn.digium.com/svn/asterisk/trunk@314666 f38db490-d61c-443f-a65b-d21fe96a405b
This commit is contained in:
mnicholson 2011-04-21 18:32:50 +00:00
parent c7b7b920af
commit 1c24e78eae
8 changed files with 295 additions and 29 deletions

View File

@ -559,6 +559,10 @@ static int max_expiry = DEFAULT_MAX_EXPIRY; /*!< Maximum accepted registr
static int default_expiry = DEFAULT_DEFAULT_EXPIRY;
static int mwi_expiry = DEFAULT_MWI_EXPIRY;
static int unauth_sessions = 0;
static int authlimit = DEFAULT_AUTHLIMIT;
static int authtimeout = DEFAULT_AUTHTIMEOUT;
/*! \brief Global jitterbuffer configuration - by default, jb is disabled */
static struct ast_jb_conf default_jbconf =
{
@ -2456,21 +2460,48 @@ static void *sip_tcp_worker_fn(void *data)
return _sip_tcp_helper_thread(NULL, tcptls_session);
}
/*! \brief Check if the authtimeout has expired.
* \param start the time when the session started
*
* \retval 0 the timeout has expired
* \retval -1 error
* \return the number of milliseconds until the timeout will expire
*/
static int sip_check_authtimeout(time_t start)
{
int timeout;
time_t now;
if(time(&now) == -1) {
ast_log(LOG_ERROR, "error executing time(): %s\n", strerror(errno));
return -1;
}
timeout = (authtimeout - (now - start)) * 1000;
if (timeout < 0) {
/* we have timed out */
return 0;
}
return timeout;
}
/*! \brief SIP TCP thread management function
This function reads from the socket, parses the packet into a request
*/
static void *_sip_tcp_helper_thread(struct sip_pvt *pvt, struct ast_tcptls_session_instance *tcptls_session)
{
int res, cl;
int res, cl, timeout = -1, authenticated = 0, flags;
time_t start;
struct sip_request req = { 0, } , reqcpy = { 0, };
struct sip_threadinfo *me = NULL;
char buf[1024] = "";
struct pollfd fds[2] = { { 0 }, { 0 }, };
struct ast_tcptls_session_args *ca = NULL;
/* If this is a server session, then the connection has already been setup,
* simply create the threadinfo object so we can access this thread for writing.
*
/* If this is a server session, then the connection has already been
* setup. Check if the authlimit has been reached and if not create the
* threadinfo object so we can access this thread for writing.
*
* if this is a client connection more work must be done.
* 1. We own the parent session args for a client connection. This pointer needs
* to be held on to so we can decrement it's ref count on thread destruction.
@ -2479,6 +2510,22 @@ static void *_sip_tcp_helper_thread(struct sip_pvt *pvt, struct ast_tcptls_sessi
* 3. Last, the tcptls_session must be started.
*/
if (!tcptls_session->client) {
if (ast_atomic_fetchadd_int(&unauth_sessions, +1) >= authlimit) {
/* unauth_sessions is decremented in the cleanup code */
goto cleanup;
}
if ((flags = fcntl(tcptls_session->fd, F_GETFL)) == -1) {
ast_log(LOG_ERROR, "error setting socket to non blocking mode, fcntl() failed: %s\n", strerror(errno));
goto cleanup;
}
flags |= O_NONBLOCK;
if (fcntl(tcptls_session->fd, F_SETFL, flags) == -1) {
ast_log(LOG_ERROR, "error setting socket to non blocking mode, fcntl() failed: %s\n", strerror(errno));
goto cleanup;
}
if (!(me = sip_threadinfo_create(tcptls_session, tcptls_session->ssl ? SIP_TRANSPORT_TLS : SIP_TRANSPORT_TCP))) {
goto cleanup;
}
@ -2510,13 +2557,41 @@ static void *_sip_tcp_helper_thread(struct sip_pvt *pvt, struct ast_tcptls_sessi
goto cleanup;
}
if(time(&start) == -1) {
ast_log(LOG_ERROR, "error executing time(): %s\n", strerror(errno));
goto cleanup;
}
for (;;) {
struct ast_str *str_save;
res = ast_poll(fds, 2, -1); /* polls for both socket and alert_pipe */
if (!tcptls_session->client && req.authenticated && !authenticated) {
authenticated = 1;
ast_atomic_fetchadd_int(&unauth_sessions, -1);
}
/* calculate the timeout for unauthenticated server sessions */
if (!tcptls_session->client && !authenticated ) {
if ((timeout = sip_check_authtimeout(start)) < 0) {
goto cleanup;
}
if (timeout == 0) {
ast_debug(2, "SIP %s server timed out\n", tcptls_session->ssl ? "SSL": "TCP");
goto cleanup;
}
} else {
timeout = -1;
}
res = ast_poll(fds, 2, timeout); /* polls for both socket and alert_pipe */
if (res < 0) {
ast_debug(2, "SIP %s server :: ast_wait_for_input returned %d\n", tcptls_session->ssl ? "SSL": "TCP", res);
goto cleanup;
} else if (res == 0) {
/* timeout */
ast_debug(2, "SIP %s server timed out\n", tcptls_session->ssl ? "SSL": "TCP");
goto cleanup;
}
/* handle the socket event, check for both reads from the socket fd,
@ -2549,6 +2624,29 @@ static void *_sip_tcp_helper_thread(struct sip_pvt *pvt, struct ast_tcptls_sessi
/* Read in headers one line at a time */
while (req.len < 4 || strncmp(REQ_OFFSET_TO_STR(&req, len - 4), "\r\n\r\n", 4)) {
if (!tcptls_session->client && !authenticated ) {
if ((timeout = sip_check_authtimeout(start)) < 0) {
goto cleanup;
}
if (timeout == 0) {
ast_debug(2, "SIP %s server timed out\n", tcptls_session->ssl ? "SSL": "TCP");
goto cleanup;
}
} else {
timeout = -1;
}
res = ast_wait_for_input(tcptls_session->fd, timeout);
if (res < 0) {
ast_debug(2, "SIP %s server :: ast_wait_for_input returned %d\n", tcptls_session->ssl ? "SSL": "TCP", res);
goto cleanup;
} else if (res == 0) {
/* timeout */
ast_debug(2, "SIP %s server timed out\n", tcptls_session->ssl ? "SSL": "TCP");
goto cleanup;
}
ast_mutex_lock(&tcptls_session->lock);
if (!fgets(buf, sizeof(buf), tcptls_session->f)) {
ast_mutex_unlock(&tcptls_session->lock);
@ -2567,6 +2665,29 @@ static void *_sip_tcp_helper_thread(struct sip_pvt *pvt, struct ast_tcptls_sessi
if (sscanf(get_header(&reqcpy, "Content-Length"), "%30d", &cl)) {
while (cl > 0) {
size_t bytes_read;
if (!tcptls_session->client && !authenticated ) {
if ((timeout = sip_check_authtimeout(start)) < 0) {
goto cleanup;
}
if (timeout == 0) {
ast_debug(2, "SIP %s server timed out", tcptls_session->ssl ? "SSL": "TCP");
goto cleanup;
}
} else {
timeout = -1;
}
res = ast_wait_for_input(tcptls_session->fd, timeout);
if (res < 0) {
ast_debug(2, "SIP %s server :: ast_wait_for_input returned %d\n", tcptls_session->ssl ? "SSL": "TCP", res);
goto cleanup;
} else if (res == 0) {
/* timeout */
ast_debug(2, "SIP %s server timed out", tcptls_session->ssl ? "SSL": "TCP");
goto cleanup;
}
ast_mutex_lock(&tcptls_session->lock);
if (!(bytes_read = fread(buf, 1, MIN(sizeof(buf) - 1, cl), tcptls_session->f))) {
ast_mutex_unlock(&tcptls_session->lock);
@ -2626,6 +2747,10 @@ static void *_sip_tcp_helper_thread(struct sip_pvt *pvt, struct ast_tcptls_sessi
ast_debug(2, "Shutting down thread for %s server\n", tcptls_session->ssl ? "SSL" : "TCP");
cleanup:
if (!tcptls_session->client && !authenticated) {
ast_atomic_fetchadd_int(&unauth_sessions, -1);
}
if (me) {
ao2_t_unlink(threadt, me, "Removing tcptls helper thread, thread is closing");
ao2_t_ref(me, -1, "Removing tcp_helper_threads threadinfo ref");
@ -21789,6 +21914,8 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int
}
}
req->authenticated = 1;
/* We have a successful authentication, process the SDP portion if there is one */
if (find_sdp(req)) {
if (process_sdp(p, req, SDP_T38_INITIATE)) {
@ -24020,8 +24147,10 @@ static int handle_request_register(struct sip_pvt *p, struct sip_request *req, s
get_header(req, "To"), ast_sockaddr_stringify(addr),
reason);
append_history(p, "RegRequest", "Failed : Account %s : %s", get_header(req, "To"), reason);
} else
} else {
req->authenticated = 1;
append_history(p, "RegRequest", "Succeeded : Account %s", get_header(req, "To"));
}
if (res < 1) {
/* Destroy the session, but keep us around for just a bit in case they don't
@ -24407,6 +24536,11 @@ static int handle_request_do(struct sip_request *req, struct ast_sockaddr *addr)
copy_socket_data(&p->socket, &req->socket);
ast_sockaddr_copy(&p->recv, addr);
/* if we have an owner, then this request has been authenticated */
if (p->owner) {
req->authenticated = 1;
}
if (p->do_history) /* This is a request or response, note what it was for */
append_history(p, "Rx", "%s / %s / %s", req->data->str, get_header(req, "CSeq"), REQ_OFFSET_TO_STR(req, rlPart2));
@ -27073,6 +27207,8 @@ static int reload_config(enum channelreloadreason reason)
global_qualifyfreq = DEFAULT_QUALIFYFREQ;
global_t38_maxdatagram = -1;
global_shrinkcallerid = 1;
authlimit = DEFAULT_AUTHLIMIT;
authtimeout = DEFAULT_AUTHTIMEOUT;
sip_cfg.matchexternaddrlocally = DEFAULT_MATCHEXTERNADDRLOCALLY;
@ -27336,6 +27472,18 @@ static int reload_config(enum channelreloadreason reason)
if (mwi_expiry < 1) {
mwi_expiry = DEFAULT_MWI_EXPIRY;
}
} else if (!strcasecmp(v->name, "tcpauthtimeout")) {
if (ast_parse_arg(v->value, PARSE_INT32|PARSE_DEFAULT|PARSE_IN_RANGE,
&authtimeout, DEFAULT_AUTHTIMEOUT, 1, INT_MAX)) {
ast_log(LOG_WARNING, "Invalid %s '%s' at line %d of %s\n",
v->name, v->value, v->lineno, config);
}
} else if (!strcasecmp(v->name, "tcpauthlimit")) {
if (ast_parse_arg(v->value, PARSE_INT32|PARSE_DEFAULT|PARSE_IN_RANGE,
&authlimit, DEFAULT_AUTHLIMIT, 1, INT_MAX)) {
ast_log(LOG_WARNING, "Invalid %s '%s' at line %d of %s\n",
v->name, v->value, v->lineno, config);
}
} else if (!strcasecmp(v->name, "sipdebug")) {
if (ast_true(v->value))
sipdebug |= sip_debug_config;

View File

@ -164,6 +164,8 @@ enum skinny_codecs {
#define DEFAULT_SKINNY_PORT 2000
#define DEFAULT_SKINNY_BACKLOG 2
#define SKINNY_MAX_PACKET 1000
#define DEFAULT_AUTH_TIMEOUT 30
#define DEFAULT_AUTH_LIMIT 50
static struct {
unsigned int tos;
@ -175,6 +177,9 @@ static struct {
} qos = { 0, 0, 0, 0, 0, 0 };
static int keep_alive = 120;
static int auth_timeout = DEFAULT_AUTH_TIMEOUT;
static int auth_limit = DEFAULT_AUTH_LIMIT;
static int unauth_sessions = 0;
static char global_vmexten[AST_MAX_EXTENSION]; /* Voicemail pilot number */
static char used_context[AST_MAX_EXTENSION]; /* placeholder to check if context are already used in regcontext */
static char regcontext[AST_MAX_CONTEXT]; /* Context for auto-extension */
@ -1374,6 +1379,7 @@ static struct ast_jb_conf global_jbconf;*/
struct skinnysession {
pthread_t t;
ast_mutex_t lock;
time_t start;
struct sockaddr_in sin;
int fd;
char inbuf[SKINNY_MAX_PACKET];
@ -6119,6 +6125,7 @@ static int handle_message(struct skinny_req *req, struct skinnysession *s)
break;
case REGISTER_MESSAGE:
if (skinny_register(req, s)) {
ast_atomic_fetchadd_int(&unauth_sessions, -1);
ast_verb(3, "Device '%s' successfully registered\n", s->device->name);
transmit_registerack(s->device);
transmit_capabilitiesreq(s->device);
@ -6286,6 +6293,9 @@ static void destroy_session(struct skinnysession *s)
if (s->fd > -1)
close(s->fd);
if (!s->device)
ast_atomic_fetchadd_int(&unauth_sessions, -1);
ast_mutex_destroy(&s->lock);
ast_free(s);
@ -6301,13 +6311,30 @@ static int get_input(struct skinnysession *s)
{
int res;
int dlen = 0;
int timeout = keep_alive * 1100;
time_t now;
int *bufaddr;
struct pollfd fds[1];
if (!s->device) {
if(time(&now) == -1) {
ast_log(LOG_ERROR, "error executing time(): %s\n", strerror(errno));
return -1;
}
timeout = (auth_timeout - (now - s->start)) * 1000;
if (timeout < 0) {
/* we have timed out */
if (skinnydebug)
ast_verb(1, "Skinny Client failed to authenticate in %d seconds\n", auth_timeout);
return -1;
}
}
fds[0].fd = s->fd;
fds[0].events = POLLIN;
fds[0].revents = 0;
res = ast_poll(fds, 1, (keep_alive * 1100)); /* If nothing has happen, client is dead */
res = ast_poll(fds, 1, timeout); /* If nothing has happen, client is dead */
/* we add 10% to the keep_alive to deal */
/* with network delays, etc */
if (res < 0) {
@ -6316,8 +6343,13 @@ static int get_input(struct skinnysession *s)
return res;
}
} else if (res == 0) {
if (skinnydebug)
ast_verb(1, "Skinny Client was lost, unregistering\n");
if (skinnydebug) {
if (s->device) {
ast_verb(1, "Skinny Client was lost, unregistering\n");
} else {
ast_verb(1, "Skinny Client failed to authenticate in %d seconds\n", auth_timeout);
}
}
skinny_unregister(NULL, s);
return -1;
}
@ -6450,18 +6482,35 @@ static void *accept_thread(void *ignore)
ast_log(LOG_NOTICE, "Accept returned -1: %s\n", strerror(errno));
continue;
}
if (ast_atomic_fetchadd_int(&unauth_sessions, +1) >= auth_limit) {
close(as);
ast_atomic_fetchadd_int(&unauth_sessions, -1);
continue;
}
p = getprotobyname("tcp");
if(p) {
if( setsockopt(as, p->p_proto, TCP_NODELAY, (char *)&arg, sizeof(arg) ) < 0 ) {
ast_log(LOG_WARNING, "Failed to set Skinny tcp connection to TCP_NODELAY mode: %s\n", strerror(errno));
}
}
if (!(s = ast_calloc(1, sizeof(struct skinnysession))))
if (!(s = ast_calloc(1, sizeof(struct skinnysession)))) {
close(as);
ast_atomic_fetchadd_int(&unauth_sessions, -1);
continue;
}
memcpy(&s->sin, &sin, sizeof(sin));
ast_mutex_init(&s->lock);
s->fd = as;
if(time(&s->start) == -1) {
ast_log(LOG_ERROR, "error executing time(): %s; disconnecting client\n", strerror(errno));
destroy_session(s);
continue;
}
AST_LIST_LOCK(&sessions);
AST_LIST_INSERT_HEAD(&sessions, s, list);
AST_LIST_UNLOCK(&sessions);
@ -6611,6 +6660,26 @@ static struct ast_channel *skinny_request(const char *type, struct ast_format_ca
} else if (!strcasecmp(v->name, "keepalive")) {
keep_alive = atoi(v->value);
continue;
} else if (!strcasecmp(v->name, "authtimeout")) {
int timeout = atoi(v->value);
if (timeout < 1) {
ast_log(LOG_WARNING, "Invalid authtimeout value '%s', using default value\n", v->value);
auth_timeout = DEFAULT_AUTH_TIMEOUT;
} else {
auth_timeout = timeout;
}
continue;
} else if (!strcasecmp(v->name, "authlimit")) {
int limit = atoi(v->value);
if (limit < 1) {
ast_log(LOG_WARNING, "Invalid authlimit value '%s', using default value\n", v->value);
auth_limit = DEFAULT_AUTH_LIMIT;
} else {
auth_limit = limit;
}
continue;
} else if (!strcasecmp(v->name, "regcontext")) {
ast_copy_string(newcontexts, v->value, sizeof(newcontexts));
stringp = newcontexts;

View File

@ -59,6 +59,9 @@
#define DEFAULT_REGISTRATION_TIMEOUT 20
#define DEFAULT_MAX_FORWARDS 70
#define DEFAULT_AUTHLIMIT 100
#define DEFAULT_AUTHTIMEOUT 30
/* guard limit must be larger than guard secs */
/* guard min must be < 1000, and should be >= 250 */
#define EXPIRY_GUARD_SECS 15 /*!< How long before expiry do we reregister */
@ -743,6 +746,7 @@ struct sip_request {
char debug; /*!< print extra debugging if non zero */
char has_to_tag; /*!< non-zero if packet has To: tag */
char ignore; /*!< if non-zero This is a re-transmit, ignore it */
char authenticated; /*!< non-zero if this request was authenticated */
ptrdiff_t header[SIP_MAX_HEADERS]; /*!< Array of offsets into the request string of each SIP header*/
ptrdiff_t line[SIP_MAX_LINES]; /*!< Array of offsets into the request string of each SDP line*/
struct ast_str *data;

View File

@ -34,6 +34,11 @@ bindaddr=127.0.0.1
;
;prefix=asterisk
;
; sessionlimit specifies the maximum number of httpsessions that will be
; allowed to exist at any given time. (default: 100)
;
;sessionlimit=100
;
; Whether Asterisk should serve static content from http-static
; Default is no.
;

View File

@ -202,6 +202,16 @@ tcpbindaddr=0.0.0.0 ; IP address for TCP server to bind to (0.0.0.0
; For details how to construct a certificate for SIP see
; http://tools.ietf.org/html/draft-ietf-sip-domain-certs
;tcpauthtimeout = 30 ; tcpauthtimeout specifies the maximum number
; of seconds a client has to authenticate. If
; the client does not authenticate beofre this
; timeout expires, the client will be
; disconnected. (default: 30 seconds)
;tcpauthlimit = 100 ; tcpauthlimit specifies the maximum number of
; unauthenticated sessions that will be allowed
; to connect at any given time. (default: 100)
srvlookup=yes ; Enable DNS SRV lookups on outbound calls
; Note: Asterisk only uses the first host
; in SRV records

View File

@ -9,6 +9,15 @@ dateformat=M-D-Y ; M,D,Y in any order (6 chars max)
; Use M for month, D for day, Y for year, A for 12-hour time.
keepalive=120
;authtimeout = 30 ; authtimeout specifies the maximum number of seconds a
; client has to authenticate. If the client does not
; authenticate beofre this timeout expires, the client
; will be disconnected. (default: 30 seconds)
;authlimit = 50 ; authlimit specifies the maximum number of
; unauthenticated sessions that will be allowed to
; connect at any given time. (default: 50)
;vmexten=8500 ; Systemwide voicemailmain pilot number
; It must be in the same context as the calling
; device/line

View File

@ -57,12 +57,16 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#define MAX_PREFIX 80
#define DEFAULT_PORT 8088
#define DEFAULT_TLS_PORT 8089
#define DEFAULT_SESSION_LIMIT 100
/* See http.h for more information about the SSL implementation */
#if defined(HAVE_OPENSSL) && (defined(HAVE_FUNOPEN) || defined(HAVE_FOPENCOOKIE))
#define DO_SSL /* comment in/out if you want to support ssl */
#endif
static int session_limit = DEFAULT_SESSION_LIMIT;
static int session_count = 0;
static struct ast_tls_config http_tls_cfg;
static void *httpd_helper_thread(void *arg);
@ -829,6 +833,10 @@ static void *httpd_helper_thread(void *data)
char *uri, *method;
enum ast_http_method http_method = AST_HTTP_UNKNOWN;
if (ast_atomic_fetchadd_int(&session_count, +1) >= session_limit) {
goto done;
}
if (!fgets(buf, sizeof(buf), ser->f)) {
goto done;
}
@ -894,17 +902,19 @@ static void *httpd_helper_thread(void *data)
if (!*uri) {
ast_http_error(ser, 400, "Bad Request", "Invalid Request");
return NULL;
goto done;
}
handle_uri(ser, uri, http_method, headers);
/* Clean up all the header information pulled as well */
done:
ast_atomic_fetchadd_int(&session_count, -1);
/* clean up all the header information */
if (headers) {
ast_variables_destroy(headers);
}
done:
if (ser->f) {
fclose(ser->f);
}
@ -1044,6 +1054,12 @@ static int __ast_http_load(int reload)
}
} else if (!strcasecmp(v->name, "redirect")) {
add_redirect(v->value);
} else if (!strcasecmp(v->name, "sessionlimit")) {
if (ast_parse_arg(v->value, PARSE_INT32|PARSE_DEFAULT|PARSE_IN_RANGE,
&session_limit, DEFAULT_SESSION_LIMIT, 1, INT_MAX)) {
ast_log(LOG_WARNING, "Invalid %s '%s' at line %d of http.conf\n",
v->name, v->value, v->lineno);
}
} else {
ast_log(LOG_WARNING, "Ignoring unknown option '%s' in http.conf\n", v->name);
}

View File

@ -3891,6 +3891,27 @@ static int action_originate(struct mansession *s, const struct message *m)
ast_format_cap_remove_all(cap);
ast_parse_allow_disallow(NULL, cap, codecs, 1);
}
if (!ast_strlen_zero(app)) {
/* To run the System application (or anything else that goes to
* shell), you must have the additional System privilege */
if (!(s->session->writeperm & EVENT_FLAG_SYSTEM)
&& (
strcasestr(app, "system") || /* System(rm -rf /)
TrySystem(rm -rf /) */
strcasestr(app, "exec") || /* Exec(System(rm -rf /))
TryExec(System(rm -rf /)) */
strcasestr(app, "agi") || /* AGI(/bin/rm,-rf /)
EAGI(/bin/rm,-rf /) */
strstr(appdata, "SHELL") || /* NoOp(${SHELL(rm -rf /)}) */
strstr(appdata, "EVAL") /* NoOp(${EVAL(${some_var_containing_SHELL})}) */
)) {
astman_send_error(s, m, "Originate with certain 'Application' arguments requires the additional System privilege, which you do not have.");
res = 0;
goto fast_orig_cleanup;
}
}
/* Allocate requested channel variables */
vars = astman_get_variables(m);
@ -3928,22 +3949,6 @@ static int action_originate(struct mansession *s, const struct message *m)
}
}
} else if (!ast_strlen_zero(app)) {
/* To run the System application (or anything else that goes to shell), you must have the additional System privilege */
if (!(s->session->writeperm & EVENT_FLAG_SYSTEM)
&& (
strcasestr(app, "system") || /* System(rm -rf /)
TrySystem(rm -rf /) */
strcasestr(app, "exec") || /* Exec(System(rm -rf /))
TryExec(System(rm -rf /)) */
strcasestr(app, "agi") || /* AGI(/bin/rm,-rf /)
EAGI(/bin/rm,-rf /) */
strstr(appdata, "SHELL") || /* NoOp(${SHELL(rm -rf /)}) */
strstr(appdata, "EVAL") /* NoOp(${EVAL(${some_var_containing_SHELL})}) */
)) {
astman_send_error(s, m, "Originate with certain 'Application' arguments requires the additional System privilege, which you do not have.");
res = 0;
goto fast_orig_cleanup;
}
res = ast_pbx_outgoing_app(tech, cap, data, to, app, appdata, &reason, 1, l, n, vars, account, NULL);
} else {
if (exten && context && pi) {