Example #1
0
static char *group_list_function_read(struct cw_channel *chan, int argc, char **argv, char *buf, size_t len)
{
struct cw_group_info *gi = NULL;
	char tmp1[1024] = "";
	char tmp2[1024] = "";

	cw_app_group_list_lock();

	for (gi = cw_app_group_list_head(); gi; gi = CW_LIST_NEXT(gi, list)) {
		if (gi->chan != chan)
			continue;
		if (!cw_strlen_zero(tmp1)) {
			cw_copy_string(tmp2, tmp1, sizeof(tmp2));
			if (!cw_strlen_zero(gi->category))
				snprintf(tmp1, sizeof(tmp1), "%s %s@%s", tmp2, gi->group, gi->category);
			else
				snprintf(tmp1, sizeof(tmp1), "%s %s", tmp2, gi->group);
		} else {
			if (!cw_strlen_zero(gi->category))
				snprintf(tmp1, sizeof(tmp1), "%s@%s", gi->group, gi->category);
			else
				snprintf(tmp1, sizeof(tmp1), "%s", gi->group);
		}
	}

	cw_app_group_list_unlock();

	cw_copy_string(buf, tmp1, len);
	return buf;
}
Example #2
0
static char *builtin_function_iftime(struct cw_channel *chan, int argc, char **argv, char *buf, size_t len)
{
    struct cw_timing timing;
    char *s, *q;

    if (argc < 4 || argc > 6 || !(s = strchr(argv[3], '?'))) {
        cw_log(LOG_ERROR, "Syntax: %s\n", if_time_func_syntax);
        return NULL;
    }
    /* Trim trailing space from the timespec */
    q = s;
    do {
        *(q--) = '\0';
    }
    while (q >= argv[3] && isspace(*q));
    pbx_extract_timing_fromargv(&timing, argc, argv);
    s++; // Move pointer after the '?' sign

    // Move pointer after ':' sign
    if ((q = strchr(s, ':'))) {
        *(q) = '\0';
        q++;
    }
    if (cw_check_timing(&timing)) {
        /* True: we want everything between '?' and ':' */
        cw_copy_string(buf, s, len);
    } else if (q && *(q) != '\0') {
        // False: we want everything after ':' (if anything) //
        cw_copy_string(buf, q, len);
    }
    return buf;
}
Example #3
0
int cw_osp_validate(char *provider, char *token, int *handle, unsigned int *timelimit, char *callerid, struct in_addr addr, char *extension)
{
	char tmp[256]="", *l, *n;
	char iabuf[INET_ADDRSTRLEN];
	char source[OSP_MAX] = ""; /* Same length as osp->source */
	char *token2;
	int tokenlen;
	struct osp_provider *osp;
	int res = 0;
	unsigned int authorised, dummy;

	if (!provider || !strlen(provider))
		provider = "default";

	token2 = cw_strdupa(token);
	tokenlen = cw_base64decode(token2, token, strlen(token));
	*handle = -1;
	if (!callerid)
		callerid = "";
	cw_copy_string(tmp, callerid, sizeof(tmp));
	cw_callerid_parse(tmp, &n, &l);
	if (!l)
		l = "";
	else {
		cw_shrink_phone_number(l);
		if (!cw_isphonenumber(l))
			l = "";
	}
	callerid = l;
	cw_mutex_lock(&osplock);
	cw_inet_ntoa(iabuf, sizeof(iabuf), addr);
	osp = providers;
	while(osp) {
		if (!strcasecmp(osp->name, provider)) {
			if (OSPPTransactionNew(osp->handle, handle)) {
				cw_log(LOG_WARNING, "Unable to create OSP Transaction handle!\n");
			} else {
				cw_copy_string(source, osp->source, sizeof(source));
				res = 1;
			}
			break;
		}
		osp = osp->next;
	}
	cw_mutex_unlock(&osplock);
	if (res) {
		res = 0;
		dummy = 0;
		if (!OSPPTransactionValidateAuthorisation(*handle, iabuf, source, NULL, NULL, 
			callerid, OSPC_E164, extension, OSPC_E164, 0, "", tokenlen, token2, &authorised, timelimit, &dummy, NULL, tokenformat)) {
			if (authorised) {
				cw_log(LOG_DEBUG, "Validated token for '%s' from '%s@%s'\n", extension, callerid, iabuf);
				res = 1;
			}
		}
	}
	return res;	
}
Example #4
0
char *cw_callerid_merge(char *buf, int bufsiz, const char *name, const char *num, const char *unknown)
{
	if (!unknown)
		unknown = "<unknown>";
	if (name && num)
		snprintf(buf, bufsiz, "\"%s\" <%s>", name, num);
	else if (name) 
		cw_copy_string(buf, name, bufsiz);
	else if (num)
		cw_copy_string(buf, num, bufsiz);
	else
		cw_copy_string(buf, unknown, bufsiz);
	return buf;
}
Example #5
0
int cw_linear_stream(struct cw_channel *chan, const char *filename, int fd, int allowoverride)
{
	struct linear_state *lin;
	char tmpf[256];
	int res = -1;
	int autoclose = 0;
	if (fd < 0) {
		if (cw_strlen_zero(filename))
			return -1;
		autoclose = 1;
		if (filename[0] == '/') 
			cw_copy_string(tmpf, filename, sizeof(tmpf));
		else
			snprintf(tmpf, sizeof(tmpf), "%s/%s/%s", (char *)cw_config_CW_VAR_DIR, "sounds", filename);
		fd = open(tmpf, O_RDONLY);
		if (fd < 0){
			cw_log(LOG_WARNING, "Unable to open file '%s': %s\n", tmpf, strerror(errno));
			return -1;
		}
	}
	lin = malloc(sizeof(struct linear_state));
	if (lin) {
		memset(lin, 0, sizeof(lin));
		lin->fd = fd;
		lin->allowoverride = allowoverride;
		lin->autoclose = autoclose;
		res = cw_generator_activate(chan, &linearstream, lin);
	}
	return res;
}
Example #6
0
int cw_app_group_match_get_count(char *groupmatch, char *category)
{
	regex_t regexbuf;
	struct cw_channel *chan;
	int count = 0;
	char *test;
	char cat[80];
	char *s;

	if (cw_strlen_zero(groupmatch))
		return 0;

	/* if regex compilation fails, return zero matches */
	if (regcomp(&regexbuf, groupmatch, REG_EXTENDED | REG_NOSUB))
		return 0;

	s = (!cw_strlen_zero(category)) ? category : GROUP_CATEGORY_PREFIX;
	cw_copy_string(cat, s, sizeof(cat));

	chan = NULL;
	while ((chan = cw_channel_walk_locked(chan)) != NULL) {
		test = pbx_builtin_getvar_helper(chan, cat);
		if (test && !regexec(&regexbuf, test, 0, NULL, 0))
			count++;
		cw_mutex_unlock(&chan->lock);
	}

	regfree(&regexbuf);

	return count;
}
Example #7
0
int cw_privacy_check(char *dest, char *cid)
{
	char tmp[256] = "";
	char *trimcid = "";
	char *n, *l;
	int res;
	char key[256], result[256];
	if (cid)
		cw_copy_string(tmp, cid, sizeof(tmp));
	cw_callerid_parse(tmp, &n, &l);
	if (l) {
		cw_shrink_phone_number(l);
		trimcid = l;
	}
	snprintf(key, sizeof(key), "%s/%s", dest, trimcid);
	res = cw_db_get("privacy", key, result, sizeof(result));
	if (!res) {
		if (!strcasecmp(result, "allow"))
			return CW_PRIVACY_ALLOW;
		if (!strcasecmp(result, "deny"))
			return CW_PRIVACY_DENY;
		if (!strcasecmp(result, "kill"))
			return CW_PRIVACY_KILL;
		if (!strcasecmp(result, "torture"))
			return CW_PRIVACY_TORTURE;
	}
	return CW_PRIVACY_UNKNOWN;
}
Example #8
0
int cw_privacy_set(char *dest, char *cid, int status)
{
	char tmp[256] = "";
	char *trimcid = "";
	char *n, *l;
	int res;
	char key[256];
	if (cid)
		cw_copy_string(tmp, cid, sizeof(tmp));
	cw_callerid_parse(tmp, &n, &l);
	if (l) {
		cw_shrink_phone_number(l);
		trimcid = l;
	}
	if (cw_strlen_zero(trimcid)) {
		/* Don't store anything for empty Caller*ID */
		return 0;
	}
	snprintf(key, sizeof(key), "%s/%s", dest, trimcid);
	if (status == CW_PRIVACY_UNKNOWN) 
		res = cw_db_del("privacy", key);
	else if (status == CW_PRIVACY_ALLOW)
		res = cw_db_put("privacy", key, "allow");
	else if (status == CW_PRIVACY_DENY)
		res = cw_db_put("privacy", key, "deny");
	else if (status == CW_PRIVACY_KILL)
		res = cw_db_put("privacy", key, "kill");
	else if (status == CW_PRIVACY_TORTURE)
		res = cw_db_put("privacy", key, "torture");
	else
		res = -1;
	return res;
}
Example #9
0
static int get_callback(void *pArg, int argc, char **argv, char **columnNames) 
{
	struct cw_db_data *result = pArg;

	cw_copy_string(result->data, argv[0], result->datalen);
	result->rownum++;
	return 0;
}
Example #10
0
int cw_callerid_split(const char *buf, char *name, int namelen, char *num, int numlen)
{
	char *tmp;
	char *l = NULL;
    char *n = NULL;
    
	tmp = cw_strdupa(buf);
	cw_callerid_parse(tmp, &n, &l);
	if (n)
		cw_copy_string(name, n, namelen);
	else
		name[0] = '\0';
	if (l) {
		cw_shrink_phone_number(l);
		cw_copy_string(num, l, numlen);
	} else
		num[0] = '\0';
	return 0;
}
Example #11
0
struct cw_var_t *cw_var_assign(const char *name, const char *value)
{
	int i;
	struct cw_var_t *var;
	unsigned int hash = cw_hash_var_name(name);
	
