Example #1
0
/**
 * Handle third party registration
 * @param msg - the SIP REGISTER message
 * @param m  - the isc_match that matched with info about where to forward it 
 * @param mark  - the isc_mark that should be used to mark the message
 * @returns #ISC_RETURN_TRUE if allowed, #ISC_RETURN_FALSE if not
 */
int isc_third_party_reg(struct sip_msg *msg, isc_match *m,isc_mark *mark)
{
	r_third_party_registration r;
	int expires=0;
	str req_uri ={0,0};
	str to ={0,0};
	str pvni ={0,0};
	str pani ={0,0};
	str cv ={0,0};

	struct hdr_field *hdr;

	LOG(L_INFO,"INFO:"M_NAME":isc_third_party_reg: Enter\n");

	/* Set Request Uri to IFC matching server name */
	req_uri.len = m->server_name.len;
	req_uri.s = m->server_name.s;

	/* Get To header*/
	to = cscf_get_public_identity(msg);


	/*TODO - check if the min/max expires is in the acceptable limits
	 * this does not work correctly if the user has multiple contacts
	 * and register/deregisters them individually!!!
	 */
	expires = cscf_get_max_expires(msg);
	
	/* Get P-Visited-Network-Id header */
	pvni = cscf_get_visited_network_id(msg, &hdr);
	/* Get P-Access-Network-Info header */
	pani = cscf_get_access_network_info(msg, &hdr);
	
	/* Get P-Charging-Vector header */
	/* Just forward the charging header received from P-CSCF */
	/* Todo: implement also according to TS 24.229, chap 5.4.1.7 */
	cv =   cscf_get_charging_vector(msg, &hdr);

	if (req_uri.s){
		
        memset(&r,0,sizeof(r_third_party_registration));

        r.req_uri = req_uri;
        r.to = to;
        r.from = isc_my_uri_sip;
        r.pvni = pvni;
        r.pani = pani;
		r.cv = cv;
        r.service_info = m->service_info;
         
		if (expires<=0) r_send_third_party_reg(&r,0);
		else r_send_third_party_reg(&r,expires+isc_expires_grace);
		return ISC_RETURN_TRUE;
	}else{
		return ISC_RETURN_FALSE;
	}	
}
Example #2
0
/**
 * Perform User Authorization Request.
 * creates and send the user authorization query
 * @param msg - the SIP message
 * @param str1 - the realm
 * @param str2 - if to do capabilities
 * @returns true if OK, false if not
 */
