update it

This commit is contained in:
Sukchan Lee 2017-03-04 23:21:05 +09:00
parent f6f5a45b21
commit 1f452fc851
8 changed files with 258 additions and 225 deletions

View File

@ -5,13 +5,14 @@ SUBDIRS = freeDiameter
noinst_LTLIBRARIES = libs6a.la
libs6a_la_SOURCES = \
hss_ctx.h hss_sm.h
milenage.h kasme.h \
s6a_app.h
nodist_libs6a_la_SOURCES = \
milenage.c kasme.c \
s6a_init.c s6a_config.c s6a_fd.c s6a_app.c s6a_dict.c \
hss_main.c hss_ctx.c \
hss_main.c hss_sm.c hss_ctx.c \
mme_init.c
libs6a_la_DEPENDENCIES = \

View File

@ -1,4 +1,4 @@
#define TRACE_MODULE _s6a_hss_ctx
#define TRACE_MODULE _hss_ctx
#include "core_debug.h"
#include "core_pool.h"

View File

@ -1,210 +1,26 @@
#define TRACE_MODULE _s6a_hss_init
#include "core_debug.h"
#include "core_pool.h"
#include "core_lib.h"
#include "kasme.h"
#include "milenage.h"
#define TRACE_MODULE _hss_init
#include "hss_ctx.h"
#include "hss_sm.h"
#include "s6a_app.h"
#define MAX_SQN_LEN 6
#define MAX_AK_LEN 6
#define MAX_XRES_LEN 8
#define MAX_KASME_LEN 32
static struct disp_hdl *hdl_fb = NULL; /* handler for fallback cb */
static struct disp_hdl *hdl_air = NULL; /* handler for Auth-Info-Request cb */
/* Default callback for the application. */
static int hss_fb_cb(struct msg **msg, struct avp *avp,
struct session *sess, void *opaque, enum disp_action *act)
{
/* This CB should never be called */
d_warn("Unexpected message received!");
return ENOTSUP;
}
/* Callback for incoming Test-Request messages */
static int hss_air_cb( struct msg **msg, struct avp *avp,
struct session *sess, void *opaque, enum disp_action *act)
{
struct msg *ans, *qry;
struct avp *avpch1, *avpch2;
struct avp_hdr *hdr;
union avp_value val;
ue_ctx_t *ue = NULL;
c_uint8_t sqn[MAX_SQN_LEN];
c_uint8_t autn[MAX_KEY_LEN];
c_uint8_t ik[MAX_KEY_LEN];
c_uint8_t ck[MAX_KEY_LEN];
c_uint8_t ak[MAX_AK_LEN];
c_uint8_t xres[MAX_XRES_LEN];
c_uint8_t kasme[MAX_KASME_LEN];
size_t xres_len = 8;
d_assert(msg, return EINVAL,);
/* Create answer header */
qry = *msg;
fd_msg_new_answer_from_req(fd_g_config->cnf_dict, msg, 0);
ans = *msg;
d_assert(fd_msg_search_avp(qry, s6a_user_name, &avp) == 0 && avp,
goto out,);
d_assert(fd_msg_avp_hdr(avp, &hdr) == 0 && hdr,,);
ue = hss_ue_ctx_find_by_imsi(
hdr->avp_value->os.data, hdr->avp_value->os.len);
if (!ue)
{
char imsi[MAX_IMSI_LEN];
strncpy(imsi, (char*)hdr->avp_value->os.data, hdr->avp_value->os.len);
d_warn("Cannot find IMSI:%s\n", imsi);
goto out;
}
d_assert(fd_msg_search_avp(qry, s6a_visited_plmn_id, &avp) == 0 &&
avp, goto out,);
d_assert(fd_msg_avp_hdr(avp, &hdr) == 0 && hdr,,);
core_generate_random_bytes(ue->rand, MAX_KEY_LEN);
milenage_opc(ue->k, ue->op, ue->opc);
milenage_generate(ue->opc, ue->amf, ue->k,
core_int_to_buffer(ue->sqn, sqn, MAX_SQN_LEN), ue->rand,
autn, ik, ck, ak, xres, &xres_len);
derive_kasme(ck, ik, hdr->avp_value->os.data, sqn, ak, kasme);
ue->sqn = (ue->sqn + 32) & 0x7ffffffffff;
/* Set the Origin-Host, Origin-Realm, andResult-Code AVPs */
d_assert(fd_msg_rescode_set(ans, "DIAMETER_SUCCESS", NULL, NULL, 1) == 0,
goto out,);
/* Set the Auth-Session-Statee AVP */
d_assert(fd_msg_avp_new(s6a_auth_session_state, 0, &avp) == 0, goto out,);
val.i32 = 1;
d_assert(fd_msg_avp_setvalue(avp, &val) == 0, goto out,);
d_assert(fd_msg_avp_add(ans, MSG_BRW_LAST_CHILD, avp) == 0, goto out,);
/* Set the Authentication-Info */
d_assert(fd_msg_avp_new(s6a_authentication_info, 0, &avp) == 0, goto out,);
d_assert(fd_msg_avp_new(s6a_e_utran_vector, 0, &avpch1) == 0, goto out,);
d_assert(fd_msg_avp_new(s6a_rand, 0, &avpch2) == 0, goto out,);
val.os.data = ue->rand;
val.os.len = MAX_KEY_LEN;
d_assert(fd_msg_avp_setvalue(avpch2, &val) == 0, goto out,);
d_assert(fd_msg_avp_add(avpch1, MSG_BRW_LAST_CHILD, avpch2) == 0,
goto out,);
d_assert(fd_msg_avp_new(s6a_xres, 0, &avpch2) == 0, goto out,);
val.os.data = xres;
val.os.len = xres_len;
d_assert(fd_msg_avp_setvalue(avpch2, &val) == 0, goto out,);
d_assert(fd_msg_avp_add(avpch1, MSG_BRW_LAST_CHILD, avpch2) == 0,
goto out,);
d_assert(fd_msg_avp_new(s6a_autn, 0, &avpch2) == 0, goto out,);
val.os.data = autn;
val.os.len = MAX_KEY_LEN;
d_assert(fd_msg_avp_setvalue(avpch2, &val) == 0, goto out,);
d_assert(fd_msg_avp_add(avpch1, MSG_BRW_LAST_CHILD, avpch2) == 0,
goto out,);
d_assert(fd_msg_avp_new(s6a_kasme, 0, &avpch2) == 0, goto out,);
val.os.data = kasme;
val.os.len = MAX_KASME_LEN;
d_assert(fd_msg_avp_setvalue(avpch2, &val) == 0, goto out,);
d_assert(fd_msg_avp_add(avpch1, MSG_BRW_LAST_CHILD, avpch2) == 0,
goto out,);
d_assert(fd_msg_avp_add(avp, MSG_BRW_LAST_CHILD, avpch1) == 0, goto out,);
d_assert(fd_msg_avp_add(ans, MSG_BRW_LAST_CHILD, avp) == 0, goto out,);
/* Send the answer */
fd_msg_send(msg, NULL, NULL);
/* Add this value to the stats */
pthread_mutex_lock(&s6a_config->stats_lock);
s6a_config->stats.nb_echoed++;
pthread_mutex_unlock(&s6a_config->stats_lock);
return 0;
out:
fd_msg_rescode_set(ans, "DIAMETER_AUTHENTICATION_REJECTED", NULL, NULL, 1);
fd_msg_send(msg, NULL, NULL);
return 0;
}
int hss_init(void)
{
struct disp_when data;
s6a_app_init(MODE_HSS);
hss_ctx_init();
hss_sm_init();
/* FIXME : this is a sample UE for testing */
{
ue_ctx_t *ue;
char buf[MAX_KEY_LEN];
#define K "465B5CE8B199B49FAA5F0A2EE238A6BC"
#define UE1_IMSI "001010123456800"
#define UE2_IMSI "001010123456796"
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);
memcpy(ue->k, core_ascii_to_hex(K, strlen(K), buf), MAX_KEY_LEN);
ue->sqn = 32;
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);
memcpy(ue->k, core_ascii_to_hex(K, strlen(K), buf), MAX_KEY_LEN);
ue->sqn = 32;
}
memset(&data, 0, sizeof(data));
data.app = s6a_appli;
data.command = s6a_cmd_air;
/* fallback CB if command != unexpected message received */
d_assert(fd_disp_register(hss_fb_cb, DISP_HOW_APPID, &data, NULL,
&hdl_fb) == 0, return -1,);
/* Now specific handler for Authentication-Information-Request */
d_assert(fd_disp_register(hss_air_cb, DISP_HOW_CC, &data, NULL,
&hdl_air) == 0, return -1,);
return 0;
}
void hss_final(void)
{
if (hdl_fb) {
(void) fd_disp_unregister(&hdl_fb, NULL);
}
if (hdl_air) {
(void) fd_disp_unregister(&hdl_air, NULL);
}
/* FIXME : this is a sample UE for testing */
{
hss_ue_ctx_remove_all();
}
hss_sm_init();
hss_ctx_final();
s6a_app_final();
return;
}

