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; }