summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIvan Kluchnikov <kluchnikovi@gmail.com>2015-08-11 07:52:42 +0300
committerIvan Kluchnikov <kluchnikovi@gmail.com>2015-10-24 12:26:15 +0300
commitf3d2e9369867aacffc69f074d9ebfb021313dcf2 (patch)
tree2429bf97bbf88c70609957e04ea72c9993cd830a
parentfe676095532bfb6fe64fbac0bbf5da7f14bcc811 (diff)
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.
-rw-r--r--openbsc/include/openbsc/auth.h5
-rw-r--r--openbsc/include/openbsc/gsm_04_08.h4
-rw-r--r--openbsc/include/openbsc/gsm_data.h4
-rw-r--r--openbsc/src/libbsc/bsc_vty.c5
-rw-r--r--openbsc/src/libcommon/gsm_data.c1
-rw-r--r--openbsc/src/libmsc/Makefile.am4
-rw-r--r--openbsc/src/libmsc/auth.c22
-rw-r--r--openbsc/src/libmsc/gsm_04_08.c24
8 files changed, 55 insertions, 14 deletions
diff --git a/openbsc/include/openbsc/auth.h b/openbsc/include/openbsc/auth.h
index 2364fb3..529ca96 100644
--- a/openbsc/include/openbsc/auth.h
+++ b/openbsc/include/openbsc/auth.h
@@ -1,6 +1,8 @@
#ifndef _AUTH_H
#define _AUTH_H
+#include <openbsc/gsm_data.h>
+
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 739e159..d3afc33 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 b67b8c6..a426862 100644
--- a/openbsc/include/openbsc/gsm_data.h
+++ b/openbsc/include/openbsc/gsm_data.h
@@ -7,6 +7,7 @@
#include <osmocom/core/select.h>
#include <openbsc/rest_octets.h>
+#include <openbsc/gprs_gsup_client.h>
/** 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 d5f7394..b256fb7 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 4ce4eca..85c7046 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 aa7d8ae..107e8ee 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 10d8edf..830d445 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 5a9e1ec..b487309 100644
--- a/openbsc/src/libmsc/gsm_04_08.c
+++ b/openbsc/src/libmsc/gsm_04_08.c
@@ -52,6 +52,7 @@
#include <openbsc/bsc_api.h>
#include <openbsc/osmo_msc.h>
#include <openbsc/handover.h>
+#include <openbsc/gsm_sup.h>
#include <osmocom/abis/e1_input.h>
#include <osmocom/core/bitvec.h>
@@ -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);