206
lib/s6a/hss_sm.c Normal file
View File

@ -0,0 +1,206 @@
#define TRACE_MODULE _hss_sm
#include "core_debug.h"
#include "core_pool.h"
#include "core_lib.h"
#include "kasme.h"
#include "milenage.h"
#include "hss_ctx.h"
#include "s6a_app.h"
#define MAX_SQN_LEN 6
#define MAX_AK_LEN 6
#define MAX_XRES_LEN 8
#define MAX_KASME_LEN 32
static struct disp_hdl *hdl_fb = NULL; /* handler for fallback cb */
static struct disp_hdl *hdl_air = NULL; /* handler for Auth-Info-Request cb */
/* Default callback for the application. */
static int hss_fb_cb(struct msg **msg, struct avp *avp,
struct session *sess, void *opaque, enum disp_action *act)
{
/* This CB should never be called */
d_warn("Unexpected message received!");
return ENOTSUP;
}
/* Callback for incoming Test-Request messages */
static int hss_air_cb( struct msg **msg, struct avp *avp,
struct session *sess, void *opaque, enum disp_action *act)
{
struct msg *ans, *qry;
struct avp *avpch1, *avpch2;
struct avp_hdr *hdr;
union avp_value val;
ue_ctx_t *ue = NULL;
c_uint8_t sqn[MAX_SQN_LEN];
c_uint8_t autn[MAX_KEY_LEN];
c_uint8_t ik[MAX_KEY_LEN];
c_uint8_t ck[MAX_KEY_LEN];
c_uint8_t ak[MAX_AK_LEN];
c_uint8_t xres[MAX_XRES_LEN];
c_uint8_t kasme[MAX_KASME_LEN];
size_t xres_len = 8;
d_assert(msg, return EINVAL,);
/* Create answer header */
qry = *msg;
fd_msg_new_answer_from_req(fd_g_config->cnf_dict, msg, 0);
ans = *msg;
d_assert(fd_msg_search_avp(qry, s6a_user_name, &avp) == 0 && avp,
goto out,);
d_assert(fd_msg_avp_hdr(avp, &hdr) == 0 && hdr,,);
ue = hss_ue_ctx_find_by_imsi(
hdr->avp_value->os.data, hdr->avp_value->os.len);
if (!ue)
{
char imsi[MAX_IMSI_LEN];
strncpy(imsi, (char*)hdr->avp_value->os.data, hdr->avp_value->os.len);
d_warn("Cannot find IMSI:%s\n", imsi);
goto out;
}
d_assert(fd_msg_search_avp(qry, s6a_visited_plmn_id, &avp) == 0 &&
avp, goto out,);
d_assert(fd_msg_avp_hdr(avp, &hdr) == 0 && hdr,,);
core_generate_random_bytes(ue->rand, MAX_KEY_LEN);
milenage_opc(ue->k, ue->op, ue->opc);
milenage_generate(ue->opc, ue->amf, ue->k,
core_int_to_buffer(ue->sqn, sqn, MAX_SQN_LEN), ue->rand,
autn, ik, ck, ak, xres, &xres_len);
derive_kasme(ck, ik, hdr->avp_value->os.data, sqn, ak, kasme);
ue->sqn = (ue->sqn + 32) & 0x7ffffffffff;
/* Set the Origin-Host, Origin-Realm, andResult-Code AVPs */
d_assert(fd_msg_rescode_set(ans, "DIAMETER_SUCCESS", NULL, NULL, 1) == 0,
goto out,);
/* Set the Auth-Session-Statee AVP */
d_assert(fd_msg_avp_new(s6a_auth_session_state, 0, &avp) == 0, goto out,);
val.i32 = 1;
d_assert(fd_msg_avp_setvalue(avp, &val) == 0, goto out,);
d_assert(fd_msg_avp_add(ans, MSG_BRW_LAST_CHILD, avp) == 0, goto out,);
/* Set the Authentication-Info */
d_assert(fd_msg_avp_new(s6a_authentication_info, 0, &avp) == 0, goto out,);
d_assert(fd_msg_avp_new(s6a_e_utran_vector, 0, &avpch1) == 0, goto out,);
d_assert(fd_msg_avp_new(s6a_rand, 0, &avpch2) == 0, goto out,);
val.os.data = ue->rand;
val.os.len = MAX_KEY_LEN;
d_assert(fd_msg_avp_setvalue(avpch2, &val) == 0, goto out,);
d_assert(fd_msg_avp_add(avpch1, MSG_BRW_LAST_CHILD, avpch2) == 0,
goto out,);
d_assert(fd_msg_avp_new(s6a_xres, 0, &avpch2) == 0, goto out,);
val.os.data = xres;
val.os.len = xres_len;
d_assert(fd_msg_avp_setvalue(avpch2, &val) == 0, goto out,);
d_assert(fd_msg_avp_add(avpch1, MSG_BRW_LAST_CHILD, avpch2) == 0,
goto out,);
d_assert(fd_msg_avp_new(s6a_autn, 0, &avpch2) == 0, goto out,);
val.os.data = autn;
val.os.len = MAX_KEY_LEN;
d_assert(fd_msg_avp_setvalue(avpch2, &val) == 0, goto out,);
d_assert(fd_msg_avp_add(avpch1, MSG_BRW_LAST_CHILD, avpch2) == 0,
goto out,);
d_assert(fd_msg_avp_new(s6a_kasme, 0, &avpch2) == 0, goto out,);
val.os.data = kasme;
val.os.len = MAX_KASME_LEN;
d_assert(fd_msg_avp_setvalue(avpch2, &val) == 0, goto out,);
d_assert(fd_msg_avp_add(avpch1, MSG_BRW_LAST_CHILD, avpch2) == 0,
goto out,);
d_assert(fd_msg_avp_add(avp, MSG_BRW_LAST_CHILD, avpch1) == 0, goto out,);
d_assert(fd_msg_avp_add(ans, MSG_BRW_LAST_CHILD, avp) == 0, goto out,);
/* Send the answer */
fd_msg_send(msg, NULL, NULL);
/* Add this value to the stats */
pthread_mutex_lock(&s6a_config->stats_lock);
s6a_config->stats.nb_echoed++;
pthread_mutex_unlock(&s6a_config->stats_lock);
return 0;
out:
fd_msg_rescode_set(ans, "DIAMETER_AUTHENTICATION_REJECTED", NULL, NULL, 1);
fd_msg_send(msg, NULL, NULL);
return 0;
}
int hss_sm_init(void)
{
struct disp_when data;
/* FIXME : this is a sample UE for testing */
{
ue_ctx_t *ue;
char buf[MAX_KEY_LEN];
#define K "465B5CE8B199B49FAA5F0A2EE238A6BC"
#define UE1_IMSI "001010123456800"
#define UE2_IMSI "001010123456796"
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);
memcpy(ue->k, core_ascii_to_hex(K, strlen(K), buf), MAX_KEY_LEN);
ue->sqn = 32;
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);
memcpy(ue->k, core_ascii_to_hex(K, strlen(K), buf), MAX_KEY_LEN);
ue->sqn = 32;
}
memset(&data, 0, sizeof(data));
data.app = s6a_appli;
data.command = s6a_cmd_air;
/* fallback CB if command != unexpected message received */
d_assert(fd_disp_register(hss_fb_cb, DISP_HOW_APPID, &data, NULL,
&hdl_fb) == 0, return -1,);
/* Now specific handler for Authentication-Information-Request */
d_assert(fd_disp_register(hss_air_cb, DISP_HOW_CC, &data, NULL,
&hdl_air) == 0, return -1,);
return 0;
}
void hss_sm_final(void)
{
if (hdl_fb) {
(void) fd_disp_unregister(&hdl_fb, NULL);
}
if (hdl_air) {
(void) fd_disp_unregister(&hdl_air, NULL);
}
/* FIXME : this is a sample UE for testing */
{
hss_ue_ctx_remove_all();
}
return;
}

