示例#1
0
static inline int pv_authorize(struct sip_msg* msg, gparam_p realm,
                               hdr_types_t hftype)
{
    static char ha1[256];
    int res;
    struct hdr_field* h;
    auth_body_t* cred;
    auth_result_t ret;
    str domain;

    if(fixup_get_svalue(msg, realm, &domain)!=0)
    {
        LM_ERR("invalid realm parameter\n");
        return -1;
    }

    if (domain.len==0)
        domain.s = 0;

    ret = pre_auth(msg, &domain, hftype, &h);

    if (ret != DO_AUTHORIZATION)
        return ret;

    cred = (auth_body_t*)h->parsed;

    res = auth_get_ha1(msg, &cred->digest.username, &domain, ha1);
    if (res < 0) {
        /* Error */
        if (sigb.reply(msg, 500, &auth_500_err, NULL) == -1) {
            LM_ERR("failed to send 500 reply\n");
        }
        return ERROR;
    }
    if (res > 0) {
        /* Username not found */
        return USER_UNKNOWN;
    }

    /* Recalculate response, it must be same to authorize successfully */
    if (!check_response(&(cred->digest),&msg->first_line.u.request.method,ha1))
    {
        return post_auth(msg, h);
    }
    return INVALID_PASSWORD;
}
示例#2
0
/**
 * @brief do WWW-Digest authentication with password taken from cfg var
 */
static int pv_authenticate(struct sip_msg *msg, char *p1, char *p2,
		char *p3, int hftype)
{
    int flags = 0;
    str realm  = {0, 0};
    str passwd = {0, 0};
	struct hdr_field* h;
	auth_body_t* cred;
	int ret;
    str hf = {0, 0};
    avp_value_t val;
	static char ha1[256];
	struct qp *qop = NULL;

	cred = 0;
	ret = AUTH_ERROR;

	if (get_str_fparam(&realm, msg, (fparam_t*)p1) < 0) {
		LM_ERR("failed to get realm value\n");
		goto error;
	}

	if(realm.len==0) {
		LM_ERR("invalid realm value - empty content\n");
		goto error;
	}

	if (get_str_fparam(&passwd, msg, (fparam_t*)p2) < 0) {
		LM_ERR("failed to get passwd value\n");
		goto error;
	}

	if(passwd.len==0) {
		LM_ERR("invalid password value - empty content\n");
		goto error;
	}

	if (get_int_fparam(&flags, msg, (fparam_t*)p3) < 0) {
		LM_ERR("invalid flags value\n");
		goto error;
	}

	switch(pre_auth(msg, &realm, hftype, &h, NULL)) {
		case ERROR:
		case BAD_CREDENTIALS:
			LM_DBG("error or bad credentials\n");
			ret = AUTH_ERROR;
			goto end;
		case CREATE_CHALLENGE:
			LM_ERR("CREATE_CHALLENGE is not a valid state\n");
			ret = AUTH_ERROR;
			goto end;
		case DO_RESYNCHRONIZATION:
			LM_ERR("DO_RESYNCHRONIZATION is not a valid state\n");
			ret = AUTH_ERROR;
			goto end;
		case NOT_AUTHENTICATED:
			LM_DBG("not authenticated\n");
			ret = AUTH_ERROR;
			goto end;
		case DO_AUTHENTICATION:
			break;
		case AUTHENTICATED:
			ret = AUTH_OK;
			goto end;
	}

	cred = (auth_body_t*)h->parsed;

	/* compute HA1 if needed */
	if ((flags&1)==0) {
		/* Plaintext password is stored in PV, calculate HA1 */
		calc_HA1(HA_MD5, &cred->digest.username.whole, &realm,
				&passwd, 0, 0, ha1);
		LM_DBG("HA1 string calculated: %s\n", ha1);
	} else {
		memcpy(ha1, passwd.s, passwd.len);
		ha1[passwd.len] = '\0';
	}

	/* Recalculate response, it must be same to authorize successfully */
	ret = auth_check_response(&(cred->digest),
				&msg->first_line.u.request.method, ha1);
	if(ret==AUTHENTICATED) {
		ret = AUTH_OK;
		switch(post_auth(msg, h)) {
			case AUTHENTICATED:
				break;
			default:
				ret = AUTH_ERROR;
				break;
		}
	} else {
		if(ret==NOT_AUTHENTICATED)
			ret = AUTH_INVALID_PASSWORD;
		else
			ret = AUTH_ERROR;
	}

end:
	if (ret < 0) {
		/* check if required to add challenge header as avp */
		if(!(flags&14))
			return ret;
		if(flags&8) {
			qop = &auth_qauthint;
		} else if(flags&4) {
			qop = &auth_qauth;
		}
		if (get_challenge_hf(msg, (cred ? cred->stale : 0),
				&realm, NULL, NULL, qop, hftype, &hf) < 0) {
			ERR("Error while creating challenge\n");
			ret = AUTH_ERROR;
		} else {
			val.s = hf;
			if(add_avp(challenge_avpid.flags | AVP_VAL_STR,
							challenge_avpid.name, val) < 0) {
				LM_ERR("Error while creating attribute with challenge\n");
				ret = AUTH_ERROR;
			}
			pkg_free(hf.s);
		}
	}

error:
	return ret;

}
示例#3
0
文件: authorize.c 项目: OPSF/uClinux
/* Authorize digest credentials */
int authorize(struct sip_msg* msg, str* realm, int hftype)
{
	auth_result_t ret;
	struct hdr_field* h;
	auth_body_t* cred = NULL;
	str* uri;
	struct sip_uri puri;
	str  domain;

	domain = *realm;

	/* see what is to do after a first look at the message */
	ret = pre_auth(msg, &domain, hftype, &h);
	
	switch(ret) 
	{
		case ERROR:            return 0;
			   
		case AUTHORIZED:       return 1;

		case NO_CREDENTIALS:   cred = NULL;
							   break;

		case DO_AUTHORIZATION: cred = (auth_body_t*)h->parsed;
							   break;
	}

	if (get_uri(msg, &uri) < 0) 
	{
		LOG(L_ERR, M_NAME":authorize(): From/To URI not found\n");
		return -1;
	}
	
	if (parse_uri(uri->s, uri->len, &puri) < 0) 
	{
		LOG(L_ERR, M_NAME":authorize(): Error while parsing From/To URI\n");
		return -1;
	}
//	user.s = (char *)pkg_malloc(puri.user.len);
//	un_escape(&(puri.user), &user);
	
	/* parse the ruri, if not yet */
	if(msg->parsed_uri_ok==0 && parse_sip_msg_uri(msg)<0)
	{
		LOG(L_ERR,M_NAME":authorize(): ERROR while parsing the Request-URI\n");
		return -1;
	}
	
	/* preliminary check */
	if(cred)
	{
		if (puri.host.len != cred->digest.realm.len) 
		{
			DBG(M_NAME":authorize(): Credentials realm and URI host do not "
				"match\n");  
			return -1;
		}
	
		if (strncasecmp(puri.host.s, cred->digest.realm.s, puri.host.len) != 0) 
		{
			DBG(M_NAME":authorize(): Credentials realm and URI host do not "
				"match\n");
			return -1;
		}
	}
	
	if( diameter_authorize(cred?h:NULL, &msg->first_line.u.request.method,
					puri, msg->parsed_uri, msg->id, rb) != 1)
	{
		send_resp(msg, 500, "Internal Server Error", NULL, 0);	
		return -1;
	}
	
	if( srv_response(msg, rb, hftype) != 1 )
		return -1;

	mark_authorized_cred(msg, h);

	return 1;
}
示例#4
0
/**
 * @brief do WWW-Digest authentication with password taken from cfg var
 */
