diff options
author | Jacob Erlbeck <jerlbeck@sysmocom.de> | 2014-11-12 10:18:09 +0100 |
---|---|---|
committer | Holger Hans Peter Freyther <holger@moiji-mobile.com> | 2014-12-09 09:27:20 +0100 |
commit | be2c8d9358084092281e7d02dc7ae0b7e4c0b4f8 (patch) | |
tree | 447342f2c1aac8287c5538c22191e1cd06baf9b3 /openbsc/src | |
parent | 33b6dadc884ec1060e401ba097523086ac34b552 (diff) |
sgsn: Integrate subscriber handling into the SGSN
This commit adds a new authorization policy 'remote' and uses
the subscriber cache for authorization when this policy is being used.
Note that there is no remote backend implemented yet. After the
IMSI/IMEI have been acquired, a request would be sent to the remote
peer. The attach/auth-ciph procedure continues when authorization
info has been received from the peer. This means, that
gprs_subscr_update() must be called then to tell the GMM layer
that it can proceed. A later commit will add VTY commands to do this
manually.
Sponsored-by: On-Waves ehf
Diffstat (limited to 'openbsc/src')
-rw-r--r-- | openbsc/src/gprs/gprs_sgsn.c | 27 | ||||
-rw-r--r-- | openbsc/src/gprs/sgsn_auth.c | 29 | ||||
-rw-r--r-- | openbsc/src/gprs/sgsn_vty.c | 8 |
3 files changed, 57 insertions, 7 deletions
diff --git a/openbsc/src/gprs/gprs_sgsn.c b/openbsc/src/gprs/gprs_sgsn.c index 71cd742df..525bfab11 100644 --- a/openbsc/src/gprs/gprs_sgsn.c +++ b/openbsc/src/gprs/gprs_sgsn.c @@ -187,6 +187,14 @@ void sgsn_mm_ctx_free(struct sgsn_mm_ctx *mm) osmo_timer_del(&mm->timer); } + /* Detach from subscriber which is possibly freed then */ + if (mm->subscr) { + struct gsm_subscriber *subscr = mm->subscr; + mm->subscr = NULL; + subscr->mm = NULL; + gprs_subscr_delete(subscr); + } + /* Unlink from global list of MM contexts */ llist_del(&mm->list); @@ -455,7 +463,24 @@ int sgsn_force_reattach_oldmsg(struct msgb *oldmsg) void sgsn_update_subscriber_data(struct sgsn_mm_ctx *mmctx, struct gsm_subscriber *subscr) { - OSMO_ASSERT(mmctx); + if (!mmctx && subscr && strlen(subscr->imsi) > 0) { + mmctx = sgsn_mm_ctx_by_imsi(subscr->imsi); + OSMO_ASSERT(!mmctx || !mmctx->subscr || mmctx->subscr == subscr); + } + + if (!mmctx) { + LOGP(DMM, LOGL_INFO, + "Subscriber data update for unregistered MM context, IMSI %s\n", + subscr->imsi); + return; + } + + LOGMMCTXP(LOGL_INFO, mmctx, "Subscriber data update"); + + if (!subscr->mm && !mmctx->subscr) { + mmctx->subscr = subscr_get(subscr); + mmctx->subscr->mm = mmctx; + } sgsn_auth_update(mmctx); } diff --git a/openbsc/src/gprs/sgsn_auth.c b/openbsc/src/gprs/sgsn_auth.c index eb85d45fb..071bdab84 100644 --- a/openbsc/src/gprs/sgsn_auth.c +++ b/openbsc/src/gprs/sgsn_auth.c @@ -22,6 +22,7 @@ #include <openbsc/sgsn.h> #include <openbsc/gprs_sgsn.h> #include <openbsc/gprs_gmm.h> +#include <openbsc/gsm_subscriber.h> #include <openbsc/debug.h> @@ -101,6 +102,18 @@ enum sgsn_auth_state sgsn_auth_state(struct sgsn_mm_ctx *mmctx) case SGSN_AUTH_POLICY_ACL_ONLY: check_acl = 1; break; + + case SGSN_AUTH_POLICY_REMOTE: + if (!mmctx->subscr) + return mmctx->auth_state; + + if (mmctx->subscr->flags & GPRS_SUBSCRIBER_UPDATE_PENDING) + return mmctx->auth_state; + + if (mmctx->subscr->authorized) + return SGSN_AUTH_ACCEPTED; + + return SGSN_AUTH_REJECTED; } if (!strlen(mmctx->imsi)) { @@ -126,7 +139,15 @@ enum sgsn_auth_state sgsn_auth_state(struct sgsn_mm_ctx *mmctx) int sgsn_auth_request(struct sgsn_mm_ctx *mmctx) { - /* TODO: Add remote subscriber update requests here */ + 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) { + LOGMMCTXP(LOGL_INFO, mmctx, + "Missing information, requesting subscriber data\n"); + return 0; + } + } sgsn_auth_update(mmctx); @@ -136,12 +157,14 @@ int sgsn_auth_request(struct sgsn_mm_ctx *mmctx) void sgsn_auth_update(struct sgsn_mm_ctx *mmctx) { enum sgsn_auth_state auth_state; + struct gsm_subscriber *subscr = mmctx->subscr; LOGMMCTXP(LOGL_DEBUG, mmctx, "Updating authorization\n"); auth_state = sgsn_auth_state(mmctx); - if (auth_state == SGSN_AUTH_UNKNOWN) { - /* Reject requests since remote updates are NYI */ + if (auth_state == SGSN_AUTH_UNKNOWN && subscr && + !(subscr->flags & GPRS_SUBSCRIBER_UPDATE_PENDING)) { + /* Reject requests if gprs_subscr_request_update fails */ LOGMMCTXP(LOGL_ERROR, mmctx, "Missing information, authorization not possible\n"); auth_state = SGSN_AUTH_REJECTED; diff --git a/openbsc/src/gprs/sgsn_vty.c b/openbsc/src/gprs/sgsn_vty.c index 63816710e..5fb230f4c 100644 --- a/openbsc/src/gprs/sgsn_vty.c +++ b/openbsc/src/gprs/sgsn_vty.c @@ -45,6 +45,7 @@ const struct value_string sgsn_auth_pol_strs[] = { { SGSN_AUTH_POLICY_OPEN, "accept-all" }, { SGSN_AUTH_POLICY_CLOSED, "closed" }, { SGSN_AUTH_POLICY_ACL_ONLY, "acl-only" }, + { SGSN_AUTH_POLICY_REMOTE, "remote" }, { 0, NULL } }; @@ -358,14 +359,15 @@ DEFUN(imsi_acl, cfg_imsi_acl_cmd, } DEFUN(cfg_auth_policy, cfg_auth_policy_cmd, - "auth-policy (accept-all|closed|acl-only)", + "auth-policy (accept-all|closed|acl-only|remote)", "Autorization Policy of SGSN\n" "Accept all IMSIs (DANGEROUS)\n" "Accept only home network subscribers or those in the ACL\n" - "Accept only subscribers in the ACL\n") + "Accept only subscribers in the ACL\n" + "Use remote subscription data only (HLR)\n") { int val = get_string_value(sgsn_auth_pol_strs, argv[0]); - OSMO_ASSERT(val >= SGSN_AUTH_POLICY_OPEN && val <= SGSN_AUTH_POLICY_ACL_ONLY); + OSMO_ASSERT(val >= SGSN_AUTH_POLICY_OPEN && val <= SGSN_AUTH_POLICY_REMOTE); g_cfg->auth_policy = val; return CMD_SUCCESS; |