sgsn: Support subscriber based authentication
This commit mainly extends sgsn_auth.c to use and support the auth_state SGSN_AUTH_AUTHENTICATE. It will be activated when IMSI and IMEI are available, authentication is required (subscr->sgsn_data->authenticate is set), but the MM context is not marked as authenticated. If the state has been set to SGSN_AUTH_AUTHENTICATE and sgsn_auth_update() is called, the GMM layer will be informed by invoking gsm0408_gprs_authenticate(). Sponsored-by: On-Waves ehf
This commit is contained in:
parent
4adb136da6
commit
2e5e94c328
|
@ -272,8 +272,8 @@ struct imsi_acl_entry {
|
|||
};
|
||||
|
||||
struct sgsn_subscriber_data {
|
||||
struct sgsn_mm_ctx *mm;
|
||||
enum sgsn_auth_state auth_state;
|
||||
struct sgsn_mm_ctx *mm;
|
||||
int authenticate;
|
||||
};
|
||||
|
||||
struct sgsn_config;
|
||||
|
|
|
@ -110,6 +110,10 @@ enum sgsn_auth_state sgsn_auth_state(struct sgsn_mm_ctx *mmctx)
|
|||
if (mmctx->subscr->flags & GPRS_SUBSCRIBER_UPDATE_PENDING)
|
||||
return mmctx->auth_state;
|
||||
|
||||
if (mmctx->subscr->sgsn_data->authenticate &&
|
||||
!mmctx->is_authenticated)
|
||||
return SGSN_AUTH_AUTHENTICATE;
|
||||
|
||||
if (mmctx->subscr->authorized)
|
||||
return SGSN_AUTH_ACCEPTED;
|
||||
|
||||
|
@ -180,6 +184,9 @@ void sgsn_auth_update(struct sgsn_mm_ctx *mmctx)
|
|||
mmctx->auth_state = auth_state;
|
||||
|
||||
switch (auth_state) {
|
||||
case SGSN_AUTH_AUTHENTICATE:
|
||||
gsm0408_gprs_authenticate(mmctx);
|
||||
break;
|
||||
case SGSN_AUTH_ACCEPTED:
|
||||
gsm0408_gprs_access_granted(mmctx);
|
||||
break;
|
||||
|
|
|
@ -441,15 +441,15 @@ DEFUN(show_subscr_cache,
|
|||
"The IMSI\n"
|
||||
|
||||
DEFUN(update_subscr_insert, update_subscr_insert_cmd,
|
||||
UPDATE_SUBSCR_STR "insert authorized (0|1)",
|
||||
UPDATE_SUBSCR_STR "insert (authorized|authenticate) (0|1)",
|
||||
UPDATE_SUBSCR_HELP
|
||||
"Insert data into the subscriber record\n"
|
||||
"Authorize the subscriber to attach\n"
|
||||
"New option value\n")
|
||||
{
|
||||
const char *imsi = argv[0];
|
||||
const char *option = "authorized";
|
||||
const char *value = argv[1];
|
||||
const char *option = argv[1];
|
||||
const char *value = argv[2];
|
||||
|
||||
struct gsm_subscriber *subscr;
|
||||
|
||||
|
@ -461,6 +461,8 @@ DEFUN(update_subscr_insert, update_subscr_insert_cmd,
|
|||
|
||||
if (!strcmp(option, "authorized"))
|
||||
subscr->authorized = atoi(value);
|
||||
else
|
||||
subscr->sgsn_data->authenticate = atoi(value);
|
||||
|
||||
subscr_put(subscr);
|
||||
|
||||
|
|
|
@ -591,6 +591,60 @@ static void test_gmm_attach_subscr(void)
|
|||
subscr_request_update_cb = __real_gprs_subscr_request_update;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
static void test_gmm_attach_subscr_fake_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_cb = my_subscr_request_update_fake_auth;
|
||||
|
||||
subscr = gprs_subscr_get_or_create("123456789012345");
|
||||
subscr->authorized = 1;
|
||||
subscr->sgsn_data->authenticate = 1;
|
||||
subscr_put(subscr);
|
||||
|
||||
printf("Auth policy 'remote', auth faked: ");
|
||||
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_cb = __real_gprs_subscr_request_update;
|
||||
}
|
||||
|
||||
/*
|
||||
* Test the GMM Rejects
|
||||
*/
|
||||
|
@ -1112,6 +1166,7 @@ int main(int argc, char **argv)
|
|||
test_gmm_status_no_mmctx();
|
||||
test_gmm_attach_acl();
|
||||
test_gmm_attach_subscr();
|
||||
test_gmm_attach_subscr_fake_auth();
|
||||
test_gmm_reject();
|
||||
test_gmm_cancel();
|
||||
test_gmm_ptmsi_allocation();
|
||||
|
|
|
@ -7,6 +7,7 @@ Testing GMM detach accept (unexpected)
|
|||
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
|
||||
Testing GMM reject
|
||||
- Attach Request (invalid MI length)
|
||||
- Attach Request (invalid MI type)
|
||||
|
|
Loading…
Reference in New Issue