示例#1
0
文件: cmd.c 项目: btriller/kamailio
// Get CK and IK from WWW-Authenticate
static int get_ck_ik(const struct sip_msg* m, str* ck, str* ik)
{
    struct hdr_field *www_auth_hdr = NULL;
    str www_auth;
    memset(&www_auth, 0, sizeof(str));

    www_auth = cscf_get_authenticate((sip_msg_t*)m, &www_auth_hdr);

    *ck = get_www_auth_param("ck", www_auth);
    if (ck->len == 0) {
        LM_ERR("Error getting CK\n");
        return -1;
    }

    *ik = get_www_auth_param("ik", www_auth);
    if (ck->len == 0) {
        LM_ERR("Error getting IK\n");
        return -1;
    }

    return 0;
}
示例#2
0
文件: security.c 项目: asyn/openvims
/**
 * Process the 401 response for REGISTER and creates the first Security-Associations.
 * IPSEc: Only the SA for P_Inc_Req - Incoming Requests is set now as the next REGISTER
 * could come over that one. 
 * @param rpl - the 401 response
 * @param str1 - not used
 * @param str2 - not used
 * @returns 1 if ok, 0 if not
 */
int P_security_401(struct sip_msg *rpl,char *str1, char *str2)
{
	struct sip_msg *req;
	struct hdr_field *hdr;	
	str sec_hdr,sec_srv={0,0};
	r_security_type sec_type;
	char cmd[256];
	r_contact *c;
	r_ipsec *ipsec;
	float sec_q=-1;
	str auth;

	if (!pcscf_use_ipsec &&!pcscf_use_tls) goto	ret_false;
	
	req = cscf_get_request_from_reply(rpl);
	if (!req){
		LOG(L_ERR,"ERR:"M_NAME":P_security_401: No transactional request found.\n");
		goto error;
	}
	auth = cscf_get_authenticate(rpl,&hdr);
	if (!auth.len){
		LOG(L_ERR,"ERR:"M_NAME":P_security_401: No WWW-Authenticate header found.\n");
		goto ret_false; 
	}
	
	sec_hdr = cscf_get_pref_security_header(req,s_security_client, &sec_type,&sec_q);
	if (!sec_hdr.len) {	
		LOG(L_DBG,"DBG:"M_NAME":P_security_401: No Security-Client header found.\n");
		goto ret_false;
	}
	LOG(L_INFO,"DBG:"M_NAME":P_security_401: Security-Client header found : <%.*s>.\n", sec_hdr.len, sec_hdr.s);	


	/* save data into registrar */
	c = save_contact_security(req, auth, sec_hdr, sec_type, sec_q);	
	if (!c) goto error;
	switch(sec_type){
		case SEC_NONE:
			break;
		case SEC_TLS:			
			/* try to add the Security-Server header */		
			sec_srv.len = s_security_server_s.len+sec_hdr.len+s_security_server_e.len;
			sec_srv.s = pkg_malloc(sec_srv.len);
			if (!sec_srv.s){
				LOG(L_ERR,"ERR:"M_NAME":P_security_401: Error allocating %d pkg bytes \n",sec_srv.len);
				goto error;
			}
			sec_srv.len=0;
			STR_APPEND(sec_srv,s_security_server_s);
			STR_APPEND(sec_srv,sec_hdr);
			STR_APPEND(sec_srv,s_security_server_e);

			if (!cscf_add_header(rpl,&sec_srv,HDR_OTHER_T)) {
				LOG(L_ERR,"ERR:"M_NAME":P_security_401: Error adding header <%.*s> \n",sec_srv.len,sec_srv.s);
				pkg_free(sec_srv.s);
				goto error;
			}
			break;
		case SEC_IPSEC:
			ipsec = c->security_temp->data.ipsec;
			/* try to add the Security-Server header */
			sprintf(cmd,"Security-Server: ipsec-3gpp; ealg=%.*s; alg=%.*s; spi-c=%d; spi-s=%d; port-c=%d; port-s=%d; q=0.1\r\n",
				ipsec->r_ealg.len,ipsec->r_ealg.s,
				ipsec->r_alg.len,ipsec->r_alg.s,
				ipsec->spi_pc,ipsec->spi_ps,
				pcscf_ipsec_port_c,pcscf_ipsec_port_s);
			
			sec_srv.len = strlen(cmd);
			sec_srv.s = pkg_malloc(sec_srv.len);
			if (!sec_srv.s){
				LOG(L_ERR,"ERR:"M_NAME":P_security_401: Error allocating %d pkg bytes \n",sec_srv.len);
				goto error;
			}
			memcpy(sec_srv.s,cmd,sec_srv.len);
			if (!cscf_add_header(rpl,&sec_srv,HDR_OTHER_T)) {
				LOG(L_ERR,"ERR:"M_NAME":P_security_401: Error adding header <%.*s> \n",sec_srv.len,sec_srv.s);
				pkg_free(sec_srv.s);
				goto error;
			}
	
			/* run the IPSec script */	
			/* P_Inc_Req */
			sprintf(cmd,"%s %.*s %d %s %d %d %.*s %.*s %.*s %.*s",
				pcscf_ipsec_P_Inc_Req,
				c->host.len,c->host.s,
				ipsec->port_uc,
				pcscf_ipsec_host,
				pcscf_ipsec_port_s,
				ipsec->spi_ps,
				ipsec->ealg.len,ipsec->ealg.s,
				ipsec->ck.len,ipsec->ck.s,
				ipsec->alg.len,ipsec->alg.s,
				ipsec->ik.len,ipsec->ik.s);

			r_unlock(c->hash);
				
			execute_cmd(cmd);
			break;						
	}
	
	return CSCF_RETURN_TRUE;
ret_false:
	return CSCF_RETURN_FALSE;
error:
	return CSCF_RETURN_ERROR;
}
示例#3
0
文件: security.c 项目: asyn/openvims
/**
 * Process the 401 response for REGISTER and creates the first Security-Associations.
 * Only the SA for P_Inc_Req - Incoming Requests is set now as the next REGISTER
 * could come over that one. 
 * @param rpl - the 401 response
 * @param str1 - not used
 * @param str2 - not used
 * @returns 1 if ok, 0 if not
 */