int I_perform_user_authorization_request(struct sip_msg* msg, char* str1, char* str2) {
    str private_identity, public_identity, visited_network_id;
    int authorization_type = AVP_IMS_UAR_REGISTRATION;
    int expires = 3600;
    struct hdr_field *hdr;
    str realm;
    contact_t *c;
    int sos_reg = 0;
    contact_body_t *b = 0;
    str call_id;
    saved_uar_transaction_t* saved_t;
    tm_cell_t *t = 0;
    int intvalue_param;
    cfg_action_t* cfg_action;

    uar_param_t* ap = (uar_param_t*) str1;
    if (fixup_get_ivalue(msg, ap->ivalue, &intvalue_param) != 0) {
        LM_ERR("no int value param passed\n");
        return CSCF_RETURN_ERROR;
    }
    cfg_action = ap->paction->next;

    realm = cscf_get_realm_from_ruri(msg);

    //check if we received what we should, we do this even though it should be done in cfg file - double checking!
    if (msg->first_line.type != SIP_REQUEST) {
        LM_ERR("ERR:I_UAR: The message is not a request\n");
        return CSCF_RETURN_ERROR;
    }
    if (msg->first_line.u.request.method.len != 8 ||
            memcmp(msg->first_line.u.request.method.s, "REGISTER", 8) != 0) {
        LM_ERR("ERR:I_UAR: The method is not a REGISTER\n");
        return CSCF_RETURN_ERROR;
    }

    private_identity = cscf_get_private_identity(msg, realm);
    if (!private_identity.len) {
        LM_ERR("ERR:I_UAR: Private Identity not found, responding with 400\n");
        cscf_reply_transactional(msg, 400, MSG_400_NO_PRIVATE);
        return CSCF_RETURN_BREAK;
    }

    public_identity = cscf_get_public_identity(msg);
    if (!public_identity.len) {
        LM_ERR("ERR:I_UAR: Public Identity not found, responding with 400\n");
        cscf_reply_transactional(msg, 400, MSG_400_NO_PUBLIC);
        return CSCF_RETURN_BREAK;

    }

    b = cscf_parse_contacts(msg);

    if (!b || (!b->contacts && !b->star)) {
        LM_DBG("DBG:I_UAR: No contacts found\n");
        return CSCF_RETURN_ERROR;
    }

    for (c = b->contacts; c; c = c->next) {

        sos_reg = cscf_get_sos_uri_param(c->uri);
        if (sos_reg == -1) {
            //error case
            LM_ERR("ERR:I_UAR: MSG_400_MALFORMED_CONTACT, responding with 400\n");
            cscf_reply_transactional(msg, 400, MSG_400_MALFORMED_CONTACT);
            return CSCF_RETURN_BREAK;
        } else if (sos_reg == -2) {
            LM_ERR("ERR:I_UAR: MSG_500_SERVER_ERROR_OUT_OF_MEMORY, responding with 500\n");
            cscf_reply_transactional(msg, 500, MSG_500_SERVER_ERROR_OUT_OF_MEMORY);
            return CSCF_RETURN_BREAK;
        }
    }

    visited_network_id = cscf_get_visited_network_id(msg, &hdr);
    if (!visited_network_id.len) {
        LM_ERR("ERR:I_UAR: Visited Network Identity not found, responding with 400\n");
        cscf_reply_transactional(msg, 400, MSG_400_NO_VISITED);
        return CSCF_RETURN_BREAK;
    }

    if (atoi(str1)) authorization_type = AVP_IMS_UAR_REGISTRATION_AND_CAPABILITIES;
    else {
        expires = cscf_get_max_expires(msg, 0);
        if (expires == 0) authorization_type = AVP_IMS_UAR_DE_REGISTRATION;
    }

    LM_DBG("SENDING UAR: PI: [%.*s], PU: [%.*s], VNID: [%.*s]\n", private_identity.len, private_identity.s,
            public_identity.len, public_identity.s,
            visited_network_id.len, visited_network_id.s);

    //before we send lets suspend the transaction
    t = tmb.t_gett();
    if (t == NULL || t == T_UNDEFINED) {
        if (tmb.t_newtran(msg) < 0) {
            LM_ERR("cannot create the transaction for UAR async\n");
            cscf_reply_transactional(msg, 480, MSG_480_DIAMETER_ERROR);
            return CSCF_RETURN_BREAK;
        }
        t = tmb.t_gett();
        if (t == NULL || t == T_UNDEFINED) {
            LM_ERR("cannot lookup the transaction\n");
            cscf_reply_transactional(msg, 480, MSG_480_DIAMETER_ERROR);
            return CSCF_RETURN_BREAK;
        }
    }

    saved_t = shm_malloc(sizeof (saved_uar_transaction_t));
    if (!saved_t) {
        LM_ERR("no more memory trying to save transaction state\n");
        return CSCF_RETURN_ERROR;

    }
    memset(saved_t, 0, sizeof (saved_uar_transaction_t));
    saved_t->act = cfg_action;

    call_id = cscf_get_call_id(msg, 0);
    saved_t->callid.s = (char*) shm_malloc(call_id.len + 1);
    if (!saved_t->callid.s) {
    	LM_ERR("no more memory trying to save transaction state : callid\n");
    	shm_free(saved_t);
    	return CSCF_RETURN_ERROR;
    }
    memset(saved_t->callid.s, 0, call_id.len + 1);
    memcpy(saved_t->callid.s, call_id.s, call_id.len);
    saved_t->callid.len = call_id.len;

    LM_DBG("Setting default AVP return code used for async callbacks to default as ERROR \n");
    create_uaa_return_code(CSCF_RETURN_ERROR);
    
    LM_DBG("Suspending SIP TM transaction\n");
    if (tmb.t_suspend(msg, &saved_t->tindex, &saved_t->tlabel) < 0) {
        LM_ERR("failed to suspend the TM processing\n");
        free_saved_uar_transaction_data(saved_t);

        cscf_reply_transactional(msg, 480, MSG_480_DIAMETER_ERROR);
        return CSCF_RETURN_BREAK;
    }

    if (cxdx_send_uar(msg, private_identity, public_identity, visited_network_id, authorization_type, sos_reg, saved_t) != 0) {
        LM_ERR("ERR:I_UAR: Error sending UAR or UAR time-out\n");
        tmb.t_cancel_suspend(saved_t->tindex, saved_t->tlabel);
        free_saved_uar_transaction_data(saved_t);
        cscf_reply_transactional(msg, 480, MSG_480_DIAMETER_ERROR);
        return CSCF_RETURN_BREAK;

    }
    //we use async replies therefore we send break and not true when successful
    return CSCF_RETURN_BREAK;
}
Example #3
0
/**
 * Handle third party registration
 * @param msg - the SIP REGISTER message
 * @param m  - the isc_match that matched with info about where to forward it
 * @param mark  - the isc_mark that should be used to mark the message
 * @returns #ISC_RETURN_TRUE if allowed, #ISC_RETURN_FALSE if not
 */