15
lib/s6a/hss_sm.h Normal file
View File

@ -0,0 +1,15 @@
#ifndef __HSS_SM_H__
#define __HSS_SM_H__
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
CORE_DECLARE(int) hss_sm_init(void);
CORE_DECLARE(void) hss_sm_final(void);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* ! __HSS_SM_H__ */

View File

@ -8,6 +8,8 @@ struct session_handler *s6a_mme_reg = NULL;
int mme_init(void)
{
s6a_app_init(MODE_MME);
d_assert(fd_sess_handler_create(&s6a_mme_reg,
(void *)free, NULL, NULL) == 0, return -1,);
@ -17,4 +19,6 @@ int mme_init(void)
void mme_final(void)
{
d_assert(fd_sess_handler_destroy(&s6a_mme_reg, NULL) == 0,,);
s6a_app_final();
}

View File

@ -10,8 +10,8 @@ static void s6a_config_dump(void)
{
d_trace(1, "------- s6a configuration dump: ---------\n");
d_trace(1, " Mode ............... : %s%s\n",
s6a_config->mode & MODE_MME ? "MME" : "",
s6a_config->mode & MODE_HSS ? "HSS" : "");
s6a_config->mode == MODE_MME ? "MME" : "",
s6a_config->mode == MODE_HSS ? "HSS" : "");
d_trace(1, " Vendor Id .......... : %u\n", s6a_config->vendor_id);
d_trace(1, " Application Id ..... : %u\n", s6a_config->appli_id);
d_trace(1, " Duration ........... : %d(sec)\n", s6a_config->duration);
@ -55,12 +55,12 @@ static void * s6a_stats(void * arg)
(long)(now.tv_nsec + 1000000000 - start.tv_nsec) / 1000);
}
if (s6a_config->mode & MODE_HSS)
if (s6a_config->mode == MODE_HSS)
{
d_trace(1, " HSS: %llu message(s) echoed\n",
copy.nb_echoed);
}
if (s6a_config->mode & MODE_MME)
else if (s6a_config->mode == MODE_MME)
{
d_trace(1, " MME:\n");
d_trace(1, " %llu message(s) sent\n", copy.nb_sent);
@ -85,6 +85,14 @@ int s6a_app_init(int mode)
d_trace_level(&_s6a_app, 0);
/* Configure Application Mode(MME, HSS) */
if (mode == MODE_HSS)
{
CHECK_FCT( s6a_fd_init(s6a_hss_config()) );
}
else if (mode == MODE_MME)
{
CHECK_FCT( s6a_fd_init(s6a_mme_config()) );
}
s6a_config->mode = mode;
/* Initialize the mutex */
@ -95,33 +103,20 @@ int s6a_app_init(int mode)
/* Install objects definitions for this test application */
CHECK_FCT( s6a_dict_init() );
/* Start the signal handler thread */
if (s6a_config->mode & MODE_MME) {
CHECK_FCT( mme_init() );
}
/* Install the handlers for incoming messages */
if (s6a_config->mode & MODE_HSS) {
CHECK_FCT( hss_init() );
}
/* Advertise the support for the test application in the peer */
CHECK_FCT( fd_disp_app_support ( s6a_appli, s6a_vendor, 1, 0 ) );
/* Start the statistics thread */
CHECK_POSIX( pthread_create(&s6a_stats_th, NULL, s6a_stats, NULL) );
return 0;
}
/* Unload */
void s6a_app_final(void)
{
if (s6a_config->mode & MODE_MME)
mme_final();
if (s6a_config->mode & MODE_HSS)
hss_final();
CHECK_FCT_DO( fd_thr_term(&s6a_stats_th), );
CHECK_POSIX_DO( pthread_mutex_destroy(&s6a_config->stats_lock), );
s6a_fd_final();
}