int P_IPSec_401(struct sip_msg *rpl,char *str1, char *str2)
{
	struct sip_msg *req;
	str auth;
	struct hdr_field *hdr;	
	str sec_cli,sec_srv={0,0};
	str ck,ik;
	char ck_c[64],ik_c[64];
	str ck_esp={ck_c,0},ik_esp={ik_c,0};
	str alg,ealg;
	str alg_setkey,ealg_setkey;
	str tmp;
	unsigned int spi_uc,spi_us;
	unsigned int spi_pc,spi_ps;
	int port_uc,port_us;
	char cmd[256];
	str ue;
	

	contact_body_t *contact;
	struct sip_uri uri;
	
	req = cscf_get_request_from_reply(rpl);
	if (!req){
		LOG(L_ERR,"ERR:"M_NAME":P_ipsec_401: No transactional request found.\n");
		goto error;
	}
	auth = cscf_get_authenticate(rpl,&hdr);
	if (!auth.len){
		LOG(L_ERR,"ERR:"M_NAME":P_ipsec_401: No authorization header found.\n");
		goto error; 
	}
	sec_cli = cscf_get_security_client(req,&hdr);
	if (!sec_cli.len){
		LOG(L_DBG,"DBG:"M_NAME":P_ipsec_401: No Security-Client header found.\n");
		goto error; 
	}
	
	/* first we look for CK, IK */
	get_qparam(auth,s_ck,ck);
	LOG(L_DBG,"DBG:"M_NAME":P_ipsec_401: CK: <%.*s>\n",
		ck.len,ck.s);
	get_qparam(auth,s_ik,ik);
	LOG(L_DBG,"DBG:"M_NAME":P_ipsec_401: IK: <%.*s>\n",
		ik.len,ik.s);
	
	/* then for algorithms */
	get_param(sec_cli,s_ealg,ealg);
	LOG(L_DBG,"DBG:"M_NAME":P_ipsec_401: Enc Algorithm: <%.*s>\n",
		ealg.len,ealg.s);
	get_param(sec_cli,s_alg,alg);
	LOG(L_DBG,"DBG:"M_NAME":P_ipsec_401: Int Algorithm: <%.*s>\n",
		alg.len,alg.s);
	/* and for spis */
	get_param(sec_cli,s_spi_c,tmp);
	strtoint(tmp,spi_uc);
	LOG(L_DBG,"DBG:"M_NAME":P_ipsec_401: SPI-C: %d\n",
		spi_uc);
	get_param(sec_cli,s_spi_s,tmp);
	strtoint(tmp,spi_us);
	LOG(L_DBG,"DBG:"M_NAME":P_ipsec_401: SPI-S: %d\n",
		spi_us);
	/* and for ports */
	get_param(sec_cli,s_port_c,tmp);
	strtoint(tmp,port_uc);
	LOG(L_DBG,"DBG:"M_NAME":P_ipsec_401: Port-C: %d\n",
		port_uc);
	get_param(sec_cli,s_port_s,tmp);
	strtoint(tmp,port_us);
	LOG(L_DBG,"DBG:"M_NAME":P_ipsec_401: Port-S: %d\n",
		port_us);
	
	
	contact = cscf_parse_contacts(req);
	if (!contact) {		
		LOG(L_ERR,"ERR:"M_NAME":P_ipsec_401: Message contains no Contact!\n");
		goto error;
	}
	if (contact->contacts){
		ue = contact->contacts->uri;
		if (parse_uri(ue.s,ue.len,&uri)){
			LOG(L_ERR,"ERR:"M_NAME":P_ipsec_401: Error parsing uri <%.*s>\n",ue.len,ue.s);
			goto error;
		}
		ue = uri.host;
		if (uri.port_no==0) port_uc=5060;
	}else
		ue = req->via1->host;
	LOG(L_DBG,"DBG:"M_NAME":P_ipsec_401: UE IP: <%.*s> \n",ue.len,ue.s);
	
	spi_pc=get_next_spi();	
	spi_ps=get_next_spi();	

	ck_esp.s[ck_esp.len++]='0';
	ck_esp.s[ck_esp.len++]='x';	
	if (ealg.len == s_des_in.len && strncasecmp(ealg.s,s_des_in.s,ealg.len)==0) {
		memcpy(ck_esp.s+ck_esp.len,ck.s,32);ck_esp.len+=32;
		memcpy(ck_esp.s+ck_esp.len,ck.s,16);ck_esp.len+=16;
		ealg_setkey = s_des_out;
	}
	else
	if (ealg.len == s_aes_in.len && strncasecmp(ealg.s,s_aes_in.s,ealg.len)==0) {
		memcpy(ck_esp.s+ck_esp.len,ck.s,ck.len);ck_esp.len+=ck.len;
		ealg_setkey = s_aes_out;
	}else {
		memcpy(ck_esp.s+ck_esp.len,ck.s,ck.len);ck_esp.len+=ck.len;
		ealg_setkey = s_null_out;
		ealg = s_null_out;
	}

	ik_esp.s[ik_esp.len++]='0';
	ik_esp.s[ik_esp.len++]='x';		
	if (alg.len == s_md5_in.len && strncasecmp(alg.s,s_md5_in.s,alg.len)==0) {
		memcpy(ik_esp.s+ik_esp.len,ik.s,ik.len);ik_esp.len+=ik.len;
		alg_setkey = s_md5_out;
	}
	else
	if (alg.len == s_sha_in.len && strncasecmp(alg.s,s_sha_in.s,alg.len)==0) {		
		memcpy(ik_esp.s+ik_esp.len,ik.s,ik.len);ik_esp.len+=ik.len;
		memcpy(ik_esp.s+ik_esp.len,"00000000",8);ik_esp.len+=8;
		alg_setkey = s_sha_out;
	}else{
		LOG(L_ERR,"ERR:"M_NAME":P_ipsec_401: Unknown Integrity algorithm <%.*s>\n",alg.len,alg.s);
		goto error;
	}

	/* try to add the Security-Server header */
	sprintf(cmd,"Security-Server: ipsec-3gpp; ealg=%.*s; alg=%.*s; spi-c=%d; spi-s=%d; port-c=%d; port-s=%d; q=0.1\r\n",
		ealg.len,ealg.s,
		alg.len,alg.s,
		spi_pc,spi_ps,
		pcscf_ipsec_port_c,pcscf_ipsec_port_s);
		
	sec_srv.len = strlen(cmd);
	sec_srv.s = pkg_malloc(sec_srv.len);
	if (!sec_srv.s){
		LOG(L_ERR,"ERR:"M_NAME":P_ipsec_401: Error allocating %d pkg bytes \n",sec_srv.len);
		goto error;
	}
	memcpy(sec_srv.s,cmd,sec_srv.len);
	if (!cscf_add_header(rpl,&sec_srv,HDR_OTHER_T)) {
		LOG(L_ERR,"ERR:"M_NAME":P_ipsec_401: Error adding header <%.*s> \n",sec_srv.len,sec_srv.s);
		pkg_free(sec_srv.s);
		goto error;
	}

	/* run the IPSec script */	
	/* P_Inc_Req */
	sprintf(cmd,"%s %.*s %d %s %d %d %.*s %.*s %.*s %.*s",
		pcscf_ipsec_P_Inc_Req,
		ue.len,ue.s,
		port_uc,
		pcscf_ipsec_host,
		pcscf_ipsec_port_s,
		spi_ps,
		ealg_setkey.len,ealg_setkey.s,
		ck_esp.len,ck_esp.s,
		alg_setkey.len,alg_setkey.s,
		ik_esp.len,ik_esp.s);
	execute_cmd(cmd);
			
	/* save data into registrar */
	save_contact_ipsec(req,rpl,
		spi_uc,spi_us,spi_pc,spi_ps,port_uc,port_us,
		ealg_setkey,ck_esp,alg_setkey,ik_esp);
	
	
	return 1;	
error:
	return 0;	
}