int pv_authenticate(struct sip_msg *msg, str *realm, str *passwd,
		int flags, int hftype, str *method)
{
	struct hdr_field* h;
	auth_body_t* cred;
	int ret;
	str hf = {0, 0};
	avp_value_t val;
	static char ha1[256];
	struct qp *qop = NULL;

	cred = 0;
	ret = AUTH_ERROR;

	switch(pre_auth(msg, realm, hftype, &h, NULL)) {
		case NONCE_REUSED:
			LM_DBG("nonce reused");
			ret = AUTH_NONCE_REUSED;
			goto end;
		case STALE_NONCE:
			LM_DBG("stale nonce\n");
			ret = AUTH_STALE_NONCE;
			goto end;
		case NO_CREDENTIALS:
			LM_DBG("no credentials\n");
			ret = AUTH_NO_CREDENTIALS;
			goto end;
		case ERROR:
		case BAD_CREDENTIALS:
			LM_DBG("error or bad credentials\n");
			ret = AUTH_ERROR;
			goto end;
		case CREATE_CHALLENGE:
			LM_ERR("CREATE_CHALLENGE is not a valid state\n");
			ret = AUTH_ERROR;
			goto end;
		case DO_RESYNCHRONIZATION:
			LM_ERR("DO_RESYNCHRONIZATION is not a valid state\n");
			ret = AUTH_ERROR;
			goto end;
		case NOT_AUTHENTICATED:
			LM_DBG("not authenticated\n");
			ret = AUTH_ERROR;
			goto end;
		case DO_AUTHENTICATION:
			break;
		case AUTHENTICATED:
			ret = AUTH_OK;
			goto end;
	}

	cred = (auth_body_t*)h->parsed;

	/* compute HA1 if needed */
	if ((flags&1)==0) {
		/* Plaintext password is stored in PV, calculate HA1 */
		calc_HA1(HA_MD5, &cred->digest.username.whole, realm,
				passwd, 0, 0, ha1);
		LM_DBG("HA1 string calculated: %s\n", ha1);
	} else {
		memcpy(ha1, passwd->s, passwd->len);
		ha1[passwd->len] = '\0';
	}

	/* Recalculate response, it must be same to authorize successfully */
	ret = auth_check_response(&(cred->digest), method, ha1);
	if(ret==AUTHENTICATED) {
		ret = AUTH_OK;
		switch(post_auth(msg, h)) {
			case AUTHENTICATED:
				break;
			default:
				ret = AUTH_ERROR;
				break;
		}
	} else {
		if(ret==NOT_AUTHENTICATED)
			ret = AUTH_INVALID_PASSWORD;
		else
			ret = AUTH_ERROR;
	}

end:
	if (ret < 0) {
		/* check if required to add challenge header as avp */
		if(!(flags&14))
			return ret;
		if(flags&8) {
			qop = &auth_qauthint;
		} else if(flags&4) {
			qop = &auth_qauth;
		}
		if (get_challenge_hf(msg, (cred ? cred->stale : 0),
					realm, NULL, NULL, qop, hftype, &hf) < 0) {
			ERR("Error while creating challenge\n");
			ret = AUTH_ERROR;
		} else {
			val.s = hf;
			if(add_avp(challenge_avpid.flags | AVP_VAL_STR,
						challenge_avpid.name, val) < 0) {
				LM_ERR("Error while creating attribute with challenge\n");
				ret = AUTH_ERROR;
			}
			pkg_free(hf.s);
		}
	}

	return ret;
}