Merge remote branch 'origin/master'

This commit is contained in:
Harald Welte 2009-12-24 09:38:38 +01:00
commit 5c706bbaf2
4 changed files with 130 additions and 14 deletions

View File

@ -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,

View File

@ -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,

View File

@ -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},

View File

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