sgsn: Add a subscriber based authentication phase

This implements the MAP way of subscriber validation when the MS
tries to perform an Attach Request:

  1. perform authentication (optionally invoke the sendAuthInfo
     procedure), starts the Auth & Ciph procedure
  2. perform update location
  3. insert subscriber data
  4. finish the update location
  5. Attach Accept / Attach Reject

The authentication triplets are used and eventually updated if all of
them have been used.

This is currently accessible via the VTY interface by the following
commands:

  - update-subscriber imsi IMSI update-auth-info
  - update-subscriber imsi IMSI update-location-result (ok|ERR-CAUSE)

Sponsored-by: On-Waves ehf
This commit is contained in:
Jacob Erlbeck 2014-11-28 14:55:25 +01:00 committed by Holger Hans Peter Freyther
parent 7921ab1593
commit 98a95ac17f
7 changed files with 315 additions and 86 deletions

View File

@ -296,16 +296,25 @@ struct gsm_auth_tuple *sgsn_auth_get_tuple(struct sgsn_mm_ctx *mmctx,
/*
* GPRS subscriber data
*/
#define GPRS_SUBSCRIBER_UPDATE_PENDING (1 << 16)
#define GPRS_SUBSCRIBER_CANCELLED (1 << 17)
#define GPRS_SUBSCRIBER_UPDATE_AUTH_INFO_PENDING (1 << 16)
#define GPRS_SUBSCRIBER_UPDATE_LOCATION_PENDING (1 << 17)
#define GPRS_SUBSCRIBER_CANCELLED (1 << 18)
#define GPRS_SUBSCRIBER_UPDATE_PENDING_MASK ( \
GPRS_SUBSCRIBER_UPDATE_LOCATION_PENDING | \
GPRS_SUBSCRIBER_UPDATE_AUTH_INFO_PENDING \
)
void gprs_subscr_init(struct sgsn_instance *sgi);
int gprs_subscr_request_update(struct sgsn_mm_ctx *mmctx);
int gprs_subscr_request_update_location(struct sgsn_mm_ctx *mmctx);
int gprs_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx);
void gprs_subscr_delete(struct gsm_subscriber *subscr);
struct gsm_subscriber *gprs_subscr_get_or_create(const char *imsi);
struct gsm_subscriber *gprs_subscr_get_or_create_by_mmctx( struct sgsn_mm_ctx *mmctx);
struct gsm_subscriber *gprs_subscr_get_by_imsi(const char *imsi);
void gprs_subscr_put_and_cancel(struct gsm_subscriber *subscr);
void gprs_subscr_update(struct gsm_subscriber *subscr);
void gprs_subscr_update_auth_info(struct gsm_subscriber *subscr);
/* Called on subscriber data updates */
void sgsn_update_subscriber_data(struct sgsn_mm_ctx *mmctx,

View File

@ -92,9 +92,18 @@ void gprs_subscr_put_and_cancel(struct gsm_subscriber *subscr)
gprs_subscr_delete(subscr);
}
int gprs_subscr_query(struct gsm_subscriber *subscr)
int gprs_subscr_query_auth_info(struct gsm_subscriber *subscr)
{
/* TODO: Implement remote query to MSC, ... */
/* TODO: Implement remote query to HLR, ... */
LOGMMCTXP(LOGL_INFO, subscr->sgsn_data->mm,
"subscriber auth info is not available (remote query NYI)\n");
return -ENOTSUP;
}
int gprs_subscr_location_update(struct gsm_subscriber *subscr)
{
/* TODO: Implement remote query to HLR, ... */
LOGMMCTXP(LOGL_INFO, subscr->sgsn_data->mm,
"subscriber data is not available (remote query NYI)\n");
@ -105,56 +114,80 @@ void gprs_subscr_update(struct gsm_subscriber *subscr)
{
LOGMMCTXP(LOGL_DEBUG, subscr->sgsn_data->mm, "Updating subscriber data\n");
subscr->flags &= ~GPRS_SUBSCRIBER_UPDATE_PENDING;
subscr->flags &= ~GPRS_SUBSCRIBER_UPDATE_LOCATION_PENDING;
subscr->flags &= ~GSM_SUBSCRIBER_FIRST_CONTACT;
sgsn_update_subscriber_data(subscr->sgsn_data->mm, subscr);
}
int gprs_subscr_request_update(struct sgsn_mm_ctx *mmctx)
void gprs_subscr_update_auth_info(struct gsm_subscriber *subscr)
{
LOGMMCTXP(LOGL_DEBUG, subscr->sgsn_data->mm,
"Updating subscriber authentication info\n");
subscr->flags &= ~GPRS_SUBSCRIBER_UPDATE_AUTH_INFO_PENDING;
subscr->flags &= ~GSM_SUBSCRIBER_FIRST_CONTACT;
sgsn_update_subscriber_data(subscr->sgsn_data->mm, subscr);
}
struct gsm_subscriber *gprs_subscr_get_or_create_by_mmctx(struct sgsn_mm_ctx *mmctx)
{
struct gsm_subscriber *subscr = NULL;
int need_update = 0;
int rc;
LOGMMCTXP(LOGL_DEBUG, mmctx, "Requesting subscriber data update\n");
if (mmctx->subscr)
return subscr_get(mmctx->subscr);
if (mmctx->subscr) {
subscr = subscr_get(mmctx->subscr);
} else if (mmctx->imsi[0]) {
if (mmctx->imsi[0])
subscr = gprs_subscr_get_by_imsi(mmctx->imsi);
need_update = 1;
}
if (!subscr) {
subscr = gprs_subscr_get_or_create(mmctx->imsi);
subscr->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
need_update = 1;
}
if (strcpy(subscr->equipment.imei, mmctx->imei) != 0) {
strncpy(subscr->equipment.imei, mmctx->imei, GSM_IMEI_LENGTH-1);
subscr->equipment.imei[GSM_IMEI_LENGTH-1] = 0;
need_update = 1;
}
if (subscr->lac != mmctx->ra.lac) {
if (subscr->lac != mmctx->ra.lac)
subscr->lac = mmctx->ra.lac;
need_update = 1;
}
if (need_update) {
subscr->flags |= GPRS_SUBSCRIBER_UPDATE_PENDING;
if (!mmctx->subscr) {
subscr->sgsn_data->mm = mmctx;
mmctx->subscr = subscr_get(subscr);
}
subscr->sgsn_data->mm = mmctx;
mmctx->subscr = subscr_get(subscr);
rc = gprs_subscr_query(subscr);
subscr_put(subscr);
return rc;
}
gprs_subscr_update(subscr);
subscr_put(subscr);
return 0;
return subscr;
}
int gprs_subscr_request_update_location(struct sgsn_mm_ctx *mmctx)
{
struct gsm_subscriber *subscr = NULL;
int rc;
LOGMMCTXP(LOGL_DEBUG, mmctx, "Requesting subscriber data update\n");
subscr = gprs_subscr_get_or_create_by_mmctx(mmctx);
subscr->flags |= GPRS_SUBSCRIBER_UPDATE_LOCATION_PENDING;
rc = gprs_subscr_location_update(subscr);
subscr_put(subscr);
return rc;
}
int gprs_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx)
{
struct gsm_subscriber *subscr = NULL;
int rc;
LOGMMCTXP(LOGL_DEBUG, mmctx, "Requesting subscriber authentication info\n");
subscr = gprs_subscr_get_or_create_by_mmctx(mmctx);
subscr->flags |= GPRS_SUBSCRIBER_UPDATE_AUTH_INFO_PENDING;
rc = gprs_subscr_query_auth_info(subscr);
subscr_put(subscr);
return rc;
}

View File

@ -23,7 +23,7 @@
#include <openbsc/gprs_sgsn.h>
#include <openbsc/gprs_gmm.h>
#include <openbsc/gsm_subscriber.h>
#include <openbsc/gsm_04_08_gprs.h>
#include <openbsc/debug.h>
const struct value_string auth_state_names[] = {
@ -107,11 +107,12 @@ enum sgsn_auth_state sgsn_auth_state(struct sgsn_mm_ctx *mmctx)
if (!mmctx->subscr)
return mmctx->auth_state;
if (mmctx->subscr->flags & GPRS_SUBSCRIBER_UPDATE_PENDING)
if (mmctx->subscr->flags & GPRS_SUBSCRIBER_UPDATE_PENDING_MASK)
return mmctx->auth_state;
if (mmctx->subscr->sgsn_data->authenticate &&
!mmctx->is_authenticated)
(!mmctx->is_authenticated ||
mmctx->subscr->sgsn_data->auth_triplets_updated))
return SGSN_AUTH_AUTHENTICATE;
if (mmctx->subscr->authorized)
@ -141,20 +142,60 @@ enum sgsn_auth_state sgsn_auth_state(struct sgsn_mm_ctx *mmctx)
return SGSN_AUTH_REJECTED;
}
/*
* This function is directly called by e.g. the GMM layer. It returns either
* after calling sgsn_auth_update directly or after triggering an asynchronous
* procedure which will call sgsn_auth_update later on.
*/
int sgsn_auth_request(struct sgsn_mm_ctx *mmctx)
{
struct gsm_subscriber *subscr;
struct gsm_auth_tuple *at;
int need_update_location;
int rc;
LOGMMCTXP(LOGL_DEBUG, mmctx, "Requesting authorization\n");
if (sgsn->cfg.auth_policy == SGSN_AUTH_POLICY_REMOTE && !mmctx->subscr) {
if (gprs_subscr_request_update(mmctx) >= 0) {
if (sgsn->cfg.auth_policy != SGSN_AUTH_POLICY_REMOTE) {
sgsn_auth_update(mmctx);
return 0;
}
need_update_location =
mmctx->subscr == NULL ||
mmctx->pending_req == GSM48_MT_GMM_ATTACH_REQ;
/* This has the side effect of registering the subscr with the mmctx */
subscr = gprs_subscr_get_or_create_by_mmctx(mmctx);
subscr_put(subscr);
OSMO_ASSERT(mmctx->subscr != NULL);
if (mmctx->subscr->sgsn_data->authenticate && !mmctx->is_authenticated) {
/* Find next tuple */
at = sgsn_auth_get_tuple(mmctx, mmctx->auth_triplet.key_seq);
if (!at) {
/* No valid tuple found, request fresh ones */
mmctx->auth_triplet.key_seq = GSM_KEY_SEQ_INVAL;
LOGMMCTXP(LOGL_INFO, mmctx,
"Missing information, requesting subscriber data\n");
return 0;
"Requesting authentication tuples\n");
rc = gprs_subscr_request_auth_info(mmctx);
if (rc >= 0)
return 0;
return rc;
}
mmctx->auth_triplet = *at;
} else if (need_update_location) {
LOGMMCTXP(LOGL_INFO, mmctx,
"Missing information, requesting subscriber data\n");
if (gprs_subscr_request_update_location(mmctx) >= 0)
return 0;
}
sgsn_auth_update(mmctx);
return 0;
}
@ -162,6 +203,7 @@ void sgsn_auth_update(struct sgsn_mm_ctx *mmctx)
{
enum sgsn_auth_state auth_state;
struct gsm_subscriber *subscr = mmctx->subscr;
struct gsm_auth_tuple *at;
auth_state = sgsn_auth_state(mmctx);
@ -170,13 +212,27 @@ void sgsn_auth_update(struct sgsn_mm_ctx *mmctx)
get_value_string(sgsn_auth_state_names, auth_state));
if (auth_state == SGSN_AUTH_UNKNOWN && subscr &&
!(subscr->flags & GPRS_SUBSCRIBER_UPDATE_PENDING)) {
/* Reject requests if gprs_subscr_request_update fails */
!(subscr->flags & GPRS_SUBSCRIBER_UPDATE_PENDING_MASK)) {
/* Reject requests if gprs_subscr_request_update_location fails */
LOGMMCTXP(LOGL_ERROR, mmctx,
"Missing information, authorization not possible\n");
auth_state = SGSN_AUTH_REJECTED;
}
if (auth_state == SGSN_AUTH_AUTHENTICATE &&
mmctx->auth_triplet.key_seq == GSM_KEY_SEQ_INVAL) {
/* The current tuple is not valid, but we are possibly called
* because new auth tuples have been received */
at = sgsn_auth_get_tuple(mmctx, mmctx->auth_triplet.key_seq);
if (!at) {
LOGMMCTXP(LOGL_ERROR, mmctx,
"Missing auth tuples, authorization not possible\n");
auth_state = SGSN_AUTH_REJECTED;
} else {
mmctx->auth_triplet = *at;
}
}
if (mmctx->auth_state == auth_state)
return;
@ -188,6 +244,9 @@ void sgsn_auth_update(struct sgsn_mm_ctx *mmctx)
switch (auth_state) {
case SGSN_AUTH_AUTHENTICATE:
if (subscr)
subscr->sgsn_data->auth_triplets_updated = 0;
gsm0408_gprs_authenticate(mmctx);
break;
case SGSN_AUTH_ACCEPTED:

View File

@ -428,13 +428,15 @@ static void subscr_dump_full_vty(struct vty *vty, struct gsm_subscriber *subscr,
}
if (subscr->flags)
vty_out(vty, " Flags: %s%s%s%s",
vty_out(vty, " Flags: %s%s%s%s%s",
subscr->flags & GSM_SUBSCRIBER_FIRST_CONTACT ?
"FIRST_CONTACT " : "",
subscr->flags & GPRS_SUBSCRIBER_CANCELLED ?
"CANCELLED " : "",
subscr->flags & GPRS_SUBSCRIBER_UPDATE_PENDING ?
"UPDATE_PENDING " : "",
subscr->flags & GPRS_SUBSCRIBER_UPDATE_LOCATION_PENDING ?
"UPDATE_LOCATION_PENDING " : "",
subscr->flags & GPRS_SUBSCRIBER_UPDATE_AUTH_INFO_PENDING ?
"AUTH_INFO_PENDING " : "",
VTY_NEWLINE);
vty_out(vty, " Use count: %u%s", subscr->use_count, VTY_NEWLINE);
@ -587,6 +589,68 @@ DEFUN(update_subscr_commit, update_subscr_commit_cmd,
return CMD_SUCCESS;
}
#define UL_ERR_STR "system-failure|data-missing|unexpected-data-value|" \
"unknown-subscriber|roaming-not-allowed"
#define UL_ERR_HELP \
"Force error code SystemFailure\n" \
"Force error code DataMissing\n" \
"Force error code UnexpectedDataValue\n" \
"Force error code UnknownSubscriber\n" \
"Force error code RoamingNotAllowed\n"
DEFUN(update_subscr_update_location_result, update_subscr_update_location_result_cmd,
UPDATE_SUBSCR_STR "update-location-result (ok|" UL_ERR_STR ")",
UPDATE_SUBSCR_HELP
"Complete the update location procedure\n"
"The update location request succeeded\n"
UL_ERR_HELP)
{
const char *imsi = argv[0];
const char *ret_code_str = argv[1];
struct gsm_subscriber *subscr;
subscr = gprs_subscr_get_by_imsi(imsi);
if (!subscr) {
vty_out(vty, "%% unable to get subscriber record for %s\n", imsi);
return CMD_WARNING;
}
if (strcmp(ret_code_str, "ok") == 0)
subscr->authorized = 1;
else
subscr->authorized = 0;
gprs_subscr_update(subscr);
subscr_put(subscr);
return CMD_SUCCESS;
}
DEFUN(update_subscr_update_auth_info, update_subscr_update_auth_info_cmd,
UPDATE_SUBSCR_STR "update-auth-info",
UPDATE_SUBSCR_HELP
"Complete the send authentication info procedure\n")
{
const char *imsi = argv[0];
struct gsm_subscriber *subscr;
subscr = gprs_subscr_get_by_imsi(imsi);
if (!subscr) {
vty_out(vty, "%% unable to get subscriber record for %s\n", imsi);
return CMD_WARNING;
}
gprs_subscr_update_auth_info(subscr);
subscr_put(subscr);
return CMD_SUCCESS;
}
int sgsn_vty_init(void)
{
install_element_ve(&show_sgsn_cmd);
@ -600,6 +664,8 @@ int sgsn_vty_init(void)
install_element(ENABLE_NODE, &update_subscr_insert_auth_triplet_cmd);
install_element(ENABLE_NODE, &update_subscr_cancel_cmd);
install_element(ENABLE_NODE, &update_subscr_commit_cmd);
install_element(ENABLE_NODE, &update_subscr_update_location_result_cmd);
install_element(ENABLE_NODE, &update_subscr_update_auth_info_cmd);
install_element(CONFIG_NODE, &cfg_sgsn_cmd);
install_node(&sgsn_node, config_write_sgsn);

View File

@ -8,7 +8,8 @@ noinst_PROGRAMS = sgsn_test
sgsn_test_SOURCES = sgsn_test.c
sgsn_test_LDFLAGS = \
-Wl,--wrap=sgsn_update_subscriber_data \
-Wl,--wrap=gprs_subscr_request_update
-Wl,--wrap=gprs_subscr_request_update_location \
-Wl,--wrap=gprs_subscr_request_auth_info
sgsn_test_LDADD = \
$(top_builddir)/src/gprs/gprs_llc_parse.o \

View File

@ -67,13 +67,22 @@ void __wrap_sgsn_update_subscriber_data(struct sgsn_mm_ctx *mmctx,
(*update_subscriber_data_cb)(mmctx, subscr);
}
/* override, requires '-Wl,--wrap=gprs_subscr_request_update' */
int __real_gprs_subscr_request_update(struct sgsn_mm_ctx *mmctx);
int (*subscr_request_update_cb)(struct sgsn_mm_ctx *mmctx) =
&__real_gprs_subscr_request_update;
/* override, requires '-Wl,--wrap=gprs_subscr_request_update_location' */
int __real_gprs_subscr_request_update_location(struct sgsn_mm_ctx *mmctx);
int (*subscr_request_update_location_cb)(struct sgsn_mm_ctx *mmctx) =
&__real_gprs_subscr_request_update_location;
int __wrap_gprs_subscr_request_update(struct sgsn_mm_ctx *mmctx) {
return (*subscr_request_update_cb)(mmctx);
int __wrap_gprs_subscr_request_update_location(struct sgsn_mm_ctx *mmctx) {
return (*subscr_request_update_location_cb)(mmctx);
};
/* override, requires '-Wl,--wrap=gprs_subscr_request_auth_info' */
int __real_gprs_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx);
int (*subscr_request_auth_info_cb)(struct sgsn_mm_ctx *mmctx) =
&__real_gprs_subscr_request_auth_info;
int __wrap_gprs_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx) {
return (*subscr_request_auth_info_cb)(mmctx);
};
static int count(struct llist_head *head)
@ -525,6 +534,12 @@ static void test_gmm_attach(void)
0x54
};
/* DTAP - Authentication and Ciphering Resp */
static const unsigned char auth_ciph_resp[] = {
0x08, 0x13, 0x00, 0x22, 0x51, 0xe5, 0x51, 0xe5, 0x23, 0x09,
0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x01
};
/* DTAP - Attach Complete */
static const unsigned char attach_compl[] = {
0x08, 0x03
@ -584,6 +599,19 @@ static void test_gmm_attach(void)
OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
if (ctx->auth_state == SGSN_AUTH_AUTHENTICATE) {
/* we expect an auth & ciph request */
OSMO_ASSERT(sgsn_tx_counter == 1);
/* inject the auth & ciph response */
send_0408_message(ctx->llme, foreign_tlli,
auth_ciph_resp, ARRAY_SIZE(auth_ciph_resp));
/* check that the MM context has not been removed due to a
* failed authorization */
OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
}
/* we expect an attach accept/reject */
OSMO_ASSERT(sgsn_tx_counter == 1);
@ -622,9 +650,9 @@ static void test_gmm_attach_acl(void)
sgsn->cfg.auth_policy = saved_auth_policy;
}
int my_subscr_request_update(struct sgsn_mm_ctx *mmctx) {
int my_subscr_request_update_location(struct sgsn_mm_ctx *mmctx) {
int rc;
rc = __real_gprs_subscr_request_update(mmctx);
rc = __real_gprs_subscr_request_update_location(mmctx);
if (rc == -ENOTSUP) {
OSMO_ASSERT(mmctx->subscr);
gprs_subscr_update(mmctx->subscr);
@ -632,13 +660,19 @@ int my_subscr_request_update(struct sgsn_mm_ctx *mmctx) {
return rc;
};
int my_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx) {
gprs_subscr_update(mmctx->subscr);
return 0;
};
static void test_gmm_attach_subscr(void)
{
const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
struct gsm_subscriber *subscr;
sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
subscr_request_update_cb = my_subscr_request_update;
subscr_request_update_location_cb = my_subscr_request_update_location;
subscr_request_auth_info_cb = my_subscr_request_auth_info;
subscr = gprs_subscr_get_or_create("123456789012345");
subscr->authorized = 1;
@ -652,37 +686,18 @@ static void test_gmm_attach_subscr(void)
gprs_subscr_delete(subscr);
sgsn->cfg.auth_policy = saved_auth_policy;
subscr_request_update_cb = __real_gprs_subscr_request_update;
subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
}
int my_subscr_request_update_fake_auth(struct sgsn_mm_ctx *mmctx) {
int rc;
rc = __real_gprs_subscr_request_update(mmctx);
if (rc == -ENOTSUP) {
struct gsm_subscriber *subscr;
int old_sgsn_tx_counter = sgsn_tx_counter;
int my_subscr_request_auth_info_fake_auth(struct sgsn_mm_ctx *mmctx)
{
/* Fake an authentication */
OSMO_ASSERT(mmctx->subscr);
mmctx->is_authenticated = 1;
gprs_subscr_update_auth_info(mmctx->subscr);
OSMO_ASSERT(mmctx->subscr);
/* Prevent subscr from being deleted */
subscr = subscr_get(mmctx->subscr);
/* Start authentication procedure */
gprs_subscr_update(subscr);
/* This will cause a GPRS AUTH AND CIPHERING REQ (cksn broken) */
OSMO_ASSERT(old_sgsn_tx_counter == sgsn_tx_counter - 1);
/* Restore sgsn_tx_counter to keep test_gmm_attach happy */
sgsn_tx_counter = old_sgsn_tx_counter;
/* Fake an authentication */
OSMO_ASSERT(subscr->sgsn_data->mm);
subscr->sgsn_data->mm->is_authenticated = 1;
gprs_subscr_update(subscr);
subscr_put(subscr);
}
return rc;
return 0;
};
static void test_gmm_attach_subscr_fake_auth(void)
@ -691,7 +706,8 @@ static void test_gmm_attach_subscr_fake_auth(void)
struct gsm_subscriber *subscr;
sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
subscr_request_update_cb = my_subscr_request_update_fake_auth;
subscr_request_update_location_cb = my_subscr_request_update_location;
subscr_request_auth_info_cb = my_subscr_request_auth_info_fake_auth;
subscr = gprs_subscr_get_or_create("123456789012345");
subscr->authorized = 1;
@ -706,7 +722,50 @@ static void test_gmm_attach_subscr_fake_auth(void)
gprs_subscr_delete(subscr);
sgsn->cfg.auth_policy = saved_auth_policy;
subscr_request_update_cb = __real_gprs_subscr_request_update;
subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
}
int my_subscr_request_auth_info_real_auth(struct sgsn_mm_ctx *mmctx)
{
struct gsm_auth_tuple at = {
.sres = {0x51, 0xe5, 0x51, 0xe5},
.key_seq = 0
};
/* Fake an authentication */
OSMO_ASSERT(mmctx->subscr);
mmctx->subscr->sgsn_data->auth_triplets[0] = at;
gprs_subscr_update_auth_info(mmctx->subscr);
return 0;
};
static void test_gmm_attach_subscr_real_auth(void)
{
const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
struct gsm_subscriber *subscr;
sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
subscr_request_update_location_cb = my_subscr_request_update_location;
subscr_request_auth_info_cb = my_subscr_request_auth_info_real_auth;
subscr = gprs_subscr_get_or_create("123456789012345");
subscr->authorized = 1;
subscr->sgsn_data->authenticate = 1;
subscr_put(subscr);
printf("Auth policy 'remote', triplet based auth: ");
test_gmm_attach();
subscr = gprs_subscr_get_by_imsi("123456789012345");
OSMO_ASSERT(subscr != NULL);
gprs_subscr_delete(subscr);
sgsn->cfg.auth_policy = saved_auth_policy;
subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
}
/*
@ -1232,6 +1291,7 @@ int main(int argc, char **argv)
test_gmm_attach_acl();
test_gmm_attach_subscr();
test_gmm_attach_subscr_fake_auth();
test_gmm_attach_subscr_real_auth();
test_gmm_reject();
test_gmm_cancel();
test_gmm_ptmsi_allocation();

View File

@ -9,6 +9,7 @@ Testing GMM Status (no MMCTX)
Auth policy 'closed': Testing GMM attach
Auth policy 'remote': Testing GMM attach
Auth policy 'remote', auth faked: Testing GMM attach
Auth policy 'remote', triplet based auth: Testing GMM attach
Testing GMM reject
- Attach Request (invalid MI length)
- Attach Request (invalid MI type)