[5/9] sgsn: Copy the msisdn to the sgsn_data and use it in PDP activation
diff mbox

Message ID 1429825244-61253-5-git-send-email-holger@freyther.de
State Changes Requested
Headers show

Commit Message

Holger Freyther April 23, 2015, 9:40 p.m. UTC
From: Holger Hans Peter Freyther <holger@moiji-mobile.com>

The MSISDN should be present for "security" reasons in the first
activation of a PDP context. Take the encoded MSISDN, store it for
future use and then put it into the PDP activation request.
---
 openbsc/include/openbsc/gprs_sgsn.h |  3 +++
 openbsc/src/gprs/gprs_subscriber.c  | 14 ++++++++++++++
 openbsc/src/gprs/sgsn_libgtp.c      | 12 ++++++++++--
 openbsc/tests/sgsn/sgsn_test.c      |  9 +++++++++
 4 files changed, 36 insertions(+), 2 deletions(-)

Patch
diff mbox

diff --git a/openbsc/include/openbsc/gprs_sgsn.h b/openbsc/include/openbsc/gprs_sgsn.h
index 2572ead..baa2d78 100644
--- a/openbsc/include/openbsc/gprs_sgsn.h
+++ b/openbsc/include/openbsc/gprs_sgsn.h
@@ -302,6 +302,9 @@  struct sgsn_subscriber_data {
 	int			auth_triplets_updated;
 	struct llist_head	pdp_list;
 	int			error_cause;
+
+	uint8_t			msisdn[9];
+	size_t			msisdn_len;
 };
 
 #define SGSN_ERROR_CAUSE_NONE (-1)
diff --git a/openbsc/src/gprs/gprs_subscriber.c b/openbsc/src/gprs/gprs_subscriber.c
index 60f223a..52e7ba7 100644
--- a/openbsc/src/gprs/gprs_subscriber.c
+++ b/openbsc/src/gprs/gprs_subscriber.c
@@ -1,6 +1,7 @@ 
 /* MS subscriber data handling */
 
 /* (C) 2014 by sysmocom s.f.m.c. GmbH
+ * (C) 2015 by Holger Hans Peter Freyther
  *
  * All Rights Reserved
  *
@@ -259,9 +260,22 @@  static struct sgsn_subscriber_pdp_data *gprs_subscr_pdp_data_get_by_id(
 static void gprs_subscr_gsup_insert_data(struct gsm_subscriber *subscr,
 					 struct gprs_gsup_message *gsup_msg)
 {
+	struct sgsn_subscriber_data *sdata = subscr->sgsn_data;
 	unsigned idx;
 	int rc;
 
+	if (gsup_msg->msisdn_enc) {
+		if (gsup_msg->msisdn_enc_len > sizeof(sdata->msisdn)) {
+			LOGP(DGPRS, LOGL_ERROR, "MSISDN too long (%zu)\n",
+				gsup_msg->msisdn_enc_len);
+			sdata->msisdn_len = 0;
+		} else {
+			memcpy(sdata->msisdn, gsup_msg->msisdn_enc,
+				gsup_msg->msisdn_enc_len);
+			sdata->msisdn_len = gsup_msg->msisdn_enc_len;
+		}
+	}
+
 	if (gsup_msg->pdp_info_compl) {
 		rc = gprs_subscr_pdp_data_clear(subscr);
 		if (rc > 0)
diff --git a/openbsc/src/gprs/sgsn_libgtp.c b/openbsc/src/gprs/sgsn_libgtp.c
index 455e8af..25b30d0 100644
--- a/openbsc/src/gprs/sgsn_libgtp.c
+++ b/openbsc/src/gprs/sgsn_libgtp.c
@@ -3,6 +3,7 @@ 
 
 /* (C) 2010 by Harald Welte <laforge@gnumonks.org>
  * (C) 2010 by On-Waves
+ * (C) 2015 by Holger Hans Peter Freyther
  * All Rights Reserved
  *
  * This program is free software; you can redistribute it and/or modify
@@ -45,6 +46,7 @@ 
 #include <openbsc/gprs_llc.h>
 #include <openbsc/gprs_sgsn.h>
 #include <openbsc/gprs_gmm.h>
+#include <openbsc/gsm_subscriber.h>
 
 #include <gtp.h>
 #include <pdp.h>
@@ -153,8 +155,14 @@  struct sgsn_pdp_ctx *sgsn_create_pdp_ctx(struct sgsn_ggsn_ctx *ggsn,
 
 	/* IMSI, TEID/TEIC, FLLU/FLLC, TID, NSAPI set in pdp_newpdp */
 
-	/* FIXME: MSISDN in BCD format from mmctx */
-	//pdp->msisdn.l/.v
+	/* Put the MSISDN in case we have it */
+	if (mmctx->subscr) {
+		pdp->msisdn.l = mmctx->subscr->sgsn_data->msisdn_len;
+		if (pdp->msisdn.l > sizeof(pdp->msisdn.v))
+			pdp->msisdn.l = sizeof(pdp->msisdn.l);
+		memcpy(pdp->msisdn.v, mmctx->subscr->sgsn_data->msisdn,
+			pdp->msisdn.l);
+	}
 
 	/* End User Address from GMM requested PDP address */
 	pdp->eua.l = TLVP_LEN(tp, OSMO_IE_GSM_REQ_PDP_ADDR);
diff --git a/openbsc/tests/sgsn/sgsn_test.c b/openbsc/tests/sgsn/sgsn_test.c
index 197be9d..f6f8cd6 100644
--- a/openbsc/tests/sgsn/sgsn_test.c
+++ b/openbsc/tests/sgsn/sgsn_test.c
@@ -414,6 +414,10 @@  static void test_subscriber_gsup(void)
 		0x02, 0x01, 0x07 /* GPRS not allowed */
 	};
 
+#define MSISDN	0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09
+
+	static const uint8_t s1_msisdn[] = { MSISDN };
+
 	static const uint8_t update_location_res[] = {
 		0x06,
 		TEST_GSUP_IMSI1_IE,
@@ -426,8 +430,11 @@  static void test_subscriber_gsup(void)
 			0x10, 0x01, 0x02,
 			0x11, 0x02, 0xf1, 0x21, /* IPv4 */
 			0x12, 0x08, 0x03, 'f', 'o', 'o', 0x03, 'a', 'p', 'n',
+		0x13, 0x09, MSISDN,
 	};
 
+#undef MSISDN
+
 	static const uint8_t update_location_err[] = {
 		0x05,
 		TEST_GSUP_IMSI1_IE,
@@ -534,6 +541,8 @@  static void test_subscriber_gsup(void)
 	OSMO_ASSERT(last_updated_subscr == s1);
 	OSMO_ASSERT(s1->flags & GPRS_SUBSCRIBER_ENABLE_PURGE);
 	OSMO_ASSERT(s1->sgsn_data->error_cause == SGSN_ERROR_CAUSE_NONE);
+	OSMO_ASSERT(s1->sgsn_data->msisdn_len == sizeof(s1_msisdn));
+	OSMO_ASSERT(memcmp(s1->sgsn_data->msisdn, s1_msisdn, sizeof(s1_msisdn)) == 0);
 	OSMO_ASSERT(!llist_empty(&s1->sgsn_data->pdp_list));
 	pdpd = llist_entry(s1->sgsn_data->pdp_list.next,
 		struct sgsn_subscriber_pdp_data, list);