diff options
author | Jacob Erlbeck <jerlbeck@sysmocom.de> | 2014-12-01 12:44:24 +0100 |
---|---|---|
committer | Holger Hans Peter Freyther <holger@moiji-mobile.com> | 2014-12-08 10:51:38 +0100 |
commit | 8ff3fb04f2e3ea192cb337c8a6dcee19fe40060a (patch) | |
tree | 77e3c9e7323d666a12f40f024d0a70a08962bcc0 | |
parent | bd0cf1190a839bbaad38b86157eaa13b7c3f7ec4 (diff) |
sgsn: Do authentication based on SRES values
Currently the SRES value in the Auth & Ciph Response is ignored.
This patch checks the SRES value in response against the value stored
in mm->auth_triplet.sres. If they don't match, an Auth & Ciph Reject
message is sent to the MS. If they match, the mm->is_authenticated
flag is set.
Note that the procedure will not be started yet.
Sponsored-by: On-Waves ehf
-rw-r--r-- | openbsc/include/openbsc/gprs_sgsn.h | 1 | ||||
-rw-r--r-- | openbsc/src/gprs/gprs_gmm.c | 34 |
2 files changed, 33 insertions, 2 deletions
diff --git a/openbsc/include/openbsc/gprs_sgsn.h b/openbsc/include/openbsc/gprs_sgsn.h index 1ffeb9fe7..3e80ae21f 100644 --- a/openbsc/include/openbsc/gprs_sgsn.h +++ b/openbsc/include/openbsc/gprs_sgsn.h @@ -130,6 +130,7 @@ struct sgsn_mm_ctx { * whether one of them can be dropped. */ enum sgsn_auth_state auth_state; + int is_authenticated; struct gsm_subscriber *subscr; }; diff --git a/openbsc/src/gprs/gprs_gmm.c b/openbsc/src/gprs/gprs_gmm.c index 6f54194b6..60a17ce95 100644 --- a/openbsc/src/gprs/gprs_gmm.c +++ b/openbsc/src/gprs/gprs_gmm.c @@ -600,6 +600,16 @@ static int gsm48_rx_gmm_auth_ciph_resp(struct sgsn_mm_ctx *ctx, struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_gmmh(msg); struct gsm48_auth_ciph_resp *acr = (struct gsm48_auth_ciph_resp *)gh->data; struct tlv_parsed tp; + struct gsm_auth_tuple *at; + int rc; + + LOGMMCTXP(LOGL_INFO, ctx, "-> GPRS AUTH AND CIPH RESPONSE\n"); + + if (ctx->auth_triplet.key_seq == GSM_KEY_SEQ_INVAL) { + LOGMMCTXP(LOGL_NOTICE, ctx, + "Unexpected Auth & Ciph Response (ignored)\n"); + return 0; + } /* Stop T3360 */ mmctx_timer_stop(ctx, 3360); @@ -611,10 +621,30 @@ static int gsm48_rx_gmm_auth_ciph_resp(struct sgsn_mm_ctx *ctx, if (!TLVP_PRESENT(&tp, GSM48_IE_GMM_AUTH_SRES) || !TLVP_PRESENT(&tp, GSM48_IE_GMM_IMEISV)) { - /* FIXME: missing mandatory IE */ + /* TODO: missing mandatory IE, return STATUS or REJ? */ + LOGMMCTXP(LOGL_ERROR, ctx, "Missing mandantory IE\n"); + return -EINVAL; } - /* FIXME: compare SRES with what we expected */ + /* Compare SRES with what we expected */ + LOGMMCTXP(LOGL_DEBUG, ctx, "checking received auth info, SRES = %s\n", + osmo_hexdump(TLVP_VAL(&tp, GSM48_IE_GMM_AUTH_SRES), + TLVP_LEN(&tp, GSM48_IE_GMM_AUTH_SRES))); + + at = &ctx->auth_triplet; + + if (TLVP_LEN(&tp, GSM48_IE_GMM_AUTH_SRES) != sizeof(at->sres) || + memcmp(TLVP_VAL(&tp, GSM48_IE_GMM_AUTH_SRES), at->sres, + sizeof(at->sres)) != 0) { + + LOGMMCTXP(LOGL_NOTICE, ctx, "Received SRES doesn't match\n"); + rc = gsm48_tx_gmm_auth_ciph_rej(ctx); + mm_ctx_cleanup_free(ctx, "GPRS AUTH AND CIPH REJECT"); + return rc; + } + + ctx->is_authenticated = 1; + /* FIXME: enable LLC cipheirng */ return 0; } |