summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Troy <dave@popvox.com>2006-04-01 16:56:25 +0000
committerDavid Troy <dave@popvox.com>2006-04-01 16:56:25 +0000
commitad2c8750819f7e236c0baaf7edf2affd50c9d0a0 (patch)
treedf3dc712677fb503d17b94591d8ab374d9167686
parent93b557bf0a56e24cd4fb3f1452c90e3e6c253e97 (diff)
downloadastmanproxy-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.users2
-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.c127
-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();
diff --git a/common.c b/src/common.c
index 5f63c15..5f63c15 100644
--- a/common.c
+++ b/src/common.c
diff --git a/config.c b/src/config.c
index f9d3b9f..bfb8d1f 100644
--- a/config.c
+++ b/src/config.c
@@ -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/csv.c b/src/csv.c
index bf8e800..bf8e800 100644
--- a/csv.c
+++ b/src/csv.c
diff --git a/dlfcn.c b/src/dlfcn.c
index 98d2373..98d2373 100644
--- a/dlfcn.c
+++ b/src/dlfcn.c
diff --git a/http.c b/src/http.c
index 6b5580d..6b5580d 100644
--- a/http.c
+++ b/src/http.c
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/log.c b/src/log.c
index d3f8d15..d3f8d15 100644
--- a/log.c
+++ b/src/log.c
diff --git a/poll.c b/src/poll.c
index a36539a..a36539a 100644
--- a/poll.c
+++ b/src/poll.c
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);
diff --git a/xml.c b/src/xml.c
index 0d6737b..0d6737b 100644
--- a/xml.c
+++ b/src/xml.c