aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc
diff options
context:
space:
mode:
authorHarald Welte <laforge@netfilter.org>2009-12-24 09:38:38 +0100
committerHarald Welte <laforge@netfilter.org>2009-12-24 09:38:38 +0100
commit5c706bbaf2e2a82776a8824d9cb88760624faabe (patch)
tree8a842fbdc18ff5b86d37da7ff0b47148d5a31277 /openbsc
parenta16ef3d23f31369399dd28b23a0c95648248cbf1 (diff)
parent3606cc576502b95d4973fac2af76d1b9bdc4705b (diff)
Merge remote branch 'origin/master'
Diffstat (limited to 'openbsc')
-rw-r--r--openbsc/include/openbsc/gsm_data.h19
-rw-r--r--openbsc/src/db.c92
-rw-r--r--openbsc/src/debug.c2
-rw-r--r--openbsc/src/input/ipaccess.c31
4 files changed, 130 insertions, 14 deletions
diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h
index c2eec4156..ff01d7287 100644
--- a/openbsc/include/openbsc/gsm_data.h
+++ b/openbsc/include/openbsc/gsm_data.h
@@ -589,6 +589,25 @@ struct gsm_sms {
char text[SMS_TEXT_SIZE];
};
+enum gsm_auth_algo {
+ AUTH_ALGO_NONE,
+ AUTH_ALGO_XOR,
+ AUTH_ALGO_COMP128v1,
+};
+
+/* Real authentication information containing Ki */
+struct gsm_auth_info {
+ enum gsm_auth_algo auth_algo;
+ unsigned int a3a8_ki_len;
+ u_int8_t a3a8_ki[16];
+};
+
+struct gsm_auth_tuple {
+ u_int8_t rand[16];
+ u_int8_t sres[8];
+ u_int8_t kc[8];
+};
+
struct gsm_network *gsm_network_init(u_int16_t country_code, u_int16_t network_code,
int (*mncc_recv)(struct gsm_network *, int, void *));
struct gsm_bts *gsm_bts_alloc(struct gsm_network *net, enum gsm_bts_type type,
diff --git a/openbsc/src/db.c b/openbsc/src/db.c
index 7b864fb43..cf9df11ad 100644
--- a/openbsc/src/db.c
+++ b/openbsc/src/db.c
@@ -123,6 +123,18 @@ static char *create_stmts[] = {
"timestamp TIMESTAMP NOT NULL, "
"value INTEGER NOT NULL, "
"name TEXT NOT NULL "
+ "CREATE TABLE IF NOT EXISTS AuthKeys ("
+ "id INTEGER PRIMARY KEY AUTOINCREMENT, "
+ "subscriber_id NUMERIC UNIQUE NOT NULL, "
+ "algorithm_id NUMERIC NOT NULL, "
+ "a3a8_ki BLOB "
+ ")",
+ "CREATE TABLE IF NOT EXISTS AuthTuples ("
+ "id INTEGER PRIMARY KEY AUTOINCREMENT, "
+ "subscriber_id NUMERIC UNIQUE NOT NULL, "
+ "rand BLOB"
+ "sres BLOB"
+ "kc BLOB"
")",
};
@@ -314,6 +326,86 @@ static int get_equipment_by_subscr(struct gsm_subscriber *subscr)
return 0;
}
+
+int get_authinfo_by_subscr(struct gsm_auth_info *ainfo,
+ struct gsm_subscriber *subscr)
+{
+ dbi_result result;
+ const unsigned char *a3a8_ki;
+
+ result = dbi_conn_queryf(conn,
+ "SELECT * FROM AuthKeys WHERE subscriber_id=%u",
+ subscr->id);
+ if (!result)
+ return -EIO;
+
+ if (!dbi_result_next_row(result)) {
+ dbi_result_free(result);
+ return -ENOENT;
+ }
+
+ ainfo->auth_algo = dbi_result_get_ulonglong(result, "algorithm_id");
+ ainfo->a3a8_ki_len = dbi_result_get_field_length(result, "a3a8_ki");
+ a3a8_ki = dbi_result_get_binary(result, "a3a8_ki");
+ if (ainfo->a3a8_ki_len > sizeof(ainfo->a3a8_ki_len))
+ ainfo->a3a8_ki_len = sizeof(ainfo->a3a8_ki_len);
+ memcpy(ainfo->a3a8_ki, a3a8_ki, ainfo->a3a8_ki_len);
+
+ dbi_result_free(result);
+
+ return 0;
+}
+
+int get_authtuple_by_subscr(struct gsm_auth_tuple *atuple,
+ struct gsm_subscriber *subscr)
+{
+ dbi_result result;
+ int len;
+ const unsigned char *blob;
+
+ result = dbi_conn_queryf(conn,
+ "SELECT * FROM AuthTuples WHERE subscriber_id=%u",
+ subscr->id);
+ if (!result)
+ return -EIO;
+
+ if (!dbi_result_next_row(result)) {
+ dbi_result_free(result);
+ return -ENOENT;
+ }
+
+ memset(atuple, 0, sizeof(atuple));
+
+ len = dbi_result_get_field_length(result, "rand");
+ if (len != sizeof(atuple->rand))
+ goto err_size;
+
+ blob = dbi_result_get_binary(result, "rand");
+ memcpy(atuple->rand, blob, len);
+
+ len = dbi_result_get_field_length(result, "sres");
+ if (len != sizeof(atuple->sres))
+ goto err_size;
+
+ blob = dbi_result_get_binary(result, "sres");
+ memcpy(atuple->sres, blob, len);
+
+ len = dbi_result_get_field_length(result, "kc");
+ if (len != sizeof(atuple->kc))
+ goto err_size;
+
+ blob = dbi_result_get_binary(result, "kc");
+ memcpy(atuple->kc, blob, len);
+
+ dbi_result_free(result);
+
+ return 0;
+
+err_size:
+ dbi_result_free(result);
+ return -EIO;
+}
+
#define BASE_QUERY "SELECT * FROM Subscriber "
struct gsm_subscriber *db_get_subscriber(struct gsm_network *net,
enum gsm_subscriber_field field,
diff --git a/openbsc/src/debug.c b/openbsc/src/debug.c
index d3d58f3fb..c02c086bb 100644
--- a/openbsc/src/debug.c
+++ b/openbsc/src/debug.c
@@ -35,7 +35,7 @@
static struct debug_category default_categories[Debug_LastEntry] = {
[DRLL] = { .enabled = 1, .loglevel = 0},
[DCC] = { .enabled = 1, .loglevel = 0},
- [DMM] = { .enabled = 1, .loglevel = 0},
+ [DNM] = { .enabled = 1, .loglevel = 0},
[DRR] = { .enabled = 1, .loglevel = 0},
[DRSL] = { .enabled = 1, .loglevel = 0},
[DMM] = { .enabled = 1, .loglevel = 0},
diff --git a/openbsc/src/input/ipaccess.c b/openbsc/src/input/ipaccess.c
index bbfb091e7..2f79a6b1b 100644
--- a/openbsc/src/input/ipaccess.c
+++ b/openbsc/src/input/ipaccess.c
@@ -213,7 +213,7 @@ static int ipaccess_rcvmsg(struct e1inp_line *line, struct msgb *msg,
&site_id, &bts_id, &trx_id);
bts = find_bts_by_unitid(e1h->gsmnet, site_id, bts_id);
if (!bts) {
- DEBUGP(DINP, "Unable to find BTS configuration for "
+ LOGP(DINP, LOGL_ERROR, "Unable to find BTS configuration for "
" %u/%u/%u, disconnecting\n", site_id, bts_id,
trx_id);
return -EIO;
@@ -270,7 +270,7 @@ struct msgb *ipaccess_read_msg(struct bsc_fd *bfd, int *error)
hh = (struct ipaccess_head *) msg->data;
ret = recv(bfd->fd, msg->data, 3, 0);
if (ret < 0) {
- fprintf(stderr, "recv error %s\n", strerror(errno));
+ LOGP(DINP, LOGL_ERROR, "recv error %s\n", strerror(errno));
msgb_free(msg);
*error = ret;
return NULL;
@@ -287,7 +287,7 @@ struct msgb *ipaccess_read_msg(struct bsc_fd *bfd, int *error)
len = ntohs(hh->len);
ret = recv(bfd->fd, msg->l2h, len, 0);
if (ret < len) {
- fprintf(stderr, "short read!\n");
+ LOGP(DINP, LOGL_ERROR, "short read!\n");
msgb_free(msg);
*error = -EIO;
return NULL;
@@ -310,9 +310,12 @@ static int handle_ts1_read(struct bsc_fd *bfd)
msg = ipaccess_read_msg(bfd, &error);
if (!msg) {
if (error == 0) {
- fprintf(stderr, "BTS disappeared, dead socket\n");
+ LOGP(DINP, LOGL_NOTICE, "BTS disappeared, dead socket\n");
e1inp_event(e1i_ts, EVT_E1_TEI_DN, 0, IPAC_PROTO_RSL);
e1inp_event(e1i_ts, EVT_E1_TEI_DN, 0, IPAC_PROTO_OML);
+ link = e1inp_lookup_sign_link(e1i_ts, IPAC_PROTO_OML, 0);
+ if (link)
+ link->trx->bts->ip_access.flags = 0;
bsc_unregister_fd(bfd);
close(bfd->fd);
bfd->fd = -1;
@@ -340,7 +343,8 @@ static int handle_ts1_read(struct bsc_fd *bfd)
link = e1inp_lookup_sign_link(e1i_ts, hh->proto, 0);
if (!link) {
- printf("no matching signalling link for hh->proto=0x%02x\n", hh->proto);
+ LOGP(DINP, LOGL_ERROR, "no matching signalling link for "
+ "hh->proto=0x%02x\n", hh->proto);
msgb_free(msg);
return -EIO;
}
@@ -362,7 +366,7 @@ static int handle_ts1_read(struct bsc_fd *bfd)
ret = abis_nm_rcvmsg(msg);
break;
default:
- DEBUGP(DMI, "Unknown IP.access protocol proto=0x%02x\n", hh->proto);
+ LOGP(DINP, LOGL_NOTICE, "Unknown IP.access protocol proto=0x%02x\n", hh->proto);
msgb_free(msg);
break;
}
@@ -462,7 +466,7 @@ static int ipaccess_fd_cb(struct bsc_fd *bfd, unsigned int what)
if (what & BSC_FD_WRITE)
rc = handle_ts1_write(bfd);
} else
- fprintf(stderr, "unknown E1 TS type %u\n", e1i_ts->type);
+ LOGP(DINP, LOGL_ERROR, "unknown E1 TS type %u\n", e1i_ts->type);
return rc;
}
@@ -492,7 +496,8 @@ static int listen_fd_cb(struct bsc_fd *listen_bfd, unsigned int what)
perror("accept");
return ret;
}
- DEBUGP(DINP, "accept()ed new OML link from %s\n", inet_ntoa(sa.sin_addr));
+ LOGP(DINP, LOGL_NOTICE, "accept()ed new OML link from %s\n",
+ inet_ntoa(sa.sin_addr));
line = talloc_zero(tall_bsc_ctx, struct e1inp_line);
if (!line) {
@@ -514,7 +519,7 @@ static int listen_fd_cb(struct bsc_fd *listen_bfd, unsigned int what)
bfd->when = BSC_FD_READ;
ret = bsc_register_fd(bfd);
if (ret < 0) {
- fprintf(stderr, "could not register FD\n");
+ LOGP(DINP, LOGL_ERROR, "could not register FD\n");
close(bfd->fd);
talloc_free(line);
return ret;
@@ -550,13 +555,13 @@ static int rsl_listen_fd_cb(struct bsc_fd *listen_bfd, unsigned int what)
perror("accept");
return bfd->fd;
}
- DEBUGP(DINP, "accept()ed new RSL link from %s\n", inet_ntoa(sa.sin_addr));
+ LOGP(DINP, LOGL_NOTICE, "accept()ed new RSL link from %s\n", inet_ntoa(sa.sin_addr));
bfd->priv_nr = 2;
bfd->cb = ipaccess_fd_cb;
bfd->when = BSC_FD_READ;
ret = bsc_register_fd(bfd);
if (ret < 0) {
- fprintf(stderr, "could not register FD\n");
+ LOGP(DINP, LOGL_ERROR, "could not register FD\n");
close(bfd->fd);
talloc_free(bfd);
return ret;
@@ -587,7 +592,7 @@ static int make_sock(struct bsc_fd *bfd, u_int16_t port,
ret = bind(bfd->fd, (struct sockaddr *) &addr, sizeof(addr));
if (ret < 0) {
- fprintf(stderr, "could not bind l2 socket %s\n",
+ LOGP(DINP, LOGL_ERROR, "could not bind l2 socket %s\n",
strerror(errno));
return -EIO;
}
@@ -623,7 +628,7 @@ int ipaccess_connect(struct e1inp_line *line, struct sockaddr_in *sa)
ret = connect(bfd->fd, (struct sockaddr *) sa, sizeof(*sa));
if (ret < 0) {
- fprintf(stderr, "could not connect socket\n");
+ LOGP(DINP, LOGL_ERROR, "could not connect socket\n");
close(bfd->fd);
return ret;
}