summaryrefslogtreecommitdiffstats
path: root/src/config.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/config.c')
-rw-r--r--src/config.c305
1 files changed, 305 insertions, 0 deletions
diff --git a/src/config.c b/src/config.c
new file mode 100644
index 0000000..f642aa6
--- /dev/null
+++ b/src/config.c
@@ -0,0 +1,305 @@
+#include <pwd.h>
+#include <grp.h>
+#include "astmanproxy.h"
+
+extern struct iohandler *iohandlers;
+
+void *add_server(char *srvspec) {
+
+ int ccount = 0;
+ struct ast_server *srv;
+ char *s;
+ char usessl[10];
+
+ /* 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(usessl, 0, sizeof (usessl) );
+
+ s = srvspec;
+ do {
+ *s = tolower(*s);
+ if ( *s == ',' ) {
+ ccount++;
+ continue;
+ }
+ switch(ccount) {
+ case 0:
+ strncat(srv->ast_host, s, 1);
+ break;
+ case 1:
+ strncat(srv->ast_port, s, 1);
+ break;
+ case 2:
+ strncat(srv->ast_user, s, 1);
+ break;
+ case 3:
+ strncat(srv->ast_pass, s, 1);
+ break;
+ case 4:
+ strncat(srv->ast_events, s, 1);
+ break;
+ case 5:
+ strncat(usessl, s, 1);
+ break;
+ }
+ } while (*(s++));
+
+
+ if (!*srv->ast_host || !*srv->ast_port || !*srv->ast_user || !*srv->ast_pass || !*srv->ast_events || !*usessl) {
+ fprintf(stderr, "Aborting: server spec incomplete: %s\n", srvspec);
+ free(srv);
+ exit(1);
+ }
+
+ srv->use_ssl = (!strcmp(usessl,"on"));
+ srv->next = pc.serverlist;
+ pc.serverlist = srv;
+
+ return 0;
+}
+
+void *processline(char *s) {
+ 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("config: %s, %s", name, value);
+
+ if ( !strcmp(name,"host") )
+ add_server(value);
+ else if (!strcmp(name,"retryinterval") )
+ pc.retryinterval = atoi(value);
+ else if (!strcmp(name,"maxretries") )
+ pc.maxretries = atoi(value);
+ else if (!strcmp(name,"listenaddress") )
+ strcpy(pc.listen_addr, value);
+ else if (!strcmp(name,"listenport") )
+ pc.listen_port = atoi(value);
+ else if (!strcmp(name,"asteriskwritetimeout") )
+ pc.asteriskwritetimeout = atoi(value);
+ else if (!strcmp(name,"clientwritetimeout") )
+ pc.clientwritetimeout = atoi(value);
+ else if (!strcmp(name,"sslclienthellotimeout") )
+ pc.sslclhellotimeout = atoi(value);
+ else if (!strcmp(name,"authrequired") )
+ pc.authrequired = strcmp(value,"yes") ? 0 : 1;
+ else if (!strcmp(name,"acceptencryptedconnection") )
+ pc.acceptencryptedconnection = strcmp(value,"yes") ? 0 : 1;
+ else if (!strcmp(name,"acceptunencryptedconnection") )
+ pc.acceptunencryptedconnection = strcmp(value,"yes") ? 0 : 1;
+ else if (!strcmp(name,"certfile") )
+ strcpy(pc.certfile, value);
+ else if (!strcmp(name,"proxykey") )
+ strcpy(pc.key, value);
+ else if (!strcmp(name,"proc_user") )
+ strcpy(pc.proc_user, value);
+ else if (!strcmp(name,"proc_group") )
+ strcpy(pc.proc_group, value);
+ else if (!strcmp(name,"logfile") )
+ strcpy(pc.logfile, value);
+ else if (!strcmp(name,"autofilter") )
+ pc.autofilter = strcmp(value,"on") ? 0 : 1;
+ else if (!strcmp(name,"outputformat") )
+ strcpy(pc.outputformat, value);
+ else if (!strcmp(name,"inputformat") )
+ strcpy(pc.inputformat, value);
+
+ return 0;
+}
+
+int LoadHandlers() {
+
+ void *dlhandle = NULL;
+ const char *error;
+ char fmt[20], moddir[80] = MDIR, modfile[80];
+ DIR *mods;
+ struct dirent *d;
+ void *rh, *wh, *och;
+ struct iohandler *io = NULL;
+
+ mods = opendir(moddir);
+ if (!mods)
+ exit(1);
+
+ while((d = readdir(mods))) {
+ /* Must end in .so to load it. */
+ if ( (strlen(d->d_name) > 3) && !strcasecmp(d->d_name + strlen(d->d_name) - 3, ".so") ) {
+
+ memset(fmt, 0, sizeof fmt);
+ strncpy(fmt, d->d_name, strlen(d->d_name) - 3);
+
+ sprintf(modfile, "%s/%s", moddir, d->d_name);
+ if (debug)
+ debugmsg("loading: module %s (%s)", fmt, modfile);
+
+ dlhandle = dlopen (modfile, RTLD_LAZY);
+ if (!dlhandle) {
+ fprintf(stderr, "dlopen failed: %s\n", dlerror());
+ exit(1);
+ }
+
+ rh = dlsym(dlhandle, "_read");
+ if ((error = dlerror()) != NULL) {
+ if (debug)
+ debugmsg("loading: note, %s_read does not exist; ignoring", fmt);
+ }
+
+ wh = dlsym(dlhandle, "_write");
+ if ((error = dlerror()) != NULL) {
+ if (debug)
+ debugmsg("loading: note, %s_write does not exist; ignoring", fmt);
+ }
+
+ och = dlsym(dlhandle, "_onconnect");
+ if ((error = dlerror()) != NULL) {
+ if (debug)
+ debugmsg("loading: note, %s_onconnect does not exist; ignoring", fmt);
+ }
+
+ if (rh || wh) {
+ io = malloc(sizeof(struct iohandler));
+ memset(io, 0, sizeof(struct iohandler));
+ strcpy(io->formatname, fmt);
+ if (rh)
+ io->read = rh;
+ if (wh)
+ io->write = wh;
+ if (och)
+ io->onconnect = och;
+
+ io->dlhandle = dlhandle;
+ io->next = iohandlers;
+ iohandlers = io;
+ } else
+ dlclose(dlhandle);
+
+ }
+ }
+ closedir(mods);
+
+ if (!iohandlers) {
+ fprintf(stderr, "Unable to load *ANY* IO Handlers from %s!\n", MDIR);
+ exit(1);
+ }
+
+ return 0;
+}
+
+
+int ReadConfig() {
+ FILE *FP;
+ char buf[1024];
+ char cfn[80];
+
+
+ memset( &pc, 0, sizeof pc );
+
+ /* Set nonzero config defaults */
+ pc.asteriskwritetimeout = 100;
+ pc.clientwritetimeout = 100;
+ pc.sslclhellotimeout = 500;
+
+ sprintf(cfn, "%s/%s", CDIR, CFILE);
+ FP = fopen( cfn, "r" );
+
+ if ( !FP )
+ {
+ fprintf(stderr, "Unable to open config file: %s/%s!\n", CDIR, CFILE);
+ 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;
+ processline(buf);
+ }
+
+ fclose(FP);
+
+ /* initialize SSL layer with our server certfile */
+ init_secure(pc.certfile);
+
+ return 0;
+}
+
+FILE *OpenLogfile() {
+ FILE *FP;
+ FP = fopen( pc.logfile, "a" );
+ if ( !FP ) {
+ fprintf(stderr, "Unable to open logfile: %s!\n", pc.logfile);
+ exit( 1 );
+ }
+
+ return FP;
+}
+
+int SetProcUID() {
+
+ struct passwd *pwent;
+ struct group *gp;
+ uid_t newuid = 0;
+ gid_t newgid = 0;
+
+ if ((pwent = (struct passwd *)getpwnam( pc.proc_user )) == NULL) {
+ fprintf(stderr, "getpwnam(%s) failed.\n", pc.proc_user);
+ return(-1);
+ } else
+ newuid = pwent->pw_uid;
+
+ if ( newuid == 0 ) {
+ fprintf(stderr, "getpwnam(%s) returned root user; aborting!\n", pc.proc_user);
+ return(-1);
+ }
+
+ if ((gp = (struct group *)getgrnam( pc.proc_group )) == NULL) {
+ fprintf(stderr, "getgrnam(%s) failed.\n", pc.proc_group);
+ return(-1);
+ } else
+ newgid = gp->gr_gid;
+
+ if ( chown( pc.logfile, newuid, newgid ) < 0 )
+ {
+ fprintf(stderr, "chown(%d,%d) of %s failed!\n", newuid, newgid, pc.logfile);
+ return( -1 );
+ }
+
+ if (setgid(newgid) < 0) {
+ fprintf(stderr, "setgid(%d) failed.\n", newgid);
+ return(-1);
+ }
+
+ if (setuid(newuid) < 0) {
+ fprintf(stderr, "setuid(%d) failed.\n", newuid);
+ return(-1);
+ }
+
+ return 0;
+}