	var = calloc(sizeof(struct cw_var_t) + strlen(name) + 1 + strlen(value) + 1, sizeof(char));

	if (var == NULL) {
		cw_log(LOG_WARNING, "Out of memory\n");
		return NULL;
	}

	var->hash = hash;
	i = strlen(name) + 1;
	cw_copy_string(var->name, name, i);
	var->value = var->name + i;
	cw_copy_string(var->value, value, strlen(value) + 1);
	
	return var;
}	
Example #12
0
static void group_function_write(struct cw_channel *chan, int argc, char **argv, const char *value)
{
	char grpcat[256];

	if (argc > 0 && argv[0][0]) {
		snprintf(grpcat, sizeof(grpcat), "%s@%s", value, argv[0]);
	} else {
		cw_copy_string(grpcat, value, sizeof(grpcat));
	}

        if (cw_app_group_set_channel(chan, grpcat))
                cw_log(LOG_WARNING, "Setting a group requires an argument (group name)\n");
}
Example #13
0
static char *builtin_function_set(struct cw_channel *chan, int argc, char **argv, char *buf, size_t len)
{
    char *p;

    if (argc != 1 || !argv[0][0] || !(p = strchr(argv[0], '='))) {
        cw_log(LOG_ERROR, "Syntax: %s\n", set_func_syntax);
        return NULL;
    }

    *(p++) = '\0';

    pbx_builtin_setvar_helper(chan, argv[0], p);
    cw_copy_string(buf, p, len);

    return buf;
}
Example #14
0
static int conference_set_pin(struct cw_conf_member *member, char *pin) {

    cw_copy_string(member->conf->pin, pin, sizeof(member->conf->pin));
    cw_log( CW_CONF_DEBUG, "Conference %s: PIN Set to %s\n",member->conf->name, member->conf->pin ) ;
    conference_queue_number( member, member->conf->pin );

    manager_event(
	EVENT_FLAG_CALL, 
	APP_CONFERENCE_MANID"SetPIN",
	"Channel: %s\r\n"
	"PIN: %s\r\n",
	member->channel_name, 
	member->conf->pin
    ) ;

    return 1;
}
Example #15
0
int cw_callerid_parse(char *instr, char **name, char **location)
{
	char *ns, *ne;
	char *ls, *le;
	char tmp[256];
	/* Try for "name" <location> format or 
	   name <location> format */
	if ((ls = strchr(instr, '<')) && (le = strchr(ls, '>'))) {
		/* Found the location */
		*le = '\0';
		*ls = '\0';
		*location = ls + 1;
		if ((ns = strchr(instr, '\"')) && (ne = strchr(ns + 1, '\"'))) {
			/* Get name out of quotes */
			*ns = '\0';
			*ne = '\0';
			*name = ns + 1;
			return 0;
		} else {
			/* Just trim off any trailing spaces */
			cw_trim_blanks(instr);
			/* And leading spaces */
			*name = cw_skip_blanks(instr);
			return 0;
		}
	} else {
		cw_copy_string(tmp, instr, sizeof(tmp));
		cw_shrink_phone_number(tmp);
		if (cw_isphonenumber(tmp)) {
			/* Assume it's just a location */
			*name = NULL;
			*location = instr;
		} else {
			/* Assume it's just a name.  Make sure it's not quoted though */
			*name = instr;
			while(**name && (isspace(**name) || (**name == '\"'))) (*name)++;
			ne = *name + strlen(*name) - 1;
			while((ne > *name) && (!*ne || isspace(*ne) || (*ne == '\"'))) { *ne = '\0'; ne--; }
			*location = NULL;
		}
		return 0;
	}
	return -1;
}
Example #16
0
static int init_keys(int fd, int argc, char *argv[])
{
	struct cw_key *key;
	int ign;
	char *kn;
	char tmp[256] = "";

	key = keys;
	while(key) {
		/* Reload keys that need pass codes now */
		if (key->ktype & KEY_NEEDS_PASSCODE) {
			kn = key->fn + strlen(cw_config_CW_KEY_DIR) + 1;
			cw_copy_string(tmp, kn, sizeof(tmp));
			try_load_key((char *)cw_config_CW_KEY_DIR, tmp, fd, fd, &ign);
		}
		key = key->next;
	}
	return RESULT_SUCCESS;
}
Example #17
0
int conference_queue_sound( struct cw_conf_member *member, char *soundfile )
{
	struct cw_conf_soundq *newsound;
	struct cw_conf_soundq **q;

	if( member == NULL ) {
	    cw_log(LOG_WARNING, "Member is null. Cannot play\n");
	    return 0;
	}

	if( soundfile == NULL ) {
	    cw_log(LOG_WARNING, "Soundfile is null. Cannot play\n");
	    return 0;
	}

	if  (
		( member->force_remove_flag == 1 ) ||
		( member->remove_flag == 1 ) 
	    )
	{
	    return 0;
	}

	newsound = calloc(1,sizeof(struct cw_conf_soundq));

	cw_copy_string(newsound->name, soundfile, sizeof(newsound->name));

	// append sound to the end of the list.

	cw_mutex_lock(&member->lock);

	for( q = &member->soundq; *q; q = &((*q)->next) ) ;;
	*q = newsound;

	cw_mutex_unlock(&member->lock);

	return 0 ;
}
Example #18
0
int cw_app_group_get_count(char *group, char *category)
{
	struct cw_channel *chan;
	int count = 0;
	char *test;
	char cat[80];
	char *s;

	if (cw_strlen_zero(group))
		return 0;

 	s = (!cw_strlen_zero(category)) ? category : GROUP_CATEGORY_PREFIX;
	cw_copy_string(cat, s, sizeof(cat));

	chan = NULL;
	while ((chan = cw_channel_walk_locked(chan)) != NULL) {
 		test = pbx_builtin_getvar_helper(chan, cat);
		if (test && !strcasecmp(test, group))
 			count++;
		cw_mutex_unlock(&chan->lock);
	}

	return count;
}
Example #19
0
static char *group_function_read(struct cw_channel *chan, int argc, char **argv, char *buf, size_t len)
{
	struct cw_group_info *gi = NULL;

   cw_app_group_list_lock();

        gi = cw_app_group_list_head();
        while (gi) {
                if (gi->chan != chan)
                        continue;
                if (cw_strlen_zero(argv))
                        break;
                if (!cw_strlen_zero(gi->category) && !strcasecmp(gi->category, argv[0]))
                        break;
                gi = CW_LIST_NEXT(gi, list);
        }

        if (gi)
                cw_copy_string(buf, gi->group, len);

        cw_app_group_list_unlock();

	return buf;
}
Example #20
0
static int do_directory(struct cw_channel *chan, struct cw_config *cfg, char *context, char *dialcontext, char digit, int last)
{
	/* Read in the first three digits..  "digit" is the first digit, already read */
	char ext[NUMDIGITS + 1];
	char name[80] = "";
	struct cw_variable *v;
	int res;
	int found=0;
	int lastuserchoice = 0;
	char *start, *pos, *conv,*stringp=NULL;

	if (cw_strlen_zero(context)) {
		cw_log(LOG_WARNING,
			"Directory must be called with an argument "
			"(context in which to interpret extensions)\n");
		return -1;
	}
	if (digit == '0') {
		if (!cw_goto_if_exists(chan, chan->context, "o", 1) ||
		    (!cw_strlen_zero(chan->proc_context) &&
		     !cw_goto_if_exists(chan, chan->proc_context, "o", 1))) {
			return 0;
		} else {
			cw_log(LOG_WARNING, "Can't find extension 'o' in current context.  "
				"Not Exiting the Directory!\n");
			res = 0;
		}
	}	
	if (digit == '*') {
		if (!cw_goto_if_exists(chan, chan->context, "a", 1) ||
		    (!cw_strlen_zero(chan->proc_context) &&
		     !cw_goto_if_exists(chan, chan->proc_context, "a", 1))) {
			return 0;
		} else {
			cw_log(LOG_WARNING, "Can't find extension 'a' in current context.  "
				"Not Exiting the Directory!\n");
			res = 0;
		}
	}	
	memset(ext, 0, sizeof(ext));
	ext[0] = digit;
	res = 0;
	if (cw_readstring(chan, ext + 1, NUMDIGITS - 1, 3000, 3000, "#") < 0) res = -1;
	if (!res) {
		/* Search for all names which start with those digits */
		v = cw_variable_browse(cfg, context);
		while(v && !res) {
			/* Find all candidate extensions */
			while(v) {
				/* Find a candidate extension */
				start = strdup(v->value);
				if (start && !strcasestr(start, "hidefromdir=yes")) {
					stringp=start;
					strsep(&stringp, ",");
					pos = strsep(&stringp, ",");
					if (pos) {
						cw_copy_string(name, pos, sizeof(name));
						/* Grab the last name */
						if (last && strrchr(pos,' '))
							pos = strrchr(pos, ' ') + 1;
						conv = convert(pos);
						if (conv) {
							if (!strcmp(conv, ext)) {
								/* Match! */
								found++;
								free(conv);
								free(start);
								break;
							}
							free(conv);
						}
					}
					free(start);
				}
				v = v->next;
			}

			if (v) {
				/* We have a match -- play a greeting if they have it */
				res = play_mailbox_owner(chan, context, dialcontext, v->name, name);
				switch (res) {
					case -1:
						/* user pressed '1' but extension does not exist, or
						 * user hungup
						 */
						lastuserchoice = 0;
						break;
					case '1':
						/* user pressed '1' and extensions exists;
						   play_mailbox_owner will already have done
						   a goto() on the channel
						 */
						lastuserchoice = res;
						break;
					case '*':
						/* user pressed '*' to skip something found */
						lastuserchoice = res;
						res = 0;
						break;
					default:
						break;
				}
				v = v->next;
			}
		}

		if (lastuserchoice != '1') {
			if (found) 
				res = cw_streamfile(chan, "dir-nomore", chan->language);
			else
				res = cw_streamfile(chan, "dir-nomatch", chan->language);
			if (!res)
				res = 1;
			return res;
		}
		return 0;
	}
	return res;
}
Example #21
0
int cw_osp_next(struct cw_osp_result *result, int cause)
{
	int res = 0;
	int tokenlen;
	unsigned int dummy=0;
	unsigned int timelimit;
	unsigned int callidlen;
	char callidstr[OSPC_CALLID_MAXSIZE] = "";
	char callednum[2048]="";
	char callingnum[2048]="";
	char destination[2048]="";
	char token[2000];
	OSPE_DEST_PROT prot;
	OSPE_DEST_OSP_ENABLED ospenabled;

	result->tech[0] = '\0';
	result->dest[0] = '\0';
	result->token[0] = '\0';

	if (result->handle > -1) {
		dummy = 0;
		if (result->numresults) {
			tokenlen = sizeof(token);
			while(!res && result->numresults) {
				result->numresults--;
				callidlen = sizeof(callidstr);
				if (!OSPPTransactionGetNextDestination(result->handle, OSPC_FAIL_INCOMPATIBLE_DEST, 0, NULL, NULL, &timelimit, &callidlen, callidstr, 
									sizeof(callednum), callednum, sizeof(callingnum), callingnum, sizeof(destination), destination, 0, NULL, &tokenlen, token)) {
					if (!OSPPTransactionIsDestOSPEnabled (result->handle, &ospenabled) && (ospenabled == OSPE_OSP_FALSE)) {
						result->token[0] = 0;
					}
					else {
						cw_base64encode(result->token, token, tokenlen, sizeof(result->token) - 1);
					}
					if ((strlen(destination) > 2) && !OSPPTransactionGetDestProtocol(result->handle, &prot)) {
						res = 1;
						/* Strip leading and trailing brackets */
						destination[strlen(destination) - 1] = '\0';
						switch(prot) {
						case OSPE_DEST_PROT_H323_SETUP:
							cw_copy_string(result->tech, "H323", sizeof(result->tech));
							snprintf(result->dest, sizeof(result->dest), "%s@%s", callednum, destination + 1);
							break;
						case OSPE_DEST_PROT_SIP:
							cw_copy_string(result->tech, "SIP", sizeof(result->tech));
							snprintf(result->dest, sizeof(result->dest), "%s@%s", callednum, destination + 1);
							break;
						case OSPE_DEST_PROT_IAX:
							cw_copy_string(result->tech, "IAX", sizeof(result->tech));
							snprintf(result->dest, sizeof(result->dest), "%s@%s", callednum, destination + 1);
							break;
						default:
							cw_log(LOG_DEBUG, "Unknown destination protocol '%d', skipping...\n", prot);
							res = 0;
						}
					} else {
						cw_log(LOG_DEBUG, "Missing destination protocol\n");
						break;
					}
				}
			}
			
		}
		if (!res) {
			OSPPTransactionDelete(result->handle);
			result->handle = -1;
		}
		
	}
	return res;
}
Example #22
0
static int osp_build(struct cw_config *cfg, char *cat)
{
	OSPTCERT TheAuthCert[MAX_CERTS];
	unsigned char Reqbuf[4096],LocalBuf[4096],AuthBuf[MAX_CERTS][4096];
	struct cw_variable *v;
	struct osp_provider *osp;
	int x,length,errorcode=0;
	int mallocd=0,i;
	char *cacerts[MAX_CERTS];
	const char *servicepoints[MAX_SERVICEPOINTS];
	OSPTPRIVATEKEY privatekey;
	OSPTCERT localcert;
	OSPTCERT *authCerts[MAX_CERTS];

	
	
	cw_mutex_lock(&osplock);
	osp = providers;
	while(osp) {
		if (!strcasecmp(osp->name, cat))
			break;
		osp = osp->next;
	}
	cw_mutex_unlock(&osplock);
	if (!osp) {
		mallocd = 1;
		osp = malloc(sizeof(struct osp_provider));
		if (!osp) {
			cw_log(LOG_WARNING, "Out of memory!\n");
			return -1;
		}
		memset(osp, 0, sizeof(struct osp_provider));
		osp->handle = -1;
	}
	cw_copy_string(osp->name, cat, sizeof(osp->name));
	snprintf(osp->localpvtkey, sizeof(osp->localpvtkey) ,"%s/%s-privatekey.pem", cw_config_CW_KEY_DIR, cat);
	snprintf(osp->localcert, sizeof(osp->localpvtkey), "%s/%s-localcert.pem", cw_config_CW_KEY_DIR, cat);
	osp->maxconnections=OSP_DEFAULT_MAX_CONNECTIONS;
	osp->retrydelay = OSP_DEFAULT_RETRY_DELAY;
	osp->retrylimit = OSP_DEFAULT_RETRY_LIMIT;
	osp->timeout = OSP_DEFAULT_TIMEOUT;
	osp->source[0] = '\0';
	cw_log(LOG_DEBUG, "Building OSP Provider '%s'\n", cat);
	v = cw_variable_browse(cfg, cat);
	while(v) {
		if (!strcasecmp(v->name, "privatekey")) {
			if (v->value[0] == '/')
				cw_copy_string(osp->localpvtkey, v->value, sizeof(osp->localpvtkey));
			else
				snprintf(osp->localpvtkey, sizeof(osp->localpvtkey), "%s/%s", cw_config_CW_KEY_DIR , v->value);
		} else if (!strcasecmp(v->name, "localcert")) {
			if (v->value[0] == '/')
				cw_copy_string(osp->localcert, v->value, sizeof(osp->localcert));
			else
				snprintf(osp->localcert, sizeof(osp->localcert), "%s/%s", cw_config_CW_KEY_DIR, v->value);
		} else if (!strcasecmp(v->name, "cacert")) {
			if (osp->cacount < MAX_CERTS) {
				if (v->value[0] == '/')
					cw_copy_string(osp->cacerts[osp->cacount], v->value, sizeof(osp->cacerts[0]));
				else
					snprintf(osp->cacerts[osp->cacount], sizeof(osp->cacerts[0]), "%s/%s", cw_config_CW_KEY_DIR, v->value);
				osp->cacount++;
			} else
				cw_log(LOG_WARNING, "Too many CA Certificates at line %d\n", v->lineno);
		} else if (!strcasecmp(v->name, "servicepoint")) {
			if (osp->spcount < MAX_SERVICEPOINTS) {
				cw_copy_string(osp->servicepoints[osp->spcount], v->value, sizeof(osp->servicepoints[0]));
				osp->spcount++;
			} else
				cw_log(LOG_WARNING, "Too many Service points at line %d\n", v->lineno);
		} else if (!strcasecmp(v->name, "maxconnections")) {
			if ((sscanf(v->value, "%d", &x) == 1) && (x > 0) && (x <= 1000)) {
				osp->maxconnections = x;
			} else
				cw_log(LOG_WARNING, "maxconnections should be an integer from 1 to 1000, not '%s' at line %d\n", v->value, v->lineno);
		} else if (!strcasecmp(v->name, "retrydelay")) {
			if ((sscanf(v->value, "%d", &x) == 1) && (x >= 0) && (x <= 10)) {
				osp->retrydelay = x;
			} else
				cw_log(LOG_WARNING, "retrydelay should be an integer from 0 to 10, not '%s' at line %d\n", v->value, v->lineno);
		} else if (!strcasecmp(v->name, "retrylimit")) {
			if ((sscanf(v->value, "%d", &x) == 1) && (x >= 0) && (x <= 100)) {
				osp->retrylimit = x;
			} else
				cw_log(LOG_WARNING, "retrylimit should be an integer from 0 to 100, not '%s' at line %d\n", v->value, v->lineno);
		} else if (!strcasecmp(v->name, "timeout")) {
			if ((sscanf(v->value, "%d", &x) == 1) && (x >= 200) && (x <= 10000)) {
				osp->timeout = x;
			} else
				cw_log(LOG_WARNING, "timeout should be an integer from 200 to 10000, not '%s' at line %d\n", v->value, v->lineno);
		} else if (!strcasecmp(v->name, "source")) {
			cw_copy_string(osp->source, v->value, sizeof(osp->source));
		}
		v = v->next;
	}
	if (osp->cacount < 1) {
		snprintf(osp->cacerts[osp->cacount], sizeof(osp->cacerts[0]), "%s/%s-cacert.pem", cw_config_CW_KEY_DIR, cat);
		osp->cacount++;
	}
	for (x=0;x<osp->cacount;x++)
		cacerts[x] = osp->cacerts[x];
	for (x=0;x<osp->spcount;x++)
		servicepoints[x] = osp->servicepoints[x];
	
	cw_mutex_lock(&osplock);
	osp->dead = 0;
	if (osp->handle > -1) {
		cw_log(LOG_DEBUG, "Deleting old handle for '%s'\n", osp->name);
		OSPPProviderDelete(osp->handle, 0);
	}
		

    length = 0;
	cw_log(LOG_DEBUG, "Loading private key for '%s' (%s)\n", osp->name, osp->localpvtkey);
    errorcode = loadPemPrivateKey(osp->localpvtkey,Reqbuf,&length);
    if (errorcode == 0)
    {
        privatekey.PrivateKeyData = Reqbuf;
        privatekey.PrivateKeyLength = length;
    }
    else
    {
         return -1;
    }

    length = 0;
	cw_log(LOG_DEBUG, "Loading local cert for '%s' (%s)\n", osp->name, osp->localcert);
    errorcode = loadPemCert(osp->localcert,LocalBuf,&length);
    if (errorcode == 0)
    {
        localcert.CertData = LocalBuf;
        localcert.CertDataLength = length;
    }
    else
    {
         return -1;
    }

    for (i=0;i<osp->cacount;i++)
    {
        length = 0;
		cw_log(LOG_DEBUG, "Loading CA cert %d for '%s' (%s)\n", i + 1, osp->name, osp->cacerts[i]);
        errorcode = loadPemCert(osp->cacerts[i],AuthBuf[i],&length);
        if (errorcode == 0)
        {
            TheAuthCert[i].CertData = AuthBuf[i];
            TheAuthCert[i].CertDataLength = length;
            authCerts[i] = &(TheAuthCert[i]);
        }
        else
        {
			return -1;        
		}
    }
	
	cw_log(LOG_DEBUG, "Creating provider handle for '%s'\n", osp->name);
	
	cw_log(LOG_DEBUG, "Service point '%s %d'\n", servicepoints[0], osp->spcount);
	
	if (OSPPProviderNew(osp->spcount, 
					    servicepoints, 
					   NULL, 
					   "localhost", 
					   &privatekey, 
					   &localcert, 
					   osp->cacount, 
					   (const OSPTCERT **)authCerts, 
					   1, 
					   300, 
					   osp->maxconnections, 
					   1, 
					   osp->retrydelay, 
					   osp->retrylimit, 
					   osp->timeout, 
					   "", 
					   "", 
					   &osp->handle)) {
		cw_log(LOG_WARNING, "Unable to initialize provider '%s'\n", cat);
		osp->dead = 1;
	}
	
	if (mallocd) {
		osp->next = providers;
		providers = osp;
	}
	cw_mutex_unlock(&osplock);	
	return 0;
}
Example #23
0
static int conf_do_originate(struct cw_conf_member *member, char *ext) {
    int res;

    pthread_t th;
    pthread_attr_t attr;
    struct fast_originate_helper *fast = malloc(sizeof(struct fast_originate_helper));

    char dst[80]="";
    char appdata[80]="";
    char *var;
    
    if (!fast) {
	res = -1;
    } else {
	memset(fast, 0, sizeof(struct fast_originate_helper));

	if (  (var = pbx_builtin_getvar_helper(member->chan, "NCONF_OUTBOUND_TIMEOUT")) ) {
	    fast->timeout = atoi(var) * 1000;
	} else
	    fast->timeout = 30000;

	strcat(dst,ext);
	strcat(dst,"@");
	if ( (var = pbx_builtin_getvar_helper(member->chan, "NCONF_OUTBOUND_CONTEXT")) )
	    strcat(dst,var);
	else
	    strcat(dst,member->chan->context);


	strcat(appdata,member->id);
	strcat(appdata,"/");
	if ( (var = pbx_builtin_getvar_helper(member->chan, "NCONF_OUTBOUND_PARAMS")) )
	    strcat(appdata,var);
	else {
	    strcat(appdata,"Sdq");
#if ENABLE_VAD
	    strcat(appdata,"V");
#endif
	}

	cw_copy_string( fast->tech, 	 "Local", sizeof(fast->tech) );
	cw_copy_string( fast->data, 	 dst, sizeof(fast->data) );
	cw_copy_string( fast->app, 	 APP_CONFERENCE_NAME, sizeof(fast->app) );
	cw_copy_string( fast->appdata, appdata, sizeof(fast->appdata) );

	if ( (var = pbx_builtin_getvar_helper(member->chan, "NCONF_OUTBOUND_CID_NAME")) )
	    cw_copy_string( fast->cid_name, var, sizeof(fast->cid_name) );
	else
	    cw_copy_string( fast->cid_name,"NavyConference",sizeof(fast->cid_name) );

	if ( (var = pbx_builtin_getvar_helper(member->chan, "NCONF_OUTBOUND_CID_NUM")) )
	    cw_copy_string( fast->cid_num, var,sizeof(fast->cid_num) );
	else
	    cw_copy_string( fast->cid_num, member->id,sizeof(fast->cid_num) );

	cw_copy_string( fast->context, "internal", sizeof(fast->context) );
	cw_copy_string( fast->exten, ext, sizeof(fast->exten) );
	fast->priority = 1;
	fast->vars=NULL;
/**/

	fast->frommember=member;

        pthread_attr_init(&attr);
	pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
	if (cw_pthread_create(&th, &attr, fast_originate, fast)) {
    	    free(fast);
	    res = -1;
	} else {
	    res = 0;
	}

    }

    cw_mutex_unlock(&member->chan->lock);
    cw_conf_member_genactivate( member ) ;

    return res;
}
Example #24
0
int conference_queue_number( struct cw_conf_member *member, char *str )
{
	struct cw_conf_soundq *newsound;
	struct cw_conf_soundq **q;

	if( member == NULL ) {
	    cw_log(LOG_WARNING, "Member is null. Cannot play\n");
	    return 0;
	}

	if( str == NULL ) {
	    cw_log(LOG_WARNING, "STRING is null. Cannot play\n");
	    return 0;
	}

	if  (
		( member->force_remove_flag == 1 ) ||
		( member->remove_flag == 1 ) 
	    )
	{
	    return 0;
	}

	const char *fn = NULL;
	char soundfile[255] = "";
	int num = 0;
	int res = 0;

	while (str[num] && !res) {
		fn = NULL;
		switch (str[num]) {
		case ('*'):
			fn = "digits/star";
			break;
		case ('#'):
			fn = "digits/pound";
			break;
		case ('-'):
			fn = "digits/minus";
			break;
		case '0':
		case '1':
		case '2':
		case '3':
		case '4':
		case '5':
		case '6':
		case '7':
		case '8':
		case '9':
			strcpy(soundfile, "digits/X");
			soundfile[7] = str[num];
			fn = soundfile;
			break;
		}
		num++;

	    if (fn) {
		newsound = calloc(1,sizeof(struct cw_conf_soundq));
		cw_copy_string(newsound->name, fn, sizeof(newsound->name));

		// append sound to the end of the list.
		cw_mutex_lock(&member->lock);

		for( q = &member->soundq; *q; q = &((*q)->next) ) ;;
		*q = newsound;

		cw_mutex_unlock(&member->lock);

	    }
	}

	return 0 ;
}
Example #25
0
static int record_exec(struct cw_channel *chan, int argc, char **argv)
{
	int res = 0;
	int count = 0;
	int percentflag = 0;
	char *ext = NULL;
	int i = 0;
	char tmp[256];

	struct cw_filestream *s = '\0';
	struct localuser *u;
	struct cw_frame *f = NULL;
	
	struct cw_dsp *sildet = NULL;   	/* silence detector dsp */
	int totalsilence = 0;
	int dspsilence = 0;
	int silence = 0;		/* amount of silence to allow */
	int gotsilence = 0;		/* did we timeout for silence? */
	int maxduration = 0;		/* max duration of recording in milliseconds */
	int gottimeout = 0;		/* did we timeout for maxduration exceeded? */
	int option_skip = 0;
	int option_noanswer = 0;
	int option_append = 0;
	int terminator = '#';
	int option_quiet = 0;
	int rfmt = 0;
	int flags;
	
	if (argc < 1 || argc > 4 || !argv[0][0]) {
		cw_log(LOG_ERROR, "Syntax: %s\n", record_syntax);
		return -1;
	}

	LOCAL_USER_ADD(u);

	if (strstr(argv[0], "%d"))
		percentflag = 1;
	ext = strrchr(argv[0], '.'); /* to support filename with a . in the filename, not format */
	if (!ext)
		ext = strchr(argv[0], ':');
	if (ext) {
		*ext = '\0';
		ext++;
	}

	if (!ext) {
		cw_log(LOG_WARNING, "No extension specified to filename!\n");
		LOCAL_USER_REMOVE(u);
		return -1;
	}

	if (argc > 1) {
		silence = atoi(argv[1]);
		if (silence > 0)
			silence *= 1000;
		else if (silence < 0)
			silence = 0;
	}
	
	if (argc > 2) {
		maxduration = atoi(argv[2]);
		if (maxduration > 0)
			maxduration *= 1000;
		else if (maxduration < 0)
			maxduration = 0;
	}

	if (argc > 3) {
		/* Retain backwards compatibility with old style options */
		if (!strcasecmp(argv[3], "skip"))
			option_skip = 1;
		else if (!strcasecmp(argv[3], "noanswer"))
			option_noanswer = 1;
		else {
			if (strchr(argv[3], 's'))
				option_skip = 1;
			if (strchr(argv[3], 'n'))
				option_noanswer = 1;
			if (strchr(argv[3], 'a'))
				option_append = 1;
			if (strchr(argv[3], 't'))
				terminator = '*';
			if (strchr(argv[3], 'q'))
				option_quiet = 1;
		}
	}
	
	/* done parsing */
	
	/* these are to allow the use of the %d in the config file for a wild card of sort to
	  create a new file with the inputed name scheme */
	if (percentflag) {
		char *piece[100];
		int pieces;

		/* Separate each piece out by the format specifier */
		pieces = cw_separate_app_args(argv[0], '%', arraysize(piece), piece);

		do {
			int tmplen;
			/* First piece has no leading percent, so it's copied verbatim */
			cw_copy_string(tmp, piece[0], sizeof(tmp));
			tmplen = strlen(tmp);
			for (i = 1; i < pieces; i++) {
				if (piece[i][0] == 'd') {
					/* Substitute the count */
					snprintf(tmp + tmplen, sizeof(tmp) - tmplen, "%d", count);
					tmplen += strlen(tmp + tmplen);
				} else if (tmplen + 2 < sizeof(tmp)) {
					/* Unknown format specifier - just copy it verbatim */
					tmp[tmplen++] = '%';
					tmp[tmplen++] = piece[i][0];
				}
				/* Copy the remaining portion of the piece */
				cw_copy_string(tmp + tmplen, &(piece[i][1]), sizeof(tmp) - tmplen);
			}
			count++;
		} while ( cw_fileexists(tmp, ext, chan->language) != -1 );
		pbx_builtin_setvar_helper(chan, "RECORDED_FILE", tmp);
	} else
		strncpy(tmp, argv[0], sizeof(tmp)-1);
	/* end of routine mentioned */
	
	
	
	if (chan->_state != CW_STATE_UP) {
		if (option_skip) {
			/* At the user's option, skip if the line is not up */
			LOCAL_USER_REMOVE(u);
			return 0;
		} else if (!option_noanswer) {
			/* Otherwise answer unless we're supposed to record while on-hook */
			res = cw_answer(chan);
		}
	}
	
	if (!res) {
	
		if (!option_quiet) {
			/* Some code to play a nice little beep to signify the start of the record operation */
			res = cw_streamfile(chan, "beep", chan->language);
			if (!res) {
				res = cw_waitstream(chan, "");
			} else {
				cw_log(LOG_WARNING, "cw_streamfile failed on %s\n", chan->name);
			}
			cw_stopstream(chan);
		}
		
		/* The end of beep code.  Now the recording starts */
		
		if (silence > 0) {
			rfmt = chan->readformat;
			res = cw_set_read_format(chan, CW_FORMAT_SLINEAR);
			if (res < 0) {
				cw_log(LOG_WARNING, "Unable to set to linear mode, giving up\n");
				LOCAL_USER_REMOVE(u);
				return -1;
			}
			sildet = cw_dsp_new();
			if (!sildet) {
				cw_log(LOG_WARNING, "Unable to create silence detector :(\n");
				LOCAL_USER_REMOVE(u);
				return -1;
			}
			cw_dsp_set_threshold(sildet, 256);
		} 
		
		
		flags = option_append ? O_CREAT|O_APPEND|O_WRONLY : O_CREAT|O_TRUNC|O_WRONLY;
		s = cw_writefile( tmp, ext, NULL, flags , 0, 0644);
		
		if (s) {
			int waitres;

			/* Request a video update */
			cw_indicate(chan, CW_CONTROL_VIDUPDATE);

			if (maxduration <= 0)
				maxduration = -1;
			
			while ((waitres = cw_waitfor(chan, maxduration)) > -1) {
				if (maxduration > 0) {
					if (waitres == 0) {
						gottimeout = 1;
						break;
					}
					maxduration = waitres;
  				}
				
				f = cw_read(chan);
				if (!f) {
					res = -1;
					break;
				}
				if (f->frametype == CW_FRAME_VOICE) {
					res = cw_writestream(s, f);
					if (res) {
						cw_log(LOG_WARNING, "Problem writing frame\n");
						cw_fr_free(f);
						break;
					}
					
					if (silence > 0) {
						dspsilence = 0;
						cw_dsp_silence(sildet, f, &dspsilence);
						if (dspsilence) {
							totalsilence = dspsilence;
						} else {
							totalsilence = 0;
						}
						if (totalsilence > silence) {
							/* Ended happily with silence */
							cw_fr_free(f);
							gotsilence = 1;
							break;
						}
					}
				}
				if (f->frametype == CW_FRAME_VIDEO) {
					res = cw_writestream(s, f);
					if (res) {
						cw_log(LOG_WARNING, "Problem writing frame\n");
						cw_fr_free(f);
						break;
					}
				}
				if ((f->frametype == CW_FRAME_DTMF) &&
					(f->subclass == terminator)) {
					cw_fr_free(f);
					break;
				}
				cw_fr_free(f);
			}
			if (!f) {
				cw_log(LOG_DEBUG, "Got hangup\n");
				res = -1;
			}
			
			if (gotsilence) {
				cw_stream_rewind(s, silence-1000);
				cw_truncstream(s);
			} else if (!gottimeout) {
				/* Strip off the last 1/4 second of it */
				cw_stream_rewind(s, 250);
				cw_truncstream(s);
			}
			cw_closestream(s);
		} else
			cw_log(LOG_WARNING, "Could not create file %s\n", tmp);
	} else
		cw_log(LOG_WARNING, "Could not answer channel '%s'\n", chan->name);
	
	if ((silence > 0) && rfmt) {
		res = cw_set_read_format(chan, rfmt);
		if (res)
			cw_log(LOG_WARNING, "Unable to restore read format on '%s'\n", chan->name);
		if (sildet)
			cw_dsp_free(sildet);
	}

	LOCAL_USER_REMOVE(u);

	return res;
}
Example #26
0
static void function_moh_write(struct cw_channel *chan, int argc, char **argv, const char *value)
{
    cw_copy_string(chan->musicclass, value, MAX_MUSICCLASS);
}
Example #27
0
static char *function_moh_read(struct cw_channel *chan, int argc, char **argv, char *buf, size_t len)
{
    cw_copy_string(buf, chan->musicclass, len);

    return buf;
}
Example #28
0
static char *builtin_function_math(struct cw_channel *chan, int argc, char **argv, char *buf, size_t len) 
{
	double fnum1;
	double fnum2;
	double ftmp = 0;
	char *op;
	int iaction=-1;
	int type_of_result=FLOAT_RESULT;

	/* dunno, big calulations :D */
	char user_result[30];

	char *mvalue1, *mvalue2=NULL, *mtype_of_result;

	if (argc != 2 || !argv[0][0] || !argv[1][0]) {
		cw_log(LOG_ERROR, "Syntax: %s\n", math_func_syntax);
		return NULL;
	}

	mvalue1 = argv[0];
	
	if ((op = strchr(mvalue1, '+'))) {
		iaction = ADDFUNCTION;
		*op = '\0';
	} else if ((op = strchr(mvalue1, '-'))) {
		iaction = SUBTRACTFUNCTION;
		*op = '\0';
	} else if ((op = strchr(mvalue1, '*'))) {
		iaction = MULTIPLYFUNCTION;
		*op = '\0';
	} else if ((op = strchr(mvalue1, '/'))) {
		iaction = DIVIDEFUNCTION;
		*op = '\0';
	} else if ((op = strchr(mvalue1, '%'))) {
		iaction = MODULUSFUNCTION;
		*op = '\0';
	} else if ((op = strchr(mvalue1, '>'))) {
		iaction = GTFUNCTION;
		*op = '\0';
		if (*(op+1) == '=') {
			*++op = '\0';
			iaction = GTEFUNCTION;
		}
	} else if ((op = strchr(mvalue1, '<'))) {
		iaction = LTFUNCTION;
		*op = '\0';
		if (*(op+1) == '=') {
			*++op = '\0';
			iaction = LTEFUNCTION;
		}
	} else if ((op = strchr(mvalue1, '='))) {
		iaction = GTFUNCTION;
		*op = '\0';
		if (*(op+1) == '=') {
			*++op = '\0';
			iaction = EQFUNCTION;
		} else
			op = NULL;
	} 
	
	if (op) 
		mvalue2 = op + 1;

	/* detect wanted type of result */
	mtype_of_result = argv[1];
	if (mtype_of_result)
	{
		if (!strcasecmp(mtype_of_result,"float") || !strcasecmp(mtype_of_result,"f"))
			type_of_result=FLOAT_RESULT;
		else if (!strcasecmp(mtype_of_result,"int") || !strcasecmp(mtype_of_result,"i"))
			type_of_result=INT_RESULT;
		else if (!strcasecmp(mtype_of_result,"hex") || !strcasecmp(mtype_of_result,"h"))
			type_of_result=HEX_RESULT;
		else if (!strcasecmp(mtype_of_result,"char") || !strcasecmp(mtype_of_result,"c"))
			type_of_result=CHAR_RESULT;
		else
		{
			cw_log(LOG_WARNING, "Unknown type of result requested '%s'.\n", mtype_of_result);
			return NULL;
		}
	}
	
	if (!mvalue1 || !mvalue2) {
		cw_log(LOG_WARNING, "Supply all the parameters - just this once, please\n");
		return NULL;
	}

	if (sscanf(mvalue1, "%lf", &fnum1) != 1) {
		cw_log(LOG_WARNING, "'%s' is not a valid number\n", mvalue1);
		return NULL;
	}

	if (sscanf(mvalue2, "%lf", &fnum2) != 1) {
		cw_log(LOG_WARNING, "'%s' is not a valid number\n", mvalue2);
		return NULL;
	}

	switch (iaction) {
	case ADDFUNCTION :
		ftmp = fnum1 + fnum2;
		break;
	case DIVIDEFUNCTION :
		if (fnum2 <= 0)
			ftmp = 0.0L; /* can't do a divide by 0 */
		else
			ftmp = (fnum1 / fnum2);
		break;
	case MULTIPLYFUNCTION :
		ftmp = (fnum1 * fnum2);
		break;
	case SUBTRACTFUNCTION :
		ftmp = (fnum1 - fnum2);
		break;
	case MODULUSFUNCTION :
	{
		int inum1 = fnum1;
		int inum2 = fnum2;
			
		ftmp = (inum1 % inum2);
		
		break;
	}
	case GTFUNCTION :
		cw_copy_string (user_result, (fnum1 > fnum2)?"TRUE":"FALSE", sizeof (user_result));
		break;
	case LTFUNCTION :
		cw_copy_string (user_result, (fnum1 < fnum2)?"TRUE":"FALSE", sizeof (user_result));
		break;
	case GTEFUNCTION :
		cw_copy_string (user_result, (fnum1 >= fnum2)?"TRUE":"FALSE", sizeof (user_result));
		break;
	case LTEFUNCTION :
		cw_copy_string (user_result, (fnum1 <= fnum2)?"TRUE":"FALSE", sizeof (user_result));
		break;					
	case EQFUNCTION :
		cw_copy_string (user_result, (fnum1 == fnum2)?"TRUE":"FALSE", sizeof (user_result));
		break;
	default :
		cw_log(LOG_WARNING, "Something happened that neither of us should be proud of %d\n", iaction);
		return NULL;
	}

	if (iaction < GTFUNCTION || iaction > EQFUNCTION) {
	    if (type_of_result == FLOAT_RESULT)
		    snprintf(user_result, sizeof(user_result), "%lf", ftmp);
	    else if (type_of_result == INT_RESULT)
		    snprintf(user_result, sizeof(user_result), "%i", (int) ftmp);
	    else if (type_of_result == HEX_RESULT)
		snprintf(user_result, sizeof(user_result), "%x", (unsigned int) ftmp);
	    else if (type_of_result == CHAR_RESULT)
		snprintf(user_result, sizeof(user_result), "%c", (unsigned char) ftmp);
	}
		
	cw_copy_string(buf, user_result, len);
	
	return buf;
}
Example #29
0
static struct cw_key *try_load_key (char *dir, char *fname, int ifd, int ofd, int *not2)
{
	int ktype = 0;
	char *c = NULL;
	char ffname[256];
	FILE *f;
	EVP_MD_CTX mdctx;
	unsigned char md_value[CW_MAX_BINARY_MD_SIZE];
	unsigned int md_len;
	struct cw_key *key;
	static int notice = 0;
	int found = 0;