int isc_third_party_reg(struct sip_msg *msg, isc_match *m, isc_mark *mark, udomain_t* d) {
    r_third_party_registration r;
    str path, path_received;
    int expires = 0;
    str req_uri = {0, 0};
    str to = {0, 0};
    str pvni = {0, 0};
    str pani = {0, 0};
    str cv = {0, 0};
	str s = {0, 0};

	impurecord_t *p;

    struct hdr_field *hdr;

    LM_DBG("isc_third_party_reg: Enter\n");

    /* Set Request Uri to IFC matching server name */
    req_uri.len = m->server_name.len;
    req_uri.s = m->server_name.s;

    /* Get To header*/
    to = cscf_get_public_identity(msg);

	if (cscf_get_originating_user(msg, &s)) {

		isc_ulb.lock_udomain(d, &s);
		if ( isc_ulb.get_impurecord(d,&s,&p) != 0) {
			isc_ulb.unlock_udomain(d, &s);
			LM_ERR("Failed to get IMPU domain from usrloc\n");
			goto no_pai;
		}
		if ( build_p_associated_uri(p->s) != 0) {
			isc_ulb.unlock_udomain(d, &s);
			LM_ERR("Failed to build P-Associated URI for 3rd party reg\n");
			goto no_pai;
		}
		isc_ulb.unlock_udomain(d, &s);
	}

    /*TODO - check if the min/max expires is in the acceptable limits
     * this does not work correctly if the user has multiple contacts
     * and register/deregisters them individually!!!
     */
no_pai:
    expires = cscf_get_max_expires(msg, 0);

    /* Get P-Visited-Network-Id header */
    pvni = cscf_get_visited_network_id(msg, &hdr);
    /* Get P-Access-Network-Info header */
    pani = cscf_get_access_network_info(msg, &hdr);

    if (build_path_vector(msg, &path, &path_received) < 0) {
	LM_ERR("Failed to parse PATH header for third-party reg\n");
	return ISC_RETURN_FALSE;
    }
    LM_DBG("PATH header in REGISTER is [%.*s]\n", path.len, path.s);

    /* Get P-Charging-Vector header */
    /* Just forward the charging header received from P-CSCF */
    /* Todo: implement also according to TS 24.229, chap 5.4.1.7 */
    cv = cscf_get_charging_vector(msg, &hdr);

    if (req_uri.s) {

	memset(&r, 0, sizeof (r_third_party_registration));

	r.req_uri = req_uri;
	r.to = to;
	r.from = isc_my_uri_sip;
	r.pvni = pvni;
	r.pani = pani;
	r.cv = cv;
	if (m->service_info.s && m->service_info.len) {
		r.body.content_type = CT_SERVICE_INFO;
		r.body.content = m->service_info;
	} else if (m->include_register_request) {
		r.body.content_type = CT_REGISTER_REQ;
                r.body.content.s = msg->first_line.u.request.method.s;
		r.body.content.len = msg->len;
	} else if (m->include_register_response) {
		struct bookmark dummy_bm;
		r.body.content_type = CT_REGISTER_RESP;
                r.body.content.s = build_res_buf_from_sip_req(200, &reg_resp_200OK, 0, msg, (unsigned int*)&r.body.content.len, &dummy_bm);
		if (!r.body.content.s) {
			LM_DBG("response building failed for body of third party register request");
			r.body.content_type = CT_NONE;
		}
	} else {
		r.body.content_type = CT_NONE;
	}
	r.path = path;

	if (expires <= 0)
	    r_send_third_party_reg(&r, 0);
	else
	    r_send_third_party_reg(&r, expires + isc_expires_grace);
	return ISC_RETURN_TRUE;
    } else {
	return ISC_RETURN_FALSE;
    }
}