From f3d2e9369867aacffc69f074d9ebfb021313dcf2 Mon Sep 17 00:00:00 2001 From: Ivan Kluchnikov Date: Tue, 11 Aug 2015 07:52:42 +0300 Subject: msc: Implement 'remote' authentication policy - All location update requests should be send to the remote HLR and accepted. - Authentication info should be also received from remote HLR. - SUP is used for sending/handling subscription data to/from remote HLR. --- openbsc/include/openbsc/auth.h | 5 ++++- openbsc/include/openbsc/gsm_04_08.h | 4 ++++ openbsc/include/openbsc/gsm_data.h | 4 ++++ openbsc/src/libbsc/bsc_vty.c | 5 +++-- openbsc/src/libcommon/gsm_data.c | 1 + openbsc/src/libmsc/Makefile.am | 4 ++++ openbsc/src/libmsc/auth.c | 22 +++++++++++++++------- openbsc/src/libmsc/gsm_04_08.c | 24 ++++++++++++++++++++---- 8 files changed, 55 insertions(+), 14 deletions(-) diff --git a/openbsc/include/openbsc/auth.h b/openbsc/include/openbsc/auth.h index 2364fb3d2..529ca96b7 100644 --- a/openbsc/include/openbsc/auth.h +++ b/openbsc/include/openbsc/auth.h @@ -1,6 +1,8 @@ #ifndef _AUTH_H #define _AUTH_H +#include + struct gsm_auth_tuple; struct gsm_subscriber; @@ -11,7 +13,8 @@ enum auth_action { AUTH_DO_AUTH = 3, /* Only authentication, no ciphering */ }; -int auth_get_tuple_for_subscr(struct gsm_auth_tuple *atuple, +int auth_get_tuple_for_subscr(enum gsm_auth_policy auth_policy, + struct gsm_auth_tuple *atuple, struct gsm_subscriber *subscr, int key_seq); #endif /* _AUTH_H */ diff --git a/openbsc/include/openbsc/gsm_04_08.h b/openbsc/include/openbsc/gsm_04_08.h index 739e159f4..d3afc3393 100644 --- a/openbsc/include/openbsc/gsm_04_08.h +++ b/openbsc/include/openbsc/gsm_04_08.h @@ -95,4 +95,8 @@ int tch_frame_down(struct gsm_network *net, uint32_t callref, struct gsm_data_fr int gsm48_multirate_config(uint8_t *lv, struct amr_multirate_conf *mr, int ms); +int gsm0408_authorize(struct gsm_subscriber_connection *conn, struct msgb *msg); +int gsm0408_loc_upd_rej(struct gsm_subscriber_connection *conn, uint8_t cause); +void release_loc_updating_req(struct gsm_subscriber_connection *conn, int release); + #endif diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h index b67b8c6b9..a4268620e 100644 --- a/openbsc/include/openbsc/gsm_data.h +++ b/openbsc/include/openbsc/gsm_data.h @@ -7,6 +7,7 @@ #include #include +#include /** annotations for msgb ownership */ #define __uses @@ -64,6 +65,7 @@ struct gsm_loc_updating_operation { struct osmo_timer_list updating_timer; unsigned int waiting_for_imsi : 1; unsigned int waiting_for_imei : 1; + unsigned int waiting_for_remote_accept : 1; unsigned int key_seq : 4; }; @@ -196,6 +198,7 @@ enum gsm_auth_policy { GSM_AUTH_POLICY_CLOSED, /* only subscribers authorized in DB */ GSM_AUTH_POLICY_ACCEPT_ALL, /* accept everyone, even if not authorized in DB */ GSM_AUTH_POLICY_TOKEN, /* accept first, send token per sms, then revoke authorization */ + GSM_AUTH_POLICY_REMOTE, }; #define GSM_T3101_DEFAULT 10 @@ -239,6 +242,7 @@ struct gsm_network { struct llist_head upqueue; struct llist_head trans_list; struct bsc_api *bsc_api; + struct gprs_gsup_client *sup_client; unsigned int num_bts; struct llist_head bts_list; diff --git a/openbsc/src/libbsc/bsc_vty.c b/openbsc/src/libbsc/bsc_vty.c index d5f739405..b256fb7f8 100644 --- a/openbsc/src/libbsc/bsc_vty.c +++ b/openbsc/src/libbsc/bsc_vty.c @@ -1352,12 +1352,13 @@ DEFUN(cfg_net_name_long, DEFUN(cfg_net_auth_policy, cfg_net_auth_policy_cmd, - "auth policy (closed|accept-all|token)", + "auth policy (closed|accept-all|token|remote)", "Authentication (not cryptographic)\n" "Set the GSM network authentication policy\n" "Require the MS to be activated in HLR\n" "Accept all MS, whether in HLR or not\n" - "Use SMS-token based authentication\n") + "Use SMS-token based authentication\n" + "Use remote subscription data only (HLR)\n") { enum gsm_auth_policy policy = gsm_auth_policy_parse(argv[0]); struct gsm_network *gsmnet = gsmnet_from_vty(vty); diff --git a/openbsc/src/libcommon/gsm_data.c b/openbsc/src/libcommon/gsm_data.c index 4ce4ecac7..85c704677 100644 --- a/openbsc/src/libcommon/gsm_data.c +++ b/openbsc/src/libcommon/gsm_data.c @@ -161,6 +161,7 @@ static const struct value_string auth_policy_names[] = { { GSM_AUTH_POLICY_CLOSED, "closed" }, { GSM_AUTH_POLICY_ACCEPT_ALL, "accept-all" }, { GSM_AUTH_POLICY_TOKEN, "token" }, + { GSM_AUTH_POLICY_REMOTE, "remote" }, { 0, NULL } }; diff --git a/openbsc/src/libmsc/Makefile.am b/openbsc/src/libmsc/Makefile.am index aa7d8ae99..107e8eee3 100644 --- a/openbsc/src/libmsc/Makefile.am +++ b/openbsc/src/libmsc/Makefile.am @@ -10,6 +10,10 @@ libmsc_a_SOURCES = auth.c \ db.c \ gsm_04_08.c gsm_04_11.c gsm_04_11_helper.c \ gsm_04_80.c \ + ../gprs/gsm_04_08_gprs.c \ + ../gprs/gprs_utils.c \ + ../gprs/gprs_gsup_messages.c ../gprs/gprs_gsup_client.c \ + gsm_sup.c \ gsm_subscriber.c \ mncc.c mncc_builtin.c mncc_sock.c \ rrlp.c \ diff --git a/openbsc/src/libmsc/auth.c b/openbsc/src/libmsc/auth.c index 10d8edf67..830d445c2 100644 --- a/openbsc/src/libmsc/auth.c +++ b/openbsc/src/libmsc/auth.c @@ -71,18 +71,21 @@ _use_comp128_v1(struct gsm_auth_info *ainfo, struct gsm_auth_tuple *atuple) * 1 -> Tuple returned, need to do auth, then enable cipher * 2 -> Tuple returned, need to enable cipher */ -int auth_get_tuple_for_subscr(struct gsm_auth_tuple *atuple, +int auth_get_tuple_for_subscr(enum gsm_auth_policy auth_policy, + struct gsm_auth_tuple *atuple, struct gsm_subscriber *subscr, int key_seq) { struct gsm_auth_info ainfo; int i, rc; - /* Get subscriber info (if any) */ - rc = db_get_authinfo_for_subscr(&ainfo, subscr); - if (rc < 0) { - LOGP(DMM, LOGL_NOTICE, - "No retrievable Ki for subscriber, skipping auth\n"); - return rc == -ENOENT ? AUTH_NOT_AVAIL : -1; + if (auth_policy != GSM_AUTH_POLICY_REMOTE) { + /* Get subscriber info (if any) */ + rc = db_get_authinfo_for_subscr(&ainfo, subscr); + if (rc < 0) { + LOGP(DMM, LOGL_NOTICE, + "No retrievable Ki for subscriber, skipping auth\n"); + return rc == -ENOENT ? AUTH_NOT_AVAIL : -1; + } } /* If possible, re-use the last tuple and skip auth */ @@ -97,6 +100,11 @@ int auth_get_tuple_for_subscr(struct gsm_auth_tuple *atuple, return AUTH_DO_CIPH; } + if (auth_policy == GSM_AUTH_POLICY_REMOTE) { + /* Request a new tuple from remote HLR */ + return 0; + } + /* Generate a new one */ atuple->use_count = 1; atuple->key_seq = (atuple->key_seq + 1) % 7; diff --git a/openbsc/src/libmsc/gsm_04_08.c b/openbsc/src/libmsc/gsm_04_08.c index 5a9e1ecc6..b48730950 100644 --- a/openbsc/src/libmsc/gsm_04_08.c +++ b/openbsc/src/libmsc/gsm_04_08.c @@ -52,6 +52,7 @@ #include #include #include +#include #include #include @@ -205,9 +206,15 @@ int gsm48_secure_channel(struct gsm_subscriber_connection *conn, int key_seq, /* If not done yet, try to get info for this user */ if (status < 0) { - rc = auth_get_tuple_for_subscr(&atuple, subscr, key_seq); - if (rc <= 0) + rc = auth_get_tuple_for_subscr(net->auth_policy, &atuple, subscr, key_seq); + if ((rc == 0) && (net->auth_policy == GSM_AUTH_POLICY_REMOTE)) { + allocate_security_operation(conn); + conn->sec_operation->cb = cb; + conn->sec_operation->cb_data = cb_data; + return subscr_query_auth_info(subscr); + } else if (rc <= 0) { status = GSM_SECURITY_NOAVAIL; + } } /* Are we done yet ? */ @@ -264,12 +271,19 @@ static int authorize_subscriber(struct gsm_loc_updating_operation *loc, return (subscriber->flags & GSM_SUBSCRIBER_FIRST_CONTACT); case GSM_AUTH_POLICY_ACCEPT_ALL: return 1; + case GSM_AUTH_POLICY_REMOTE: + if (loc->waiting_for_remote_accept) { + subscr_location_update(subscriber); + return 0; + } else { + return 1; + } default: return 0; } } -static void release_loc_updating_req(struct gsm_subscriber_connection *conn, int release) +void release_loc_updating_req(struct gsm_subscriber_connection *conn, int release) { if (!conn->loc_operation) return; @@ -340,7 +354,7 @@ static int _gsm0408_authorize_sec_cb(unsigned int hooknum, unsigned int event, return rc; } -static int gsm0408_authorize(struct gsm_subscriber_connection *conn, struct msgb *msg) +int gsm0408_authorize(struct gsm_subscriber_connection *conn, struct msgb *msg) { if (!conn->loc_operation) return 0; @@ -665,6 +679,8 @@ static int mm_rx_loc_upd_req(struct gsm_subscriber_connection *conn, struct msgb conn->subscr = subscr; conn->subscr->equipment.classmark1 = lu->classmark1; + conn->loc_operation->waiting_for_remote_accept = 1; + /* check if we can let the subscriber into our network immediately * or if we need to wait for identity responses. */ return gsm0408_authorize(conn, msg); -- cgit v1.2.3