	/* Make sure its name is a public or private key */

	if ((c = strstr(fname, ".pub")) && !strcmp(c, ".pub")) {
		ktype = CW_KEY_PUBLIC;
	} else if ((c = strstr(fname, ".key")) && !strcmp(c, ".key")) {
		ktype = CW_KEY_PRIVATE;
	} else
		return NULL;

	/* Get actual filename */
	snprintf(ffname, sizeof(ffname), "%s/%s", dir, fname);

	cw_mutex_lock(&keylock);
	key = keys;
	while(key) {
		/* Look for an existing version already */
		if (!strcasecmp(key->fn, ffname)) 
			break;
		key = key->next;
	}
	cw_mutex_unlock(&keylock);

	/* Open file */
	f = fopen(ffname, "r");
	if (!f) {
		cw_log(LOG_WARNING, "Unable to open key file %s: %s\n", ffname, strerror(errno));
		return NULL;
	}
	EVP_DigestInit(&mdctx, EVP_md5());
	while(!feof(f)) {
		/* Calculate a "whatever" quality md5sum of the key */
		char buf[256];
		memset(buf, 0, 256);
		fgets(buf, sizeof(buf), f);
		if (!feof(f)) {
			EVP_DigestUpdate(&mdctx, (unsigned char *) buf, strlen(buf));
		}
	}
	EVP_DigestFinal(&mdctx, md_value, &md_len);
	if (key) {
		/* If the MD5 sum is the same, and it isn't awaiting a passcode 
		   then this is far enough */
		if (!memcmp(md_value, key->md_value, md_len) &&
		    !(key->ktype & KEY_NEEDS_PASSCODE)) {
			fclose(f);
			key->delme = 0;
			return NULL;
		} else {
			/* Preserve keytype */
			ktype = key->ktype;
			/* Recycle the same structure */
			found++;
		}
	}

