summaryrefslogtreecommitdiffstats
path: root/src/proxyfunc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/proxyfunc.c')
-rw-r--r--src/proxyfunc.c622
1 files changed, 315 insertions, 307 deletions
diff --git a/src/proxyfunc.c b/src/proxyfunc.c
index 434baff..484da78 100644
--- a/src/proxyfunc.c
+++ b/src/proxyfunc.c
@@ -1,3 +1,13 @@
+/* Asterisk Manager Proxy
+ Copyright (c) 2005-2006 David C. Troy <dave@popvox.com>
+
+ This program is free software, distributed under the terms of
+ the GNU General Public License.
+
+ proxyfunc.c
+ Functions specific to the manager proxy, not found in standard Asterisk AMI
+*/
+
#include "astmanproxy.h"
#include "md5.h"
@@ -7,384 +17,382 @@ extern pthread_mutex_t serverlock;
extern pthread_mutex_t userslock;
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;
+ 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;
+ 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;
+ struct message mo;
+ char *value;
- value = astman_get_header(m, "OutputFormat");
- SetIOHandlers(s, s->input->formatname, value);
+ value = astman_get_header(m, "OutputFormat");
+ SetIOHandlers(s, s->input->formatname, value);
- memset(&mo, 0, sizeof(struct message));
- AddHeader(&mo, "ProxyResponse: Success");
- AddHeader(&mo, "OutputFormat: %s", s->output->formatname );
+ memset(&mo, 0, sizeof(struct message));
+ AddHeader(&mo, "ProxyResponse: Success");
+ AddHeader(&mo, "OutputFormat: %s", s->output->formatname );
- s->output->write(s, &mo);
+ s->output->write(s, &mo);
- return 0;
+ return 0;
}
int ProxyChallenge(struct mansession *s, struct message *m) {
- struct message mo;
+ struct message mo;
- if ( strcasecmp("MD5", astman_get_header(m, "AuthType")) ) {
- SendError(s, "Must specify AuthType");
- return 1;
- }
+ if ( strcasecmp("MD5", astman_get_header(m, "AuthType")) ) {
+ SendError(s, "Must specify AuthType");
+ return 1;
+ }
- if (!*s->challenge)
- snprintf(s->challenge, sizeof(s->challenge), "%d", rand());
+ if (!*s->challenge)
+ snprintf(s->challenge, sizeof(s->challenge), "%d", rand());
- memset(&mo, 0, sizeof(struct message));
- AddHeader(&mo, "Response: Success");
- AddHeader(&mo, "Challenge: %s", s->challenge);
+ memset(&mo, 0, sizeof(struct message));
+ AddHeader(&mo, "Response: Success");
+ AddHeader(&mo, "Challenge: %s", s->challenge);
- s->output->write(s, &mo);
- return 0;
+ 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;
+ 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;
}
int AuthMD5(char *key, char *challenge, char *password) {
- int x;
- int len=0;
- char md5key[256] = "";
- struct MD5Context md5;
- unsigned char digest[16];
+ int x;
+ int len=0;
+ char md5key[256] = "";
+ struct MD5Context md5;
+ unsigned char digest[16];
- if (!*key || !*challenge || !*password )
+ if (!*key || !*challenge || !*password )
return 1;
- if (debug)
- debugmsg("MD5 password=%s, challenge=%s", password, challenge);
-
- MD5Init(&md5);
- MD5Update(&md5, (unsigned char *) challenge, strlen(challenge));
- MD5Update(&md5, (unsigned char *) password, strlen(password));
- MD5Final(digest, &md5);
- for (x=0;x<16;x++)
- len += sprintf(md5key + len, "%2.2x", digest[x]);
- if( debug ) {
- debugmsg("MD5 computed=%s, received=%s", md5key, key);
- }
- if (!strcmp(md5key, key))
+ if (debug)
+ debugmsg("MD5 password=%s, challenge=%s", password, challenge);
+
+ MD5Init(&md5);
+ MD5Update(&md5, (unsigned char *) challenge, strlen(challenge));
+ MD5Update(&md5, (unsigned char *) password, strlen(password));
+ MD5Final(digest, &md5);
+ for (x=0;x<16;x++)
+ len += sprintf(md5key + len, "%2.2x", digest[x]);
+ if( debug ) {
+ debugmsg("MD5 computed=%s, received=%s", md5key, key);
+ }
+ if (!strcmp(md5key, key))
return 0;
- else
+ else
return 1;
}
void *ProxyLogin(struct mansession *s, struct message *m) {
- struct message mo;
- struct proxy_user *pu;
- char *user, *secret, *key;
+ struct message mo;
+ struct proxy_user *pu;
+ char *user, *secret, *key;
- user = astman_get_header(m, "Username");
- secret = astman_get_header(m, "Secret");
- key = astman_get_header(m, "Key");
+ user = astman_get_header(m, "Username");
+ secret = astman_get_header(m, "Secret");
+ key = astman_get_header(m, "Key");
- memset(&mo, 0, sizeof(struct message));
- if( debug )
- debugmsg("Login attempt as: %s/%s", user, secret);
+ memset(&mo, 0, sizeof(struct message));
+ if( debug )
+ debugmsg("Login attempt as: %s/%s", user, secret);
- pthread_mutex_lock(&userslock);
- pu = pc.userlist;
- while( pu ) {
+ pthread_mutex_lock(&userslock);
+ pu = pc.userlist;
+ while( pu ) {
if ( !strcmp(user, pu->username) ) {
- if (!AuthMD5(key, s->challenge, pu->secret) ||
- !strcmp(secret, pu->secret) ) {
- AddHeader(&mo, "Response: Success");
- AddHeader(&mo, "Message: Authentication accepted");
- s->output->write(s, &mo);
- pthread_mutex_lock(&s->lock);
- s->authenticated = 1;
- strcpy(s->user.channel, pu->channel);
- strcpy(s->user.icontext, pu->icontext);
- strcpy(s->user.ocontext, pu->ocontext);
- pthread_mutex_unlock(&s->lock);
- if( debug )
- debugmsg("Login as: %s", user);
- break;
- }
- }
- pu = pu->next;
- }
- pthread_mutex_unlock(&userslock);
-
- if( !pu ) {
- SendError(s, "Authentication failed");
- pthread_mutex_lock(&s->lock);
- s->authenticated = 0;
- pthread_mutex_unlock(&s->lock);
- if( debug )
- debugmsg("Login failed as: %s/%s", user, secret);
- }
-
-
- return 0;
+ if (!AuthMD5(key, s->challenge, pu->secret) || !strcmp(secret, pu->secret) ) {
+ AddHeader(&mo, "Response: Success");
+ AddHeader(&mo, "Message: Authentication accepted");
+ s->output->write(s, &mo);
+ pthread_mutex_lock(&s->lock);
+ s->authenticated = 1;
+ strcpy(s->user.channel, pu->channel);
+ strcpy(s->user.icontext, pu->icontext);
+ strcpy(s->user.ocontext, pu->ocontext);
+ pthread_mutex_unlock(&s->lock);
+ if( debug )
+ debugmsg("Login as: %s", user);
+ break;
+ }
+ }
+ pu = pu->next;
+ }
+ pthread_mutex_unlock(&userslock);
+
+ if( !pu ) {
+ SendError(s, "Authentication failed");
+ pthread_mutex_lock(&s->lock);
+ s->authenticated = 0;
+ pthread_mutex_unlock(&s->lock);
+ if( debug )
+ debugmsg("Login failed as: %s/%s", user, secret);
+ }
+
+ return 0;
}
void *ProxyLogoff(struct mansession *s) {
- struct message m;
+ struct message m;
- memset(&m, 0, sizeof(struct message));
- AddHeader(&m, "Goodbye: Y'all come back now, y'hear?");
+ memset(&m, 0, sizeof(struct message));
+ AddHeader(&m, "Goodbye: Y'all come back now, y'hear?");
- s->output->write(s, &m);
+ s->output->write(s, &m);
- destroy_session(s);
- if (debug)
- debugmsg("Client logged off - exiting thread");
- pthread_exit(NULL);
- return 0;
+ 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) );
- 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;
+ 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) );
+ 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;
+ 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;
+ 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
+ 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;
+ return 0;
}
int proxyerror_do(struct mansession *s, char *err)
{
- struct message mo;
+ struct message mo;
- memset(&mo, 0, sizeof(struct message));
- AddHeader(&mo, "ProxyResponse: Error");
- AddHeader(&mo, "Message: %s", err);
+ memset(&mo, 0, sizeof(struct message));
+ AddHeader(&mo, "ProxyResponse: Error");
+ AddHeader(&mo, "Message: %s", err);
- s->output->write(s, &mo);
+ s->output->write(s, &mo);
- return 0;
+ return 0;
}
int ValidateAction(struct message *m, struct mansession *s, int inbound) {
- char *channel, *channel1, *channel2;
- char *context;
- char *uchannel;
- char *ucontext;
-
- if( pc.authrequired && !s->authenticated )
- return 0;
-
- if( inbound )
- ucontext = s->user.icontext;
- else
- ucontext = s->user.ocontext;
- uchannel = s->user.channel;
-
- channel = astman_get_header(m, "Channel");
- if( channel[0] != '\0' && uchannel[0] != '\0' )
- if( strncasecmp( channel, uchannel, strlen(uchannel) ) ) {
- if( debug )
- debugmsg("Message filtered (chan): %s != %s", channel, uchannel);
- return 0;
- }
-
- channel1 = astman_get_header(m, "Channel1");
- channel2 = astman_get_header(m, "Channel2");
- if( (channel1[0] != '\0' || channel2[0] != '\0') && uchannel[0] != '\0' )
- if( !(strncasecmp( channel1, uchannel, strlen(uchannel) ) == 0 ||
- strncasecmp( channel2, uchannel, strlen(uchannel) ) == 0) ) {
- if( debug )
- debugmsg("Message filtered (chan): %s/%s != %s", channel1, channel2, uchannel);
- return 0;
- }
-
- context = astman_get_header(m, "Context");
- if( context[0] != '\0' && ucontext[0] != '\0' )
- if( strcasecmp( context, ucontext ) ) {
- if( debug )
- debugmsg("Message filtered (ctxt): %s != %s", context, ucontext);
- return 0;
- }
-
- return 1;
+ char *channel, *channel1, *channel2;
+ char *context;
+ char *uchannel;
+ char *ucontext;
+
+ if( pc.authrequired && !s->authenticated )
+ return 0;
+
+ if( inbound )
+ ucontext = s->user.icontext;
+ else
+ ucontext = s->user.ocontext;
+ uchannel = s->user.channel;
+
+ channel = astman_get_header(m, "Channel");
+ if( channel[0] != '\0' && uchannel[0] != '\0' )
+ if( strncasecmp( channel, uchannel, strlen(uchannel) ) ) {
+ if( debug )
+ debugmsg("Message filtered (chan): %s != %s", channel, uchannel);
+ return 0;
+ }
+
+ channel1 = astman_get_header(m, "Channel1");
+ channel2 = astman_get_header(m, "Channel2");
+ if( (channel1[0] != '\0' || channel2[0] != '\0') && uchannel[0] != '\0' )
+ if( !(strncasecmp( channel1, uchannel, strlen(uchannel) ) == 0 ||
+ strncasecmp( channel2, uchannel, strlen(uchannel) ) == 0) ) {
+ if( debug )
+ debugmsg("Message filtered (chan): %s/%s != %s", channel1, channel2, uchannel);
+ return 0;
+ }
+
+ context = astman_get_header(m, "Context");
+ if( context[0] != '\0' && ucontext[0] != '\0' )
+ if( strcasecmp( context, ucontext ) ) {
+ if( debug )
+ debugmsg("Message filtered (ctxt): %s != %s", context, ucontext);
+ return 0;
+ }
+
+ return 1;
}
void *SendError(struct mansession *s, char *errmsg) {
- struct message m;
+ struct message m;
- memset(&m, 0, sizeof(struct message));
- AddHeader(&m, "Response: Error");
- AddHeader(&m, "Message: %s", errmsg);
+ memset(&m, 0, sizeof(struct message));
+ AddHeader(&m, "Response: Error");
+ AddHeader(&m, "Message: %s", errmsg);
- s->output->write(s, &m);
+ s->output->write(s, &m);
- return 0;
+ return 0;
}