blob: bbc728ed1839ccb8d76928f4d6bb7a6f1b7180c5 [file] [log] [blame]
Neels Hofmeyr98509462017-10-09 17:28:53 +02001/* (C) 2017 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
2 * All Rights Reserved
3 *
4 * Author: Neels Hofmeyr <nhofmeyr@sysmocom.de>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU Affero General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU Affero General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 *
19 */
20
21#include <stdio.h>
22#include <errno.h>
23#include <getopt.h>
24#include <inttypes.h>
25
26#include <osmocom/core/application.h>
27#include <osmocom/core/utils.h>
28#include <osmocom/core/logging.h>
29
Neels Hofmeyr008ce4b2019-12-04 01:04:32 +010030#include <osmocom/gsupclient/gsup_peer_id.h>
Neels Hofmeyr2f758032019-11-20 00:37:07 +010031#include <osmocom/hlr/db.h>
32#include <osmocom/hlr/logging.h>
Neels Hofmeyr98509462017-10-09 17:28:53 +020033
34#define comment_start() fprintf(stderr, "\n===== %s\n", __func__);
35#define comment(fmt, args...) fprintf(stderr, "\n--- " fmt "\n\n", ## args);
36#define comment_end() fprintf(stderr, "===== %s: SUCCESS\n\n", __func__);
37
Neels Hofmeyrb6837e32017-10-10 23:20:26 +020038#define fill_invalid(x) _fill_invalid(&x, sizeof(x))
39static void _fill_invalid(void *dest, size_t size)
40{
41 uint8_t *pos = dest;
42 size_t remain = size;
43 int wrote = 0;
44 do {
45 remain -= wrote;
46 pos += wrote;
47 wrote = snprintf((void*)pos, remain, "-invalid-data");
48 } while (wrote < remain);
49}
50
Neels Hofmeyr98509462017-10-09 17:28:53 +020051/* Perform a function call and verbosely assert that its return value is as expected.
52 * The return code is then available in g_rc. */
53#define ASSERT_RC(call, expect_rc) \
54 do { \
Ruben Undheim8b860e52018-11-16 08:47:26 +010055 if ((expect_rc) == -ENOKEY) \
56 fprintf(stderr, #call " --> -ENOKEY\n"); \
57 else if ((expect_rc) == -ENOTSUP) \
58 fprintf(stderr, #call " --> -ENOTSUP\n"); \
59 else \
60 fprintf(stderr, #call " --> " #expect_rc "\n"); \
Neels Hofmeyr98509462017-10-09 17:28:53 +020061 g_rc = call; \
62 if (g_rc != (expect_rc)) \
63 fprintf(stderr, " MISMATCH: got rc = %d, expected: " \
64 #expect_rc " = %d\n", g_rc, expect_rc); \
65 OSMO_ASSERT(g_rc == (expect_rc)); \
66 fprintf(stderr, "\n"); \
67 } while (0)
68
69/* Do db_subscr_get_by_xxxx and verbosely assert that its return value is as expected.
70 * Print the subscriber struct to stderr to be validated by db_test.err.
71 * The result is then available in g_subscr. */
72#define ASSERT_SEL(by, val, expect_rc) \
73 do { \
74 int rc; \
Neels Hofmeyrb6837e32017-10-10 23:20:26 +020075 fill_invalid(g_subscr); \
Ruben Undheim8b860e52018-11-16 08:47:26 +010076 if ((expect_rc) == -ENOKEY) \
77 fprintf(stderr, "db_subscr_get_by_" #by "(dbc, " #val ", &g_subscr) --> -ENOKEY \n"); \
78 else if ((expect_rc) == -ENOTSUP) \
79 fprintf(stderr, "db_subscr_get_by_" #by "(dbc, " #val ", &g_subscr) --> -ENOTSUP \n"); \
80 else \
81 fprintf(stderr, "db_subscr_get_by_" #by "(dbc, " #val ", &g_subscr) --> " \
Neels Hofmeyr98509462017-10-09 17:28:53 +020082 #expect_rc "\n"); \
83 rc = db_subscr_get_by_##by(dbc, val, &g_subscr); \
84 if (rc != (expect_rc)) \
85 fprintf(stderr, " MISMATCH: got rc = %d, expected: " \
86 #expect_rc " = %d\n", rc, expect_rc); \
87 OSMO_ASSERT(rc == (expect_rc)); \
88 if (!rc) \
89 dump_subscr(&g_subscr); \
90 fprintf(stderr, "\n"); \
91 } while (0)
92
Neels Hofmeyr1332a172017-10-10 02:25:00 +020093/* Do db_get_auth_data() and verbosely assert that its return value is as expected.
94 * Print the subscriber struct to stderr to be validated by db_test.err.
95 * The results are then available in g_aud2g and g_aud3g. */
96#define ASSERT_SEL_AUD(imsi, expect_rc, expect_id) \
97 do { \
Neels Hofmeyrb6837e32017-10-10 23:20:26 +020098 fill_invalid(g_aud2g); \
99 fill_invalid(g_aud3g); \
Neels Hofmeyr1332a172017-10-10 02:25:00 +0200100 g_id = 0; \
101 ASSERT_RC(db_get_auth_data(dbc, imsi, &g_aud2g, &g_aud3g, &g_id), expect_rc); \
Neels Hofmeyr57a87922017-10-09 17:51:13 +0200102 if (!g_rc) { \
Neels Hofmeyr1332a172017-10-10 02:25:00 +0200103 dump_aud("2G", &g_aud2g); \
104 dump_aud("3G", &g_aud3g); \
105 }\
106 if (g_id != expect_id) {\
107 fprintf(stderr, "MISMATCH: got subscriber id %"PRId64 \
108 ", expected %"PRId64"\n", g_id, (int64_t)(expect_id)); \
109 OSMO_ASSERT(g_id == expect_id); \
110 } \
111 fprintf(stderr, "\n"); \
112 } while (0)
113
Neels Hofmeyr2dee60e2017-11-23 15:27:50 +0100114#define N_VECTORS 3
115
116#define ASSERT_DB_GET_AUC(imsi, expect_rc) \
117 do { \
118 struct osmo_auth_vector vec[N_VECTORS]; \
Harald Welte06f5af22019-08-21 20:01:31 +0200119 ASSERT_RC(db_get_auc(dbc, imsi, 3, vec, N_VECTORS, NULL, NULL, false), expect_rc); \
Neels Hofmeyr2dee60e2017-11-23 15:27:50 +0100120 } while (0)
121
122/* Not linking the real auc_compute_vectors(), just returning num_vec.
123 * This gets called by db_get_auc(), but we're only interested in its rc. */
124int auc_compute_vectors(struct osmo_auth_vector *vec, unsigned int num_vec,
125 struct osmo_sub_auth_data *aud2g,
126 struct osmo_sub_auth_data *aud3g,
127 const uint8_t *rand_auts, const uint8_t *auts)
128{ return num_vec; }
129
Neels Hofmeyr98509462017-10-09 17:28:53 +0200130static struct db_context *dbc = NULL;
131static void *ctx = NULL;
132static struct hlr_subscriber g_subscr;
Neels Hofmeyr1332a172017-10-10 02:25:00 +0200133static struct osmo_sub_auth_data g_aud2g;
134static struct osmo_sub_auth_data g_aud3g;
Neels Hofmeyr98509462017-10-09 17:28:53 +0200135static int g_rc;
Neels Hofmeyr9c2bbc82017-10-09 17:30:32 +0200136static int64_t g_id;
Neels Hofmeyr98509462017-10-09 17:28:53 +0200137
138#define Pfv(name, fmt, val) \
139 fprintf(stderr, " ." #name " = " fmt ",\n", val)
140#define Pfo(name, fmt, obj) \
141 Pfv(name, fmt, obj->name)
142
143/* Print a subscriber struct to stderr to be validated by db_test.err. */
144void dump_subscr(struct hlr_subscriber *subscr)
145{
146#define Ps(name) \
147 if (*subscr->name) \
148 Pfo(name, "'%s'", subscr)
Neels Hofmeyrf13a8bc2019-11-20 02:36:45 +0100149#define Pgt(name) \
150 Pfv(name, "%s", osmo_ipa_name_to_str(&subscr->name))
Neels Hofmeyr98509462017-10-09 17:28:53 +0200151#define Pd(name) \
152 Pfv(name, "%"PRId64, (int64_t)subscr->name)
153#define Pd_nonzero(name) \
154 if (subscr->name) \
155 Pd(name)
156#define Pb(if_val, name) \
157 if (subscr->name == (if_val)) \
158 Pfv(name, "%s", subscr->name ? "true" : "false")
159
160 fprintf(stderr, "struct hlr_subscriber {\n");
161 Pd(id);
162 Ps(imsi);
163 Ps(msisdn);
Oliver Smith81db3892019-01-09 12:03:51 +0100164 Ps(imei);
Neels Hofmeyr98509462017-10-09 17:28:53 +0200165 Ps(vlr_number);
166 Ps(sgsn_number);
167 Ps(sgsn_address);
168 Pd_nonzero(periodic_lu_timer);
169 Pd_nonzero(periodic_rau_tau_timer);
170 Pb(false, nam_cs);
171 Pb(false, nam_ps);
172 if (subscr->lmsi)
173 Pfo(lmsi, "0x%x", subscr);
174 Pb(true, ms_purged_cs);
175 Pb(true, ms_purged_ps);
176 fprintf(stderr, "}\n");
177#undef Ps
178#undef Pd
179#undef Pd_nonzero
180#undef Pb
181}
182
183void dump_aud(const char *label, struct osmo_sub_auth_data *aud)
184{
185 if (aud->type == OSMO_AUTH_TYPE_NONE) {
186 fprintf(stderr, "%s: none\n", label);
187 return;
188 }
189
190 fprintf(stderr, "%s: struct osmo_sub_auth_data {\n", label);
191#define Pf(name, fmt) \
192 Pfo(name, fmt, aud)
193#define Phex(name) \
194 Pfv(name, "'%s'", osmo_hexdump_nospc(aud->name, sizeof(aud->name)))
195
196 Pfv(type, "%s", osmo_sub_auth_type_name(aud->type));
197 Pfv(algo, "%s", osmo_auth_alg_name(aud->algo));
198 switch (aud->type) {
199 case OSMO_AUTH_TYPE_GSM:
200 Phex(u.gsm.ki);
201 break;
202 case OSMO_AUTH_TYPE_UMTS:
203 Phex(u.umts.opc);
204 Pf(u.umts.opc_is_op, "%u");
205 Phex(u.umts.k);
206 Phex(u.umts.amf);
207 if (aud->u.umts.sqn) {
208 Pf(u.umts.sqn, "%"PRIu64);
209 Pf(u.umts.sqn, "0x%"PRIx64);
210 }
211 if (aud->u.umts.ind_bitlen)
212 Pf(u.umts.ind_bitlen, "%u");
213 break;
214 default:
215 OSMO_ASSERT(false);
216 }
217
218 fprintf(stderr, "}\n");
219
220#undef Pf
221#undef Phex
222}
223
Oliver Smith6401b902019-07-24 11:32:45 +0200224void db_raw_sql(struct db_context *dbc, const char *sql)
225{
226 sqlite3_stmt *stmt;
227
228 fprintf(stderr, "raw SQL: %s\n", sql);
229 ASSERT_RC(sqlite3_prepare_v2(dbc->db, sql, -1, &stmt, NULL), SQLITE_OK);
230 ASSERT_RC(sqlite3_step(stmt), SQLITE_DONE);
231 db_remove_reset(stmt);
232 sqlite3_finalize(stmt);
233}
234
Neels Hofmeyr98509462017-10-09 17:28:53 +0200235static const char *imsi0 = "123456789000000";
236static const char *imsi1 = "123456789000001";
237static const char *imsi2 = "123456789000002";
238static const char *short_imsi = "123456";
239static const char *unknown_imsi = "999999999";
240
Neels Hofmeyrf13a8bc2019-11-20 02:36:45 +0100241static int db_subscr_lu_str(struct db_context *dbc, int64_t subscr_id,
242 const char *vlr_or_sgsn_number, bool is_ps)
243{
244 struct osmo_ipa_name vlr_nr;
245 osmo_ipa_name_set_str(&vlr_nr, vlr_or_sgsn_number);
246 return db_subscr_lu(dbc, subscr_id, &vlr_nr, is_ps, NULL);
247}
248
Neels Hofmeyr98509462017-10-09 17:28:53 +0200249static void test_subscr_create_update_sel_delete()
250{
251 int64_t id0, id1, id2, id_short;
252 comment_start();
253
254 comment("Create with valid / invalid IMSI");
255
Oliver Smithcd2af5e2019-03-06 13:17:39 +0100256 ASSERT_RC(db_subscr_create(dbc, imsi0, DB_SUBSCR_FLAG_NAM_CS | DB_SUBSCR_FLAG_NAM_PS), 0);
Neels Hofmeyr98509462017-10-09 17:28:53 +0200257 ASSERT_SEL(imsi, imsi0, 0);
258 id0 = g_subscr.id;
Oliver Smithcd2af5e2019-03-06 13:17:39 +0100259 ASSERT_RC(db_subscr_create(dbc, imsi1, DB_SUBSCR_FLAG_NAM_CS | DB_SUBSCR_FLAG_NAM_PS), 0);
Neels Hofmeyr98509462017-10-09 17:28:53 +0200260 ASSERT_SEL(imsi, imsi1, 0);
261 id1 = g_subscr.id;
Oliver Smithcd2af5e2019-03-06 13:17:39 +0100262 ASSERT_RC(db_subscr_create(dbc, imsi2, DB_SUBSCR_FLAG_NAM_CS | DB_SUBSCR_FLAG_NAM_PS), 0);
Neels Hofmeyr98509462017-10-09 17:28:53 +0200263 ASSERT_SEL(imsi, imsi2, 0);
264 id2 = g_subscr.id;
Oliver Smithcd2af5e2019-03-06 13:17:39 +0100265 ASSERT_RC(db_subscr_create(dbc, imsi0, DB_SUBSCR_FLAG_NAM_CS | DB_SUBSCR_FLAG_NAM_PS), -EIO);
Neels Hofmeyr98509462017-10-09 17:28:53 +0200266 ASSERT_SEL(imsi, imsi0, 0);
Oliver Smithcd2af5e2019-03-06 13:17:39 +0100267 ASSERT_RC(db_subscr_create(dbc, imsi1, DB_SUBSCR_FLAG_NAM_CS | DB_SUBSCR_FLAG_NAM_PS), -EIO);
268 ASSERT_RC(db_subscr_create(dbc, imsi1, DB_SUBSCR_FLAG_NAM_CS | DB_SUBSCR_FLAG_NAM_PS), -EIO);
Neels Hofmeyr98509462017-10-09 17:28:53 +0200269 ASSERT_SEL(imsi, imsi1, 0);
Oliver Smithcd2af5e2019-03-06 13:17:39 +0100270 ASSERT_RC(db_subscr_create(dbc, imsi2, DB_SUBSCR_FLAG_NAM_CS | DB_SUBSCR_FLAG_NAM_PS), -EIO);
271 ASSERT_RC(db_subscr_create(dbc, imsi2, DB_SUBSCR_FLAG_NAM_CS | DB_SUBSCR_FLAG_NAM_PS), -EIO);
Neels Hofmeyr98509462017-10-09 17:28:53 +0200272 ASSERT_SEL(imsi, imsi2, 0);
273
Oliver Smithcd2af5e2019-03-06 13:17:39 +0100274 ASSERT_RC(db_subscr_create(dbc, "123456789 000003", DB_SUBSCR_FLAG_NAM_CS | DB_SUBSCR_FLAG_NAM_PS), -EINVAL);
Neels Hofmeyr9c2bbc82017-10-09 17:30:32 +0200275 ASSERT_SEL(imsi, "123456789000003", -ENOENT);
Neels Hofmeyr98509462017-10-09 17:28:53 +0200276
Oliver Smithcd2af5e2019-03-06 13:17:39 +0100277 ASSERT_RC(db_subscr_create(dbc, "123456789000002123456", DB_SUBSCR_FLAG_NAM_CS | DB_SUBSCR_FLAG_NAM_PS),
278 -EINVAL);
Neels Hofmeyr9c2bbc82017-10-09 17:30:32 +0200279 ASSERT_SEL(imsi, "123456789000002123456", -ENOENT);
Neels Hofmeyr98509462017-10-09 17:28:53 +0200280
Oliver Smithcd2af5e2019-03-06 13:17:39 +0100281 ASSERT_RC(db_subscr_create(dbc, "foobar123", DB_SUBSCR_FLAG_NAM_CS | DB_SUBSCR_FLAG_NAM_PS), -EINVAL);
Neels Hofmeyr9c2bbc82017-10-09 17:30:32 +0200282 ASSERT_SEL(imsi, "foobar123", -ENOENT);
Neels Hofmeyr98509462017-10-09 17:28:53 +0200283
Oliver Smithcd2af5e2019-03-06 13:17:39 +0100284 ASSERT_RC(db_subscr_create(dbc, "123", DB_SUBSCR_FLAG_NAM_CS | DB_SUBSCR_FLAG_NAM_PS), -EINVAL);
Neels Hofmeyr9c2bbc82017-10-09 17:30:32 +0200285 ASSERT_SEL(imsi, "123", -ENOENT);
Neels Hofmeyr98509462017-10-09 17:28:53 +0200286
Oliver Smithcd2af5e2019-03-06 13:17:39 +0100287 ASSERT_RC(db_subscr_create(dbc, short_imsi, DB_SUBSCR_FLAG_NAM_CS | DB_SUBSCR_FLAG_NAM_PS), 0);
Neels Hofmeyr98509462017-10-09 17:28:53 +0200288 ASSERT_SEL(imsi, short_imsi, 0);
289 id_short = g_subscr.id;
290
Oliver Smith6b73fd92019-03-06 13:49:05 +0100291 comment("Check if subscriber exists (by IMSI)");
292
293 ASSERT_RC(db_subscr_exists_by_imsi(dbc, imsi0), 0);
294 ASSERT_RC(db_subscr_exists_by_imsi(dbc, unknown_imsi), -ENOENT);
Neels Hofmeyr98509462017-10-09 17:28:53 +0200295
296 comment("Set valid / invalid MSISDN");
297
298 ASSERT_SEL(imsi, imsi0, 0);
299 ASSERT_RC(db_subscr_update_msisdn_by_imsi(dbc, imsi0, "54321"), 0);
300 ASSERT_SEL(imsi, imsi0, 0);
Neels Hofmeyr9c2bbc82017-10-09 17:30:32 +0200301 ASSERT_SEL(msisdn, "54321", 0);
Neels Hofmeyr98509462017-10-09 17:28:53 +0200302 ASSERT_RC(db_subscr_update_msisdn_by_imsi(dbc, imsi0,
303 "54321012345678912345678"), -EINVAL);
304 ASSERT_SEL(imsi, imsi0, 0);
Neels Hofmeyr9c2bbc82017-10-09 17:30:32 +0200305 ASSERT_SEL(msisdn, "54321", 0);
306 ASSERT_SEL(msisdn, "54321012345678912345678", -ENOENT);
Neels Hofmeyr98509462017-10-09 17:28:53 +0200307 ASSERT_RC(db_subscr_update_msisdn_by_imsi(dbc, imsi0,
308 "543 21"), -EINVAL);
309 ASSERT_SEL(imsi, imsi0, 0);
Neels Hofmeyr9c2bbc82017-10-09 17:30:32 +0200310 ASSERT_SEL(msisdn, "543 21", -ENOENT);
Neels Hofmeyr98509462017-10-09 17:28:53 +0200311 ASSERT_RC(db_subscr_update_msisdn_by_imsi(dbc, imsi0,
312 "foobar123"), -EINVAL);
313 ASSERT_SEL(imsi, imsi0, 0);
Neels Hofmeyr9c2bbc82017-10-09 17:30:32 +0200314 ASSERT_SEL(msisdn, "foobar123", -ENOENT);
Neels Hofmeyr98509462017-10-09 17:28:53 +0200315 ASSERT_RC(db_subscr_update_msisdn_by_imsi(dbc, imsi0,
316 "5"), 0);
317 ASSERT_SEL(imsi, imsi0, 0);
Neels Hofmeyr9c2bbc82017-10-09 17:30:32 +0200318 ASSERT_SEL(msisdn, "5", 0);
319 ASSERT_SEL(msisdn, "54321", -ENOENT);
Neels Hofmeyr98509462017-10-09 17:28:53 +0200320 ASSERT_RC(db_subscr_update_msisdn_by_imsi(dbc, imsi0,
321 "543210123456789"), 0);
322 ASSERT_SEL(imsi, imsi0, 0);
Neels Hofmeyr9c2bbc82017-10-09 17:30:32 +0200323 ASSERT_SEL(msisdn, "543210123456789", 0);
Neels Hofmeyr98509462017-10-09 17:28:53 +0200324 ASSERT_RC(db_subscr_update_msisdn_by_imsi(dbc, imsi0,
325 "5432101234567891"), -EINVAL);
326 ASSERT_SEL(imsi, imsi0, 0);
Neels Hofmeyr9c2bbc82017-10-09 17:30:32 +0200327 ASSERT_SEL(msisdn, "5432101234567891", -ENOENT);
Neels Hofmeyr98509462017-10-09 17:28:53 +0200328
Vadim Yanitskiyc13599d2019-03-30 17:03:42 +0700329 comment("Check if subscriber exists (by MSISDN)");
330
331 ASSERT_RC(db_subscr_exists_by_msisdn(dbc, "543210123456789"), 0);
332 ASSERT_RC(db_subscr_exists_by_msisdn(dbc, "5432101234567891"), -ENOENT);
333
Neels Hofmeyr98509462017-10-09 17:28:53 +0200334 comment("Set MSISDN on non-existent / invalid IMSI");
335
336 ASSERT_RC(db_subscr_update_msisdn_by_imsi(dbc, unknown_imsi, "99"), -ENOENT);
Neels Hofmeyr9c2bbc82017-10-09 17:30:32 +0200337 ASSERT_SEL(msisdn, "99", -ENOENT);
Neels Hofmeyr98509462017-10-09 17:28:53 +0200338
339 ASSERT_RC(db_subscr_update_msisdn_by_imsi(dbc, "foobar", "99"), -ENOENT);
Neels Hofmeyr9c2bbc82017-10-09 17:30:32 +0200340 ASSERT_SEL(msisdn, "99", -ENOENT);
Neels Hofmeyr98509462017-10-09 17:28:53 +0200341
Oliver Smith81db3892019-01-09 12:03:51 +0100342 comment("Set valid / invalid IMEI");
343
344 ASSERT_RC(db_subscr_update_imei_by_imsi(dbc, imsi0, "12345678901234"), 0);
345 ASSERT_SEL(imei, "12345678901234", 0);
346
347 ASSERT_RC(db_subscr_update_imei_by_imsi(dbc, imsi0, "123456789012345"), -EINVAL); /* too long */
348 ASSERT_SEL(imei, "12345678901234", 0);
349 ASSERT_SEL(imei, "123456789012345", -ENOENT);
350
351 comment("Set the same IMEI again");
352 ASSERT_RC(db_subscr_update_imei_by_imsi(dbc, imsi0, "12345678901234"), 0);
353 ASSERT_SEL(imei, "12345678901234", 0);
354
355 comment("Remove IMEI");
356 ASSERT_RC(db_subscr_update_imei_by_imsi(dbc, imsi0, NULL), 0);
357 ASSERT_SEL(imei, "12345678901234", -ENOENT);
358
Neels Hofmeyre8ccd502017-10-06 04:10:06 +0200359 comment("Set / unset nam_cs and nam_ps");
360
361 /* nam_val, is_ps */
362 ASSERT_RC(db_subscr_nam(dbc, imsi0, false, true), 0);
363 ASSERT_SEL(imsi, imsi0, 0);
364 ASSERT_RC(db_subscr_nam(dbc, imsi0, false, false), 0);
365 ASSERT_SEL(imsi, imsi0, 0);
366 ASSERT_RC(db_subscr_nam(dbc, imsi0, true, false), 0);
367 ASSERT_SEL(imsi, imsi0, 0);
368 ASSERT_RC(db_subscr_nam(dbc, imsi0, true, true), 0);
369 ASSERT_SEL(imsi, imsi0, 0);
370
371 comment("Set / unset nam_cs and nam_ps *again*");
372 ASSERT_RC(db_subscr_nam(dbc, imsi0, false, true), 0);
373 ASSERT_SEL(imsi, imsi0, 0);
374 ASSERT_RC(db_subscr_nam(dbc, imsi0, false, true), 0);
375 ASSERT_SEL(imsi, imsi0, 0);
376 ASSERT_RC(db_subscr_nam(dbc, imsi0, false, false), 0);
377 ASSERT_SEL(imsi, imsi0, 0);
378 ASSERT_RC(db_subscr_nam(dbc, imsi0, false, false), 0);
379 ASSERT_SEL(imsi, imsi0, 0);
380 ASSERT_RC(db_subscr_nam(dbc, imsi0, true, true), 0);
381 ASSERT_SEL(imsi, imsi0, 0);
382 ASSERT_RC(db_subscr_nam(dbc, imsi0, true, true), 0);
383 ASSERT_SEL(imsi, imsi0, 0);
384 ASSERT_RC(db_subscr_nam(dbc, imsi0, true, false), 0);
385 ASSERT_SEL(imsi, imsi0, 0);
386 ASSERT_RC(db_subscr_nam(dbc, imsi0, true, false), 0);
387 ASSERT_SEL(imsi, imsi0, 0);
388
389 comment("Set nam_cs and nam_ps on non-existent / invalid IMSI");
390
391 ASSERT_RC(db_subscr_nam(dbc, unknown_imsi, false, true), -ENOENT);
392 ASSERT_RC(db_subscr_nam(dbc, unknown_imsi, false, false), -ENOENT);
393 ASSERT_SEL(imsi, unknown_imsi, -ENOENT);
394
395 ASSERT_RC(db_subscr_nam(dbc, "foobar", false, true), -ENOENT);
396 ASSERT_RC(db_subscr_nam(dbc, "foobar", false, false), -ENOENT);
397
Neels Hofmeyrdd783052017-10-09 17:36:08 +0200398 comment("Record LU for PS and CS (SGSN and VLR names)");
399
Neels Hofmeyrf13a8bc2019-11-20 02:36:45 +0100400 ASSERT_RC(db_subscr_lu_str(dbc, id0, "5952", true), 0);
Neels Hofmeyrdd783052017-10-09 17:36:08 +0200401 ASSERT_SEL(id, id0, 0);
Neels Hofmeyrf13a8bc2019-11-20 02:36:45 +0100402 ASSERT_RC(db_subscr_lu_str(dbc, id0, "712", false), 0);
Neels Hofmeyrdd783052017-10-09 17:36:08 +0200403 ASSERT_SEL(id, id0, 0);
404
405 comment("Record LU for PS and CS (SGSN and VLR names) *again*");
406
Neels Hofmeyrf13a8bc2019-11-20 02:36:45 +0100407 ASSERT_RC(db_subscr_lu_str(dbc, id0, "111", true), 0);
Neels Hofmeyrdd783052017-10-09 17:36:08 +0200408 ASSERT_SEL(id, id0, 0);
Neels Hofmeyrf13a8bc2019-11-20 02:36:45 +0100409 ASSERT_RC(db_subscr_lu_str(dbc, id0, "111", true), 0);
Neels Hofmeyrdd783052017-10-09 17:36:08 +0200410 ASSERT_SEL(id, id0, 0);
Neels Hofmeyrf13a8bc2019-11-20 02:36:45 +0100411 ASSERT_RC(db_subscr_lu_str(dbc, id0, "222", false), 0);
Neels Hofmeyrdd783052017-10-09 17:36:08 +0200412 ASSERT_SEL(id, id0, 0);
Neels Hofmeyrf13a8bc2019-11-20 02:36:45 +0100413 ASSERT_RC(db_subscr_lu_str(dbc, id0, "222", false), 0);
Neels Hofmeyrdd783052017-10-09 17:36:08 +0200414 ASSERT_SEL(id, id0, 0);
415
416 comment("Unset LU info for PS and CS (SGSN and VLR names)");
Neels Hofmeyrf13a8bc2019-11-20 02:36:45 +0100417 ASSERT_RC(db_subscr_lu_str(dbc, id0, "", true), 0);
Neels Hofmeyrdd783052017-10-09 17:36:08 +0200418 ASSERT_SEL(id, id0, 0);
Neels Hofmeyrf13a8bc2019-11-20 02:36:45 +0100419 ASSERT_RC(db_subscr_lu_str(dbc, id0, "", false), 0);
Neels Hofmeyrdd783052017-10-09 17:36:08 +0200420 ASSERT_SEL(id, id0, 0);
421
Neels Hofmeyrf13a8bc2019-11-20 02:36:45 +0100422 ASSERT_RC(db_subscr_lu_str(dbc, id0, "111", true), 0);
423 ASSERT_RC(db_subscr_lu_str(dbc, id0, "222", false), 0);
Neels Hofmeyrdd783052017-10-09 17:36:08 +0200424 ASSERT_SEL(id, id0, 0);
Neels Hofmeyrf13a8bc2019-11-20 02:36:45 +0100425 ASSERT_RC(db_subscr_lu_str(dbc, id0, NULL, true), 0);
Neels Hofmeyrdd783052017-10-09 17:36:08 +0200426 ASSERT_SEL(id, id0, 0);
Neels Hofmeyrf13a8bc2019-11-20 02:36:45 +0100427 ASSERT_RC(db_subscr_lu_str(dbc, id0, NULL, false), 0);
Neels Hofmeyrdd783052017-10-09 17:36:08 +0200428 ASSERT_SEL(id, id0, 0);
429
430 comment("Record LU for non-existent ID");
Neels Hofmeyrf13a8bc2019-11-20 02:36:45 +0100431 ASSERT_RC(db_subscr_lu_str(dbc, 99999, "5952", true), -ENOENT);
432 ASSERT_RC(db_subscr_lu_str(dbc, 99999, "712", false), -ENOENT);
Neels Hofmeyrdd783052017-10-09 17:36:08 +0200433 ASSERT_SEL(id, 99999, -ENOENT);
434
Neels Hofmeyre50121e2017-10-09 17:48:51 +0200435 comment("Purge and un-purge PS and CS");
436
437 /* purge_val, is_ps */
438 ASSERT_RC(db_subscr_purge(dbc, imsi0, true, true), 0);
439 ASSERT_SEL(imsi, imsi0, 0);
440 ASSERT_RC(db_subscr_purge(dbc, imsi0, true, false), 0);
441 ASSERT_SEL(imsi, imsi0, 0);
442 ASSERT_RC(db_subscr_purge(dbc, imsi0, false, false), 0);
443 ASSERT_SEL(imsi, imsi0, 0);
444 ASSERT_RC(db_subscr_purge(dbc, imsi0, false, true), 0);
445 ASSERT_SEL(imsi, imsi0, 0);
446
447 comment("Purge PS and CS *again*");
448
449 ASSERT_RC(db_subscr_purge(dbc, imsi0, true, true), 0);
450 ASSERT_SEL(imsi, imsi0, 0);
451 ASSERT_RC(db_subscr_purge(dbc, imsi0, true, true), 0);
452 ASSERT_SEL(imsi, imsi0, 0);
453 ASSERT_RC(db_subscr_purge(dbc, imsi0, false, true), 0);
454 ASSERT_SEL(imsi, imsi0, 0);
455 ASSERT_RC(db_subscr_purge(dbc, imsi0, false, true), 0);
456 ASSERT_SEL(imsi, imsi0, 0);
457 ASSERT_RC(db_subscr_purge(dbc, imsi0, true, false), 0);
458 ASSERT_SEL(imsi, imsi0, 0);
459 ASSERT_RC(db_subscr_purge(dbc, imsi0, true, false), 0);
460 ASSERT_SEL(imsi, imsi0, 0);
461 ASSERT_RC(db_subscr_purge(dbc, imsi0, false, false), 0);
462 ASSERT_SEL(imsi, imsi0, 0);
463 ASSERT_RC(db_subscr_purge(dbc, imsi0, false, false), 0);
464 ASSERT_SEL(imsi, imsi0, 0);
465
466 comment("Purge on non-existent / invalid IMSI");
467
468 ASSERT_RC(db_subscr_purge(dbc, unknown_imsi, true, true), -ENOENT);
469 ASSERT_SEL(imsi, unknown_imsi, -ENOENT);
470 ASSERT_RC(db_subscr_purge(dbc, unknown_imsi, true, false), -ENOENT);
471 ASSERT_SEL(imsi, unknown_imsi, -ENOENT);
472
Neels Hofmeyr98509462017-10-09 17:28:53 +0200473 comment("Delete non-existent / invalid IDs");
474
475 ASSERT_RC(db_subscr_delete_by_id(dbc, 999), -ENOENT);
476 ASSERT_RC(db_subscr_delete_by_id(dbc, -10), -ENOENT);
477
478 comment("Delete subscribers");
479
480 ASSERT_SEL(imsi, imsi0, 0);
481 ASSERT_RC(db_subscr_delete_by_id(dbc, id0), 0);
Neels Hofmeyr9c2bbc82017-10-09 17:30:32 +0200482 ASSERT_SEL(imsi, imsi0, -ENOENT);
Neels Hofmeyr98509462017-10-09 17:28:53 +0200483 ASSERT_RC(db_subscr_delete_by_id(dbc, id0), -ENOENT);
484
485 ASSERT_SEL(imsi, imsi1, 0);
486 ASSERT_RC(db_subscr_delete_by_id(dbc, id1), 0);
Neels Hofmeyr9c2bbc82017-10-09 17:30:32 +0200487 ASSERT_SEL(imsi, imsi1, -ENOENT);
Neels Hofmeyr98509462017-10-09 17:28:53 +0200488
489 ASSERT_SEL(imsi, imsi2, 0);
490 ASSERT_RC(db_subscr_delete_by_id(dbc, id2), 0);
Neels Hofmeyr9c2bbc82017-10-09 17:30:32 +0200491 ASSERT_SEL(imsi, imsi2, -ENOENT);
Neels Hofmeyr98509462017-10-09 17:28:53 +0200492
493 ASSERT_SEL(imsi, short_imsi, 0);
494 ASSERT_RC(db_subscr_delete_by_id(dbc, id_short), 0);
Neels Hofmeyr9c2bbc82017-10-09 17:30:32 +0200495 ASSERT_SEL(imsi, short_imsi, -ENOENT);
Neels Hofmeyr98509462017-10-09 17:28:53 +0200496
Oliver Smithcd2af5e2019-03-06 13:17:39 +0100497 comment("Create and delete subscribers with non-default nam_cs and nam_ps");
498
499 ASSERT_RC(db_subscr_create(dbc, imsi0, 0x00), 0);
500 ASSERT_SEL(imsi, imsi0, 0);
501 id0 = g_subscr.id;
502 ASSERT_RC(db_subscr_create(dbc, imsi1, DB_SUBSCR_FLAG_NAM_CS), 0);
503 ASSERT_SEL(imsi, imsi1, 0);
504 id1 = g_subscr.id;
505 ASSERT_RC(db_subscr_create(dbc, imsi2, DB_SUBSCR_FLAG_NAM_PS), 0);
506 ASSERT_SEL(imsi, imsi2, 0);
507 id2 = g_subscr.id;
508
509 ASSERT_RC(db_subscr_delete_by_id(dbc, id0), 0);
510 ASSERT_RC(db_subscr_delete_by_id(dbc, id1), 0);
511 ASSERT_RC(db_subscr_delete_by_id(dbc, id2), 0);
512
Neels Hofmeyr98509462017-10-09 17:28:53 +0200513 comment_end();
514}
515
Neels Hofmeyr1332a172017-10-10 02:25:00 +0200516static const struct sub_auth_data_str *mk_aud_2g(enum osmo_auth_algo algo,
517 const char *ki)
518{
519 static struct sub_auth_data_str aud;
520 aud = (struct sub_auth_data_str){
521 .type = OSMO_AUTH_TYPE_GSM,
522 .algo = algo,
523 .u.gsm.ki = ki,
524 };
525 return &aud;
526}
527
528static const struct sub_auth_data_str *mk_aud_3g(enum osmo_auth_algo algo,
529 const char *opc, bool opc_is_op,
530 const char *k, unsigned int ind_bitlen)
531{
532 static struct sub_auth_data_str aud;
533 aud = (struct sub_auth_data_str){
534 .type = OSMO_AUTH_TYPE_UMTS,
535 .algo = algo,
536 .u.umts.k = k,
537 .u.umts.opc = opc,
538 .u.umts.opc_is_op = opc_is_op ? 1 : 0,
539 .u.umts.ind_bitlen = ind_bitlen,
540 };
541 return &aud;
542}
543
544static void test_subscr_aud()
545{
546 int64_t id;
547
548 comment_start();
549
550 comment("Get auth data for non-existent subscriber");
Neels Hofmeyr57a87922017-10-09 17:51:13 +0200551 ASSERT_SEL_AUD(unknown_imsi, -ENOENT, 0);
Neels Hofmeyr2dee60e2017-11-23 15:27:50 +0100552 ASSERT_DB_GET_AUC(imsi0, -ENOENT);
Neels Hofmeyr1332a172017-10-10 02:25:00 +0200553
554 comment("Create subscriber");
555
Oliver Smithcd2af5e2019-03-06 13:17:39 +0100556 ASSERT_RC(db_subscr_create(dbc, imsi0, DB_SUBSCR_FLAG_NAM_CS | DB_SUBSCR_FLAG_NAM_PS), 0);
Neels Hofmeyr1332a172017-10-10 02:25:00 +0200557 ASSERT_SEL(imsi, imsi0, 0);
558
559 id = g_subscr.id;
Neels Hofmeyrbd1dca02017-11-23 15:25:30 +0100560 ASSERT_SEL_AUD(imsi0, -ENOKEY, id);
Neels Hofmeyr2dee60e2017-11-23 15:27:50 +0100561 ASSERT_DB_GET_AUC(imsi0, -ENOKEY);
Neels Hofmeyr1332a172017-10-10 02:25:00 +0200562
563
564 comment("Set auth data, 2G only");
565
566 ASSERT_RC(db_subscr_update_aud_by_id(dbc, id,
567 mk_aud_2g(OSMO_AUTH_ALG_COMP128v1, "0123456789abcdef0123456789abcdef")),
568 0);
Neels Hofmeyr57a87922017-10-09 17:51:13 +0200569 ASSERT_SEL_AUD(imsi0, 0, id);
Neels Hofmeyr2dee60e2017-11-23 15:27:50 +0100570 ASSERT_DB_GET_AUC(imsi0, N_VECTORS);
Neels Hofmeyr1332a172017-10-10 02:25:00 +0200571
572 /* same again */
573 ASSERT_RC(db_subscr_update_aud_by_id(dbc, id,
574 mk_aud_2g(OSMO_AUTH_ALG_COMP128v1, "0123456789abcdef0123456789abcdef")),
575 0);
Neels Hofmeyr57a87922017-10-09 17:51:13 +0200576 ASSERT_SEL_AUD(imsi0, 0, id);
Neels Hofmeyr1332a172017-10-10 02:25:00 +0200577
578 ASSERT_RC(db_subscr_update_aud_by_id(dbc, id,
579 mk_aud_2g(OSMO_AUTH_ALG_COMP128v2, "BeadedBeeAced1EbbedDefacedFacade")),
580 0);
Neels Hofmeyr57a87922017-10-09 17:51:13 +0200581 ASSERT_SEL_AUD(imsi0, 0, id);
Neels Hofmeyr1332a172017-10-10 02:25:00 +0200582
583 ASSERT_RC(db_subscr_update_aud_by_id(dbc, id,
584 mk_aud_2g(OSMO_AUTH_ALG_COMP128v3, "DeafBeddedBabeAcceededFadedDecaf")),
585 0);
Neels Hofmeyr57a87922017-10-09 17:51:13 +0200586 ASSERT_SEL_AUD(imsi0, 0, id);
Neels Hofmeyr1332a172017-10-10 02:25:00 +0200587
588 ASSERT_RC(db_subscr_update_aud_by_id(dbc, id,
589 mk_aud_2g(OSMO_AUTH_ALG_XOR, "CededEffacedAceFacedBadFadedBeef")),
590 0);
Neels Hofmeyr57a87922017-10-09 17:51:13 +0200591 ASSERT_SEL_AUD(imsi0, 0, id);
Neels Hofmeyr1332a172017-10-10 02:25:00 +0200592
593 comment("Remove 2G auth data");
594
595 ASSERT_RC(db_subscr_update_aud_by_id(dbc, id,
596 mk_aud_2g(OSMO_AUTH_ALG_NONE, NULL)),
597 0);
Neels Hofmeyrbd1dca02017-11-23 15:25:30 +0100598 ASSERT_SEL_AUD(imsi0, -ENOKEY, id);
Neels Hofmeyr2dee60e2017-11-23 15:27:50 +0100599 ASSERT_DB_GET_AUC(imsi0, -ENOKEY);
Neels Hofmeyr1332a172017-10-10 02:25:00 +0200600
601 /* Removing nothing results in -ENOENT */
602 ASSERT_RC(db_subscr_update_aud_by_id(dbc, id,
603 mk_aud_2g(OSMO_AUTH_ALG_NONE, NULL)),
604 -ENOENT);
605
606 ASSERT_RC(db_subscr_update_aud_by_id(dbc, id,
607 mk_aud_2g(OSMO_AUTH_ALG_XOR, "CededEffacedAceFacedBadFadedBeef")),
608 0);
Neels Hofmeyr57a87922017-10-09 17:51:13 +0200609 ASSERT_SEL_AUD(imsi0, 0, id);
Neels Hofmeyr1332a172017-10-10 02:25:00 +0200610
611 ASSERT_RC(db_subscr_update_aud_by_id(dbc, id,
612 mk_aud_2g(OSMO_AUTH_ALG_NONE, "f000000000000f00000000000f000000")),
613 0);
Neels Hofmeyrbd1dca02017-11-23 15:25:30 +0100614 ASSERT_SEL_AUD(imsi0, -ENOKEY, id);
Neels Hofmeyr2dee60e2017-11-23 15:27:50 +0100615 ASSERT_DB_GET_AUC(imsi0, -ENOKEY);
Neels Hofmeyr1332a172017-10-10 02:25:00 +0200616
617
618 comment("Set auth data, 3G only");
619
620 ASSERT_RC(db_subscr_update_aud_by_id(dbc, id,
621 mk_aud_3g(OSMO_AUTH_ALG_MILENAGE,
622 "BeefedCafeFaceAcedAddedDecadeFee", true,
623 "C01ffedC1cadaeAc1d1f1edAcac1aB0a", 5)),
624 0);
Neels Hofmeyr57a87922017-10-09 17:51:13 +0200625 ASSERT_SEL_AUD(imsi0, 0, id);
Neels Hofmeyr2dee60e2017-11-23 15:27:50 +0100626 ASSERT_DB_GET_AUC(imsi0, N_VECTORS);
Neels Hofmeyr1332a172017-10-10 02:25:00 +0200627
628 /* same again */
629 ASSERT_RC(db_subscr_update_aud_by_id(dbc, id,
630 mk_aud_3g(OSMO_AUTH_ALG_MILENAGE,
631 "BeefedCafeFaceAcedAddedDecadeFee", true,
632 "C01ffedC1cadaeAc1d1f1edAcac1aB0a", 5)),
633 0);
Neels Hofmeyr57a87922017-10-09 17:51:13 +0200634 ASSERT_SEL_AUD(imsi0, 0, id);
Neels Hofmeyr1332a172017-10-10 02:25:00 +0200635
636 ASSERT_RC(db_subscr_update_aud_by_id(dbc, id,
637 mk_aud_3g(OSMO_AUTH_ALG_MILENAGE,
638 "Deaf0ff1ceD0d0DabbedD1ced1ceF00d", true,
639 "F1bbed0afD0eF0bD0ffed0ddF1fe0b0e", 0)),
640 0);
Neels Hofmeyr57a87922017-10-09 17:51:13 +0200641 ASSERT_SEL_AUD(imsi0, 0, id);
Neels Hofmeyr1332a172017-10-10 02:25:00 +0200642
643 ASSERT_RC(db_subscr_update_aud_by_id(dbc, id,
644 mk_aud_3g(OSMO_AUTH_ALG_MILENAGE,
645 "BeefedCafeFaceAcedAddedDecadeFee", false,
646 "DeafBeddedBabeAcceededFadedDecaf",
647 OSMO_MILENAGE_IND_BITLEN_MAX)),
648 0);
Neels Hofmeyr57a87922017-10-09 17:51:13 +0200649 ASSERT_SEL_AUD(imsi0, 0, id);
Neels Hofmeyr1332a172017-10-10 02:25:00 +0200650
651 ASSERT_RC(db_subscr_update_aud_by_id(dbc, id,
652 mk_aud_3g(OSMO_AUTH_ALG_MILENAGE,
653 "CededEffacedAceFacedBadFadedBeef", false,
654 "BeefedCafeFaceAcedAddedDecadeFee", 5)),
655 0);
Neels Hofmeyr57a87922017-10-09 17:51:13 +0200656 ASSERT_SEL_AUD(imsi0, 0, id);
Neels Hofmeyr1332a172017-10-10 02:25:00 +0200657
658 comment("Remove 3G auth data");
659
660 ASSERT_RC(db_subscr_update_aud_by_id(dbc, id,
661 mk_aud_3g(OSMO_AUTH_ALG_NONE, NULL, false, NULL, 0)),
662 0);
Neels Hofmeyrbd1dca02017-11-23 15:25:30 +0100663 ASSERT_SEL_AUD(imsi0, -ENOKEY, id);
Neels Hofmeyr2dee60e2017-11-23 15:27:50 +0100664 ASSERT_DB_GET_AUC(imsi0, -ENOKEY);
Neels Hofmeyr1332a172017-10-10 02:25:00 +0200665
666 /* Removing nothing results in -ENOENT */
667 ASSERT_RC(db_subscr_update_aud_by_id(dbc, id,
668 mk_aud_3g(OSMO_AUTH_ALG_NONE, NULL, false, NULL, 0)),
669 -ENOENT);
670
671 ASSERT_RC(db_subscr_update_aud_by_id(dbc, id,
672 mk_aud_3g(OSMO_AUTH_ALG_MILENAGE,
673 "CededEffacedAceFacedBadFadedBeef", false,
674 "BeefedCafeFaceAcedAddedDecadeFee", 5)),
675 0);
Neels Hofmeyr57a87922017-10-09 17:51:13 +0200676 ASSERT_SEL_AUD(imsi0, 0, id);
Neels Hofmeyr2dee60e2017-11-23 15:27:50 +0100677 ASSERT_DB_GET_AUC(imsi0, N_VECTORS);
Neels Hofmeyr1332a172017-10-10 02:25:00 +0200678
679 ASSERT_RC(db_subscr_update_aud_by_id(dbc, id,
680 mk_aud_3g(OSMO_AUTH_ALG_NONE,
681 "asdfasdfasd", false,
682 "asdfasdfasdf", 99999)),
683 0);
Neels Hofmeyrbd1dca02017-11-23 15:25:30 +0100684 ASSERT_SEL_AUD(imsi0, -ENOKEY, id);
Neels Hofmeyr2dee60e2017-11-23 15:27:50 +0100685 ASSERT_DB_GET_AUC(imsi0, -ENOKEY);
Neels Hofmeyr1332a172017-10-10 02:25:00 +0200686
687
688 comment("Set auth data, 2G and 3G");
689
690 ASSERT_RC(db_subscr_update_aud_by_id(dbc, id,
691 mk_aud_2g(OSMO_AUTH_ALG_COMP128v3, "CededEffacedAceFacedBadFadedBeef")),
692 0);
693 ASSERT_RC(db_subscr_update_aud_by_id(dbc, id,
694 mk_aud_3g(OSMO_AUTH_ALG_MILENAGE,
695 "BeefedCafeFaceAcedAddedDecadeFee", false,
696 "DeafBeddedBabeAcceededFadedDecaf", 5)),
697 0);
Neels Hofmeyr57a87922017-10-09 17:51:13 +0200698 ASSERT_SEL_AUD(imsi0, 0, id);
Neels Hofmeyr2dee60e2017-11-23 15:27:50 +0100699 ASSERT_DB_GET_AUC(imsi0, N_VECTORS);
Neels Hofmeyr1332a172017-10-10 02:25:00 +0200700
701
702 comment("Set invalid auth data");
703
704 ASSERT_RC(db_subscr_update_aud_by_id(dbc, id,
705 mk_aud_2g(99999, "f000000000000f00000000000f000000")),
706 -EINVAL);
Neels Hofmeyr57a87922017-10-09 17:51:13 +0200707 ASSERT_SEL_AUD(imsi0, 0, id);
Neels Hofmeyr1332a172017-10-10 02:25:00 +0200708
709 ASSERT_RC(db_subscr_update_aud_by_id(dbc, id,
710 mk_aud_2g(OSMO_AUTH_ALG_XOR, "f000000000000f00000000000f000000f00000000")),
711 -EINVAL);
Neels Hofmeyr57a87922017-10-09 17:51:13 +0200712 ASSERT_SEL_AUD(imsi0, 0, id);
Neels Hofmeyr1332a172017-10-10 02:25:00 +0200713
714 ASSERT_RC(db_subscr_update_aud_by_id(dbc, id,
715 mk_aud_2g(OSMO_AUTH_ALG_XOR, "f00")),
716 -EINVAL);
Neels Hofmeyr57a87922017-10-09 17:51:13 +0200717 ASSERT_SEL_AUD(imsi0, 0, id);
Neels Hofmeyr1332a172017-10-10 02:25:00 +0200718
719 ASSERT_RC(db_subscr_update_aud_by_id(dbc, id,
720 mk_aud_2g(OSMO_AUTH_ALG_MILENAGE, "0123456789abcdef0123456789abcdef")),
721 -EINVAL);
Neels Hofmeyr57a87922017-10-09 17:51:13 +0200722 ASSERT_SEL_AUD(imsi0, 0, id);
Neels Hofmeyr1332a172017-10-10 02:25:00 +0200723
724 ASSERT_RC(db_subscr_update_aud_by_id(dbc, id,
725 mk_aud_3g(OSMO_AUTH_ALG_MILENAGE,
726 "0f000000000000f00000000000f000000", false,
727 "f000000000000f00000000000f000000", 5)),
728 -EINVAL);
Neels Hofmeyr57a87922017-10-09 17:51:13 +0200729 ASSERT_SEL_AUD(imsi0, 0, id);
Neels Hofmeyr1332a172017-10-10 02:25:00 +0200730
731 ASSERT_RC(db_subscr_update_aud_by_id(dbc, id,
732 mk_aud_3g(OSMO_AUTH_ALG_MILENAGE,
733 "f000000000000f00000000000f000000", false,
734 "000000000000f00000000000f000000", 5)),
735 -EINVAL);
Neels Hofmeyr57a87922017-10-09 17:51:13 +0200736 ASSERT_SEL_AUD(imsi0, 0, id);
Neels Hofmeyr1332a172017-10-10 02:25:00 +0200737
738 ASSERT_RC(db_subscr_update_aud_by_id(dbc, id,
739 mk_aud_3g(OSMO_AUTH_ALG_MILENAGE,
740 "f000000000000f00000000000f000000", false,
741 "f000000000000f00000000000f000000",
742 OSMO_MILENAGE_IND_BITLEN_MAX + 1)),
743 -EINVAL);
Neels Hofmeyr57a87922017-10-09 17:51:13 +0200744 ASSERT_SEL_AUD(imsi0, 0, id);
Neels Hofmeyr1332a172017-10-10 02:25:00 +0200745
746 ASSERT_RC(db_subscr_update_aud_by_id(dbc, id,
747 mk_aud_3g(OSMO_AUTH_ALG_MILENAGE,
748 "X000000000000f00000000000f000000", false,
749 "f000000000000f00000000000f000000", 5)),
750 -EINVAL);
Neels Hofmeyr57a87922017-10-09 17:51:13 +0200751 ASSERT_SEL_AUD(imsi0, 0, id);
Neels Hofmeyr1332a172017-10-10 02:25:00 +0200752
753 ASSERT_RC(db_subscr_update_aud_by_id(dbc, id,
754 mk_aud_3g(OSMO_AUTH_ALG_MILENAGE,
755 "f000000000000f00000000000f000000", false,
756 "f000000000000 f00000000000 f000000", 5)),
757 -EINVAL);
Neels Hofmeyr57a87922017-10-09 17:51:13 +0200758 ASSERT_SEL_AUD(imsi0, 0, id);
Neels Hofmeyr1332a172017-10-10 02:25:00 +0200759
760 comment("Delete subscriber");
761
762 ASSERT_SEL(imsi, imsi0, 0);
763 ASSERT_RC(db_subscr_delete_by_id(dbc, id), 0);
764 ASSERT_SEL(imsi, imsi0, -ENOENT);
765
766 comment("Re-add subscriber and verify auth data didn't come back");
767
Oliver Smithcd2af5e2019-03-06 13:17:39 +0100768 ASSERT_RC(db_subscr_create(dbc, imsi0, DB_SUBSCR_FLAG_NAM_CS | DB_SUBSCR_FLAG_NAM_PS), 0);
Neels Hofmeyr1332a172017-10-10 02:25:00 +0200769 ASSERT_SEL(imsi, imsi0, 0);
770
771 /* For this test to work, we want to get the same subscriber ID back,
772 * and make sure there are no auth data leftovers for this ID. */
773 OSMO_ASSERT(id == g_subscr.id);
Neels Hofmeyrbd1dca02017-11-23 15:25:30 +0100774 ASSERT_SEL_AUD(imsi0, -ENOKEY, id);
Neels Hofmeyr2dee60e2017-11-23 15:27:50 +0100775 ASSERT_DB_GET_AUC(imsi0, -ENOKEY);
Neels Hofmeyr1332a172017-10-10 02:25:00 +0200776
777 ASSERT_RC(db_subscr_delete_by_id(dbc, id), 0);
778 ASSERT_SEL(imsi, imsi0, -ENOENT);
Neels Hofmeyr2dee60e2017-11-23 15:27:50 +0100779 ASSERT_DB_GET_AUC(imsi0, -ENOENT);
Neels Hofmeyr1332a172017-10-10 02:25:00 +0200780
781 comment_end();
782}
783
Oliver Smith6401b902019-07-24 11:32:45 +0200784/* Make each key too short in this test. Note that we can't set them longer than the allowed size without changing the
785 * table structure. */
786static void test_subscr_aud_invalid_len()
787{
788 int64_t id;
789
790 comment_start();
791 comment("Create subscriber");
792 ASSERT_RC(db_subscr_create(dbc, imsi0, DB_SUBSCR_FLAG_NAM_CS | DB_SUBSCR_FLAG_NAM_PS), 0);
793 ASSERT_SEL(imsi, imsi0, 0);
794 id = g_subscr.id;
795
796
797 /* Invalid Ki length */
798 comment("Set auth data, 2G only, with invalid Ki length");
799 ASSERT_RC(db_subscr_update_aud_by_id(dbc, id,
800 mk_aud_2g(OSMO_AUTH_ALG_COMP128v1, "0123456789abcdef0123456789abcdef")),
801 0);
802 /* Use raw SQL to avoid length check in db_subscr_update_aud_by_id(). This changes all rows in the table, which
803 * is fine for this test (implicit WHERE 1). */
804 db_raw_sql(dbc, "UPDATE auc_2g SET ki = '0123456789abcdef0123456789abcde'");
805 ASSERT_SEL_AUD(imsi0, -ENOKEY, id);
806
807 comment("Remove 2G auth data");
808 ASSERT_RC(db_subscr_update_aud_by_id(dbc, id,
809 mk_aud_2g(OSMO_AUTH_ALG_NONE, NULL)),
810 0);
811
812 /* Invalid K length */
813 comment("Set auth data, 3G only, with invalid K length");
814 ASSERT_RC(db_subscr_update_aud_by_id(dbc, id,
815 mk_aud_3g(OSMO_AUTH_ALG_MILENAGE,
816 "BeefedCafeFaceAcedAddedDecadeFee", true,
817 "C01ffedC1cadaeAc1d1f1edAcac1aB0a", 5)),
818 0);
819 db_raw_sql(dbc, "UPDATE auc_3g SET k = 'C01ffedC1cadaeAc1d1f1edAcac1aB0'");
820 ASSERT_SEL_AUD(imsi0, -EIO, id);
821
822 /* Invalid OP length */
823 comment("Set auth data, 3G only, with invalid OP length");
824 ASSERT_RC(db_subscr_update_aud_by_id(dbc, id,
825 mk_aud_3g(OSMO_AUTH_ALG_MILENAGE,
826 "BeefedCafeFaceAcedAddedDecadeFee", true,
827 "C01ffedC1cadaeAc1d1f1edAcac1aB0a", 5)),
828 0);
829 db_raw_sql(dbc, "UPDATE auc_3g SET op = 'BeefedCafeFaceAcedAddedDecadeFe'");
830 ASSERT_SEL_AUD(imsi0, -EIO, id);
831
832 /* Invalid OPC length */
833 comment("Set auth data, 3G only, with invalid OPC length");
834 ASSERT_RC(db_subscr_update_aud_by_id(dbc, id,
835 mk_aud_3g(OSMO_AUTH_ALG_MILENAGE,
836 "BeefedCafeFaceAcedAddedDecadeFee", false,
837 "C01ffedC1cadaeAc1d1f1edAcac1aB0a", 5)),
838 0);
839 db_raw_sql(dbc, "UPDATE auc_3g SET opc = 'BeefedCafeFaceAcedAddedDecadeFe'");
840 ASSERT_SEL_AUD(imsi0, -EIO, id);
841
842
843 comment("Delete subscriber");
844 ASSERT_RC(db_subscr_delete_by_id(dbc, id), 0);
845 comment_end();
846}
847
Neels Hofmeyr1cbdb702017-10-09 23:03:57 +0200848static void test_subscr_sqn()
849{
850 int64_t id;
851
852 comment_start();
853
854 comment("Set SQN for unknown subscriber");
855
856 ASSERT_RC(db_update_sqn(dbc, 99, 999), -ENOENT);
857 ASSERT_SEL(id, 99, -ENOENT);
858
859 ASSERT_RC(db_update_sqn(dbc, 9999, 99), -ENOENT);
860 ASSERT_SEL(id, 9999, -ENOENT);
861
862 comment("Create subscriber");
863
Oliver Smithcd2af5e2019-03-06 13:17:39 +0100864 ASSERT_RC(db_subscr_create(dbc, imsi0, DB_SUBSCR_FLAG_NAM_CS | DB_SUBSCR_FLAG_NAM_PS), 0);
Neels Hofmeyr1cbdb702017-10-09 23:03:57 +0200865 ASSERT_SEL(imsi, imsi0, 0);
866
867 id = g_subscr.id;
Neels Hofmeyrbd1dca02017-11-23 15:25:30 +0100868 ASSERT_SEL_AUD(imsi0, -ENOKEY, id);
Neels Hofmeyr1cbdb702017-10-09 23:03:57 +0200869
870 comment("Set SQN, but no 3G auth data present");
871
872 ASSERT_RC(db_update_sqn(dbc, id, 123), -ENOENT);
Neels Hofmeyrbd1dca02017-11-23 15:25:30 +0100873 ASSERT_SEL_AUD(imsi0, -ENOKEY, id);
Neels Hofmeyr1cbdb702017-10-09 23:03:57 +0200874
875 ASSERT_RC(db_update_sqn(dbc, id, 543), -ENOENT);
Neels Hofmeyrbd1dca02017-11-23 15:25:30 +0100876 ASSERT_SEL_AUD(imsi0, -ENOKEY, id);
Neels Hofmeyr1cbdb702017-10-09 23:03:57 +0200877
878 comment("Set auth 3G data");
879
880 ASSERT_RC(db_subscr_update_aud_by_id(dbc, id,
881 mk_aud_3g(OSMO_AUTH_ALG_MILENAGE,
882 "BeefedCafeFaceAcedAddedDecadeFee", true,
883 "C01ffedC1cadaeAc1d1f1edAcac1aB0a", 5)),
884 0);
885 ASSERT_SEL_AUD(imsi0, 0, id);
886
887 comment("Set SQN");
888
889 ASSERT_RC(db_update_sqn(dbc, id, 23315), 0);
890 ASSERT_SEL_AUD(imsi0, 0, id);
891
892 ASSERT_RC(db_update_sqn(dbc, id, 23315), 0);
893 ASSERT_SEL_AUD(imsi0, 0, id);
894
895 ASSERT_RC(db_update_sqn(dbc, id, 423), 0);
896 ASSERT_SEL_AUD(imsi0, 0, id);
897
898 comment("Set SQN: thru uint64_t range, using the int64_t SQLite bind");
899
900 ASSERT_RC(db_update_sqn(dbc, id, 0), 0);
901 ASSERT_SEL_AUD(imsi0, 0, id);
902
903 ASSERT_RC(db_update_sqn(dbc, id, INT64_MAX), 0);
904 ASSERT_SEL_AUD(imsi0, 0, id);
905
906 ASSERT_RC(db_update_sqn(dbc, id, INT64_MIN), 0);
907 ASSERT_SEL_AUD(imsi0, 0, id);
908
909 ASSERT_RC(db_update_sqn(dbc, id, UINT64_MAX), 0);
910 ASSERT_SEL_AUD(imsi0, 0, id);
911
912 comment("Delete subscriber");
913
914 ASSERT_SEL(imsi, imsi0, 0);
915 ASSERT_RC(db_subscr_delete_by_id(dbc, id), 0);
916 ASSERT_SEL(imsi, imsi0, -ENOENT);
917
918 comment_end();
919}
920
Neels Hofmeyrba0b5bd2019-12-12 04:04:53 +0100921static void test_ind()
922{
923 comment_start();
924
925#define ASSERT_IND(VLR, IND) do { \
926 unsigned int ind; \
927 struct osmo_gsup_peer_id vlr; \
928 OSMO_ASSERT(!osmo_gsup_peer_id_set_str(&vlr, OSMO_GSUP_PEER_ID_IPA_NAME, VLR)); \
929 ASSERT_RC(db_ind(dbc, &vlr, &ind), 0); \
930 fprintf(stderr, "%s ind = %u\n\n", osmo_quote_str((char*)vlr.ipa_name.val, vlr.ipa_name.len), ind); \
931 if (ind != (IND)) \
932 fprintf(stderr, " ERROR: expected " #IND "\n"); \
933 } while (0)
934#define IND_DEL(VLR) do { \
935 struct osmo_gsup_peer_id vlr; \
936 OSMO_ASSERT(!osmo_gsup_peer_id_set_str(&vlr, OSMO_GSUP_PEER_ID_IPA_NAME, VLR)); \
937 ASSERT_RC(db_ind_del(dbc, &vlr), 0); \
938 fprintf(stderr, "%s ind deleted\n\n", osmo_quote_str((char*)vlr.ipa_name.val, vlr.ipa_name.len)); \
939 } while (0)
940
941 ASSERT_IND("msc-23", 1);
942 ASSERT_IND("sgsn-11", 2);
943 ASSERT_IND("msc-42", 3);
944 ASSERT_IND("sgsn-22", 4);
945 ASSERT_IND("msc-0x17", 5);
946 ASSERT_IND("sgsn-0xaa", 6);
947 ASSERT_IND("msc-42", 3);
948 ASSERT_IND("sgsn-22", 4);
949 ASSERT_IND("msc-0x17", 5);
950 ASSERT_IND("sgsn-0xaa", 6);
951 ASSERT_IND("sgsn-0xbb", 7);
952 ASSERT_IND("msc-0x2a", 8);
953 ASSERT_IND("msc-42", 3);
954 ASSERT_IND("sgsn-22", 4);
955 ASSERT_IND("msc-23", 1);
956 ASSERT_IND("sgsn-11", 2);
957
958 IND_DEL("msc-0x17"); /* dropped IND == 5 */
959 ASSERT_IND("msc-0x2a", 8); /* known CS remains where it is */
960 ASSERT_IND("any-unknown", 9); /* new VLR takes a new IND from the end */
961
962 comment_end();
963}
964
Neels Hofmeyr98509462017-10-09 17:28:53 +0200965static struct {
966 bool verbose;
967} cmdline_opts = {
968 .verbose = false,
969};
970
971static void print_help(const char *program)
972{
973 printf("Usage:\n"
974 " %s [-v] [N [N...]]\n"
975 "Options:\n"
976 " -h --help show this text.\n"
977 " -v --verbose print source file and line numbers\n",
978 program
979 );
980}
981
982static void handle_options(int argc, char **argv)
983{
984 while (1) {
985 int option_index = 0, c;
986 static struct option long_options[] = {
987 {"help", 0, 0, 'h'},
988 {"verbose", 1, 0, 'v'},
989 {0, 0, 0, 0}
990 };
991
992 c = getopt_long(argc, argv, "hv",
993 long_options, &option_index);
994 if (c == -1)
995 break;
996
997 switch (c) {
998 case 'h':
999 print_help(argv[0]);
1000 exit(0);
1001 case 'v':
1002 cmdline_opts.verbose = true;
1003 break;
1004 default:
1005 /* catch unknown options *as well as* missing arguments. */
1006 fprintf(stderr, "Error in command line options. Exiting.\n");
1007 exit(-1);
1008 break;
1009 }
1010 }
1011
1012 if (optind < argc) {
1013 fprintf(stderr, "too many args\n");
1014 exit(-1);
1015 }
1016}
1017
1018int main(int argc, char **argv)
1019{
1020 printf("db_test.c\n");
1021
1022 ctx = talloc_named_const(NULL, 1, "db_test");
1023
1024 handle_options(argc, argv);
1025
Pau Espin Pedrol51530312018-04-17 15:07:06 +02001026 osmo_init_logging2(ctx, &hlr_log_info);
Neels Hofmeyr98509462017-10-09 17:28:53 +02001027 log_set_print_filename(osmo_stderr_target, cmdline_opts.verbose);
1028 log_set_print_timestamp(osmo_stderr_target, 0);
1029 log_set_use_color(osmo_stderr_target, 0);
1030 log_set_print_category(osmo_stderr_target, 1);
Neels Hofmeyr6eb231e2017-10-27 03:35:45 +02001031 log_parse_category_mask(osmo_stderr_target, "DMAIN,1:DDB,1:DAUC,1");
Neels Hofmeyr98509462017-10-09 17:28:53 +02001032
1033 /* omit the SQLite version and compilation flags from test output */
1034 log_set_log_level(osmo_stderr_target, LOGL_ERROR);
Neels Hofmeyrd3814b92017-11-21 12:28:07 +01001035 /* Disable SQLite logging so that we're not vulnerable on SQLite error messages changing across
1036 * library versions. */
Stefan Sperling8f3a7cc2018-11-27 12:10:45 +01001037 dbc = db_open(ctx, "db_test.db", false, false);
Neels Hofmeyr98509462017-10-09 17:28:53 +02001038 log_set_log_level(osmo_stderr_target, 0);
1039 OSMO_ASSERT(dbc);
1040
1041 test_subscr_create_update_sel_delete();
Neels Hofmeyr1332a172017-10-10 02:25:00 +02001042 test_subscr_aud();
Oliver Smith6401b902019-07-24 11:32:45 +02001043 test_subscr_aud_invalid_len();
Neels Hofmeyr1cbdb702017-10-09 23:03:57 +02001044 test_subscr_sqn();
Neels Hofmeyrba0b5bd2019-12-12 04:04:53 +01001045 test_ind();
Neels Hofmeyr98509462017-10-09 17:28:53 +02001046
1047 printf("Done\n");
Vadim Yanitskiydc301542019-07-26 18:38:49 +07001048 db_close(dbc);
Neels Hofmeyr98509462017-10-09 17:28:53 +02001049 return 0;
1050}
1051
1052/* stubs */
Neels Hofmeyr00b1d432017-10-17 01:43:48 +02001053void *lu_op_alloc_conn(void *conn)
1054{ OSMO_ASSERT(false); return NULL; }
1055void lu_op_tx_del_subscr_data(void *luop)
1056{ OSMO_ASSERT(false); }
1057void lu_op_free(void *luop)
1058{ OSMO_ASSERT(false); }