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 | |
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
-rw-r--r-- | astmanproxy.users | 2 | ||||
-rw-r--r-- | src/astmanproxy.c (renamed from astmanproxy.c) | 24 | ||||
-rw-r--r-- | src/common.c (renamed from common.c) | 0 | ||||
-rw-r--r-- | src/config.c (renamed from config.c) | 2 | ||||
-rw-r--r-- | src/config_perms.c | 127 | ||||
-rw-r--r-- | src/csv.c (renamed from csv.c) | 0 | ||||
-rw-r--r-- | src/dlfcn.c (renamed from dlfcn.c) | 0 | ||||
-rw-r--r-- | src/http.c (renamed from http.c) | 0 | ||||
-rw-r--r-- | src/include/astmanproxy.h (renamed from astmanproxy.h) | 12 | ||||
-rw-r--r-- | src/include/dlfcn-compat.h (renamed from dlfcn-compat.h) | 0 | ||||
-rw-r--r-- | src/include/poll-compat.h (renamed from poll-compat.h) | 0 | ||||
-rw-r--r-- | src/log.c (renamed from log.c) | 0 | ||||
-rw-r--r-- | src/poll.c (renamed from poll.c) | 0 | ||||
-rw-r--r-- | src/proxyfunc.c (renamed from proxyfunc.c) | 100 | ||||
-rw-r--r-- | src/standard.c (renamed from standard.c) | 6 | ||||
-rw-r--r-- | src/xml.c (renamed from xml.c) | 0 |
16 files changed, 254 insertions, 19 deletions
diff --git a/astmanproxy.users b/astmanproxy.users new file mode 100644 index 0000000..2645fc9 --- /dev/null +++ b/astmanproxy.users @@ -0,0 +1,2 @@ +; user=secret,channel,out_context (to Asterisk),in_context (From Asterisk) +steve=steve,SIP/snom190,local, diff --git a/astmanproxy.c b/src/astmanproxy.c index c0a8470..6c82594 100644 --- a/astmanproxy.c +++ b/src/astmanproxy.c @@ -10,12 +10,15 @@ extern int LoadHandlers( void ); extern void ReadConfig( void ); +extern void ReadPerms( void ); extern FILE *OpenLogfile( void ); extern int SetProcUID( void ); extern void *proxyaction_do(char *proxyaction, struct message *m, struct mansession *s); -extern void *ProxyLogin(struct mansession *s); +extern void *ProxyLogin(struct mansession *s, char* username, char* secret); extern void *ProxyLogoff(struct mansession *s); +extern int ValidateAction(struct message *m, struct mansession *s, int inbound); +extern void *SendError(struct mansession *s); int ConnectAsterisk(struct mansession *s); @@ -25,6 +28,7 @@ struct iohandler *iohandlers = NULL; pthread_mutex_t sessionlock; pthread_mutex_t serverlock; +pthread_mutex_t userslock; pthread_mutex_t loglock; pthread_mutex_t debuglock; static int asock = -1; @@ -38,6 +42,8 @@ void hup(int sig) { } proxylog = OpenLogfile(); logmsg("Received HUP -- reopened log"); + ReadPerms(); + logmsg("Received HUP -- reread permissions"); } void leave(int sig) { @@ -169,9 +175,9 @@ int WriteClients(struct message *m) { c = sessions; while (c) { - if ( !c->server && m->hdrcount>1 ) { + if ( !c->server && m->hdrcount>1 && ValidateAction(m, c, 1) ) { if (c->autofilter && c->actionid) { - actionid = astman_get_header(m, "ActionID"); + actionid = astman_get_header(m, ACTION_ID); if ( !strcmp(actionid, c->actionid) ) { c->output->write(c, m); } @@ -266,19 +272,21 @@ void *session_do(struct mansession *s) } proxyaction = astman_get_header(&m, "ProxyAction"); - actionid = astman_get_header(&m, "ActionID"); + actionid = astman_get_header(&m, ACTION_ID); action = astman_get_header(&m, "Action"); if ( !strcasecmp(action, "Login") ) - ProxyLogin(s); + ProxyLogin(s, astman_get_header(&m, "UserName"), astman_get_header(&m, "Secret")); else if ( !strcasecmp(action, "Logoff") ) ProxyLogoff(s); else if ( !(*proxyaction == '\0') ) proxyaction_do(proxyaction, &m, s); - else { + else if ( ValidateAction(&m, s ,0) ) { if ( !(*actionid == '\0') ) setactionid(actionid, &m, s); if ( !WriteAsterisk(&m) ) break; + } else { + SendError(s); } } else if (res < 0) break; @@ -617,9 +625,13 @@ int main(int argc, char *argv[]) /* Initialize global mutexes */ pthread_mutex_init(&sessionlock, NULL); + pthread_mutex_init(&userslock, NULL); pthread_mutex_init(&loglock, NULL); pthread_mutex_init(&debuglock, NULL); + /* Read initial state for user permissions */ + ReadPerms(); + /* Initialize global client/server list */ sessions = NULL; LaunchAsteriskThreads(); @@ -229,7 +229,7 @@ FILE *OpenLogfile() { FILE *FP; FP = fopen( pc.logfile, "a" ); if ( !FP ) { - fprintf(stderr, "Unable to open logfile: %s!", pc.logfile); + fprintf(stderr, "Unable to open logfile: %s!\n", pc.logfile); exit( 1 ); } diff --git a/src/config_perms.c b/src/config_perms.c new file mode 100644 index 0000000..939d90f --- /dev/null +++ b/src/config_perms.c @@ -0,0 +1,127 @@ +/* #include <pwd.h> */ +/* #include <grp.h> */ +#include "astmanproxy.h" + +extern pthread_mutex_t userslock; + +void *free_userperm(struct proxy_user *pu) { + struct proxy_user *next_pu; + + while( pu ) { + next_pu = pu->next; + free( pu ); + pu = next_pu; + } + return 0; +} + +void *add_userperm(char* username, char *userspec, struct proxy_user **pu) { + + int ccount = 0; + struct proxy_user *user; + char *s; + + /* malloc ourselves a server credentials structure */ + user = malloc(sizeof(struct proxy_user)); + if ( !user ) { + fprintf(stderr, "Failed to allocate user credentials: %s\n", strerror(errno)); + exit(1); + } + memset(user, 0, sizeof (struct proxy_user) ); + + s = userspec; + strncpy(user->username, username, sizeof(user->username)-1 ); + do { + if ( *s == ',' ) { + ccount++; + continue; + } + switch(ccount) { + case 0: + strncat(user->secret, s, 1); + break; + case 1: + strncat(user->channel, s, 1); + break; + case 2: + strncat(user->ocontext, s, 1); + break; + case 3: + strncat(user->icontext, s, 1); + break; + } + } while (*(s++)); + + user->next = *pu; + *pu = user; + + return 0; +} + +void *processperm(char *s, struct proxy_user **pu) { + char name[80],value[80]; + int nvstate = 0; + + + memset (name,0,sizeof name); + memset (value,0,sizeof value); + + do { + *s = tolower(*s); + + if ( *s == ' ' || *s == '\t') + continue; + if ( *s == ';' || *s == '#' || *s == '\r' || *s == '\n' ) + break; + if ( *s == '=' ) { + nvstate = 1; + continue; + } + if (!nvstate) + strncat(name, s, 1); + else + strncat(value, s, 1); + } while (*(s++)); + + if (debug) + debugmsg("perm: %s, %s", name, value); + + add_userperm(name,value,pu); + + return 0; +} + +int ReadPerms() { + FILE *FP; + char buf[1024]; + char cfn[80]; + struct proxy_user *pu; + + pu=0; + sprintf(cfn, "%s/%s", PDIR, PFILE); + FP = fopen( cfn, "r" ); + + if ( !FP ) + { + fprintf(stderr, "Unable to open permissions file: %s/%s!\n", PDIR, PFILE); + exit( 1 ); + } + + if (debug) + debugmsg("config: parsing configuration file: %s", cfn); + + while ( fgets( buf, sizeof buf, FP ) ) { + if (*buf == ';' || *buf == '\r' || *buf == '\n' || *buf == '#') continue; + processperm(buf,&pu); + } + + fclose(FP); + + pthread_mutex_lock(&userslock); + free_userperm(pc.userlist); + pc.userlist=pu; + pthread_mutex_unlock(&userslock); + + return 0; +} + diff --git a/astmanproxy.h b/src/include/astmanproxy.h index 566ae69..f5718aa 100644 --- a/astmanproxy.h +++ b/src/include/astmanproxy.h @@ -31,6 +31,7 @@ #define PROXY_BANNER "Asterisk Call Manager Proxy" #define PROXY_SHUTDOWN "ProxyMessage: Proxy Shutting Down" +#define ACTION_ID "ActionID" struct ast_server { char nickname[80]; @@ -43,8 +44,18 @@ struct ast_server { struct ast_server *next; }; +struct proxy_user { + char username[80]; + char secret[80]; + char channel[80]; + char icontext[80]; + char ocontext[80]; + struct proxy_user *next; +}; + struct proxyconfig { struct ast_server *serverlist; + struct proxy_user *userlist; char listen_addr[INET_ADDRSTRLEN]; int listen_port; char inputformat[80]; @@ -82,6 +93,7 @@ struct mansession { int authenticated; int connected; struct ast_server *server; + struct proxy_user user; char actionid[MAX_LEN]; struct mansession *next; }; diff --git a/dlfcn-compat.h b/src/include/dlfcn-compat.h index 7c5e87f..7c5e87f 100644 --- a/dlfcn-compat.h +++ b/src/include/dlfcn-compat.h diff --git a/poll-compat.h b/src/include/poll-compat.h index 79eab15..79eab15 100644 --- a/poll-compat.h +++ b/src/include/poll-compat.h diff --git a/proxyfunc.c b/src/proxyfunc.c index 11132ff..51ed5c6 100644 --- a/proxyfunc.c +++ b/src/proxyfunc.c @@ -3,6 +3,7 @@ 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; @@ -86,20 +87,41 @@ void *ProxySetAutoFilter(struct mansession *s, struct message *m) { return 0; } -void *ProxyLogin(struct mansession *s) { +void *ProxyLogin(struct mansession *s, char *user, char *secret) { 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 */ + struct proxy_user *pu; memset(&m, 0, sizeof(struct message)); - AddHeader(&m, "Response: Success"); - AddHeader(&m, "Message: Authentication accepted"); - - s->output->write(s, &m); + 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; } @@ -256,3 +278,59 @@ int proxyerror_do(struct mansession *s, char *err) 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; +} + diff --git a/standard.c b/src/standard.c index de62cf7..5933e45 100644 --- a/standard.c +++ b/src/standard.c @@ -49,7 +49,11 @@ int _write(struct mansession *s, struct message *m) { if (debug) debugmsg("in standard_write module..."); pthread_mutex_lock(&s->lock); for (i=0; i<m->hdrcount; i++) { - write(s->fd, m->headers[i], strlen(m->headers[i]) ); + if( strncasecmp( m->headers[i], "CallerID: <unknown>", 19 ) == 0 ) { + write(s->fd, "CallerID: ", 10); + } else { + write(s->fd, m->headers[i], strlen(m->headers[i]) ); + } write(s->fd, "\r\n", 2); } write(s->fd, "\r\n", 2); |