浏览代码

modules/ims_usrloc_pcscf: added storage for IPSEC security as well as DB storage

Jason Penton 11 年之前
父节点
当前提交
794fa76d0a

+ 19 - 0
modules/ims_usrloc_pcscf/udomain.c

@@ -590,6 +590,25 @@ int get_pcontact_by_src(udomain_t* _d, str * _host, unsigned short _port, unsign
 	return ret;
 }
 
+int update_security(udomain_t* _d, security_type _t, security_t* _s, struct pcontact* _c) {
+	if (db_mode == WRITE_THROUGH && db_update_pcontact_security(_c, _t, _s) != 0) {
+		LM_ERR("Error updating security for contact in DB\n");
+		return -1;
+	}
+	_c->security = _s;
+	return 0;
+}
+
+int update_temp_security(udomain_t* _d, security_type _t, security_t* _s, struct pcontact* _c) {
+	if (db_mode == WRITE_THROUGH && db_update_pcontact_security_temp(_c, _t, _s) != 0) {
+		LM_ERR("Error updating temp security for contact in DB\n");
+		return -1;
+	}
+	_c->security_temp = _s;
+	return 0;
+}
+
+
 int assert_identity(udomain_t* _d, str * _host, unsigned short _port, unsigned short _proto, str * _identity) {
 	int i;
 	struct pcontact* c;

+ 2 - 0
modules/ims_usrloc_pcscf/udomain.h

@@ -80,6 +80,8 @@ int get_pcontact(udomain_t* _d, str* _aor, struct pcontact** _r);
 int get_pcontact_by_src(udomain_t* _d, str * _host, unsigned short _port, unsigned short _proto, struct pcontact** _c);
 int assert_identity(udomain_t* _d, str * _host, unsigned short _port, unsigned short _proto, str * _identity);
 int delete_pcontact(udomain_t* _d, str* _aor, struct pcontact* _r);
+int update_security(udomain_t* _d, security_type _t, security_t* _s, struct pcontact* _c);
+int update_temp_security(udomain_t* _d, security_type _t, security_t* _s, struct pcontact* _c);
 
 int preload_udomain(db1_con_t* _c, udomain_t* _d);
 

+ 2 - 0
modules/ims_usrloc_pcscf/usrloc.c

@@ -77,6 +77,8 @@ int bind_usrloc(usrloc_api_t* api) {
 	api->update_pcontact = update_pcontact;
 	api->update_rx_regsession = update_rx_regsession;
 	api->get_all_ucontacts = get_all_ucontacts;
+	api->update_security = update_security;
+	api->update_temp_security = update_temp_security;
 	api->register_ulcb = register_ulcb;
 
 	return 0;

+ 8 - 0
modules/ims_usrloc_pcscf/usrloc.h

@@ -226,6 +226,11 @@ typedef int (*register_udomain_t)(const char* _n, struct udomain** _d);
 typedef int (*get_udomain_t)(const char* _n, udomain_t** _d);
 typedef int (*get_all_ucontacts_t)(void* buf, int len, unsigned int flags, unsigned int part_idx, unsigned int part_max);
 
+/*security related API signatures */
+typedef int (*update_security_t)(struct udomain* _d, security_type _t, security_t* _s, struct pcontact* _c);
+typedef int (*update_temp_security_t)(struct udomain* _d, security_type _t, security_t* _s, struct pcontact* _c);
+
+
 /*! usrloc API export structure */
 typedef struct usrloc_api {
 	int use_domain; /*! use_domain module parameter */
@@ -246,6 +251,9 @@ typedef struct usrloc_api {
 	update_rx_regsession_t update_rx_regsession;
 	get_all_ucontacts_t get_all_ucontacts;
 
+	update_security_t update_security;
+	update_temp_security_t update_temp_security;
+
 	register_ulcb_t register_ulcb;
 } usrloc_api_t;
 

+ 213 - 0
modules/ims_usrloc_pcscf/usrloc_db.c

@@ -23,6 +23,32 @@ str expires_col			= str_init(EXPIRES_COL);
 str service_routes_col	= str_init(SERVICE_ROUTES_COL);
 str socket_col			= str_init(SOCKET_COL);
 str public_ids_col		= str_init(PUBLIC_IDS_COL);
+str security_type_col 	= str_init(SECURITY_TYPE_COL);
+str protocol_col 		= str_init(PROTOCOL_COL);
+str mode_col			= str_init(MODE_COL);
+str ck_col				= str_init(CK_COL);
+str ik_col 				= str_init(IK_COL);
+str ealg_col			= str_init(EALG_COL);
+str ialg_col 			= str_init(IALG_COL);
+str port_uc_col			= str_init(PORTUC_COL);
+str port_us_col 		= str_init(PORTUS_COL);
+str spi_pc_col 			= str_init(SPIPC_COL);
+str spi_ps_col 			= str_init(SPIPS_COL);
+str spi_uc_col 			= str_init(SPIUC_COL);
+str spi_us_col 			= str_init(SPIUS_COL);
+str t_security_type_col	= str_init(T_SECURITY_TYPE_COL);
+str t_protocol_col 		= str_init(T_PROTOCOL_COL);
+str t_mode_col			= str_init(T_MODE_COL);
+str t_ck_col			= str_init(T_CK_COL);
+str t_ik_col 			= str_init(T_IK_COL);
+str t_ealg_col			= str_init(T_EALG_COL);
+str t_ialg_col 			= str_init(T_IALG_COL);
+str t_port_uc_col		= str_init(T_PORTUC_COL);
+str t_port_us_col 		= str_init(T_PORTUS_COL);
+str t_spi_pc_col 		= str_init(T_SPIPC_COL);
+str t_spi_ps_col 		= str_init(T_SPIPS_COL);
+str t_spi_uc_col 		= str_init(T_SPIUC_COL);
+str t_spi_us_col 		= str_init(T_SPIUS_COL);
 
 t_reusable_buffer service_route_buffer = {0,0,0};
 t_reusable_buffer impu_buffer = {0,0,0};
@@ -293,6 +319,193 @@ int db_insert_pcontact(struct pcontact* _c)
 	return 0;
 }
 
+int db_update_pcontact_security_temp(struct pcontact* _c, security_type _t, security_t* _s) {
+	db_val_t match_values[1];
+	db_key_t match_keys[1] = { &aor_col };
+	db_key_t update_keys[13] = { &t_security_type_col, &t_protocol_col,
+			&t_mode_col, &t_ck_col, &t_ik_col, &t_ealg_col, &t_ialg_col, &t_port_uc_col,
+			&t_port_us_col, &t_spi_pc_col, &t_spi_ps_col, &t_spi_uc_col, &t_spi_us_col };
+	db_val_t values[13];
+
+	LM_DBG("updating temp security for pcontact: %.*s\n", _c->aor.len, _c->aor.s);
+
+	VAL_TYPE(match_values) = DB1_STR;
+	VAL_NULL(match_values) = 0;
+	VAL_STR(match_values) = _c->aor;
+
+	if (use_location_pcscf_table(_c->domain) < 0) {
+		LM_ERR("Error trying to use table %.*s\n", _c->domain->len, _c->domain->s);
+		return -1;
+	}
+
+	VAL_TYPE(values) = DB1_INT;
+	VAL_TIME(values) = _s?_s->type:0;
+	VAL_NULL(values) = 0;
+
+	switch (_t) {
+	case SECURITY_IPSEC: {
+		ipsec_t* ipsec = _s?_s->data.ipsec:0;
+		str s_empty = {0,0};
+		int i = 1;
+		VAL_TYPE(values + i) = DB1_STR;
+		VAL_NULL(values + i) = ipsec?0:1;
+		VAL_STR(values + i) = ipsec?ipsec->prot:s_empty;
+
+		VAL_TYPE(values + ++i) = DB1_STR;
+		VAL_NULL(values + i) = ipsec?0:1;
+		VAL_STR(values + i) = ipsec?ipsec->mod:s_empty;
+
+		VAL_TYPE(values + ++i) = DB1_STR;
+		VAL_NULL(values + i) = ipsec?0:1;
+		VAL_STR(values + i) = ipsec?ipsec->ck:s_empty;
+		VAL_TYPE(values + ++i) = DB1_STR;
+		VAL_NULL(values + i) = ipsec?0:1;
+		VAL_STR(values + i) = ipsec?ipsec->ik:s_empty;
+		VAL_TYPE(values + ++i) = DB1_STR;
+		VAL_NULL(values + i) = ipsec?0:1;
+		VAL_STR(values + i) = ipsec?ipsec->ealg:s_empty;
+		VAL_TYPE(values + ++i) = DB1_STR;
+		VAL_NULL(values + i) = ipsec?0:1;
+		VAL_STR(values + i) = ipsec?ipsec->alg:s_empty;
+		VAL_TYPE(values + ++i) = DB1_INT;
+		VAL_NULL(values + i) = ipsec?0:1;
+		VAL_INT(values + i) = ipsec?ipsec->port_uc:0;
+		VAL_TYPE(values + ++i) = DB1_INT;
+		VAL_NULL(values + i) = ipsec?0:1;
+		VAL_INT(values + i) = ipsec?ipsec->port_us:0;
+		VAL_TYPE(values + ++i) = DB1_BIGINT;
+		VAL_NULL(values + i) = ipsec?0:1;
+		VAL_BIGINT(values + i) = ipsec?ipsec->spi_pc:0;
+		VAL_TYPE(values + ++i) = DB1_BIGINT;
+		VAL_NULL(values + i) = ipsec?0:1;
+		VAL_BIGINT(values + i) = ipsec?ipsec->spi_ps:0;
+		VAL_TYPE(values + ++i) = DB1_BIGINT;
+		VAL_NULL(values + i) = ipsec?0:1;
+		VAL_BIGINT(values + i) = ipsec?ipsec->spi_uc:0;
+		VAL_TYPE(values + ++i) = DB1_BIGINT;
+		VAL_NULL(values + i) = ipsec?0:1;
+		VAL_BIGINT(values + i) = ipsec?ipsec->spi_us:0;
+
+		if ((ul_dbf.update(ul_dbh, match_keys, NULL, match_values, update_keys,
+				values, 1, 13)) != 0) {
+			LM_ERR("could not update database info\n");
+			return -1;
+		}
+
+		if (ul_dbf.affected_rows && ul_dbf.affected_rows(ul_dbh) == 0) {
+			LM_DBG("no existing rows for an update... doing insert\n");
+			if (db_insert_pcontact(_c) != 0) {
+				LM_ERR("Failed to insert a pcontact on update\n");
+			}
+		}
+		break;
+	}
+	default:
+		LM_WARN("not yet implemented or unknown security type\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+int db_update_pcontact_security(struct pcontact* _c, security_type _t, security_t* _s) {
+	db_val_t match_values[1];
+	db_key_t match_keys[1] = { &aor_col };
+	db_key_t update_keys[13] = { &security_type_col, &protocol_col,
+			&mode_col, &ck_col, &ik_col, &ealg_col, &ialg_col, &port_uc_col,
+			&port_us_col, &spi_pc_col, &spi_ps_col, &spi_uc_col, &spi_us_col };
+	db_val_t values[13];
+
+	LM_DBG("updating security for pcontact: %.*s\n", _c->aor.len, _c->aor.s);
+
+	VAL_TYPE(match_values) = DB1_STR;
+	VAL_NULL(match_values) = 0;
+	VAL_STR(match_values) = _c->aor;
+
+	if (use_location_pcscf_table(_c->domain) < 0) {
+		LM_ERR("Error trying to use table %.*s\n", _c->domain->len, _c->domain->s);
+		return -1;
+	}
+
+	VAL_TYPE(values) = DB1_INT;
+	VAL_TIME(values) = _s?_s->type:0;
+	VAL_NULL(values) = 0;
+
+	switch (_t) {
+	case SECURITY_IPSEC: {
+		ipsec_t* ipsec = _s?_s->data.ipsec:0;
+		int i = 1;
+		str s_empty = {0,0};
+		VAL_TYPE(values + i) = DB1_STR;
+		VAL_NULL(values + i) = ipsec?0:1;
+		VAL_STR(values + i) = ipsec?ipsec->prot:s_empty;
+
+		VAL_TYPE(values + ++i) = DB1_STR;
+		VAL_NULL(values + i) = ipsec?0:1;
+		VAL_STR(values + i) = ipsec?ipsec->mod:s_empty;
+
+		VAL_TYPE(values + ++i) = DB1_STR;
+		VAL_NULL(values + i) = ipsec?0:1;
+		VAL_STR(values + i) = ipsec?ipsec->ck:s_empty;
+
+		VAL_TYPE(values + ++i) = DB1_STR;
+		VAL_NULL(values + i) = ipsec?0:1;
+		VAL_STR(values + i) = ipsec?ipsec->ik:s_empty;
+
+		VAL_TYPE(values + ++i) = DB1_STR;
+		VAL_NULL(values + i) = ipsec?0:1;
+		VAL_STR(values + i) = ipsec?ipsec->ealg:s_empty;
+
+		VAL_TYPE(values + ++i) = DB1_STR;
+		VAL_NULL(values + i) = ipsec?0:1;
+		VAL_STR(values + i) = ipsec?ipsec->alg:s_empty;
+
+		VAL_TYPE(values + ++i) = DB1_INT;
+		VAL_NULL(values + i) = ipsec?0:1;
+		VAL_INT(values + i) = ipsec?ipsec->port_uc:0;
+
+		VAL_TYPE(values + ++i) = DB1_INT;
+		VAL_NULL(values + i) = ipsec?0:1;
+		VAL_INT(values + i) = ipsec?ipsec->port_us:0;
+
+		VAL_TYPE(values + ++i) = DB1_BIGINT;
+		VAL_NULL(values + i) = ipsec?0:1;
+		VAL_BIGINT(values + i) = ipsec?ipsec->spi_pc:0;
+
+		VAL_TYPE(values + ++i) = DB1_BIGINT;
+		VAL_NULL(values + i) = ipsec?0:1;
+		VAL_BIGINT(values + i) = ipsec?ipsec->spi_ps:0;
+
+		VAL_TYPE(values + ++i) = DB1_BIGINT;
+		VAL_NULL(values + i) = ipsec?0:1;
+		VAL_BIGINT(values + i) = ipsec?ipsec->spi_uc:0;
+
+		VAL_TYPE(values + ++i) = DB1_BIGINT;
+		VAL_NULL(values + i) = ipsec?0:1;
+		VAL_BIGINT(values + i) = ipsec?ipsec->spi_us:0;
+
+		if ((ul_dbf.update(ul_dbh, match_keys, NULL, match_values, update_keys,
+				values, 1, 13)) != 0) {
+			LM_ERR("could not update database info\n");
+			return -1;
+		}
+
+		if (ul_dbf.affected_rows && ul_dbf.affected_rows(ul_dbh) == 0) {
+			LM_DBG("no existing rows for an update... doing insert\n");
+			if (db_insert_pcontact(_c) != 0) {
+				LM_ERR("Failed to insert a pcontact on update\n");
+			}
+		}
+		break;
+	}
+	default:
+		LM_WARN("not yet implemented or unknown security type\n");
+		return -1;
+	}
+
+	return 0;
+}
+
 /* take a contact structure and a pointer to some memory and returns a list of public identities in the format
  * <impu1><impu2>....<impu(n)>
  * make sure p already has memory allocated

+ 28 - 0
modules/ims_usrloc_pcscf/usrloc_db.h

@@ -64,6 +64,32 @@ typedef enum location_pcscf_fields_idx {
 #define SERVICE_ROUTES_COL	"service_routes"
 #define SOCKET_COL			"socket"
 #define PUBLIC_IDS_COL		"public_ids"
+#define SECURITY_TYPE_COL	"security_type"
+#define PROTOCOL_COL		"protocol"
+#define MODE_COL			"mode"
+#define CK_COL				"ck"
+#define IK_COL				"ik"
+#define EALG_COL			"ealg"
+#define IALG_COL			"ialg"
+#define PORTUC_COL			"port_uc"
+#define PORTUS_COL			"port_us"
+#define SPIPC_COL			"spi_pc"
+#define SPIPS_COL			"spi_ps"
+#define SPIUC_COL			"spi_uc"
+#define SPIUS_COL			"spi_us"
+#define T_SECURITY_TYPE_COL	"t_security_type"
+#define T_PROTOCOL_COL		"t_protocol"
+#define T_MODE_COL			"t_mode"
+#define T_CK_COL			"t_ck"
+#define T_IK_COL			"t_ik"
+#define T_EALG_COL			"t_ealg"
+#define T_IALG_COL			"t_ialg"
+#define T_PORTUC_COL		"t_port_uc"
+#define T_PORTUS_COL		"t_port_us"
+#define T_SPIPC_COL			"t_spi_pc"
+#define T_SPIPS_COL			"t_spi_ps"
+#define T_SPIUC_COL			"t_spi_uc"
+#define T_SPIUS_COL			"t_spi_us"
 
 extern db1_con_t* ul_dbh;
 extern db_func_t ul_dbf;
@@ -102,5 +128,7 @@ void free_impu_buf(void);
 int db_insert_pcontact(pcontact_t* _c);
 int db_delete_pcontact(pcontact_t* _c);
 int db_update_pcontact(pcontact_t* _c);
+int db_update_pcontact_security_temp(struct pcontact* _c, security_type _t, security_t* _s);
+int db_update_pcontact_security(struct pcontact* _c, security_type _t, security_t* _s);
 
 #endif /* USRLOC_DB_H_ */