Beispiel #1
0
static int parse_attr_params(void)
{
	str tmp;

	tmp = reply_code_attr;
	trim(&tmp);
	if (!tmp.len || tmp.s[0] != '$') {
		ERR("Invalid attribute name '%.*s'\n", tmp.len, tmp.s);
		return -1;
	}
	tmp.s++; tmp.len--;
	if (parse_avp_ident(&tmp, &avpid_code) < 0) {
		ERR("Error while parsing attribute name '%.*s'\n", tmp.len, tmp.s);
		return -1;
	}

	tmp = reply_reason_attr;
	trim(&tmp);
	if (!tmp.len || tmp.s[0] != '$') {
		ERR("Invalid attribute name '%.*s'\n", tmp.len, tmp.s);
		return -1;
	}
	tmp.s++; tmp.len--;
	if (parse_avp_ident(&tmp, &avpid_reason) < 0) {
		ERR("Error while parsing attribute name '%.*s'\n", tmp.len, tmp.s);
		return -1;
	}

	tmp = contact_attr;
	trim(&tmp);
	if (!tmp.len || tmp.s[0] != '$') {
		ERR("Invalid attribute name '%.*s'\n", tmp.len, tmp.s);
		return -1;
	}
	tmp.s++; tmp.len--;
	if (parse_avp_ident(&tmp, &avpid_contact) < 0) {
		ERR("Error while parsing attribute name '%.*s'\n", tmp.len, tmp.s);
		return -1;
	}

	return 0;
}
Beispiel #2
0
static int select_attr_fixup(str* res, select_t* s, struct sip_msg* msg)
{
	avp_ident_t *avp_ident;

#define SEL_PARAM_IDX	1

	if (! msg) { /* fixup call */
		str attr_name;
		
		if (s->params[SEL_PARAM_IDX].type != SEL_PARAM_STR) {
			ERR("attribute name expected.\n");
			return -1;
		}

		attr_name = s->params[SEL_PARAM_IDX].v.s;
		DEBUG("fix up for attribute '%.*s'\n", STR_FMT(&attr_name));

		if (! (avp_ident = pkg_malloc(sizeof(avp_ident_t)))) {
			ERR("out of mem; requested: %d.\n", (int)sizeof(avp_ident_t));
			return -1;
		}
		memset(avp_ident, 0, sizeof(avp_ident_t));

		/* skip leading `$' */
		if ((1 < attr_name.len) && (attr_name.s[0] == '$')) {
			attr_name.len --;
			attr_name.s ++;
		}
		if (parse_avp_ident(&attr_name, avp_ident) < 0) {
			ERR("failed to parse attribute name: `%.*s'.\n", STR_FMT(&attr_name));
			pkg_free(avp_ident);
		}
		s->params[SEL_PARAM_IDX].v.p = avp_ident;
		s->params[SEL_PARAM_IDX].type = SEL_PARAM_PTR;
	} else { /* run time call */
		avp_t *ret;
		avp_value_t val;

#ifdef EXTRA_DEBUG
		assert(s->params[SEL_PARAM_IDX].type == SEL_PARAM_PTR);
#endif
		avp_ident = s->params[SEL_PARAM_IDX].v.p;
		ret = search_first_avp(avp_ident->flags, avp_ident->name, &val, NULL);
		if (ret && ret->flags & AVP_VAL_STR)
			*res = val.s;
	}

	return 0;

#undef SEL_PARAM_IDX
}
Beispiel #3
0
static int get_avp_id(avp_ident_t* id, fparam_t* p, struct sip_msg* msg)
{
    str str_id;
    avp_t* avp;
    avp_value_t val;
    int ret;

    switch(p->type) {
    case FPARAM_AVP:
	avp = search_avp(p->v.avp, &val, 0);
	if (!avp) {
	    DBG("get_avp_id: AVP %s does not exist\n", p->orig);
	    return -1;
	}
	if ((avp->flags & AVP_VAL_STR) == 0) {
	    DBG("get_avp_id: Not a string AVP\n");
	    return -1;
	}
	str_id = val.s;
	break;

    case FPARAM_SELECT:
	ret = run_select(&str_id, p->v.select, msg);
	if (ret < 0 || ret > 0) return -1;
	break;

	case FPARAM_STR:
	str_id = p->v.str;
	break;

    default:
	ERR("Invalid parameter type in get_avp_id\n");
	return -1;
    }

    return parse_avp_ident(&str_id, id);
}
Beispiel #4
0
static int mod_init(void)
{
    str attr;
    
    DBG("auth module - initializing\n");
    
	/* If the parameter was not used */
    if (sec_param == 0) {
		/* Generate secret using random generator */
		if (generate_random_secret() < 0) {
			LOG(L_ERR, "auth:mod_init: Error while generating random secret\n");
			return -3;
		}
    } else {
		/* Otherwise use the parameter's value */
		secret1.s = sec_param;
		secret1.len = strlen(secret1.s);
		
		if (auth_checks_reg || auth_checks_ind || auth_checks_ood) {
			/* divide the secret in half: one half for secret1 and one half for
			 *  secret2 */
			secret2.len = secret1.len/2;
			secret1.len -= secret2.len;
			secret2.s = secret1.s + secret1.len;
			if (secret2.len < 16) {
				WARN("auth: consider a longer secret when extra auth checks are"
					 " enabled (the config secret is divided in 2!)\n");
			}
		}
    }
    
    if ((!challenge_attr.s || challenge_attr.len == 0) ||
		challenge_attr.s[0] != '$') {
		ERR("auth: Invalid value of challenge_attr module parameter\n");
		return -1;
    }
    
    attr.s = challenge_attr.s + 1;
    attr.len = challenge_attr.len - 1;
    
    if (parse_avp_ident(&attr, &challenge_avpid) < 0) {
		ERR("auth: Error while parsing value of challenge_attr module parameter\n");
		return -1;
    }
	
    parse_qop(&qop);
	switch(qop.qop_parsed){
		case QOP_OTHER:
			ERR("auth: Unsupported qop parameter value\n");
			return -1;
		case QOP_AUTH:
		case QOP_AUTHINT:
			if (nc_enabled){
#ifndef USE_NC
				WARN("auth: nounce count support enabled from config, but"
					" disabled at compile time (recompile with -DUSE_NC)\n");
				nc_enabled=0;
#else
				if (nid_crt==0)
					init_nonce_id();
				if (init_nonce_count()!=0)
					return -1;
#endif
			}
#ifdef USE_NC
			else{
				INFO("auth: qop set, but nonce-count (nc_enabled) support"
						" disabled\n");
			}
#endif
			break;
		default:
			if (nc_enabled){
				WARN("auth: nonce-count support enabled, but qop not set\n");
				nc_enabled=0;
			}
			break;
	}
	if (otn_enabled){
#ifdef USE_OT_NONCE
		if (nid_crt==0) init_nonce_id();
		if (init_ot_nonce()!=0) 
			return -1;
#else
		WARN("auth: one-time-nonce support enabled from config, but "
				"disabled at compile time (recompile with -DUSE_OT_NONCE)\n");
		otn_enabled=0;
#endif /* USE_OT_NONCE */
	}

    return 0;
}
Beispiel #5
0
/** Generic parameter fixup function.
 *  Creates a fparam_t structure.
 *  @param type  contains allowed parameter types
 *  @param param is the parameter that will be fixed-up
 *
 * @return
 *    0 on success,
 *    1 if the param doesn't match the specified type
 *    <0 on failure
 */
