Merge remote branch 'origin/master'
This commit is contained in:
commit
5c706bbaf2
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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},
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue