open5gs/lib/s6a/hss_init.c

231 lines
6.7 KiB
C
Raw Normal View History

2017-03-02 02:43:26 +00:00
#define TRACE_MODULE _s6a_hss_init
2017-02-28 03:03:53 +00:00
2017-02-27 14:01:15 +00:00
#include "core_debug.h"
2017-03-02 02:43:26 +00:00
#include "core_pool.h"
2017-03-02 05:18:24 +00:00
#include "core_lib.h"
2017-02-24 01:50:49 +00:00
2017-03-02 13:47:43 +00:00
#include "milenage.h"
2017-03-02 02:43:26 +00:00
#include "hss_ctx.h"
2017-02-24 01:50:49 +00:00
#include "s6a_app.h"
2017-03-02 02:43:26 +00:00
static struct disp_hdl *hss_hdl_fb = NULL; /* handler for fallback cb */
static struct disp_hdl *hss_hdl_tr = NULL; /* handler for Test-Request req cb */
2017-02-24 01:50:49 +00:00
2017-03-03 03:57:19 +00:00
static void hss_auth_send_err_msg(struct msg **msg)
{
struct msg *ans;
d_assert(fd_msg_new_answer_from_req(fd_g_config->cnf_dict, msg, 0) == 0
&& *msg, goto out1,);
ans = *msg;
/* Set the Origin-Host, Origin-Realm, andResult-Code AVPs */
d_assert(fd_msg_rescode_set(ans, "DIAMETER_AUTHENTICATION_REJECTED",
NULL, NULL, 1) == 0, goto out2,);
/* Send the answer */
d_assert(fd_msg_send(msg, NULL, NULL) == 0, goto out2,);
return;
out2:
d_assert(fd_msg_free(ans) == 0,,);
out1:
return;
}
2017-02-24 01:50:49 +00:00
/* Default callback for the application. */
2017-03-02 02:43:26 +00:00
static int hss_fb_cb(struct msg **msg, struct avp *avp,
2017-02-28 12:55:19 +00:00
struct session *sess, void *opaque, enum disp_action *act)
2017-02-24 01:50:49 +00:00
{
/* This CB should never be called */
2017-02-27 14:01:15 +00:00
d_warn("Unexpected message received!");
2017-02-24 01:50:49 +00:00
return ENOTSUP;
}
/* Callback for incoming Test-Request messages */
2017-03-02 02:43:26 +00:00
static int hss_air_cb( struct msg **msg, struct avp *avp,
2017-02-28 12:55:19 +00:00
struct session *sess, void *opaque, enum disp_action *act)
2017-02-24 01:50:49 +00:00
{
struct msg *ans, *qry;
2017-02-28 15:21:20 +00:00
struct avp *avpch1, *avpch2;
2017-03-02 13:47:43 +00:00
struct avp_hdr *hdr;
2017-02-28 15:21:20 +00:00
union avp_value val;
2017-03-02 13:47:43 +00:00
ue_ctx_t *ue = NULL;
c_uint8_t mac_a[8];
c_uint8_t seq[6];
c_uint8_t xres[8];
c_uint8_t ak[6];
c_uint8_t autn[16];
int i;
2017-02-24 01:50:49 +00:00
2017-03-03 03:57:19 +00:00
d_assert(msg, return EINVAL,);
2017-02-24 01:50:49 +00:00
2017-03-03 03:57:19 +00:00
/* Parse request message */
2017-02-24 01:50:49 +00:00
qry = *msg;
2017-03-02 13:47:43 +00:00
2017-03-03 03:57:19 +00:00
d_assert(fd_msg_search_avp(qry, s6a_user_name, &avp) && avp, goto out1,);
2017-03-02 13:47:43 +00:00
d_assert(fd_msg_avp_hdr(avp, &hdr) && hdr,,);
2017-03-03 03:57:19 +00:00
ue = hss_ue_ctx_find_by_imsi(
hdr->avp_value->os.data, hdr->avp_value->os.len);
d_assert(ue, goto out1,);
2017-03-02 13:47:43 +00:00
core_generate_random_bytes(ue->rand, MAX_KEY_LEN);
milenage_opc(ue->k, hss_self()->op, ue->opc);
milenage_f1(ue->opc, ue->k, ue->rand, core_uint64_to_array(seq, ue->seq),
hss_self()->amf, mac_a, NULL);
milenage_f2345(ue->opc, ue->k, ue->rand, xres, NULL, NULL, ak, NULL);
for ( i = 0; i < 6; i++)
autn[i] = seq[i] ^ ak[i];
memcpy(&autn[6], hss_self()->amf, 2);
memcpy(&autn[7], mac_a, 8);
ue->seq = (ue->seq + 32) & 0x7ffffffffff;
2017-02-24 01:50:49 +00:00
2017-03-03 03:57:19 +00:00
/* Create answer header */
d_assert(fd_msg_new_answer_from_req(fd_g_config->cnf_dict, msg, 0) == 0
&& *msg, goto out1,);
ans = *msg;
/* Set the Origin-Host, Origin-Realm, andResult-Code AVPs */
2017-02-28 12:55:19 +00:00
d_assert(fd_msg_rescode_set(ans, "DIAMETER_SUCCESS", NULL, NULL, 1) == 0,
2017-03-03 03:57:19 +00:00
goto out2,);
2017-02-28 15:21:20 +00:00
/* Set the Auth-Session-Statee AVP */
2017-03-03 03:57:19 +00:00
d_assert(fd_msg_avp_new(s6a_auth_session_state, 0, &avp) == 0, goto out2,);
2017-02-28 15:21:20 +00:00
val.i32 = 1;
2017-03-03 03:57:19 +00:00
d_assert(fd_msg_avp_setvalue(avp, &val) == 0, goto out2,);
d_assert(fd_msg_avp_add(ans, MSG_BRW_LAST_CHILD, avp) == 0, goto out2,);
2017-02-28 15:21:20 +00:00
/* Set the Authentication-Info */
2017-03-03 03:57:19 +00:00
d_assert(fd_msg_avp_new(s6a_authentication_info, 0, &avp) == 0, goto out2,);
d_assert(fd_msg_avp_new(s6a_e_utran_vector, 0, &avpch1) == 0, goto out2,);
2017-02-28 15:21:20 +00:00
#define TEST_RAND "RAND_123456"
2017-03-03 03:57:19 +00:00
d_assert(fd_msg_avp_new(s6a_rand, 0, &avpch2) == 0, goto out2,);
2017-02-28 15:21:20 +00:00
val.os.data = (unsigned char*)TEST_RAND;
val.os.len = strlen(TEST_RAND);
2017-03-03 03:57:19 +00:00
d_assert(fd_msg_avp_setvalue(avpch2, &val) == 0, goto out2,);
2017-02-28 15:21:20 +00:00
d_assert(fd_msg_avp_add(avpch1, MSG_BRW_LAST_CHILD, avpch2) == 0,
2017-03-03 03:57:19 +00:00
goto out2,);
2017-02-28 15:21:20 +00:00
#define TEST_XRES "XRES_123456"
2017-03-03 03:57:19 +00:00
d_assert(fd_msg_avp_new(s6a_xres, 0, &avpch2) == 0, goto out2,);
2017-02-28 15:21:20 +00:00
val.os.data = (unsigned char*)TEST_XRES;
val.os.len = strlen(TEST_XRES);
2017-03-03 03:57:19 +00:00
d_assert(fd_msg_avp_setvalue(avpch2, &val) == 0, goto out2,);
2017-02-28 15:21:20 +00:00
d_assert(fd_msg_avp_add(avpch1, MSG_BRW_LAST_CHILD, avpch2) == 0,
2017-03-03 03:57:19 +00:00
goto out2,);
2017-02-28 15:21:20 +00:00
#define TEST_AUTH "AUTH_123456"
2017-03-03 03:57:19 +00:00
d_assert(fd_msg_avp_new(s6a_autn, 0, &avpch2) == 0, goto out2,);
2017-02-28 15:21:20 +00:00
val.os.data = (unsigned char*)TEST_AUTH;
val.os.len = strlen(TEST_AUTH);
2017-03-03 03:57:19 +00:00
d_assert(fd_msg_avp_setvalue(avpch2, &val) == 0, goto out2,);
2017-02-28 15:21:20 +00:00
d_assert(fd_msg_avp_add(avpch1, MSG_BRW_LAST_CHILD, avpch2) == 0,
2017-03-03 03:57:19 +00:00
goto out2,);
2017-02-28 15:21:20 +00:00
#define TEST_KASME "KASME_123456"
2017-03-03 03:57:19 +00:00
d_assert(fd_msg_avp_new(s6a_kasme, 0, &avpch2) == 0, goto out2,);
2017-02-28 15:21:20 +00:00
val.os.data = (unsigned char*)TEST_KASME;
val.os.len = strlen(TEST_KASME);
2017-03-03 03:57:19 +00:00
d_assert(fd_msg_avp_setvalue(avpch2, &val) == 0, goto out2,);
2017-02-28 15:21:20 +00:00
d_assert(fd_msg_avp_add(avpch1, MSG_BRW_LAST_CHILD, avpch2) == 0,
2017-03-03 03:57:19 +00:00
goto out2,);
2017-02-28 15:21:20 +00:00
2017-03-03 03:57:19 +00:00
d_assert(fd_msg_avp_add(avp, MSG_BRW_LAST_CHILD, avpch1) == 0, goto out2,);
d_assert(fd_msg_avp_add(ans, MSG_BRW_LAST_CHILD, avp) == 0, goto out2,);
2017-02-24 01:50:49 +00:00
/* Send the answer */
2017-03-03 03:57:19 +00:00
d_assert(fd_msg_send(msg, NULL, NULL) == 0, goto out2,);
2017-02-24 01:50:49 +00:00
/* Add this value to the stats */
2017-02-28 12:55:19 +00:00
d_assert(pthread_mutex_lock(&s6a_config->stats_lock) == 0,,) ;
2017-02-28 02:21:10 +00:00
s6a_config->stats.nb_echoed++;
2017-02-28 12:55:19 +00:00
d_assert(pthread_mutex_unlock(&s6a_config->stats_lock) == 0,,);
d_assert(fd_msg_free(qry) == 0,,);
2017-02-24 01:50:49 +00:00
return 0;
2017-03-03 03:57:19 +00:00
out2:
2017-02-28 12:55:19 +00:00
d_assert(fd_msg_free(ans) == 0,,);
2017-03-03 03:57:19 +00:00
out1:
hss_auth_send_err_msg(msg);
d_assert(fd_msg_free(qry) == 0,,);
2017-02-28 12:55:19 +00:00
return -1;
2017-02-24 01:50:49 +00:00
}
2017-03-02 02:43:26 +00:00
int hss_init(void)
2017-02-24 01:50:49 +00:00
{
struct disp_when data;
2017-03-02 02:43:26 +00:00
hss_ctx_init();
/* FIXME : this is a sample UE for testing */
{
ue_ctx_t *ue;
2017-03-02 13:47:43 +00:00
char buf[MAX_KEY_LEN];
2017-03-02 02:43:26 +00:00
2017-03-02 05:18:24 +00:00
#define K "465B5CE8B199B49FAA5F0A2EE238A6BC"
2017-03-02 13:47:43 +00:00
#define UE1_IMSI "001010123456800"
#define UE2_IMSI "001010123456796"
2017-03-02 02:43:26 +00:00
ue = hss_ue_ctx_add();
d_assert(ue, return -1, "UE context add failed");
strcpy((char*)ue->imsi, UE1_IMSI);
ue->imsi_len = strlen(UE1_IMSI);
2017-03-02 13:47:43 +00:00
memcpy(ue->k, core_ascii_to_hex(K, strlen(K), buf), MAX_KEY_LEN);
2017-03-03 03:57:19 +00:00
ue->seq = 32;
2017-03-02 02:43:26 +00:00
ue = hss_ue_ctx_add();
d_assert(ue, return -1, "UE context add failed");
strcpy((char*)ue->imsi, UE2_IMSI);
ue->imsi_len = strlen(UE2_IMSI);
2017-03-02 13:47:43 +00:00
memcpy(ue->k, core_ascii_to_hex(K, strlen(K), buf), MAX_KEY_LEN);
2017-03-03 03:57:19 +00:00
ue->seq = 32;
2017-03-02 02:43:26 +00:00
}
2017-02-24 01:50:49 +00:00
memset(&data, 0, sizeof(data));
2017-02-27 14:01:15 +00:00
data.app = s6a_appli;
data.command = s6a_cmd_air;
2017-02-24 01:50:49 +00:00
2017-02-27 14:01:15 +00:00
/* fallback CB if command != unexpected message received */
2017-03-02 02:43:26 +00:00
d_assert(fd_disp_register(hss_fb_cb, DISP_HOW_APPID, &data, NULL,
&hss_hdl_fb) == 0, return -1,);
2017-02-24 01:50:49 +00:00
2017-02-27 14:01:15 +00:00
/* Now specific handler for Authentication-Information-Request */
2017-03-02 02:43:26 +00:00
d_assert(fd_disp_register(hss_air_cb, DISP_HOW_CC, &data, NULL,
&hss_hdl_tr) == 0, return -1,);
2017-02-24 01:50:49 +00:00
return 0;
}
2017-03-02 02:43:26 +00:00
void hss_final(void)
2017-02-24 01:50:49 +00:00
{
2017-03-02 02:43:26 +00:00
if (hss_hdl_fb) {
(void) fd_disp_unregister(&hss_hdl_fb, NULL);
2017-02-24 01:50:49 +00:00
}
2017-03-02 02:43:26 +00:00
if (hss_hdl_tr) {
(void) fd_disp_unregister(&hss_hdl_tr, NULL);
2017-02-24 01:50:49 +00:00
}
2017-03-02 02:43:26 +00:00
/* FIXME : this is a sample UE for testing */
{
hss_ue_ctx_remove_all();
}
hss_ctx_final();
2017-02-24 01:50:49 +00:00
return;
}