Index: README-SERIOUSLY.bestpractices.txt
===================================================================
--- README-SERIOUSLY.bestpractices.txt (revision 403915)
+++ README-SERIOUSLY.bestpractices.txt (revision 403916)
@@ -26,6 +26,9 @@
* Manager Class Authorizations:
Recognizing potential issues with certain classes of authorization
+* Avoid Privilege Escalations:
+ Disable the ability to execute functions that may escalate privileges
+
----------------
Additional Links
----------------
@@ -344,3 +347,24 @@
not running Asterisk as root, can prevent serious problems from arising when
allowing external connections to originate calls into Asterisk.
+===========================
+Avoid Privilege Escalations
+===========================
+
+External control protocols, such as Manager, often have the ability to get and
+set channel variables; which allows the execution of dialplan functions.
+
+Dialplan functions within Asterisk are incredibly powerful, which is wonderful
+for building applications using Asterisk. But during the read or write
+execution, certain diaplan functions do much more. For example, reading the
+SHELL() function can execute arbitrary commands on the system Asterisk is
+running on. Writing to the FILE() function can change any file that Asterisk has
+write access to.
+
+When these functions are executed from an external protocol, that execution
+could result in a privilege escalation. Asterisk can inhibit the execution of
+these functions, if live_dangerously in the [options] section of asterisk.conf
+is set to no.
+
+For backwards compatibility, live_dangerously defaults to yes, and must be
+explicitly set to no to enable this privilege escalation protection.
Index: UPGRADE.txt
===================================================================
--- UPGRADE.txt (revision 403915)
+++ UPGRADE.txt (revision 403916)
@@ -19,6 +19,16 @@
===
===========================================================
+from 10.12.3 to 10.12.4:
+
+* Certain dialplan functions have been marked as 'dangerous', and may only be
+ executed from the dialplan. Execution from extenal sources (AMI's GetVar and
+ SetVar actions; etc.) may be inhibited by setting live_dangerously in the
+ [options] section of asterisk.conf to no. SHELL(), channel locking, and direct
+ file read/write functions are marked as dangerous. DB_DELETE() and
+ REALTIME_DESTROY() are marked as dangerous for reads, but can now safely
+ accept writes (which ignore the provided value).
+
from 10.12.0 to 10.12.1:
* Asterisk would previously not output certain error messages when a remote
Index: funcs/func_env.c
===================================================================
--- funcs/func_env.c (revision 403915)
+++ funcs/func_env.c (revision 403916)
@@ -71,6 +71,11 @@
+
+ If live_dangerously in asterisk.conf
+ is set to no, this function can only be executed from the
+ dialplan, and not directly from external protocols.
+
@@ -167,6 +172,11 @@
Set(FILE(/tmp/foo.txt,-1,,l)=bar)
; Append "bar" to the file with a newline
Set(FILE(/tmp/foo.txt,,,al)=bar)
+
+ If live_dangerously in asterisk.conf
+ is set to no, this function can only be executed from the
+ dialplan, and not directly from external protocols.
+
[FILE_COUNT_LINE]
@@ -197,6 +207,11 @@
Returns the number of lines, or -1 on error.
+
+ If live_dangerously in asterisk.conf
+ is set to no, this function can only be executed from the
+ dialplan, and not directly from external protocols.
+
[FILE]
@@ -216,6 +231,11 @@
'd' - DOS "\r\n" format
'm' - Macintosh "\r" format
'x' - Cannot be determined
+
+ If live_dangerously in asterisk.conf
+ is set to no, this function can only be executed from the
+ dialplan, and not directly from external protocols.
+
[FILE]
@@ -1258,10 +1278,10 @@
int res = 0;
res |= ast_custom_function_register(&env_function);
- res |= ast_custom_function_register(&stat_function);
- res |= ast_custom_function_register(&file_function);
- res |= ast_custom_function_register(&file_count_line_function);
- res |= ast_custom_function_register(&file_format_function);
+ res |= ast_custom_function_register_escalating(&stat_function, AST_CFE_READ);
+ res |= ast_custom_function_register_escalating(&file_function, AST_CFE_BOTH);
+ res |= ast_custom_function_register_escalating(&file_count_line_function, AST_CFE_READ);
+ res |= ast_custom_function_register_escalating(&file_format_function, AST_CFE_READ);
return res;
}
Index: funcs/func_shell.c
===================================================================
--- funcs/func_shell.c (revision 403915)
+++ funcs/func_shell.c (revision 403916)
@@ -88,11 +88,17 @@
Collects the output generated by a command executed by the system shell
- Example: Set(foo=${SHELL(echo \bar\)})
- The command supplied to this function will be executed by the
- system's shell, typically specified in the SHELL environment variable. There
- are many different system shells available with somewhat different behaviors,
- so the output generated by this function may vary between platforms.
+ Example: Set(foo=${SHELL(echo bar)})
+
+ The command supplied to this function will be executed by the
+ system's shell, typically specified in the SHELL environment variable. There
+ are many different system shells available with somewhat different behaviors,
+ so the output generated by this function may vary between platforms.
+
+ If live_dangerously in asterisk.conf
+ is set to no, this function can only be executed from the
+ dialplan, and not directly from external protocols.
+
@@ -109,7 +115,7 @@
static int load_module(void)
{
- return ast_custom_function_register(&shell_function);
+ return ast_custom_function_register_escalating(&shell_function, AST_CFE_READ);
}
AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Collects the output generated by a command executed by the system shell");
Index: funcs/func_db.c
===================================================================
--- funcs/func_db.c (revision 403915)
+++ funcs/func_db.c (revision 403916)
@@ -110,6 +110,12 @@
This function will retrieve a value from the Asterisk database
and then remove that key from the database. DB_RESULT
will be set to the key's value if it exists.
+
+ If live_dangerously in asterisk.conf
+ is set to no, this function can only be read from the
+ dialplan, and not directly from external protocols. It can, however, be
+ executed as a write operation (DB_DELETE(family, key)=ignored)
+
[DBdel]
@@ -311,10 +317,22 @@
return 0;
}
+/*!
+ * \brief Wrapper to execute DB_DELETE from a write operation. Allows execution
+ * even if live_dangerously is disabled.
+ */
+static int function_db_delete_write(struct ast_channel *chan, const char *cmd, char *parse,
+ const char *value)
+{
+ /* Throwaway to hold the result from the read */
+ char buf[128];
+ return function_db_delete(chan, cmd, parse, buf, sizeof(buf));
+}
static struct ast_custom_function db_delete_function = {
.name = "DB_DELETE",
.read = function_db_delete,
+ .write = function_db_delete_write,
};
static int unload_module(void)
@@ -335,7 +353,7 @@
res |= ast_custom_function_register(&db_function);
res |= ast_custom_function_register(&db_exists_function);
- res |= ast_custom_function_register(&db_delete_function);
+ res |= ast_custom_function_register_escalating(&db_delete_function, AST_CFE_READ);
res |= ast_custom_function_register(&db_keys_function);
return res;
Index: funcs/func_lock.c
===================================================================
--- funcs/func_lock.c (revision 403915)
+++ funcs/func_lock.c (revision 403916)
@@ -59,6 +59,11 @@
Returns 1 if the lock was obtained or 0 on error.
To avoid the possibility of a deadlock, LOCK will only attempt to
obtain the lock for 3 seconds if the channel already has another lock.
+
+ If live_dangerously in asterisk.conf
+ is set to no, this function can only be executed from the
+ dialplan, and not directly from external protocols.
+
@@ -72,6 +77,11 @@
Attempts to grab a named lock exclusively, and prevents other channels
from obtaining the same lock. Returns 1 if the lock was
available or 0 otherwise.
+
+ If live_dangerously in asterisk.conf
+ is set to no, this function can only be executed from the
+ dialplan, and not directly from external protocols.
+
@@ -86,6 +96,11 @@
had a lock or 0 otherwise.
It is generally unnecessary to unlock in a hangup routine, as any locks
held are automatically freed when the channel is destroyed.
+
+ If live_dangerously in asterisk.conf
+ is set to no, this function can only be executed from the
+ dialplan, and not directly from external protocols.
+
***/
@@ -502,9 +517,9 @@
static int load_module(void)
{
- int res = ast_custom_function_register(&lock_function);
- res |= ast_custom_function_register(&trylock_function);
- res |= ast_custom_function_register(&unlock_function);
+ int res = ast_custom_function_register_escalating(&lock_function, AST_CFE_READ);
+ res |= ast_custom_function_register_escalating(&trylock_function, AST_CFE_READ);
+ res |= ast_custom_function_register_escalating(&unlock_function, AST_CFE_READ);
if (ast_pthread_create_background(&broker_tid, NULL, lock_broker, NULL)) {
ast_log(LOG_ERROR, "Failed to start lock broker thread. Unloading func_lock module.\n");
Index: funcs/func_realtime.c
===================================================================
--- funcs/func_realtime.c (revision 403915)
+++ funcs/func_realtime.c (revision 403916)
@@ -115,6 +115,12 @@
This function acts in the same way as REALTIME(....) does, except that
it destroys the matched record in the RT engine.
+
+ If live_dangerously in asterisk.conf
+ is set to no, this function can only be read from the
+ dialplan, and not directly from external protocols. It can, however, be
+ executed as a write operation (REALTIME_DESTROY(family, fieldmatch)=ignored)
+
[REALTIME]
@@ -432,18 +438,32 @@
return -1;
}
- resultslen = 0;
- n = 0;
- for (var = head; var; n++, var = var->next)
- resultslen += strlen(var->name) + strlen(var->value);
- /* add space for delimiters and final '\0' */
- resultslen += n * (strlen(args.delim1) + strlen(args.delim2)) + 1;
+ if (len > 0) {
+ resultslen = 0;
+ n = 0;
+ for (var = head; var; n++, var = var->next) {
+ resultslen += strlen(var->name) + strlen(var->value);
+ }
+ /* add space for delimiters and final '\0' */
+ resultslen += n * (strlen(args.delim1) + strlen(args.delim2)) + 1;
- out = ast_str_alloca(resultslen);
- for (var = head; var; var = var->next) {
- ast_str_append(&out, 0, "%s%s%s%s", var->name, args.delim2, var->value, args.delim1);
+ if (resultslen > len) {
+ /* Unfortunately this does mean that we cannot destroy
+ * the row anymore. But OTOH, we're not destroying
+ * someones data without giving him the chance to look
+ * at it. */
+ ast_log(LOG_WARNING, "Failed to fetch/destroy. Realtime data is too large: need %zu, have %zu.\n", resultslen, len);
+ return -1;
+ }
+
+ /* len is going to be sensible, so we don't need to check for
+ * stack overflows here. */
+ out = ast_str_alloca(resultslen);
+ for (var = head; var; var = var->next) {
+ ast_str_append(&out, 0, "%s%s%s%s", var->name, args.delim2, var->value, args.delim1);
+ }
+ ast_copy_string(buf, ast_str_buffer(out), len);
}
- ast_copy_string(buf, ast_str_buffer(out), len);
ast_destroy_realtime(args.family, args.fieldmatch, args.value, SENTINEL);
ast_variables_destroy(head);
@@ -454,6 +474,15 @@
return 0;
}
+/*!
+ * \brief Wrapper to execute REALTIME_DESTROY from a write operation. Allows
+ * execution even if live_dangerously is disabled.
+ */
+static int function_realtime_writedestroy(struct ast_channel *chan, const char *cmd, char *data, const char *value)
+{
+ return function_realtime_readdestroy(chan, cmd, data, NULL, 0);
+}
+
static struct ast_custom_function realtime_function = {
.name = "REALTIME",
.read = function_realtime_read,
@@ -479,6 +508,7 @@
static struct ast_custom_function realtime_destroy_function = {
.name = "REALTIME_DESTROY",
.read = function_realtime_readdestroy,
+ .write = function_realtime_writedestroy,
};
static int unload_module(void)
@@ -497,7 +527,7 @@
int res = 0;
res |= ast_custom_function_register(&realtime_function);
res |= ast_custom_function_register(&realtime_store_function);
- res |= ast_custom_function_register(&realtime_destroy_function);
+ res |= ast_custom_function_register_escalating(&realtime_destroy_function, AST_CFE_READ);
res |= ast_custom_function_register(&realtimefield_function);
res |= ast_custom_function_register(&realtimehash_function);
return res;
Index: include/asterisk/pbx.h
===================================================================
--- include/asterisk/pbx.h (revision 403915)
+++ include/asterisk/pbx.h (revision 403916)
@@ -1171,16 +1171,44 @@
int ast_custom_function_unregister(struct ast_custom_function *acf);
/*!
+ * \brief Description of the ways in which a function may escalate privileges.
+ */
+enum ast_custom_function_escalation {
+ AST_CFE_NONE,
+ AST_CFE_READ,
+ AST_CFE_WRITE,
+ AST_CFE_BOTH,
+};
+
+/*!
* \brief Register a custom function
*/
#define ast_custom_function_register(acf) __ast_custom_function_register(acf, ast_module_info->self)
/*!
+ * \brief Register a custom function which requires escalated privileges.
+ *
+ * Examples would be SHELL() (for which a read needs permission to execute
+ * arbitrary code) or FILE() (for which write needs permission to change files
+ * on the filesystem).
+ */
+#define ast_custom_function_register_escalating(acf, escalation) __ast_custom_function_register_escalating(acf, escalation, ast_module_info->self)
+
+/*!
* \brief Register a custom function
*/
int __ast_custom_function_register(struct ast_custom_function *acf, struct ast_module *mod);
/*!
+ * \brief Register a custom function which requires escalated privileges.
+ *
+ * Examples would be SHELL() (for which a read needs permission to execute
+ * arbitrary code) or FILE() (for which write needs permission to change files
+ * on the filesystem).
+ */
+int __ast_custom_function_register_escalating(struct ast_custom_function *acf, enum ast_custom_function_escalation escalation, struct ast_module *mod);
+
+/*!
* \brief Retrieve the number of active calls
*/
int ast_active_calls(void);
@@ -1293,6 +1321,32 @@
*/
char *ast_complete_applications(const char *line, const char *word, int state);
+/*!
+ * \brief Enable/disable the execution of 'dangerous' functions from external
+ * protocols (AMI, etc.).
+ *
+ * These dialplan functions (such as \c SHELL) provide an opportunity for
+ * privilege escalation. They are okay to invoke from the dialplan, but external
+ * protocols with permission controls should not normally invoke them.
+ *
+ * This function can globally enable/disable the execution of dangerous
+ * functions from external protocols.
+ *
+ * \param new_live_dangerously If true, enable the execution of escalating
+ * functions from external protocols.
+ */
+void pbx_live_dangerously(int new_live_dangerously);
+
+/*!
+ * \brief Inhibit (in the current thread) the execution of dialplan functions
+ * which cause privilege escalations. If pbx_live_dangerously() has been
+ * called, this function has no effect.
+ *
+ * \return 0 if successfuly marked current thread.
+ * \return Non-zero if marking current thread failed.
+ */
+int ast_thread_inhibit_escalations(void);
+
#if defined(__cplusplus) || defined(c_plusplus)
}
#endif
Index: main/asterisk.c
===================================================================
--- main/asterisk.c (revision 403915)
+++ main/asterisk.c (revision 403916)
@@ -3034,6 +3034,8 @@
unsigned int dbdir:1;
unsigned int keydir:1;
} found = { 0, 0 };
+ /* Default to true for backward compatibility */
+ int live_dangerously = 1;
if (ast_opt_override_config) {
cfg = ast_config_load2(ast_config_AST_CONFIG_FILE, "" /* core, can't reload */, config_flags);
@@ -3246,8 +3248,11 @@
ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_HIDE_CONSOLE_CONNECT);
} else if (!strcasecmp(v->name, "lockconfdir")) {
ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_LOCK_CONFIG_DIR);
+ } else if (!strcasecmp(v->name, "live_dangerously")) {
+ live_dangerously = ast_true(v->value);
}
}
+ pbx_live_dangerously(live_dangerously);
for (v = ast_variable_browse(cfg, "compat"); v; v = v->next) {
float version;
if (sscanf(v->value, "%30f", &version) != 1) {
Index: main/pbx.c
===================================================================
--- main/pbx.c (revision 403915)
+++ main/pbx.c (revision 403916)
@@ -822,8 +822,19 @@
AST_THREADSTORAGE(switch_data);
AST_THREADSTORAGE(extensionstate_buf);
+/*!
+ * \brief A thread local indicating whether the current thread can run
+ * 'dangerous' dialplan functions.
+ */
+AST_THREADSTORAGE(thread_inhibit_escalations_tl);
/*!
+ * \brief Set to true (non-zero) to globally allow all dangerous dialplan
+ * functions to run.
+ */
+static int live_dangerously;
+
+/*!
\brief ast_exten: An extension
The dialplan is saved as a linked list with each context
having it's own linked list of extensions - one item per
@@ -1307,6 +1318,19 @@
static AST_RWLIST_HEAD_STATIC(acf_root, ast_custom_function);
+/*!
+ * \brief Extra information for an \ref ast_custom_function holding privilege
+ * escalation information. Kept in a separate structure for ABI compatibility.
+ */
+struct ast_custom_escalating_function {
+ AST_RWLIST_ENTRY(ast_custom_escalating_function) list;
+ const struct ast_custom_function *acf;
+ unsigned int read_escalates:1;
+ unsigned int write_escalates:1;
+};
+
+static AST_RWLIST_HEAD_STATIC(escalation_root, ast_custom_escalating_function);
+
/*! \brief Declaration of builtin applications */
static struct pbx_builtin {
char name[AST_MAX_APP];
@@ -3900,6 +3924,7 @@
int ast_custom_function_unregister(struct ast_custom_function *acf)
{
struct ast_custom_function *cur;
+ struct ast_custom_escalating_function *cur_escalation;
if (!acf) {
return -1;
@@ -3916,9 +3941,64 @@
}
AST_RWLIST_UNLOCK(&acf_root);
+ /* Remove from the escalation list */
+ AST_RWLIST_WRLOCK(&escalation_root);
+ AST_RWLIST_TRAVERSE_SAFE_BEGIN(&escalation_root, cur_escalation, list) {
+ if (cur_escalation->acf == acf) {
+ AST_RWLIST_REMOVE_CURRENT(list);
+ break;
+ }
+ }
+ AST_RWLIST_TRAVERSE_SAFE_END;
+ AST_RWLIST_UNLOCK(&escalation_root);
+
return cur ? 0 : -1;
}
+/*!
+ * \brief Returns true if given custom function escalates privileges on read.
+ *
+ * \param acf Custom function to query.
+ * \return True (non-zero) if reads escalate privileges.
+ * \return False (zero) if reads just read.
+ */
+static int read_escalates(const struct ast_custom_function *acf) {
+ int res = 0;
+ struct ast_custom_escalating_function *cur_escalation;
+
+ AST_RWLIST_RDLOCK(&escalation_root);
+ AST_RWLIST_TRAVERSE(&escalation_root, cur_escalation, list) {
+ if (cur_escalation->acf == acf) {
+ res = cur_escalation->read_escalates;
+ break;
+ }
+ }
+ AST_RWLIST_UNLOCK(&escalation_root);
+ return res;
+}
+
+/*!
+ * \brief Returns true if given custom function escalates privileges on write.
+ *
+ * \param acf Custom function to query.
+ * \return True (non-zero) if writes escalate privileges.
+ * \return False (zero) if writes just write.
+ */
+static int write_escalates(const struct ast_custom_function *acf) {
+ int res = 0;
+ struct ast_custom_escalating_function *cur_escalation;
+
+ AST_RWLIST_RDLOCK(&escalation_root);
+ AST_RWLIST_TRAVERSE(&escalation_root, cur_escalation, list) {
+ if (cur_escalation->acf == acf) {
+ res = cur_escalation->write_escalates;
+ break;
+ }
+ }
+ AST_RWLIST_UNLOCK(&escalation_root);
+ return res;
+}
+
/*! \internal
* \brief Retrieve the XML documentation of a specified ast_custom_function,
* and populate ast_custom_function string fields.
@@ -4020,6 +4100,50 @@
return 0;
}
+int __ast_custom_function_register_escalating(struct ast_custom_function *acf, enum ast_custom_function_escalation escalation, struct ast_module *mod)
+{
+ struct ast_custom_escalating_function *acf_escalation = NULL;
+ int res;
+
+ res = __ast_custom_function_register(acf, mod);
+ if (res != 0) {
+ return -1;
+ }
+
+ if (escalation == AST_CFE_NONE) {
+ /* No escalations; no need to do anything else */
+ return 0;
+ }
+
+ acf_escalation = ast_calloc(1, sizeof(*acf_escalation));
+ if (!acf_escalation) {
+ ast_custom_function_unregister(acf);
+ return -1;
+ }
+
+ acf_escalation->acf = acf;
+ switch (escalation) {
+ case AST_CFE_NONE:
+ break;
+ case AST_CFE_READ:
+ acf_escalation->read_escalates = 1;
+ break;
+ case AST_CFE_WRITE:
+ acf_escalation->write_escalates = 1;
+ break;
+ case AST_CFE_BOTH:
+ acf_escalation->read_escalates = 1;
+ acf_escalation->write_escalates = 1;
+ break;
+ }
+
+ AST_RWLIST_WRLOCK(&escalation_root);
+ AST_RWLIST_INSERT_TAIL(&escalation_root, acf_escalation, list);
+ AST_RWLIST_UNLOCK(&escalation_root);
+
+ return 0;
+}
+
/*! \brief return a pointer to the arguments of the function,
* and terminates the function name with '\\0'
*/
@@ -4041,6 +4165,124 @@
return args;
}
+void pbx_live_dangerously(int new_live_dangerously)
+{
+ if (new_live_dangerously && !live_dangerously) {
+ ast_log(LOG_WARNING, "Privilege escalation protection disabled!\n"
+ "See https://wiki.asterisk.org/wiki/x/1gKfAQ for more details.\n");
+ }
+
+ if (!new_live_dangerously && live_dangerously) {
+ ast_log(LOG_NOTICE, "Privilege escalation protection enabled.\n");
+ }
+ live_dangerously = new_live_dangerously;
+}
+
+int ast_thread_inhibit_escalations(void)
+{
+ int *thread_inhibit_escalations;
+
+ thread_inhibit_escalations = ast_threadstorage_get(
+ &thread_inhibit_escalations_tl, sizeof(*thread_inhibit_escalations));
+
+ if (thread_inhibit_escalations == NULL) {
+ ast_log(LOG_ERROR, "Error inhibiting privilege escalations for current thread\n");
+ return -1;
+ }
+
+ *thread_inhibit_escalations = 1;
+ return 0;
+}
+
+/*!
+ * \brief Indicates whether the current thread inhibits the execution of
+ * dangerous functions.
+ *
+ * \return True (non-zero) if dangerous function execution is inhibited.
+ * \return False (zero) if dangerous function execution is allowed.
+ */
+static int thread_inhibits_escalations(void)
+{
+ int *thread_inhibit_escalations;
+
+ thread_inhibit_escalations = ast_threadstorage_get(
+ &thread_inhibit_escalations_tl, sizeof(*thread_inhibit_escalations));
+
+ if (thread_inhibit_escalations == NULL) {
+ ast_log(LOG_ERROR, "Error checking thread's ability to run dangerous functions\n");
+ /* On error, assume that we are inhibiting */
+ return 1;
+ }
+
+ return *thread_inhibit_escalations;
+}
+
+/*!
+ * \brief Determines whether execution of a custom function's read function
+ * is allowed.
+ *
+ * \param acfptr Custom function to check
+ * \return True (non-zero) if reading is allowed.
+ * \return False (zero) if reading is not allowed.
+ */
+static int is_read_allowed(struct ast_custom_function *acfptr)
+{
+ if (!acfptr) {
+ return 1;
+ }
+
+ if (!read_escalates(acfptr)) {
+ return 1;
+ }
+
+ if (!thread_inhibits_escalations()) {
+ return 1;
+ }
+
+ if (live_dangerously) {
+ /* Global setting overrides the thread's preference */
+ ast_debug(2, "Reading %s from a dangerous context\n",
+ acfptr->name);
+ return 1;
+ }
+
+ /* We have no reason to allow this function to execute */
+ return 0;
+}
+
+/*!
+ * \brief Determines whether execution of a custom function's write function
+ * is allowed.
+ *
+ * \param acfptr Custom function to check
+ * \return True (non-zero) if writing is allowed.
+ * \return False (zero) if writing is not allowed.
+ */
+static int is_write_allowed(struct ast_custom_function *acfptr)
+{
+ if (!acfptr) {
+ return 1;
+ }
+
+ if (!write_escalates(acfptr)) {
+ return 1;
+ }
+
+ if (!thread_inhibits_escalations()) {
+ return 1;
+ }
+
+ if (live_dangerously) {
+ /* Global setting overrides the thread's preference */
+ ast_debug(2, "Writing %s from a dangerous context\n",
+ acfptr->name);
+ return 1;
+ }
+
+ /* We have no reason to allow this function to execute */
+ return 0;
+}
+
int ast_func_read(struct ast_channel *chan, const char *function, char *workspace, size_t len)
{
char *copy = ast_strdupa(function);
@@ -4053,6 +4295,8 @@
ast_log(LOG_ERROR, "Function %s not registered\n", copy);
} else if (!acfptr->read && !acfptr->read2) {
ast_log(LOG_ERROR, "Function %s cannot be read\n", copy);
+ } else if (!is_read_allowed(acfptr)) {
+ ast_log(LOG_ERROR, "Dangerous function %s read blocked\n", copy);
} else if (acfptr->read) {
if (acfptr->mod) {
u = __ast_module_user_add(acfptr->mod, chan);
@@ -4090,6 +4334,8 @@
ast_log(LOG_ERROR, "Function %s not registered\n", copy);
} else if (!acfptr->read && !acfptr->read2) {
ast_log(LOG_ERROR, "Function %s cannot be read\n", copy);
+ } else if (!is_read_allowed(acfptr)) {
+ ast_log(LOG_ERROR, "Dangerous function %s read blocked\n", copy);
} else {
if (acfptr->mod) {
u = __ast_module_user_add(acfptr->mod, chan);
@@ -4129,11 +4375,13 @@
char *args = func_args(copy);
struct ast_custom_function *acfptr = ast_custom_function_find(copy);
- if (acfptr == NULL)
+ if (acfptr == NULL) {
ast_log(LOG_ERROR, "Function %s not registered\n", copy);
- else if (!acfptr->write)
+ } else if (!acfptr->write) {
ast_log(LOG_ERROR, "Function %s cannot be written to\n", copy);
- else {
+ } else if (!is_write_allowed(acfptr)) {
+ ast_log(LOG_ERROR, "Dangerous function %s write blocked\n", copy);
+ } else {
int res;
struct ast_module_user *u = NULL;
if (acfptr->mod)
Index: main/tcptls.c
===================================================================
--- main/tcptls.c (revision 403915)
+++ main/tcptls.c (revision 403916)
@@ -48,6 +48,7 @@
#include "asterisk/options.h"
#include "asterisk/manager.h"
#include "asterisk/astobj2.h"
+#include "asterisk/pbx.h"
/*! \brief
* replacement read/write functions for SSL support.
@@ -161,6 +162,16 @@
char err[256];
#endif
+ /* TCP/TLS connections are associated with external protocols, and
+ * should not be allowed to execute 'dangerous' functions. This may
+ * need to be pushed down into the individual protocol handlers, but
+ * this seems like a good general policy.
+ */
+ if (ast_thread_inhibit_escalations()) {
+ ast_log(LOG_ERROR, "Failed to inhibit privilege escalations; killing connection\n");
+ return NULL;
+ }
+
/*
* open a FILE * as appropriate.
*/
Index: configs/asterisk.conf.sample
===================================================================
--- configs/asterisk.conf.sample (revision 403915)
+++ configs/asterisk.conf.sample (revision 403916)
@@ -74,6 +74,12 @@
;lockconfdir = no ; Protect the directory containing the
; configuration files (/etc/asterisk) with a
; lock.
+;live_dangerously = no ; Enable the execution of 'dangerous' dialplan
+ ; functions from external sources (AMI,
+ ; etc.) These functions (such as SHELL) are
+ ; considered dangerous because they can allow
+ ; privilege escalation.
+ ; Default yes, for backward compatability.
; Changing the following lines may compromise your security.
;[files]
Property changes on: .
___________________________________________________________________
Modified: branch-1.8-merged
- /branches/1.8:1-279056,279113,279227,279273,279280,279314,279390,279410,279442,279472,279502,279504,279562,279566,279568,279598,279601,279619,279636-279815,279817,279850,279887,279916,279949,279953,280023,280058,280090,280161,280195,280225,280233,280235,280269,280302,280307,280343,280346,280391,280414,280446,280450,280519,280549,280552,280557,280624,280628,280672,280740,280742,280777-280778,280809,280879,280909,280984,281052,281085,281294,281325,281356,281358,281429,281432,281466,281529,281532,281568,281575,281650,281687,281723,281760,281764,281870,281874-281875,281913,281982,282015,282047,282066,282098,282131,282200-282201,282236,282269,282271,282302,282334,282366,282468,282470,282543,282545,282577,282608,282638-282639,282671-282672,282740,282826,282860,282891,282895,282979,283013,283050,283173,283175,283177,283207,283209,283230,283241,283319,283350,283382,283457,283493,283527,283559,283561,283595,283627,283629,283659,283692,283770,283882,283951,284032,284065,284096,284127,284158,284281,284318,284415,284473,284477,284561,284597,284610,284632,284666,284696,284698,284701,284705,284779-284780,284849-284850,284852,284921,284950,284952,284967,285006,285017,285057,285090,285161-285162,285195,285197,285268,285336,285367,285369,285371,285373,285386,285455,285484,285527,285530,285533,285564,285568,285640,285711,285745,285819,285931,285962,286112,286118,286120,286189,286270,286426,286457,286528,286558,286588,286617,286647,286682,286758,286834,286868,286904-286905,286931,287015,287017,287020,287056,287116,287120,287193,287195,287269-287271,287309,287388,287471,287559,287639,287643,287645,287647,287661,287683,287701,287757,287760,287833,287863,287893,287895,287897,287929,287931,287935,288007,288079-288080,288082,288157,288159,288194,288268,288341,288345,288418,288507,288572,288606,288638,288640,288713,288748,288821,288852,288925,288927,292740-292741,292787,292794,292825,292868,292906,292969,293119,293159,293197,293305,293341,293418,293496,293530,293611,293648,293724,293803,293807,293887,293924,293970,294047,294049,294084,294125,294207,294243,294278,294313,294349,294430,294466,294501,294535,294569,294605,294734,294740,294745,294823,294905,294911,294989,295078,295164,295201,295278,295282,295361,295404,295441,295477,295516,295670,295673,295711,295747,295866,295869,295949,296002,296084,296167,296230,296352,296354,296391,296429,296467,296534,296582,296628,296673,296787,296870,296951,296992,297075,297157-297495,297535,297607,297733,297821,297825,297909,297952,297957,297965,298051,298054,298195,298394,298478,298482,298539,298598,298685,298773,298818,298827,298960,299088,299131,299138,299248,299312,299353,299405,299449,299583,299626,299752,299794,299820,299865,299907,299948,299989,300082,300166,300214,300301,300384,300430,300433,300521,300575,300623,300714,300798,300955,301047,301090,301134,301177,301221,301263,301308,301311,301402,301446,301504,301595,301683,302462,302505,302549,302552,302555,302600,302634,302680,302713,302785,302789,302831,302834,302837,302918,302921,303009,303107,303153,303467,303549,303678,303771,303860,303907,303962,304007,304097,304150,304186,304245,304251,304339,304462,304466,304554,304638,304683,304727,304730,304774,304777,304866,304908,304950,304985,305040,305083,305603,305692,305753,305798,305838,305844,305923,306124,306127,306215,306324,306356,306575,306619,306674,306866,306962,306967,306979,306999,307065,307092,307142,307228,307273,307467,307536,307750,307793,307837,307879,307962,308010,308098,308150,308242,308288,308416,308622,308679,308723,308815,308903,308945,308991,309035,309084,309126,309170,309204,309256,309403,309445,309448,309495,309542,309585,309678,309720,309765,309808,309858,309994,310039,310088,310142,310231,310240,310287,310415,310462,310587,310636,310734,310781,310834,310902,310993,310999,311050,311141,311197,311295,311297,311342,311352,311497,311558,311612,311615,311687,311751,311799,311874,311930,312022,312117,312211,312286-312288,312461,312509,312575,312766,312866,312889,312949,313001,313048,313142,313190,313279,313366,313368-313369,313434,313517,313588,313615,313658,313700,313780,313860,314017,314067-314069,314203,314206,314251,314358,314417,314550,314628,314732,314779-314780,314959,315001,315053,315213,315259,315349,315394,315446,315452,315503,315645,315673,315765,315810,315894,316094,316193,316206,316215,316217,316224,316265,316330-316331,316334,316336,316429,316476,316617,316650,316663,316709,316831,316917-316919,317058,317104,317196,317281,317283,317336,317370,317425,317427,317429,317474,317476,317478,317480,317484,317486,317530,317584,317670,317805,317837,317865,317867,317917-317918,317967,317969,318055,318057,318142,318148,318231,318233,318282,318337,318351,318436,318499,318549-318550,318671,318720,318783,318868,318917,318919,318921,319083,319085,319142,319145,319204,319259,319365,319367,319469,319529,319552,319654,319758,319812,319866,319938,319997,320007,320057,320059,320162,320180,320237,320338,320445,320504,320560,320568,320573,320650,320716,320796,320823,320883,320947,321042,321044,321100,321155,321211,321273,321330,321333,321337,321392,321436,321511,321515,321517,321528,321537,321547,321685,321812-321813,321871,321924,321926,322069,322189,322322,322425,322484,322749,322807,322865,322923,322981,323040,323154,323213,323370-323371,323392-323394,323456,323608,323610,323669-323670,323672,323754,323859,323863,323866,323932,323990,324048,324115,324174,324176,324178,324237,324241,324364,324479,324481,324484,324491,324557,324652,324678,324685,324768,324849,324914,324955,325091,325152,325212,325339,325416,325537,325545,325610,325614,325673,325740,325821,325877,325935,326144,326209,326291,326411,326484,326681,326683,326689,326830,326985,327044,327046,327106,327211,327411,327512,327682,327793,327852,327888,327890,327950,328014,328205,328209,328302,328427,328540,328593,328608,328663,328716,328770,328823,328878,328935,328987,329027,329144,329199,329203,329299,329333,329471,329527,329529,329613,329709,329767,329895,329991,329994,330050,330107,330203,330213,330311,330368,330433,330575,330578,330581,330648,330705,330762,330827,330843,331038,331142,331146,331248,331315,331461,331517,331575,331578,331635,331649,331658,331714,331771,331774,331867,331886,331955,332021,332026,332100,332118,332176,332264,332320,332355,332446,332503,332559,332699,332759,332816-332817,332874,332876,332939,333010,333201,333265,333267,333339,333378,333569,333630,333784-333785,333836,333947,334006,334009,334012,334156,334229,334234,334296,334355,334453,334616,334620,334682,334840,334843,334953,335064,335319,335341,335433,335497,335618,335655,335720,335790,335851,335911,335978,336093,336166,336234,336294,336312,336314,336378,336440,336499,336501,336569,336572,336658,336716,336733,336791,336877,336977,337007,337061,337115,337118,337325,337344,337353,337430,337486,337541,337720,337774,337839,337898,337973,338084,338224,338227,338235,338322,338416,338492,338551,338555,338663,338718,338800,339086-339087,339144,339147,339244,339297,339352,339406,339504-339506,339511,339566,339625,339719,339776,339830,339884,339938,340108,340164,340263,340279,340284,340365,340418,340470,340522,340534,340576,340662,340715,340809,340863,340878,340970,341022,341074,341088,341108-341112,341189,341254,341312,341314,341366,341379,341435,341529,341664,341704,341717,341806,341809,342061,342223,342276,342328,342380,342383,342435,342484,342487,342545,342602,342661,342769,342869,342927,342990,343047,343102,343157,343181,343220,343276,343281,343336,343375,343577,343621,343637,343690,343791,343851,343936,344048,344102,344157-344158,344215,344268,344330,344385,344439,344536,344539,344608,344661,344715,344769,344823,344835,344837,344843,344899,344965,345062-345063,345160,345163,345219,345273,345285,345370,345431,345487,345546,345682,345828-345829,345923,345976,346030,346086,346144,346147,346239,346292,346472,346564,346697,346700,346762,346899,346951,346954,347006,347058,347111,347131,347166,347239,347292,347369,347438,347531,347595,347718,347811,347995,348101,348154,348157,348212,348310,348362,348401,348464,348516,348647,348735,348833,348888,348940,348992,349044,349144,349194,349289,349339,349450,349482,349504,349529,349558,349672,349728,349731,349819,349872,349968,350023,350679,350730,350733,350736,350788-350789,350837,350885,350888,350975,351027,351080,351130,351182,351233,351284,351287,351306,351396,351450,351504,351559,351611,351618,351707,351759,351858,351860,352014,352016,352029,352090,352144,352199,352230,352291,352367,352424,352511,352514,352551,352612,352643,352704,352755,352807,352862,352955,352959,353077,353126,353175,353260,353320,353368,353371,353454,353502,353550,353598,353720,353769-353770,353867,353915,353999,354116,354216,354263,354348,354492,354495,354542,354545,354547,354655,354702,354749,354835,354889,354953,355009,355056,355136,355182,355228,355268,355319,355365,355448,355458,355529,355574,355608,355622,355732,355746,355793,355850,355901,355904,355949,355952,355997,356107,356214,356290-356337,356430,356475,356521,356604,356650,356677,356797,356917,356963,357093,357212,357266,357352,357356,357386,357407,357416,357455,357490,357575,357665,357761,357809,357811,357894,357940,357986,358011,358029,358115,358162,358214,358260,358278,358377,358435,358438,358484,358530,358643,358810,358859,358943,358978,359050,359053,359056,359059,359069,359088,359110,359116,359157,359211,359259,359344,359356,359451-359452,359457,359486,359508,359558,359609,359656,359706,359809,359892,359979,360033,360086-360087,360138,360262,360309,360356-360357,360360,360363,360413,360471,360474,360488,360574,360625,360712,360862,360884,360933,360987,361040,361090,361142,361201,361210,361269,361329,361332,361380,361403-361412,361471,361558,361606,361657,361705,361753,361803,361854,361955,361972,362079,362082,362151,362201,362204,362253,362304,362354-362355,362359,362362,362428,362485,362536,362586,362677,362680,362729,362815,362868,362997,363102,363106,363141,363209,363375,363428,363687,363730,363788,363875,363934,363986,364046,364060,364108,364203,364258,364277,364340-364341,364578,364635,364649,364706,364769,364786,364840-364841,364899,364902,365006-365068,365143,365159,365298,365313,365398,365474,365476,365574,365631,365692,365896,365989,366048,366052,366094,366167,366240,366296,366389,366409,366547,366597,366740,366791,366880,366882,366944,367002,367027,367266,367292,367362,367416,367469,367678,367730,367781,367906,367976,367980,368039,368092,368218,368308,368405,368469,368498,368520,368533,368567,368586,368604,368625,368644,368719,368738,368759,368807,368830,368852,368873,368894,368898,368927,369001-369002,369043,369066,369108,369146,369195,369214,369235,369238,369258,369262,369282,369302,369323-369324,369327,369351-369352,369390,369436,369471,369490,369557,369579,369626,369652,369708,369731,369750,369792,369818,369869,369937,369970,369993,370014,370017,370081,370131,370183,370205,370252,370273,370275,370360,370383,370428-370429,370494,370563,370618,370642,370666,370697,370769-370771,370797,370856,370900,370923,370952,370985,370988,371011-371012,371060,371089,371141,371198,371201,371270,371306,371337,371357,371392-371393,371436,371469,371544,371590,371662,371690,371718,371747,371782,371787,371824,371860,371888,371919,371961,371998,372015,372048,372089,372158,372185,372212,372239,372339,372354,372390,372417,372444,372471,372517,372554,372581,372620,372624,372628,372655,372682,372709,372736,372763,372765,372804,372840,372902,372932,372959,373024,373061,373090,373131,373165,373236,373242,373298,373342,373424,373438,373467,373500,373504,373532,373550,373578,373617-373618,373640,373652,373666,373702,373705,373735,373768,373773,373815,373848,373878,373909,373945,373989,374032,374177,374230,374335,374365,374384,374426,374456,374475,374479,374536,374570-374581,374686,374727,374758,374802,374843,374905,374977,375025,375059,375074,375111,375146,375189,375216,375272,375299,375325,375361,375388,375415,375450,375484,375528,375594,375625,375658,375698,375727,375758,375793,375800,375862,375893,375964,375993-375994,376029,376058,376087,376142,376166,376199,376232,376262,376306-376307,376340,376389,376428,376469,376521,376586,376627,376657,376688,376725,376758,376788,376834,376864,376868,376901,376919,376950,377037,377069,377073,377104,377135,377165,377256-377257,377398,377431,377487,377509,377557,377591,377623,377655,377704,377708,377740,377771,377806,377837,377840,377847,377881,377922,377946,378036,378088,378092,378119,378217,378269,378303,378663,379509,379760,390181,397710,397756
+ /branches/1.8:1-279056,279113,279227,279273,279280,279314,279390,279410,279442,279472,279502,279504,279562,279566,279568,279598,279601,279619,279636-279815,279817,279850,279887,279916,279949,279953,280023,280058,280090,280161,280195,280225,280233,280235,280269,280302,280307,280343,280346,280391,280414,280446,280450,280519,280549,280552,280557,280624,280628,280672,280740,280742,280777-280778,280809,280879,280909,280984,281052,281085,281294,281325,281356,281358,281429,281432,281466,281529,281532,281568,281575,281650,281687,281723,281760,281764,281870,281874-281875,281913,281982,282015,282047,282066,282098,282131,282200-282201,282236,282269,282271,282302,282334,282366,282468,282470,282543,282545,282577,282608,282638-282639,282671-282672,282740,282826,282860,282891,282895,282979,283013,283050,283173,283175,283177,283207,283209,283230,283241,283319,283350,283382,283457,283493,283527,283559,283561,283595,283627,283629,283659,283692,283770,283882,283951,284032,284065,284096,284127,284158,284281,284318,284415,284473,284477,284561,284597,284610,284632,284666,284696,284698,284701,284705,284779-284780,284849-284850,284852,284921,284950,284952,284967,285006,285017,285057,285090,285161-285162,285195,285197,285268,285336,285367,285369,285371,285373,285386,285455,285484,285527,285530,285533,285564,285568,285640,285711,285745,285819,285931,285962,286112,286118,286120,286189,286270,286426,286457,286528,286558,286588,286617,286647,286682,286758,286834,286868,286904-286905,286931,287015,287017,287020,287056,287116,287120,287193,287195,287269-287271,287309,287388,287471,287559,287639,287643,287645,287647,287661,287683,287701,287757,287760,287833,287863,287893,287895,287897,287929,287931,287935,288007,288079-288080,288082,288157,288159,288194,288268,288341,288345,288418,288507,288572,288606,288638,288640,288713,288748,288821,288852,288925,288927,292740-292741,292787,292794,292825,292868,292906,292969,293119,293159,293197,293305,293341,293418,293496,293530,293611,293648,293724,293803,293807,293887,293924,293970,294047,294049,294084,294125,294207,294243,294278,294313,294349,294430,294466,294501,294535,294569,294605,294734,294740,294745,294823,294905,294911,294989,295078,295164,295201,295278,295282,295361,295404,295441,295477,295516,295670,295673,295711,295747,295866,295869,295949,296002,296084,296167,296230,296352,296354,296391,296429,296467,296534,296582,296628,296673,296787,296870,296951,296992,297075,297157-297495,297535,297607,297733,297821,297825,297909,297952,297957,297965,298051,298054,298195,298394,298478,298482,298539,298598,298685,298773,298818,298827,298960,299088,299131,299138,299248,299312,299353,299405,299449,299583,299626,299752,299794,299820,299865,299907,299948,299989,300082,300166,300214,300301,300384,300430,300433,300521,300575,300623,300714,300798,300955,301047,301090,301134,301177,301221,301263,301308,301311,301402,301446,301504,301595,301683,302462,302505,302549,302552,302555,302600,302634,302680,302713,302785,302789,302831,302834,302837,302918,302921,303009,303107,303153,303467,303549,303678,303771,303860,303907,303962,304007,304097,304150,304186,304245,304251,304339,304462,304466,304554,304638,304683,304727,304730,304774,304777,304866,304908,304950,304985,305040,305083,305603,305692,305753,305798,305838,305844,305923,306124,306127,306215,306324,306356,306575,306619,306674,306866,306962,306967,306979,306999,307065,307092,307142,307228,307273,307467,307536,307750,307793,307837,307879,307962,308010,308098,308150,308242,308288,308416,308622,308679,308723,308815,308903,308945,308991,309035,309084,309126,309170,309204,309256,309403,309445,309448,309495,309542,309585,309678,309720,309765,309808,309858,309994,310039,310088,310142,310231,310240,310287,310415,310462,310587,310636,310734,310781,310834,310902,310993,310999,311050,311141,311197,311295,311297,311342,311352,311497,311558,311612,311615,311687,311751,311799,311874,311930,312022,312117,312211,312286-312288,312461,312509,312575,312766,312866,312889,312949,313001,313048,313142,313190,313279,313366,313368-313369,313434,313517,313588,313615,313658,313700,313780,313860,314017,314067-314069,314203,314206,314251,314358,314417,314550,314628,314732,314779-314780,314959,315001,315053,315213,315259,315349,315394,315446,315452,315503,315645,315673,315765,315810,315894,316094,316193,316206,316215,316217,316224,316265,316330-316331,316334,316336,316429,316476,316617,316650,316663,316709,316831,316917-316919,317058,317104,317196,317281,317283,317336,317370,317425,317427,317429,317474,317476,317478,317480,317484,317486,317530,317584,317670,317805,317837,317865,317867,317917-317918,317967,317969,318055,318057,318142,318148,318231,318233,318282,318337,318351,318436,318499,318549-318550,318671,318720,318783,318868,318917,318919,318921,319083,319085,319142,319145,319204,319259,319365,319367,319469,319529,319552,319654,319758,319812,319866,319938,319997,320007,320057,320059,320162,320180,320237,320338,320445,320504,320560,320568,320573,320650,320716,320796,320823,320883,320947,321042,321044,321100,321155,321211,321273,321330,321333,321337,321392,321436,321511,321515,321517,321528,321537,321547,321685,321812-321813,321871,321924,321926,322069,322189,322322,322425,322484,322749,322807,322865,322923,322981,323040,323154,323213,323370-323371,323392-323394,323456,323608,323610,323669-323670,323672,323754,323859,323863,323866,323932,323990,324048,324115,324174,324176,324178,324237,324241,324364,324479,324481,324484,324491,324557,324652,324678,324685,324768,324849,324914,324955,325091,325152,325212,325339,325416,325537,325545,325610,325614,325673,325740,325821,325877,325935,326144,326209,326291,326411,326484,326681,326683,326689,326830,326985,327044,327046,327106,327211,327411,327512,327682,327793,327852,327888,327890,327950,328014,328205,328209,328302,328427,328540,328593,328608,328663,328716,328770,328823,328878,328935,328987,329027,329144,329199,329203,329299,329333,329471,329527,329529,329613,329709,329767,329895,329991,329994,330050,330107,330203,330213,330311,330368,330433,330575,330578,330581,330648,330705,330762,330827,330843,331038,331142,331146,331248,331315,331461,331517,331575,331578,331635,331649,331658,331714,331771,331774,331867,331886,331955,332021,332026,332100,332118,332176,332264,332320,332355,332446,332503,332559,332699,332759,332816-332817,332874,332876,332939,333010,333201,333265,333267,333339,333378,333569,333630,333784-333785,333836,333947,334006,334009,334012,334156,334229,334234,334296,334355,334453,334616,334620,334682,334840,334843,334953,335064,335319,335341,335433,335497,335618,335655,335720,335790,335851,335911,335978,336093,336166,336234,336294,336312,336314,336378,336440,336499,336501,336569,336572,336658,336716,336733,336791,336877,336977,337007,337061,337115,337118,337325,337344,337353,337430,337486,337541,337720,337774,337839,337898,337973,338084,338224,338227,338235,338322,338416,338492,338551,338555,338663,338718,338800,339086-339087,339144,339147,339244,339297,339352,339406,339504-339506,339511,339566,339625,339719,339776,339830,339884,339938,340108,340164,340263,340279,340284,340365,340418,340470,340522,340534,340576,340662,340715,340809,340863,340878,340970,341022,341074,341088,341108-341112,341189,341254,341312,341314,341366,341379,341435,341529,341664,341704,341717,341806,341809,342061,342223,342276,342328,342380,342383,342435,342484,342487,342545,342602,342661,342769,342869,342927,342990,343047,343102,343157,343181,343220,343276,343281,343336,343375,343577,343621,343637,343690,343791,343851,343936,344048,344102,344157-344158,344215,344268,344330,344385,344439,344536,344539,344608,344661,344715,344769,344823,344835,344837,344843,344899,344965,345062-345063,345160,345163,345219,345273,345285,345370,345431,345487,345546,345682,345828-345829,345923,345976,346030,346086,346144,346147,346239,346292,346472,346564,346697,346700,346762,346899,346951,346954,347006,347058,347111,347131,347166,347239,347292,347369,347438,347531,347595,347718,347811,347995,348101,348154,348157,348212,348310,348362,348401,348464,348516,348647,348735,348833,348888,348940,348992,349044,349144,349194,349289,349339,349450,349482,349504,349529,349558,349672,349728,349731,349819,349872,349968,350023,350679,350730,350733,350736,350788-350789,350837,350885,350888,350975,351027,351080,351130,351182,351233,351284,351287,351306,351396,351450,351504,351559,351611,351618,351707,351759,351858,351860,352014,352016,352029,352090,352144,352199,352230,352291,352367,352424,352511,352514,352551,352612,352643,352704,352755,352807,352862,352955,352959,353077,353126,353175,353260,353320,353368,353371,353454,353502,353550,353598,353720,353769-353770,353867,353915,353999,354116,354216,354263,354348,354492,354495,354542,354545,354547,354655,354702,354749,354835,354889,354953,355009,355056,355136,355182,355228,355268,355319,355365,355448,355458,355529,355574,355608,355622,355732,355746,355793,355850,355901,355904,355949,355952,355997,356107,356214,356290-356337,356430,356475,356521,356604,356650,356677,356797,356917,356963,357093,357212,357266,357352,357356,357386,357407,357416,357455,357490,357575,357665,357761,357809,357811,357894,357940,357986,358011,358029,358115,358162,358214,358260,358278,358377,358435,358438,358484,358530,358643,358810,358859,358943,358978,359050,359053,359056,359059,359069,359088,359110,359116,359157,359211,359259,359344,359356,359451-359452,359457,359486,359508,359558,359609,359656,359706,359809,359892,359979,360033,360086-360087,360138,360262,360309,360356-360357,360360,360363,360413,360471,360474,360488,360574,360625,360712,360862,360884,360933,360987,361040,361090,361142,361201,361210,361269,361329,361332,361380,361403-361412,361471,361558,361606,361657,361705,361753,361803,361854,361955,361972,362079,362082,362151,362201,362204,362253,362304,362354-362355,362359,362362,362428,362485,362536,362586,362677,362680,362729,362815,362868,362997,363102,363106,363141,363209,363375,363428,363687,363730,363788,363875,363934,363986,364046,364060,364108,364203,364258,364277,364340-364341,364578,364635,364649,364706,364769,364786,364840-364841,364899,364902,365006-365068,365143,365159,365298,365313,365398,365474,365476,365574,365631,365692,365896,365989,366048,366052,366094,366167,366240,366296,366389,366409,366547,366597,366740,366791,366880,366882,366944,367002,367027,367266,367292,367362,367416,367469,367678,367730,367781,367906,367976,367980,368039,368092,368218,368308,368405,368469,368498,368520,368533,368567,368586,368604,368625,368644,368719,368738,368759,368807,368830,368852,368873,368894,368898,368927,369001-369002,369043,369066,369108,369146,369195,369214,369235,369238,369258,369262,369282,369302,369323-369324,369327,369351-369352,369390,369436,369471,369490,369557,369579,369626,369652,369708,369731,369750,369792,369818,369869,369937,369970,369993,370014,370017,370081,370131,370183,370205,370252,370273,370275,370360,370383,370428-370429,370494,370563,370618,370642,370666,370697,370769-370771,370797,370856,370900,370923,370952,370985,370988,371011-371012,371060,371089,371141,371198,371201,371270,371306,371337,371357,371392-371393,371436,371469,371544,371590,371662,371690,371718,371747,371782,371787,371824,371860,371888,371919,371961,371998,372015,372048,372089,372158,372185,372212,372239,372339,372354,372390,372417,372444,372471,372517,372554,372581,372620,372624,372628,372655,372682,372709,372736,372763,372765,372804,372840,372902,372932,372959,373024,373061,373090,373131,373165,373236,373242,373298,373342,373424,373438,373467,373500,373504,373532,373550,373578,373617-373618,373640,373652,373666,373702,373705,373735,373768,373773,373815,373848,373878,373909,373945,373989,374032,374177,374230,374335,374365,374384,374426,374456,374475,374479,374536,374570-374581,374686,374727,374758,374802,374843,374905,374977,375025,375059,375074,375111,375146,375189,375216,375272,375299,375325,375361,375388,375415,375450,375484,375528,375594,375625,375658,375698,375727,375758,375793,375800,375862,375893,375964,375993-375994,376029,376058,376087,376142,376166,376199,376232,376262,376306-376307,376340,376389,376428,376469,376521,376586,376627,376657,376688,376725,376758,376788,376834,376864,376868,376901,376919,376950,377037,377069,377073,377104,377135,377165,377256-377257,377398,377431,377487,377509,377557,377591,377623,377655,377704,377708,377740,377771,377806,377837,377840,377847,377881,377922,377946,378036,378088,378092,378119,378217,378269,378303,378663,379509,379760,390181,397710,397756,403913