int fix_param(int type, void** param)
{
	fparam_t* p;
	str name, s;
	int num;
	int err;

	p = (fparam_t*)pkg_malloc(sizeof(fparam_t));
	if (!p) {
		LM_ERR("No memory left\n");
		return E_OUT_OF_MEM;
	}
	memset(p, 0, sizeof(fparam_t));
	p->orig = *param;

	switch(type) {
		case FPARAM_UNSPEC:
			LM_ERR("Invalid type value\n");
			goto error;
		case FPARAM_STRING:
			p->v.asciiz = *param;
			/* no break */
		case FPARAM_STR:
			p->v.str.s = (char*)*param;
			p->v.str.len = strlen(p->v.str.s);
			p->fixed = &p->v;
			break;
		case FPARAM_INT:
			s.s = (char*)*param;
			s.len = strlen(s.s);
			err = str2sint(&s, &num);
			if (err == 0) {
				p->v.i = (int)num;
			} else {
				/* Not a number */
				pkg_free(p);
				return 1;
			}
			p->fixed = (void*)(long)num;
			break;
		case FPARAM_REGEX:
			if ((p->v.regex = pkg_malloc(sizeof(regex_t))) == 0) {
				LM_ERR("No memory left\n");
				goto error;
			}
			if (regcomp(p->v.regex, *param,
						REG_EXTENDED|REG_ICASE|REG_NEWLINE)) {
				pkg_free(p->v.regex);
				p->v.regex=0;
				/* not a valid regex */
				goto no_match;
			}
			p->fixed = p->v.regex;
			break;
		case FPARAM_AVP:
			name.s = (char*)*param;
			name.len = strlen(name.s);
			trim(&name);
			if (!name.len || name.s[0] != '$') {
				/* Not an AVP identifier */
				goto no_match;
			}
			name.s++;
			name.len--;
			if (parse_avp_ident(&name, &p->v.avp) < 0) {
				/* invalid avp identifier (=> no match) */
				goto no_match;
			}
			p->fixed = &p->v;
			break;
		case FPARAM_SELECT:
			name.s = (char*)*param;
			name.len = strlen(name.s);
			trim(&name);
			if (!name.len || name.s[0] != '@') {
				/* Not a select identifier */
				goto no_match;
			}
			if (parse_select(&name.s, &p->v.select) < 0) {
				LM_ERR("Error while parsing select identifier\n");
				goto error;
			}
			p->fixed = &p->v;
			break;
		case FPARAM_SUBST:
			s.s = *param;
			s.len = strlen(s.s);
			p->v.subst = subst_parser(&s);
			if (!p->v.subst) {
				LM_ERR("Error while parsing regex substitution\n");
				goto error;
			}
			p->fixed = &p->v;
			break;
		case FPARAM_PVS:
			name.s = (char*)*param;
			name.len = strlen(name.s);
			trim(&name);
			if (!name.len || name.s[0] != '$'){
				/* not a pvs identifier */
				goto no_match;
			}
			p->v.pvs=pkg_malloc(sizeof(pv_spec_t));
			if (p->v.pvs==0){
				LM_ERR("out of memory while parsing pv_spec_t\n");
				goto error;
			}
			if (pv_parse_spec2(&name, p->v.pvs, 1)==0){
				/* not a valid pvs identifier (but it might be an avp) */
				pkg_free(p->v.pvs);
				p->v.pvs=0;
				goto no_match;
			}
			p->fixed = p->v.pvs;
			break;
		case FPARAM_PVE:
			name.s = (char*)*param;
			name.len = strlen(name.s);
			if (pv_parse_format(&name, &p->v.pve)<0){
				LM_ERR("bad PVE format: \"%.*s\"\n", name.len, name.s);
				goto error;
			}
			p->fixed = &p->v;
			break;
	}

	p->type = type;
	*param = (void*)p;
	return 0;

no_match:
	pkg_free(p);
	return 1;
error:
	pkg_free(p);
	return E_UNSPEC;
}
Beispiel #6
0
static int mod_init(void)
{
	str attr;

	DBG("auth module - initializing\n");

	auth_realm_prefix.len = strlen(auth_realm_prefix.s);

	/* bind the SL API */
	if (sl_load_api(&slb)!=0) {
		LM_ERR("cannot bind to SL API\n");
		return -1;
	}

	/* If the parameter was not used */
	if (sec_param == 0) {
		/* Generate secret using random generator */
		if (generate_random_secret() < 0) {
			LM_ERR("Error while generating random secret\n");
			return -3;
		}
	} else {
		/* Otherwise use the parameter's value */
		secret1.s = sec_param;
		secret1.len = strlen(secret1.s);

		if (auth_checks_reg || auth_checks_ind || auth_checks_ood) {
			/* divide the secret in half: one half for secret1 and one half for
			 *  secret2 */
			secret2.len = secret1.len/2;
			secret1.len -= secret2.len;
			secret2.s = secret1.s + secret1.len;
			if (secret2.len < 16) {
				LM_WARN("consider a longer secret when extra auth checks are"
						" enabled (the config secret is divided in 2!)\n");
			}
		}
	}

	if ((!challenge_attr.s || challenge_attr.len == 0) ||
			challenge_attr.s[0] != '$') {
		LM_ERR("Invalid value of challenge_attr module parameter\n");
		return -1;
	}

	attr.s = challenge_attr.s + 1;
	attr.len = challenge_attr.len - 1;

	if (parse_avp_ident(&attr, &challenge_avpid) < 0) {
		LM_ERR("Error while parsing value of challenge_attr module"
				" parameter\n");
		return -1;
	}

	parse_qop(&auth_qop);
	switch(auth_qop.qop_parsed){
		case QOP_OTHER:
			LM_ERR("Unsupported qop parameter value\n");
			return -1;
		case QOP_AUTH:
		case QOP_AUTHINT:
			if (nc_enabled){
#ifndef USE_NC
				LM_WARN("nounce count support enabled from config, but"
						" disabled at compile time (recompile with -DUSE_NC)\n");
				nc_enabled=0;
#else
				if (nid_crt==0)
					init_nonce_id();
				if (init_nonce_count()!=0)
					return -1;
#endif
			}
#ifdef USE_NC
			else{
				LM_INFO("qop set, but nonce-count (nc_enabled) support"
						" disabled\n");
			}
#endif
			break;
		default:
			if (nc_enabled){
				LM_WARN("nonce-count support enabled, but qop not set\n");
				nc_enabled=0;
			}
			break;
	}
	if (otn_enabled){
#ifdef USE_OT_NONCE
		if (nid_crt==0) init_nonce_id();
		if (init_ot_nonce()!=0)
			return -1;
#else
		LM_WARN("one-time-nonce support enabled from config, but "
				"disabled at compile time (recompile with -DUSE_OT_NONCE)\n");
		otn_enabled=0;
#endif /* USE_OT_NONCE */
	}

	if (auth_algorithm.len == 0 || strcmp(auth_algorithm.s, "MD5") == 0) {
		hash_hex_len = HASHHEXLEN;
		calc_HA1 = calc_HA1_md5;
		calc_response = calc_response_md5;
	}
	else if (strcmp(auth_algorithm.s, "SHA-256") == 0) {
		hash_hex_len = HASHHEXLEN_SHA256;
		calc_HA1 = calc_HA1_sha256;
		calc_response = calc_response_sha256;
	}
	else {
		LM_ERR("Invalid algorithm provided."
				" Possible values are \"\", \"MD5\" or \"SHA-256\"\n");
		return -1;
	}

	return 0;
}