	/* Make fname just be the normal name now */
	*c = '\0';
	if (!key) {
		key = (struct cw_key *)malloc(sizeof(struct cw_key));
		if (!key) {
			cw_log(LOG_WARNING, "Out of memory\n");
			fclose(f);
			return NULL;
		}
		memset(key, 0, sizeof(struct cw_key));
	}
	/* At this point we have a key structure (old or new).  Time to
	   fill it with what we know */
	/* Gotta lock if this one already exists */
	if (found)
		cw_mutex_lock(&keylock);
	/* First the filename */
	cw_copy_string(key->fn, ffname, sizeof(key->fn));
	/* Then the name */
	cw_copy_string(key->name, fname, sizeof(key->name));
	key->ktype = ktype;
	/* Yes, assume we're going to be deleted */
	key->delme = 1;
	/* Keep the key type */
	memcpy(key->md_value, md_value, md_len);
	key->md_len = md_len;
	/* Can I/O takes the FD we're given */
	key->infd = ifd;
	key->outfd = ofd;
	/* Reset the file back to the beginning */
	rewind(f);
	/* Now load the key with the right method */
	if (ktype == CW_KEY_PUBLIC)
		key->rsa = PEM_read_RSA_PUBKEY(f, NULL, pw_cb, key);
	else
		key->rsa = PEM_read_RSAPrivateKey(f, NULL, pw_cb, key);
	fclose(f);
	if (key->rsa) {
		if (RSA_size(key->rsa) == 128) {
			/* Key loaded okay */
			key->ktype &= ~KEY_NEEDS_PASSCODE;
			if (option_verbose > 2)
				cw_verbose(VERBOSE_PREFIX_3 "Loaded %s key '%s'\n", key->ktype == CW_KEY_PUBLIC ? "PUBLIC" : "PRIVATE", key->name);
			if (option_debug)
				cw_log(LOG_DEBUG, "Key '%s' loaded OK\n", key->name);
			key->delme = 0;
		} else
			cw_log(LOG_NOTICE, "Key '%s' is not expected size.\n", key->name);
	} else if (key->infd != -2) {
		cw_log(LOG_WARNING, "Key load %s '%s' failed\n",key->ktype == CW_KEY_PUBLIC ? "PUBLIC" : "PRIVATE", key->name);
		if (ofd > -1) {
			ERR_print_errors_fp(stderr);
		} else
			ERR_print_errors_fp(stderr);
	} else {
		cw_log(LOG_NOTICE, "Key '%s' needs passcode.\n", key->name);
		key->ktype |= KEY_NEEDS_PASSCODE;
		if (!notice) {
			if (!option_initcrypto) 
				cw_log(LOG_NOTICE, "Add the '-i' flag to the callweaver command line if you want to automatically initialize passcodes at launch.\n");
			notice++;
		}
		/* Keep it anyway */
		key->delme = 0;
		/* Print final notice about "init keys" when done */
		*not2 = 1;
	}
	if (found)
		cw_mutex_unlock(&keylock);
	if (!found) {
		cw_mutex_lock(&keylock);
		key->next = keys;
		keys = key;
		cw_mutex_unlock(&keylock);
	}
	return key;
}
Example #30
0
int cw_play_and_prepend(struct cw_channel *chan, char *playfile, char *recordfile, int maxtime, char *fmt, int *duration, int beep, int silencethreshold, int maxsilence)
{
	int d = 0;
	char *fmts;
	char comment[256];
	int x, fmtcnt=1, res=-1,outmsg=0;
	struct cw_frame *f;
	struct cw_filestream *others[MAX_OTHER_FORMATS];
	struct cw_filestream *realfiles[MAX_OTHER_FORMATS];
	char *sfmt[MAX_OTHER_FORMATS];
	char *stringp=NULL;
	time_t start, end;
	struct cw_dsp *sildet;   	/* silence detector dsp */
	int totalsilence = 0;
	int dspsilence = 0;
	int gotsilence = 0;		/* did we timeout for silence? */
	int rfmt=0;	
	char prependfile[80];
	
	if (silencethreshold < 0)
		silencethreshold = global_silence_threshold;

	if (maxsilence < 0)
		maxsilence = global_maxsilence;

	/* barf if no pointer passed to store duration in */
	if (duration == NULL) {
		cw_log(LOG_WARNING, "Error play_and_prepend called without duration pointer\n");
		return -1;
	}

	cw_log(LOG_DEBUG,"play_and_prepend: %s, %s, '%s'\n", playfile ? playfile : "<None>", recordfile, fmt);
	snprintf(comment,sizeof(comment),"Playing %s, Recording to: %s on %s\n", playfile ? playfile : "<None>", recordfile, chan->name);

	if (playfile || beep) {	
		if (!beep)
			d = cw_play_and_wait(chan, playfile);
		if (d > -1)
			d = cw_streamfile(chan, "beep",chan->language);
		if (!d)
			d = cw_waitstream(chan,"");
		if (d < 0)
			return -1;
	}
	cw_copy_string(prependfile, recordfile, sizeof(prependfile));	
	strncat(prependfile, "-prepend", sizeof(prependfile) - strlen(prependfile) - 1);
			
	fmts = cw_strdupa(fmt);
	
	stringp=fmts;
	strsep(&stringp, "|,");
	cw_log(LOG_DEBUG,"Recording Formats: sfmts=%s\n", fmts);	
	sfmt[0] = cw_strdupa(fmts);
	
	while((fmt = strsep(&stringp, "|,"))) {
		if (fmtcnt > MAX_OTHER_FORMATS - 1) {
			cw_log(LOG_WARNING, "Please increase MAX_OTHER_FORMATS in app_voicemail.c\n");
			break;
		}
		sfmt[fmtcnt++] = cw_strdupa(fmt);
	}

	time(&start);
	end=start;  /* pre-initialize end to be same as start in case we never get into loop */
	for (x=0;x<fmtcnt;x++) {
		others[x] = cw_writefile(prependfile, sfmt[x], comment, O_TRUNC, 0, 0700);
		cw_verbose( VERBOSE_PREFIX_3 "x=%d, open writing:  %s format: %s, %p\n", x, prependfile, sfmt[x], others[x]);
		if (!others[x]) {
			break;
		}
	}
	
	sildet = cw_dsp_new(); /* Create the silence detector */
	if (!sildet) {
		cw_log(LOG_WARNING, "Unable to create silence detector :(\n");
		return -1;
	}
	cw_dsp_set_threshold(sildet, silencethreshold);

	if (maxsilence > 0) {
		rfmt = chan->readformat;
		res = cw_set_read_format(chan, CW_FORMAT_SLINEAR);
		if (res < 0) {
			cw_log(LOG_WARNING, "Unable to set to linear mode, giving up\n");
			return -1;
		}
	}
						
	if (x == fmtcnt) {
	/* Loop forever, writing the packets we read to the writer(s), until
	   we read a # or get a hangup */
		f = NULL;
		for(;;) {
		 	res = cw_waitfor(chan, 2000);
			if (!res) {
				cw_log(LOG_DEBUG, "One waitfor failed, trying another\n");
				/* Try one more time in case of masq */
			 	res = cw_waitfor(chan, 2000);
				if (!res) {
					cw_log(LOG_WARNING, "No audio available on %s??\n", chan->name);
					res = -1;
				}
			}
			
			if (res < 0) {
				f = NULL;
				break;
			}
			f = cw_read(chan);
			if (!f)
				break;
			if (f->frametype == CW_FRAME_VOICE) {
				/* write each format */
				for (x=0;x<fmtcnt;x++) {
					if (!others[x])
						break;
					res = cw_writestream(others[x], f);
				}
				
				/* Silence Detection */
				if (maxsilence > 0) {
					dspsilence = 0;
					cw_dsp_silence(sildet, f, &dspsilence);
					if (dspsilence)
						totalsilence = dspsilence;
					else
						totalsilence = 0;
					
					if (totalsilence > maxsilence) {
					/* Ended happily with silence */
					if (option_verbose > 2) 
						cw_verbose( VERBOSE_PREFIX_3 "Recording automatically stopped after a silence of %d seconds\n", totalsilence/1000);
					cw_fr_free(f);
					gotsilence = 1;
					outmsg=2;
					break;
					}
				}
				/* Exit on any error */
				if (res) {
					cw_log(LOG_WARNING, "Error writing frame\n");
					cw_fr_free(f);
					break;
				}
			} else if (f->frametype == CW_FRAME_VIDEO) {
				/* Write only once */
				cw_writestream(others[0], f);
			} else if (f->frametype == CW_FRAME_DTMF) {
				/* stop recording with any digit */
				if (option_verbose > 2) 
					cw_verbose( VERBOSE_PREFIX_3 "User ended message by pressing %c\n", f->subclass);
				res = 't';
				outmsg = 2;
				cw_fr_free(f);
				break;
			}
			if (maxtime) {
				time(&end);
				if (maxtime < (end - start)) {
					if (option_verbose > 2)
						cw_verbose( VERBOSE_PREFIX_3 "Took too long, cutting it short...\n");
					res = 't';
					outmsg=2;
					cw_fr_free(f);
					break;
				}
			}
			cw_fr_free(f);
		}
		if (end == start)
            time(&end);
		if (!f) {
			if (option_verbose > 2) 
				cw_verbose( VERBOSE_PREFIX_3 "User hung up\n");
			res = -1;
			outmsg=1;
#if 0
			/* delete all the prepend files */
			for (x=0;x<fmtcnt;x++) {
				if (!others[x])
					break;
				cw_closestream(others[x]);
				cw_filedelete(prependfile, sfmt[x]);
			}
#endif
		}
	} else {
		cw_log(LOG_WARNING, "Error creating writestream '%s', format '%s'\n", prependfile, sfmt[x]); 
	}
	*duration = end - start;
#if 0
	if (outmsg > 1) {
#else
	if (outmsg) {
#endif
		struct cw_frame *fr;
		for (x=0;x<fmtcnt;x++) {
			snprintf(comment, sizeof(comment), "Opening the real file %s.%s\n", recordfile, sfmt[x]);
			realfiles[x] = cw_readfile(recordfile, sfmt[x], comment, O_RDONLY, 0, 0);
			if (!others[x] || !realfiles[x])
				break;
			if (totalsilence)
				cw_stream_rewind(others[x], totalsilence-200);
			else
				cw_stream_rewind(others[x], 200);
			cw_truncstream(others[x]);
			/* add the original file too */
			while ((fr = cw_readframe(realfiles[x]))) {
				cw_writestream(others[x],fr);
			}
			cw_closestream(others[x]);
			cw_closestream(realfiles[x]);
			cw_filerename(prependfile, recordfile, sfmt[x]);
#if 0
			cw_verbose("Recording Format: sfmts=%s, prependfile %s, recordfile %s\n", sfmt[x],prependfile,recordfile);
#endif
			cw_filedelete(prependfile, sfmt[x]);
		}
	}
	if (rfmt) {
		if (cw_set_read_format(chan, rfmt)) {
			cw_log(LOG_WARNING, "Unable to restore format %s to channel '%s'\n", cw_getformatname(rfmt), chan->name);
		}
	}
	if (outmsg) {
		if (outmsg > 1) {
			/* Let them know it worked */
			cw_streamfile(chan, "auth-thankyou", chan->language);
			cw_waitstream(chan, "");
		}
	}	
	return res;
}

/* Channel group core functions */

int cw_app_group_split_group(char *data, char *group, int group_max, char *category, int category_max)
{
	int res=0;
	char tmp[256];
	char *grp=NULL, *cat=NULL;

	if (!cw_strlen_zero(data)) {
		cw_copy_string(tmp, data, sizeof(tmp));
		grp = tmp;
		cat = strchr(tmp, '@');
		if (cat) {
			*cat = '\0';
			cat++;
		}
	}

	if (!cw_strlen_zero(grp))
		cw_copy_string(group, grp, group_max);
	else
		res = -1;

	if (cat)
		snprintf(category, category_max, "%s_%s", GROUP_CATEGORY_PREFIX, cat);
	else
		cw_copy_string(category, GROUP_CATEGORY_PREFIX, category_max);

	return res;
}