mirror of
				https://gitea.osmocom.org/cellular-infrastructure/osmo-mgw.git
				synced 2025-11-03 21:43:32 +00:00 
			
		
		
		
	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:
		
				
					committed by
					
						
						Holger Hans Peter Freyther
					
				
			
			
				
	
			
			
			
						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)
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user