aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc/src/gsm_04_08.c
diff options
context:
space:
mode:
authorSylvain Munaut <tnt@246tNt.com>2009-12-24 00:28:46 +0100
committerHarald Welte <laforge@gnumonks.org>2010-06-14 20:43:52 +0200
commitba87f458ec744e97b4456832ec37f612bd513508 (patch)
tree8f9b7d63d3479fd001df929f115e04f8f4bf914e /openbsc/src/gsm_04_08.c
parent267fba0a2b6ea1e660fb8f25953ec640b290580b (diff)
gsm_04_08: Establish secure channel on CM SERVICE REQUEST
Note that establishing a secure channel is considered to be an implicit CM SERVICE ACK. Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
Diffstat (limited to 'openbsc/src/gsm_04_08.c')
-rw-r--r--openbsc/src/gsm_04_08.c31
1 files changed, 30 insertions, 1 deletions
diff --git a/openbsc/src/gsm_04_08.c b/openbsc/src/gsm_04_08.c
index 1db89c964..562c24d43 100644
--- a/openbsc/src/gsm_04_08.c
+++ b/openbsc/src/gsm_04_08.c
@@ -706,6 +706,34 @@ static int gsm48_tx_mm_serv_rej(struct gsm_subscriber_connection *conn,
return gsm48_sendmsg(msg, NULL);
}
+static int _gsm48_rx_mm_serv_req_sec_cb(
+ unsigned int hooknum, unsigned int event,
+ struct msgb *msg, void *data, void *param)
+{
+ struct gsm_lchan *lchan = data;
+ int rc = 0;
+
+ switch (event) {
+ case GSM_SECURITY_AUTH_FAILED:
+ /* Nothing to do */
+ break;
+
+ case GSM_SECURITY_NOAVAIL:
+ rc = gsm48_tx_mm_serv_ack(lchan);
+ break;
+
+ case GSM_SECURITY_SUCCEEDED:
+ /* nothing to do. CIPHER MODE COMMAND is
+ * implicit CM SERV ACK */
+ break;
+
+ default:
+ rc = -EINVAL;
+ };
+
+ return rc;
+}
+
/*
* Handle CM Service Requests
* a) Verify that the packet is long enough to contain the information
@@ -781,7 +809,8 @@ static int gsm48_rx_mm_serv_req(struct msgb *msg)
memcpy(subscr->equipment.classmark2, classmark2, classmark2_len);
db_sync_equipment(&subscr->equipment);
- return gsm48_tx_mm_serv_ack(msg->lchan);
+ return gsm48_secure_channel(msg->lchan, req->cipher_key_seq,
+ _gsm48_rx_mm_serv_req_sec_cb, NULL);
}
static int gsm48_rx_mm_imsi_detach_ind(struct msgb *msg)