#include "astmanproxy.h" extern struct mansession *sessions; extern struct iohandler *iohandlers; extern pthread_mutex_t serverlock; void *ProxyListIOHandlers(struct mansession *s) { struct message m; struct iohandler *i; memset(&m, 0, sizeof(struct message)); AddHeader(&m, "ProxyResponse: Success"); i = iohandlers; while (i && (m.hdrcount < MAX_HEADERS - 1) ) { if (i->read) AddHeader(&m, "InputHandler: %s", i->formatname); if (i->write) AddHeader(&m, "OutputHandler: %s", i->formatname); i = i->next; } s->output->write(s, &m); return 0; } void *ProxyListSessions(struct mansession *s) { struct message m; struct mansession *c; char iabuf[INET_ADDRSTRLEN]; memset(&m, 0, sizeof(struct message)); AddHeader(&m, "ProxyResponse: Success"); c = sessions; while (c && (m.hdrcount < MAX_HEADERS - 1) ) { if (!c->server) { AddHeader(&m, "ProxyClientSession: %s", ast_inet_ntoa(iabuf, sizeof(iabuf), c->sin.sin_addr), c->actionid); AddHeader(&m, "ProxyClientInputHandler: %s", c->input->formatname); AddHeader(&m, "ProxyClientOutputHandler: %s", c->output->formatname); } else AddHeader(&m, "ProxyServerSession: %s", ast_inet_ntoa(iabuf, sizeof(iabuf), c->sin.sin_addr)); c = c->next; } s->output->write(s, &m); return 0; } void *ProxySetOutputFormat(struct mansession *s, struct message *m) { struct message mo; char *value; value = astman_get_header(m, "OutputFormat"); SetIOHandlers(s, s->input->formatname, value); /* TODO: this is retarded */ memset(&mo, 0, sizeof(struct message)); AddHeader(&mo, "ProxyResponse: Success"); AddHeader(&mo, "OutputFormat: %s", s->output->formatname ); s->output->write(s, &mo); return 0; } void *ProxySetAutoFilter(struct mansession *s, struct message *m) { struct message mo; char *value; int i; value = astman_get_header(m, "AutoFilter"); if ( !strcasecmp(value, "on") ) i = 1; else i = 0; pthread_mutex_lock(&s->lock); s->autofilter = i; pthread_mutex_unlock(&s->lock); memset(&mo, 0, sizeof(struct message)); AddHeader(&mo, "ProxyResponse: Success"); AddHeader(&mo, "AutoFilter: %d", s->autofilter); s->output->write(s, &mo); return 0; } void *ProxyLogin(struct mansession *s) { struct message m; /* Send back dummy output for clients that insist on authenticating the old way */ /* Mostly, we want to avoid sending this to Asterisk */ /* Response: Success */ /* Message: Authentication accepted */ memset(&m, 0, sizeof(struct message)); AddHeader(&m, "Response: Success"); AddHeader(&m, "Message: Authentication accepted"); s->output->write(s, &m); return 0; } void *ProxyLogoff(struct mansession *s) { struct message m; memset(&m, 0, sizeof(struct message)); AddHeader(&m, "Goodbye: Y'all come back now, y'hear?"); s->output->write(s, &m); destroy_session(s); if (debug) debugmsg("Client logged off - exiting thread"); pthread_exit(NULL); return 0; } int ProxyAddServer(struct mansession *s, struct message *m) { struct message mo; struct ast_server *srv; int res = 0; /* malloc ourselves a server credentials structure */ srv = malloc(sizeof(struct ast_server)); if ( !srv ) { fprintf(stderr, "Failed to allocate server credentials: %s\n", strerror(errno)); exit(1); } memset(srv, 0, sizeof (struct ast_server) ); /* TODO: Disallow adding of duplicate servers? Or not, I suppose that could be useful (events on/off) */ memset(srv, 0, sizeof(struct ast_server) ); memset(&mo, 0, sizeof(struct message)); strcpy(srv->ast_host, astman_get_header(m, "Server")); strcpy(srv->ast_user, astman_get_header(m, "Username")); strcpy(srv->ast_pass, astman_get_header(m, "Secret")); strcpy(srv->ast_port, astman_get_header(m, "Port")); strcpy(srv->ast_events, astman_get_header(m, "Events")); if (*srv->ast_host && *srv->ast_user && *srv->ast_pass && *srv->ast_port && *srv->ast_events) { pthread_mutex_lock(&serverlock); srv->next = pc.serverlist; pc.serverlist = srv; pthread_mutex_unlock(&serverlock); res = StartServer(srv); } else res = 1; if (res) { AddHeader(&mo, "ProxyResponse: Failure"); AddHeader(&mo, "Message: Could not add %s", srv->ast_host); } else { AddHeader(&mo, "ProxyResponse: Success"); AddHeader(&mo, "Message: Added %s", srv->ast_host); } s->output->write(s, &mo); return 0; } int ProxyDropServer(struct mansession *s, struct message *m) { struct message mo; struct mansession *srv; char *value; int res; memset(&mo, 0, sizeof(struct message)); value = astman_get_header(m, "Server"); srv = sessions; while (*value && srv) { if (srv->server && !strcmp(srv->server->ast_host, value)) break; srv = srv->next; } if (srv) { destroy_session(srv); debugmsg("Dropping Server %s", value); AddHeader(&mo, "ProxyResponse: Success"); AddHeader(&mo, "Message: Dropped %s", value); res = 0; } else { debugmsg("Failed to Drop Server %s -- not found", value); AddHeader(&mo, "ProxyResponse: Failure"); AddHeader(&mo, "Message: Cannot Drop Server %s, Does Not Exist", value); res = 1; } s->output->write(s, &mo); return res; } void *ProxyListServers(struct mansession *s) { struct message m; struct mansession *c; char iabuf[INET_ADDRSTRLEN]; memset(&m, 0, sizeof(struct message)); AddHeader(&m, "ProxyResponse: Success"); c = sessions; while (c) { if (c->server) { AddHeader(&m, "ProxyListServer I: %s H: %s U: %s P: %s E: %s ", ast_inet_ntoa(iabuf, sizeof(iabuf), c->sin.sin_addr), c->server->ast_host, c->server->ast_user, c->server->ast_port, c->server->ast_events); } c = c->next; } s->output->write(s, &m); return 0; } void *proxyaction_do(char *proxyaction, struct message *m, struct mansession *s) { if (!strcasecmp(proxyaction,"SetOutputFormat")) ProxySetOutputFormat(s, m); else if (!strcasecmp(proxyaction,"SetAutoFilter")) ProxySetAutoFilter(s, m); else if (!strcasecmp(proxyaction,"ListSessions")) ProxyListSessions(s); else if (!strcasecmp(proxyaction,"AddServer")) ProxyAddServer(s, m); else if (!strcasecmp(proxyaction,"DropServer")) ProxyDropServer(s, m); else if (!strcasecmp(proxyaction,"ListServers")) ProxyListServers(s); else if (!strcasecmp(proxyaction,"ListIOHandlers")) ProxyListIOHandlers(s); else if (!strcasecmp(proxyaction,"Logoff")) ProxyLogoff(s); else proxyerror_do(s, "Invalid Proxy Action"); return 0; } int proxyerror_do(struct mansession *s, char *err) { struct message mo; memset(&mo, 0, sizeof(struct message)); AddHeader(&mo, "ProxyResponse: Error"); AddHeader(&mo, "Message: %s", err); s->output->write(s, &mo); return 0; }