diff options
author | David Troy <dave@popvox.com> | 2006-04-01 16:56:25 +0000 |
---|---|---|
committer | David Troy <dave@popvox.com> | 2006-04-01 16:56:25 +0000 |
commit | ad2c8750819f7e236c0baaf7edf2affd50c9d0a0 (patch) | |
tree | df3dc712677fb503d17b94591d8ab374d9167686 /src/proxyfunc.c | |
parent | 93b557bf0a56e24cd4fb3f1452c90e3e6c253e97 (diff) | |
download | astmanproxy-ad2c8750819f7e236c0baaf7edf2affd50c9d0a0.tar.gz astmanproxy-ad2c8750819f7e236c0baaf7edf2affd50c9d0a0.tar.xz astmanproxy-ad2c8750819f7e236c0baaf7edf2affd50c9d0a0.zip |
git-svn-id: http://svncommunity.digium.com/svn/astmanproxy/branches/1.20pre@34 f02b47b9-160a-0410-81a6-dc3441afb0ec
Diffstat (limited to 'src/proxyfunc.c')
-rw-r--r-- | src/proxyfunc.c | 336 |
1 files changed, 336 insertions, 0 deletions
diff --git a/src/proxyfunc.c b/src/proxyfunc.c new file mode 100644 index 0000000..51ed5c6 --- /dev/null +++ b/src/proxyfunc.c @@ -0,0 +1,336 @@ +#include "astmanproxy.h" + +extern struct mansession *sessions; +extern struct iohandler *iohandlers; +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; +} + +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, char *user, char *secret) { + struct message m; + struct proxy_user *pu; + + memset(&m, 0, sizeof(struct message)); + if( debug ) + debugmsg("Login attempt as: %s/%s", user, secret); + + pthread_mutex_lock(&userslock); + pu = pc.userlist; + while( pu ) { + if ( !strcmp(user, pu->username) && !strcmp(secret, pu->secret) ) { + AddHeader(&m, "Response: Success"); + AddHeader(&m, "Message: Authentication accepted"); + s->output->write(s, &m); + s->authenticated = 1; + strcpy(s->user.channel, pu->channel); + strcpy(s->user.icontext, pu->icontext); + strcpy(s->user.ocontext, pu->ocontext); + if( debug ) + debugmsg("Login as: %s", user); + break; + } + pu = pu->next; + } + pthread_mutex_unlock(&userslock); + + if( !pu ) { + AddHeader(&m, "Response: Error"); + AddHeader(&m, "Message: Authentication failed"); + s->output->write(s, &m); + s->authenticated = 0; + if( debug ) + debugmsg("Login failed as: %s/%s", user, secret); + } + + 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; +} + +int ValidateAction(struct message *m, struct mansession *s, int inbound) { + char *channel, *channel1, *channel2; + char *context; + char *uchannel; + char *ucontext; + + if( !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) { + struct message m; + + memset(&m, 0, sizeof(struct message)); + AddHeader(&m, "Response: Error"); + AddHeader(&m, "Message: Action Filtered"); + + s->output->write(s, &m); + + return 0; +} + |