View File

@ -14,6 +14,7 @@ static int check_signal(int signum);
int s6a_init()
{
status_t rv;
int ret;
semaphore_id semaphore;
rv = semaphore_create(&semaphore, 0);
@ -31,21 +32,18 @@ int s6a_init()
rv = semaphore_delete(semaphore);
d_assert(rv == CORE_OK, _exit(EXIT_FAILURE), "semaphore_delete() failed");
CHECK_FCT_DO(s6a_fd_init(s6a_hss_config()),
_exit(EXIT_FAILURE));
CHECK_FCT_DO(s6a_app_init(MODE_HSS), _exit(EXIT_FAILURE));
ret = hss_init();
if (ret != 0) _exit(EXIT_FAILURE);
signal_thread(check_signal);
s6a_final();
hss_final();
_exit(EXIT_SUCCESS);
}
/* Parent */
CHECK_FCT_DO(s6a_fd_init(s6a_mme_config()), return -1);
CHECK_FCT_DO(s6a_app_init(MODE_MME), return -1);
ret = mme_init();
if (ret != 0) return -1;
rv = semaphore_post(semaphore);
d_assert(rv == CORE_OK, return -1, "semaphore_post() failed");
@ -55,9 +53,7 @@ int s6a_init()
void s6a_final()
{
s6a_app_final();
s6a_fd_final();
mme_final();
core_kill(s6a_hss_pid, SIGTERM);
}