diff options
author | Sylvain Munaut <tnt@246tNt.com> | 2010-12-01 22:38:03 +0100 |
---|---|---|
committer | Sylvain Munaut <tnt@246tNt.com> | 2010-12-01 23:04:26 +0100 |
commit | 5a86e06eb3b8747da2aa8548a9547d219c64de64 (patch) | |
tree | 8282e0c7e72e8ed3a616b6fd522bd6feb50c2863 /openbsc | |
parent | 0fbfd1bb52ba373a3eb1fb4baff3ab1d21f3a453 (diff) |
auth/ciph: Enable securing of channel directly after paging response
This protects MT services
Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
Diffstat (limited to 'openbsc')
-rw-r--r-- | openbsc/src/gsm_subscriber.c | 58 |
1 files changed, 55 insertions, 3 deletions
diff --git a/openbsc/src/gsm_subscriber.c b/openbsc/src/gsm_subscriber.c index 06762a50d..bd76faec7 100644 --- a/openbsc/src/gsm_subscriber.c +++ b/openbsc/src/gsm_subscriber.c @@ -30,6 +30,7 @@ #include <osmocore/talloc.h> #include <openbsc/gsm_subscriber.h> +#include <openbsc/gsm_04_08.h> #include <openbsc/debug.h> #include <openbsc/paging.h> #include <openbsc/signal.h> @@ -39,6 +40,9 @@ void *tall_sub_req_ctx; extern struct llist_head *subscr_bsc_active_subscriber(void); +int gsm48_secure_channel(struct gsm_subscriber_connection *conn, int key_seq, + gsm_cbfn *cb, void *cb_data); + /* * Struct for pending channel requests. This is managed in the @@ -64,11 +68,11 @@ struct subscr_request { * We got the channel assigned and can now hand this channel * over to one of our callbacks. */ -static int subscr_paging_cb(unsigned int hooknum, unsigned int event, - struct msgb *msg, void *data, void *param) +static int subscr_paging_dispatch(unsigned int hooknum, unsigned int event, + struct msgb *msg, void *data, void *param) { struct subscr_request *request; - struct gsm_subscriber *subscr = (struct gsm_subscriber *)param; + struct gsm_subscriber *subscr = param; /* There is no request anymore... */ if (llist_empty(&subscr->requests)) @@ -91,6 +95,54 @@ static int subscr_paging_cb(unsigned int hooknum, unsigned int event, return 0; } +static int subscr_paging_sec_cb(unsigned int hooknum, unsigned int event, + struct msgb *msg, void *data, void *param) +{ + int rc; + + switch (event) { + case GSM_SECURITY_AUTH_FAILED: + /* Dispatch as paging failure */ + rc = subscr_paging_dispatch( + GSM_HOOK_RR_PAGING, GSM_PAGING_EXPIRED, + msg, data, param); + break; + + case GSM_SECURITY_NOAVAIL: + case GSM_SECURITY_SUCCEEDED: + /* Dispatch as paging failure */ + rc = subscr_paging_dispatch( + GSM_HOOK_RR_PAGING, GSM_PAGING_SUCCEEDED, + msg, data, param); + break; + + default: + rc = -EINVAL; + } + + return rc; +} + +static int subscr_paging_cb(unsigned int hooknum, unsigned int event, + struct msgb *msg, void *data, void *param) +{ + struct gsm_subscriber_connection *conn = data; + struct gsm48_hdr *gh; + struct gsm48_pag_resp *pr; + + /* Other cases mean problem, dispatch direclty */ + if (event != GSM_PAGING_SUCCEEDED) + return subscr_paging_dispatch(hooknum, event, msg, data, param); + + /* Get paging response */ + gh = msgb_l3(msg); + pr = (struct gsm48_pag_resp *)gh->data; + + /* We _really_ have a channel, secure it now ! */ + return gsm48_secure_channel(conn, pr->key_seq, subscr_paging_sec_cb, param); +} + + static void subscr_send_paging_request(struct gsm_subscriber *subscr) { struct subscr_request *request; |