00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include "asterisk.h"
00036
00037 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 150816 $")
00038
00039 #include <stdio.h>
00040 #include <stdlib.h>
00041 #include <string.h>
00042 #include <ctype.h>
00043 #include <sys/time.h>
00044 #include <sys/types.h>
00045 #include <netdb.h>
00046 #include <sys/socket.h>
00047 #include <netinet/in.h>
00048 #include <netinet/tcp.h>
00049 #include <arpa/inet.h>
00050 #include <signal.h>
00051 #include <errno.h>
00052 #include <unistd.h>
00053
00054 #include "asterisk/channel.h"
00055 #include "asterisk/file.h"
00056 #include "asterisk/manager.h"
00057 #include "asterisk/config.h"
00058 #include "asterisk/callerid.h"
00059 #include "asterisk/lock.h"
00060 #include "asterisk/logger.h"
00061 #include "asterisk/options.h"
00062 #include "asterisk/cli.h"
00063 #include "asterisk/app.h"
00064 #include "asterisk/pbx.h"
00065 #include "asterisk/md5.h"
00066 #include "asterisk/acl.h"
00067 #include "asterisk/utils.h"
00068 #include "asterisk/http.h"
00069 #include "asterisk/threadstorage.h"
00070 #include "asterisk/linkedlists.h"
00071 #include "asterisk/term.h"
00072 #include "asterisk/astobj2.h"
00073
00074 struct fast_originate_helper {
00075 char tech[AST_MAX_EXTENSION];
00076 char data[AST_MAX_EXTENSION];
00077 int timeout;
00078 int format;
00079 char app[AST_MAX_APP];
00080 char appdata[AST_MAX_EXTENSION];
00081 char cid_name[AST_MAX_EXTENSION];
00082 char cid_num[AST_MAX_EXTENSION];
00083 char context[AST_MAX_CONTEXT];
00084 char exten[AST_MAX_EXTENSION];
00085 char idtext[AST_MAX_EXTENSION];
00086 char account[AST_MAX_ACCOUNT_CODE];
00087 int priority;
00088 struct ast_variable *vars;
00089 };
00090
00091 struct eventqent {
00092 int usecount;
00093 int category;
00094 struct eventqent *next;
00095 char eventdata[1];
00096 };
00097
00098 static int enabled;
00099 static int portno = DEFAULT_MANAGER_PORT;
00100 static int asock = -1;
00101 static int displayconnects = 1;
00102 static int timestampevents;
00103 static int httptimeout = 60;
00104
00105 static pthread_t t;
00106 static int block_sockets;
00107 static int num_sessions;
00108
00109
00110 struct eventqent *master_eventq = NULL;
00111
00112 AST_THREADSTORAGE(manager_event_buf, manager_event_buf_init);
00113 #define MANAGER_EVENT_BUF_INITSIZE 256
00114
00115 AST_THREADSTORAGE(astman_append_buf, astman_append_buf_init);
00116 #define ASTMAN_APPEND_BUF_INITSIZE 256
00117
00118 static struct permalias {
00119 int num;
00120 char *label;
00121 } perms[] = {
00122 { EVENT_FLAG_SYSTEM, "system" },
00123 { EVENT_FLAG_CALL, "call" },
00124 { EVENT_FLAG_LOG, "log" },
00125 { EVENT_FLAG_VERBOSE, "verbose" },
00126 { EVENT_FLAG_COMMAND, "command" },
00127 { EVENT_FLAG_AGENT, "agent" },
00128 { EVENT_FLAG_USER, "user" },
00129 { EVENT_FLAG_CONFIG, "config" },
00130 { -1, "all" },
00131 { 0, "none" },
00132 };
00133
00134 #define MAX_BLACKLIST_CMD_LEN 2
00135 static struct {
00136 char *words[AST_MAX_CMD_LEN];
00137 } command_blacklist[] = {
00138 {{ "module", "load", NULL }},
00139 {{ "module", "unload", NULL }},
00140 };
00141
00142 struct mansession {
00143
00144 pthread_t t;
00145
00146 ast_mutex_t __lock;
00147
00148 struct sockaddr_in sin;
00149
00150 int fd;
00151
00152 int inuse;
00153
00154 int needdestroy;
00155
00156 pthread_t waiting_thread;
00157
00158 uint32_t managerid;
00159
00160 time_t sessiontimeout;
00161
00162 struct ast_dynamic_str *outputstr;
00163
00164 char username[80];
00165
00166 char challenge[10];
00167
00168 int authenticated;
00169
00170 int readperm;
00171
00172 int writeperm;
00173
00174 char inbuf[1024];
00175 int inlen;
00176 int send_events;
00177 int displaysystemname;
00178
00179 struct eventqent *eventq;
00180
00181 int writetimeout;
00182 int pending_event;
00183 AST_LIST_ENTRY(mansession) list;
00184 };
00185
00186 static AST_LIST_HEAD_STATIC(sessions, mansession);
00187
00188 struct ast_manager_user {
00189 char username[80];
00190 char *secret;
00191 char *deny;
00192 char *permit;
00193 char *read;
00194 char *write;
00195 unsigned int displayconnects:1;
00196 int keep;
00197 AST_LIST_ENTRY(ast_manager_user) list;
00198 };
00199
00200 static AST_LIST_HEAD_STATIC(users, ast_manager_user);
00201
00202 static struct manager_action *first_action;
00203 AST_RWLOCK_DEFINE_STATIC(actionlock);
00204
00205
00206 static char *authority_to_str(int authority, char *res, int reslen)
00207 {
00208 int running_total = 0, i;
00209
00210 memset(res, 0, reslen);
00211 for (i = 0; i < (sizeof(perms) / sizeof(perms[0])) - 1; i++) {
00212 if (authority & perms[i].num) {
00213 if (*res) {
00214 strncat(res, ",", (reslen > running_total) ? reslen - running_total - 1 : 0);
00215 running_total++;
00216 }
00217 strncat(res, perms[i].label, (reslen > running_total) ? reslen - running_total - 1 : 0);
00218 running_total += strlen(perms[i].label);
00219 }
00220 }
00221
00222 if (ast_strlen_zero(res))
00223 ast_copy_string(res, "<none>", reslen);
00224
00225 return res;
00226 }
00227
00228 static char *complete_show_mancmd(const char *line, const char *word, int pos, int state)
00229 {
00230 struct manager_action *cur;
00231 int which = 0;
00232 char *ret = NULL;
00233
00234 ast_rwlock_rdlock(&actionlock);
00235 for (cur = first_action; cur; cur = cur->next) {
00236 if (!strncasecmp(word, cur->action, strlen(word)) && ++which > state) {
00237 ret = ast_strdup(cur->action);
00238 break;
00239 }
00240 }
00241 ast_rwlock_unlock(&actionlock);
00242
00243 return ret;
00244 }
00245
00246 static void xml_copy_escape(char **dst, size_t *maxlen, const char *src, int lower)
00247 {
00248 while (*src && (*maxlen > 6)) {
00249 switch (*src) {
00250 case '<':
00251 strcpy(*dst, "<");
00252 (*dst) += 4;
00253 *maxlen -= 4;
00254 break;
00255 case '>':
00256 strcpy(*dst, ">");
00257 (*dst) += 4;
00258 *maxlen -= 4;
00259 break;
00260 case '\"':
00261 strcpy(*dst, """);
00262 (*dst) += 6;
00263 *maxlen -= 6;
00264 break;
00265 case '\'':
00266 strcpy(*dst, "'");
00267 (*dst) += 6;
00268 *maxlen -= 6;
00269 break;
00270 case '&':
00271 strcpy(*dst, "&");
00272 (*dst) += 5;
00273 *maxlen -= 5;
00274 break;
00275 default:
00276 *(*dst)++ = lower ? tolower(*src) : *src;
00277 (*maxlen)--;
00278 }
00279 src++;
00280 }
00281 }
00282
00283 struct variable_count {
00284 char *varname;
00285 int count;
00286 };
00287
00288 static int compress_char(char c)
00289 {
00290 c &= 0x7f;
00291 if (c < 32)
00292 return 0;
00293 else if (c >= 'a' && c <= 'z')
00294 return c - 64;
00295 else if (c > 'z')
00296 return '_';
00297 else
00298 return c - 32;
00299 }
00300
00301 static int variable_count_hash_fn(const void *vvc, const int flags)
00302 {
00303 const struct variable_count *vc = vvc;
00304 int res = 0, i;
00305 for (i = 0; i < 5; i++) {
00306 if (vc->varname[i] == '\0')
00307 break;
00308 res += compress_char(vc->varname[i]) << (i * 6);
00309 }
00310 return res;
00311 }
00312
00313 static int variable_count_cmp_fn(void *obj, void *vstr, int flags)
00314 {
00315
00316
00317
00318
00319 struct variable_count *vc = obj;
00320 char *str = vstr;
00321 return !strcmp(vc->varname, str) ? CMP_MATCH | CMP_STOP : 0;
00322 }
00323
00324 static char *xml_translate(char *in, struct ast_variable *vars)
00325 {
00326 struct ast_variable *v;
00327 char *dest = NULL;
00328 char *out, *tmp, *var, *val;
00329 char *objtype = NULL;
00330 int colons = 0;
00331 int breaks = 0;
00332 size_t len;
00333 int count = 1;
00334 int escaped = 0;
00335 int inobj = 0;
00336 int x;
00337 struct variable_count *vc = NULL;
00338 struct ao2_container *vco = NULL;
00339
00340 for (v = vars; v; v = v->next) {
00341 if (!dest && !strcasecmp(v->name, "ajaxdest"))
00342 dest = v->value;
00343 else if (!objtype && !strcasecmp(v->name, "ajaxobjtype"))
00344 objtype = v->value;
00345 }
00346 if (!dest)
00347 dest = "unknown";
00348 if (!objtype)
00349 objtype = "generic";
00350 for (x = 0; in[x]; x++) {
00351 if (in[x] == ':')
00352 colons++;
00353 else if (in[x] == '\n')
00354 breaks++;
00355 else if (strchr("&\"<>\'", in[x]))
00356 escaped++;
00357 }
00358 len = (size_t) (strlen(in) + colons * 5 + breaks * (40 + strlen(dest) + strlen(objtype)) + escaped * 10);
00359 out = ast_malloc(len);
00360 if (!out)
00361 return 0;
00362 tmp = out;
00363 while (*in) {
00364 var = in;
00365 while (*in && (*in >= 32))
00366 in++;
00367 if (*in) {
00368 if ((count > 3) && inobj) {
00369 ast_build_string(&tmp, &len, " /></response>\n");
00370 inobj = 0;
00371
00372
00373 ao2_ref(vco, -1);
00374 vco = NULL;
00375 }
00376 count = 0;
00377 while (*in && (*in < 32)) {
00378 *in = '\0';
00379 in++;
00380 count++;
00381 }
00382 val = strchr(var, ':');
00383 if (val) {
00384 *val = '\0';
00385 val++;
00386 if (*val == ' ')
00387 val++;
00388 if (!inobj) {
00389 vco = ao2_container_alloc(37, variable_count_hash_fn, variable_count_cmp_fn);
00390 ast_build_string(&tmp, &len, "<response type='object' id='%s'><%s", dest, objtype);
00391 inobj = 1;
00392 }
00393
00394
00395 if ((vc = ao2_find(vco, var, 0)))
00396 vc->count++;
00397 else {
00398
00399 vc = ao2_alloc(sizeof(*vc), NULL);
00400 vc->varname = var;
00401 vc->count = 1;
00402 ao2_link(vco, vc);
00403 }
00404
00405 ast_build_string(&tmp, &len, " ");
00406 xml_copy_escape(&tmp, &len, var, 1);
00407 if (vc->count > 1)
00408 ast_build_string(&tmp, &len, "-%d", vc->count);
00409 ast_build_string(&tmp, &len, "='");
00410 xml_copy_escape(&tmp, &len, val, 0);
00411 ast_build_string(&tmp, &len, "'");
00412 ao2_ref(vc, -1);
00413 }
00414 }
00415 }
00416 if (inobj)
00417 ast_build_string(&tmp, &len, " /></response>\n");
00418 if (vco)
00419 ao2_ref(vco, -1);
00420 return out;
00421 }
00422
00423 static char *html_translate(char *in)
00424 {
00425 int x;
00426 int colons = 0;
00427 int breaks = 0;
00428 size_t len;
00429 int count = 1;
00430 char *tmp, *var, *val, *out;
00431
00432 for (x=0; in[x]; x++) {
00433 if (in[x] == ':')
00434 colons++;
00435 if (in[x] == '\n')
00436 breaks++;
00437 }
00438 len = strlen(in) + colons * 40 + breaks * 40;
00439 out = ast_malloc(len);
00440 if (!out)
00441 return 0;
00442 tmp = out;
00443 while (*in) {
00444 var = in;
00445 while (*in && (*in >= 32))
00446 in++;
00447 if (*in) {
00448 if ((count % 4) == 0){
00449 ast_build_string(&tmp, &len, "<tr><td colspan=\"2\"><hr></td></tr>\r\n");
00450 }
00451 count = 0;
00452 while (*in && (*in < 32)) {
00453 *in = '\0';
00454 in++;
00455 count++;
00456 }
00457 val = strchr(var, ':');
00458 if (val) {
00459 *val = '\0';
00460 val++;
00461 if (*val == ' ')
00462 val++;
00463 ast_build_string(&tmp, &len, "<tr><td>%s</td><td>%s</td></tr>\r\n", var, val);
00464 }
00465 }
00466 }
00467 return out;
00468 }
00469
00470
00471
00472 static struct ast_manager_user *ast_get_manager_by_name_locked(const char *name)
00473 {
00474 struct ast_manager_user *user = NULL;
00475
00476 AST_LIST_TRAVERSE(&users, user, list)
00477 if (!strcasecmp(user->username, name))
00478 break;
00479 return user;
00480 }
00481
00482 void astman_append(struct mansession *s, const char *fmt, ...)
00483 {
00484 va_list ap;
00485 struct ast_dynamic_str *buf;
00486
00487 ast_mutex_lock(&s->__lock);
00488
00489 if (!(buf = ast_dynamic_str_thread_get(&astman_append_buf, ASTMAN_APPEND_BUF_INITSIZE))) {
00490 ast_mutex_unlock(&s->__lock);
00491 return;
00492 }
00493
00494 va_start(ap, fmt);
00495 ast_dynamic_str_thread_set_va(&buf, 0, &astman_append_buf, fmt, ap);
00496 va_end(ap);
00497
00498 if (s->fd > -1)
00499 ast_carefulwrite(s->fd, buf->str, strlen(buf->str), s->writetimeout);
00500 else {
00501 if (!s->outputstr && !(s->outputstr = ast_calloc(1, sizeof(*s->outputstr)))) {
00502 ast_mutex_unlock(&s->__lock);
00503 return;
00504 }
00505
00506 ast_dynamic_str_append(&s->outputstr, 0, "%s", buf->str);
00507 }
00508
00509 ast_mutex_unlock(&s->__lock);
00510 }
00511
00512 static int handle_showmancmd(int fd, int argc, char *argv[])
00513 {
00514 struct manager_action *cur;
00515 char authority[80];
00516 int num;
00517
00518 if (argc != 4)
00519 return RESULT_SHOWUSAGE;
00520
00521 ast_rwlock_rdlock(&actionlock);
00522 for (cur = first_action; cur; cur = cur->next) {
00523 for (num = 3; num < argc; num++) {
00524 if (!strcasecmp(cur->action, argv[num])) {
00525 ast_cli(fd, "Action: %s\nSynopsis: %s\nPrivilege: %s\n%s\n", cur->action, cur->synopsis, authority_to_str(cur->authority, authority, sizeof(authority) -1), cur->description ? cur->description : "");
00526 }
00527 }
00528 }
00529 ast_rwlock_unlock(&actionlock);
00530
00531 return RESULT_SUCCESS;
00532 }
00533
00534 static int handle_showmanager(int fd, int argc, char *argv[])
00535 {
00536 struct ast_manager_user *user = NULL;
00537
00538 if (argc != 4)
00539 return RESULT_SHOWUSAGE;
00540
00541 AST_LIST_LOCK(&users);
00542
00543 if (!(user = ast_get_manager_by_name_locked(argv[3]))) {
00544 ast_cli(fd, "There is no manager called %s\n", argv[3]);
00545 AST_LIST_UNLOCK(&users);
00546 return -1;
00547 }
00548
00549 ast_cli(fd,"\n");
00550 ast_cli(fd,
00551 " username: %s\n"
00552 " secret: %s\n"
00553 " deny: %s\n"
00554 " permit: %s\n"
00555 " read: %s\n"
00556 " write: %s\n"
00557 "displayconnects: %s\n",
00558 (user->username ? user->username : "(N/A)"),
00559 (user->secret ? "<Set>" : "(N/A)"),
00560 (user->deny ? user->deny : "(N/A)"),
00561 (user->permit ? user->permit : "(N/A)"),
00562 (user->read ? user->read : "(N/A)"),
00563 (user->write ? user->write : "(N/A)"),
00564 (user->displayconnects ? "yes" : "no"));
00565
00566 AST_LIST_UNLOCK(&users);
00567
00568 return RESULT_SUCCESS;
00569 }
00570
00571
00572 static int handle_showmanagers(int fd, int argc, char *argv[])
00573 {
00574 struct ast_manager_user *user = NULL;
00575 int count_amu = 0;
00576
00577 if (argc != 3)
00578 return RESULT_SHOWUSAGE;
00579
00580 AST_LIST_LOCK(&users);
00581
00582
00583 if (AST_LIST_EMPTY(&users)) {
00584 ast_cli(fd, "There are no manager users.\n");
00585 AST_LIST_UNLOCK(&users);
00586 return RESULT_SUCCESS;
00587 }
00588
00589 ast_cli(fd, "\nusername\n--------\n");
00590
00591 AST_LIST_TRAVERSE(&users, user, list) {
00592 ast_cli(fd, "%s\n", user->username);
00593 count_amu++;
00594 }
00595
00596 AST_LIST_UNLOCK(&users);
00597
00598 ast_cli(fd,"-------------------\n");
00599 ast_cli(fd,"%d manager users configured.\n", count_amu);
00600
00601 return RESULT_SUCCESS;
00602 }
00603
00604
00605
00606
00607 static int handle_showmancmds(int fd, int argc, char *argv[])
00608 {
00609 struct manager_action *cur;
00610 char authority[80];
00611 char *format = " %-15.15s %-15.15s %-55.55s\n";
00612
00613 ast_cli(fd, format, "Action", "Privilege", "Synopsis");
00614 ast_cli(fd, format, "------", "---------", "--------");
00615
00616 ast_rwlock_rdlock(&actionlock);
00617 for (cur = first_action; cur; cur = cur->next)
00618 ast_cli(fd, format, cur->action, authority_to_str(cur->authority, authority, sizeof(authority) -1), cur->synopsis);
00619 ast_rwlock_unlock(&actionlock);
00620
00621 return RESULT_SUCCESS;
00622 }
00623
00624
00625
00626 static int handle_showmanconn(int fd, int argc, char *argv[])
00627 {
00628 struct mansession *s;
00629 char *format = " %-15.15s %-15.15s\n";
00630
00631 ast_cli(fd, format, "Username", "IP Address");
00632
00633 AST_LIST_LOCK(&sessions);
00634 AST_LIST_TRAVERSE(&sessions, s, list)
00635 ast_cli(fd, format,s->username, ast_inet_ntoa(s->sin.sin_addr));
00636 AST_LIST_UNLOCK(&sessions);
00637
00638 return RESULT_SUCCESS;
00639 }
00640
00641
00642
00643 static int handle_showmaneventq(int fd, int argc, char *argv[])
00644 {
00645 struct eventqent *s;
00646
00647 AST_LIST_LOCK(&sessions);
00648 for (s = master_eventq; s; s = s->next) {
00649 ast_cli(fd, "Usecount: %d\n",s->usecount);
00650 ast_cli(fd, "Category: %d\n", s->category);
00651 ast_cli(fd, "Event:\n%s", s->eventdata);
00652 }
00653 AST_LIST_UNLOCK(&sessions);
00654
00655 return RESULT_SUCCESS;
00656 }
00657
00658 static char showmancmd_help[] =
00659 "Usage: manager show command <actionname>\n"
00660 " Shows the detailed description for a specific Asterisk manager interface command.\n";
00661
00662 static char showmancmds_help[] =
00663 "Usage: manager show commands\n"
00664 " Prints a listing of all the available Asterisk manager interface commands.\n";
00665
00666 static char showmanconn_help[] =
00667 "Usage: manager show connected\n"
00668 " Prints a listing of the users that are currently connected to the\n"
00669 "Asterisk manager interface.\n";
00670
00671 static char showmaneventq_help[] =
00672 "Usage: manager show eventq\n"
00673 " Prints a listing of all events pending in the Asterisk manger\n"
00674 "event queue.\n";
00675
00676 static char showmanagers_help[] =
00677 "Usage: manager show users\n"
00678 " Prints a listing of all managers that are currently configured on that\n"
00679 " system.\n";
00680
00681 static char showmanager_help[] =
00682 " Usage: manager show user <user>\n"
00683 " Display all information related to the manager user specified.\n";
00684
00685 static struct ast_cli_entry cli_show_manager_command_deprecated = {
00686 { "show", "manager", "command", NULL },
00687 handle_showmancmd, NULL,
00688 NULL, complete_show_mancmd };
00689
00690 static struct ast_cli_entry cli_show_manager_commands_deprecated = {
00691 { "show", "manager", "commands", NULL },
00692 handle_showmancmds, NULL,
00693 NULL };
00694
00695 static struct ast_cli_entry cli_show_manager_connected_deprecated = {
00696 { "show", "manager", "connected", NULL },
00697 handle_showmanconn, NULL,
00698 NULL };
00699
00700 static struct ast_cli_entry cli_show_manager_eventq_deprecated = {
00701 { "show", "manager", "eventq", NULL },
00702 handle_showmaneventq, NULL,
00703 NULL };
00704
00705 static struct ast_cli_entry cli_manager[] = {
00706 { { "manager", "show", "command", NULL },
00707 handle_showmancmd, "Show a manager interface command",
00708 showmancmd_help, complete_show_mancmd, &cli_show_manager_command_deprecated },
00709
00710 { { "manager", "show", "commands", NULL },
00711 handle_showmancmds, "List manager interface commands",
00712 showmancmds_help, NULL, &cli_show_manager_commands_deprecated },
00713
00714 { { "manager", "show", "connected", NULL },
00715 handle_showmanconn, "List connected manager interface users",
00716 showmanconn_help, NULL, &cli_show_manager_connected_deprecated },
00717
00718 { { "manager", "show", "eventq", NULL },
00719 handle_showmaneventq, "List manager interface queued events",
00720 showmaneventq_help, NULL, &cli_show_manager_eventq_deprecated },
00721
00722 { { "manager", "show", "users", NULL },
00723 handle_showmanagers, "List configured manager users",
00724 showmanagers_help, NULL, NULL },
00725
00726 { { "manager", "show", "user", NULL },
00727 handle_showmanager, "Display information on a specific manager user",
00728 showmanager_help, NULL, NULL },
00729 };
00730
00731 static void unuse_eventqent(struct eventqent *e)
00732 {
00733 if (ast_atomic_dec_and_test(&e->usecount) && e->next)
00734 pthread_kill(t, SIGURG);
00735 }
00736
00737 static void free_session(struct mansession *s)
00738 {
00739 struct eventqent *eqe;
00740 if (s->fd > -1)
00741 close(s->fd);
00742 if (s->outputstr)
00743 free(s->outputstr);
00744 ast_mutex_destroy(&s->__lock);
00745 while (s->eventq) {
00746 eqe = s->eventq;
00747 s->eventq = s->eventq->next;
00748 unuse_eventqent(eqe);
00749 }
00750 free(s);
00751 }
00752
00753 static void destroy_session(struct mansession *s)
00754 {
00755 AST_LIST_LOCK(&sessions);
00756 AST_LIST_REMOVE(&sessions, s, list);
00757 num_sessions--;
00758 free_session(s);
00759 AST_LIST_UNLOCK(&sessions);
00760 }
00761
00762 const char *astman_get_header(const struct message *m, char *var)
00763 {
00764 char cmp[80];
00765 int x;
00766
00767 snprintf(cmp, sizeof(cmp), "%s: ", var);
00768
00769 for (x = 0; x < m->hdrcount; x++) {
00770 if (!strncasecmp(cmp, m->headers[x], strlen(cmp)))
00771 return m->headers[x] + strlen(cmp);
00772 }
00773
00774 return "";
00775 }
00776
00777 struct ast_variable *astman_get_variables(const struct message *m)
00778 {
00779 int varlen, x, y;
00780 struct ast_variable *head = NULL, *cur;
00781 char *var, *val;
00782
00783 char *parse;
00784 AST_DECLARE_APP_ARGS(args,
00785 AST_APP_ARG(vars)[32];
00786 );
00787
00788 varlen = strlen("Variable: ");
00789
00790 for (x = 0; x < m->hdrcount; x++) {
00791 if (strncasecmp("Variable: ", m->headers[x], varlen))
00792 continue;
00793
00794 parse = ast_strdupa(m->headers[x] + varlen);
00795
00796 AST_STANDARD_APP_ARGS(args, parse);
00797 if (args.argc) {
00798 for (y = 0; y < args.argc; y++) {
00799 if (!args.vars[y])
00800 continue;
00801 var = val = ast_strdupa(args.vars[y]);
00802 strsep(&val, "=");
00803 if (!val || ast_strlen_zero(var))
00804 continue;
00805 cur = ast_variable_new(var, val);
00806 if (head) {
00807 cur->next = head;
00808 head = cur;
00809 } else
00810 head = cur;
00811 }
00812 }
00813 }
00814
00815 return head;
00816 }
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826 void astman_send_error(struct mansession *s, const struct message *m, char *error)
00827 {
00828 const char *id = astman_get_header(m,"ActionID");
00829
00830 astman_append(s, "Response: Error\r\n");
00831 if (!ast_strlen_zero(id))
00832 astman_append(s, "ActionID: %s\r\n", id);
00833 astman_append(s, "Message: %s\r\n\r\n", error);
00834 }
00835
00836 void astman_send_response(struct mansession *s, const struct message *m, char *resp, char *msg)
00837 {
00838 const char *id = astman_get_header(m,"ActionID");
00839
00840 astman_append(s, "Response: %s\r\n", resp);
00841 if (!ast_strlen_zero(id))
00842 astman_append(s, "ActionID: %s\r\n", id);
00843 if (msg)
00844 astman_append(s, "Message: %s\r\n\r\n", msg);
00845 else
00846 astman_append(s, "\r\n");
00847 }
00848
00849 void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
00850 {
00851 astman_send_response(s, m, "Success", msg);
00852 }
00853
00854
00855
00856
00857
00858
00859 static int ast_instring(const char *bigstr, const char *smallstr, char delim)
00860 {
00861 const char *val = bigstr, *next;
00862
00863 do {
00864 if ((next = strchr(val, delim))) {
00865 if (!strncmp(val, smallstr, (next - val)))
00866 return 1;
00867 else
00868 continue;
00869 } else
00870 return !strcmp(smallstr, val);
00871
00872 } while (*(val = (next + 1)));
00873
00874 return 0;
00875 }
00876
00877 static int get_perm(const char *instr)
00878 {
00879 int x = 0, ret = 0;
00880
00881 if (!instr)
00882 return 0;
00883
00884 for (x = 0; x < (sizeof(perms) / sizeof(perms[0])); x++) {
00885 if (ast_instring(instr, perms[x].label, ','))
00886 ret |= perms[x].num;
00887 }
00888
00889 return ret;
00890 }
00891
00892 static int ast_is_number(const char *string)
00893 {
00894 int ret = 1, x = 0;
00895
00896 if (!string)
00897 return 0;
00898
00899 for (x = 0; x < strlen(string); x++) {
00900 if (!(string[x] >= 48 && string[x] <= 57)) {
00901 ret = 0;
00902 break;
00903 }
00904 }
00905
00906 return ret ? atoi(string) : 0;
00907 }
00908
00909 static int strings_to_mask(const char *string)
00910 {
00911 int x, ret = -1;
00912
00913 x = ast_is_number(string);
00914
00915 if (x)
00916 ret = x;
00917 else if (ast_strlen_zero(string))
00918 ret = -1;
00919 else if (ast_false(string))
00920 ret = 0;
00921 else if (ast_true(string)) {
00922 ret = 0;
00923 for (x=0; x<sizeof(perms) / sizeof(perms[0]); x++)
00924 ret |= perms[x].num;
00925 } else {
00926 ret = 0;
00927 for (x=0; x<sizeof(perms) / sizeof(perms[0]); x++) {
00928 if (ast_instring(string, perms[x].label, ','))
00929 ret |= perms[x].num;
00930 }
00931 }
00932
00933 return ret;
00934 }
00935
00936
00937
00938
00939
00940 static int set_eventmask(struct mansession *s, const char *eventmask)
00941 {
00942 int maskint = strings_to_mask(eventmask);
00943
00944 ast_mutex_lock(&s->__lock);
00945 if (maskint >= 0)
00946 s->send_events = maskint;
00947 ast_mutex_unlock(&s->__lock);
00948
00949 return maskint;
00950 }
00951
00952 static int authenticate(struct mansession *s, const struct message *m)
00953 {
00954 struct ast_config *cfg;
00955 char *cat;
00956 const char *user = astman_get_header(m, "Username");
00957 const char *pass = astman_get_header(m, "Secret");
00958 const char *authtype = astman_get_header(m, "AuthType");
00959 const char *key = astman_get_header(m, "Key");
00960 const char *events = astman_get_header(m, "Events");
00961
00962 cfg = ast_config_load("manager.conf");
00963 if (!cfg)
00964 return -1;
00965 cat = ast_category_browse(cfg, NULL);
00966 while (cat) {
00967 if (strcasecmp(cat, "general")) {
00968
00969 if (!strcasecmp(cat, user)) {
00970 struct ast_variable *v;
00971 struct ast_ha *ha = NULL;
00972 char *password = NULL;
00973
00974 for (v = ast_variable_browse(cfg, cat); v; v = v->next) {
00975 if (!strcasecmp(v->name, "secret")) {
00976 password = v->value;
00977 } else if (!strcasecmp(v->name, "displaysystemname")) {
00978 if (ast_true(v->value)) {
00979 if (ast_strlen_zero(ast_config_AST_SYSTEM_NAME)) {
00980 s->displaysystemname = 1;
00981 } else {
00982 ast_log(LOG_ERROR, "Can't enable displaysystemname in manager.conf - no system name configured in asterisk.conf\n");
00983 }
00984