blob: c99dde44c6c47694dde665c22dfa21362b2b3899 [file] [log] [blame]
Holger Hans Peter Freyther9dbc3f82014-03-23 12:06:36 +01001/*
2 * (C) 2014 by Holger Hans Peter Freyther
3 * (C) 2014 by sysmocom s.f.m.c. GmbH
4 *
5 * All Rights Reserved
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU Affero General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Affero General Public License for more details.
16 *
17 * You should have received a copy of the GNU Affero General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 *
20 */
Max0fcd2e22016-06-07 15:32:16 +020021
Harald Welteba874b82014-08-20 23:47:15 +020022#include <osmocom/ctrl/control_cmd.h>
Neels Hofmeyr93bafb62017-01-13 03:12:08 +010023#include <osmocom/core/utils.h>
Holger Hans Peter Freyther9dbc3f82014-03-23 12:06:36 +010024#include <openbsc/gsm_data.h>
25#include <openbsc/gsm_subscriber.h>
26#include <openbsc/db.h>
Holger Hans Peter Freyther2d99eeb2014-03-23 14:01:08 +010027#include <openbsc/debug.h>
Holger Hans Peter Freyther9dbc3f82014-03-23 12:06:36 +010028
Maxe6052c42016-06-30 10:25:49 +020029#include <stdbool.h>
30
Holger Hans Peter Freyther9bcb1a52016-04-06 22:41:12 +020031static bool alg_supported(const char *alg)
32{
33 /*
34 * TODO: share this with the vty_interface and extend to all
35 * algorithms supported by libosmocore now. Make it table based
36 * as well.
37 */
38 if (strcasecmp(alg, "none") == 0)
39 return true;
40 if (strcasecmp(alg, "xor") == 0)
41 return true;
42 if (strcasecmp(alg, "comp128v1") == 0)
43 return true;
44 return false;
45}
46
Holger Hans Peter Freyther9dbc3f82014-03-23 12:06:36 +010047static int verify_subscriber_modify(struct ctrl_cmd *cmd, const char *value, void *d)
48{
Holger Hans Peter Freyther9bcb1a52016-04-06 22:41:12 +020049 char *tmp, *imsi, *msisdn, *alg, *ki, *saveptr = NULL;
Jacob Erlbeck76606d32014-10-28 14:57:53 +010050 int rc = 0;
Holger Hans Peter Freyther9dbc3f82014-03-23 12:06:36 +010051
52 tmp = talloc_strdup(cmd, value);
53 if (!tmp)
54 return 1;
55
56 imsi = strtok_r(tmp, ",", &saveptr);
57 msisdn = strtok_r(NULL, ",", &saveptr);
Holger Hans Peter Freyther9bcb1a52016-04-06 22:41:12 +020058 alg = strtok_r(NULL, ",", &saveptr);
59 ki = strtok_r(NULL, ",", &saveptr);
Holger Hans Peter Freyther9dbc3f82014-03-23 12:06:36 +010060
61 if (!imsi || !msisdn)
Jacob Erlbeck76606d32014-10-28 14:57:53 +010062 rc = 1;
Harald Welted3fa84d2016-04-20 17:50:17 +020063 else if (strlen(imsi) > GSM23003_IMSI_MAX_DIGITS)
Jacob Erlbeck76606d32014-10-28 14:57:53 +010064 rc = 1;
65 else if (strlen(msisdn) >= GSM_EXTENSION_LENGTH)
66 rc = 1;
Holger Hans Peter Freyther9bcb1a52016-04-06 22:41:12 +020067 else if (alg) {
68 if (!alg_supported(alg))
69 rc = 1;
70 else if (strcasecmp(alg, "none") != 0 && !ki)
71 rc = 1;
72 }
Jacob Erlbeck76606d32014-10-28 14:57:53 +010073
74 talloc_free(tmp);
75 return rc;
Holger Hans Peter Freyther9dbc3f82014-03-23 12:06:36 +010076}
77
Holger Hans Peter Freyther9dbc3f82014-03-23 12:06:36 +010078static int set_subscriber_modify(struct ctrl_cmd *cmd, void *data)
79{
80 struct gsm_network *net = cmd->node;
Holger Hans Peter Freyther9bcb1a52016-04-06 22:41:12 +020081 char *tmp, *imsi, *msisdn, *alg, *ki, *saveptr = NULL;
Holger Hans Peter Freyther9dbc3f82014-03-23 12:06:36 +010082 struct gsm_subscriber* subscr;
83 int rc;
84
85 tmp = talloc_strdup(cmd, cmd->value);
86 if (!tmp)
87 return 1;
88
89 imsi = strtok_r(tmp, ",", &saveptr);
90 msisdn = strtok_r(NULL, ",", &saveptr);
Holger Hans Peter Freyther9bcb1a52016-04-06 22:41:12 +020091 alg = strtok_r(NULL, ",", &saveptr);
92 ki = strtok_r(NULL, ",", &saveptr);
Holger Hans Peter Freyther9dbc3f82014-03-23 12:06:36 +010093
Jacob Erlbeck1e30a282014-12-03 09:28:24 +010094 subscr = subscr_get_by_imsi(net->subscr_group, imsi);
Holger Hans Peter Freyther9dbc3f82014-03-23 12:06:36 +010095 if (!subscr)
Maxe6052c42016-06-30 10:25:49 +020096 subscr = subscr_create_subscriber(net->subscr_group, imsi);
Holger Hans Peter Freyther9dbc3f82014-03-23 12:06:36 +010097 if (!subscr)
98 goto fail;
99
100 subscr->authorized = 1;
Neels Hofmeyr93bafb62017-01-13 03:12:08 +0100101 osmo_strlcpy(subscr->extension, msisdn, sizeof(subscr->extension));
Holger Hans Peter Freyther9dbc3f82014-03-23 12:06:36 +0100102
103 /* put it back to the db */
104 rc = db_sync_subscriber(subscr);
105 db_subscriber_update(subscr);
Holger Hans Peter Freyther9bcb1a52016-04-06 22:41:12 +0200106
107 /* handle optional ciphering */
108 if (alg) {
109 if (strcasecmp(alg, "none") == 0)
110 db_sync_authinfo_for_subscr(NULL, subscr);
111 else {
112 struct gsm_auth_info ainfo = { 0, };
113 /* the verify should make sure that this is okay */
114 OSMO_ASSERT(alg);
115 OSMO_ASSERT(ki);
116
117 if (strcasecmp(alg, "xor") == 0)
118 ainfo.auth_algo = AUTH_ALGO_XOR;
119 else if (strcasecmp(alg, "comp128v1") == 0)
120 ainfo.auth_algo = AUTH_ALGO_COMP128v1;
121
122 rc = osmo_hexparse(ki, ainfo.a3a8_ki, sizeof(ainfo.a3a8_ki));
123 if (rc < 0) {
124 subscr_put(subscr);
125 talloc_free(tmp);
126 cmd->reply = "Failed to parse KI";
127 return CTRL_CMD_ERROR;
128 }
129
130 ainfo.a3a8_ki_len = rc;
131 db_sync_authinfo_for_subscr(&ainfo, subscr);
132 rc = 0;
133 }
134 db_sync_lastauthtuple_for_subscr(NULL, subscr);
135 }
Holger Hans Peter Freyther9dbc3f82014-03-23 12:06:36 +0100136 subscr_put(subscr);
137
138 talloc_free(tmp);
139
140 if (rc != 0) {
141 cmd->reply = "Failed to store the record in the DB";
142 return CTRL_CMD_ERROR;
143 }
144
145 cmd->reply = "OK";
146 return CTRL_CMD_REPLY;
147
148fail:
149 talloc_free(tmp);
150 cmd->reply = "Failed to create subscriber";
151 return CTRL_CMD_ERROR;
152}
153
Maxf6e51702017-01-11 18:37:55 +0100154CTRL_CMD_DEFINE_WO(subscriber_modify, "subscriber-modify-v1");
Holger Hans Peter Freyther2d99eeb2014-03-23 14:01:08 +0100155
156static int set_subscriber_delete(struct ctrl_cmd *cmd, void *data)
157{
158 int was_used = 0;
159 int rc;
160 struct gsm_subscriber *subscr;
161 struct gsm_network *net = cmd->node;
162
Jacob Erlbeck1e30a282014-12-03 09:28:24 +0100163 subscr = subscr_get_by_imsi(net->subscr_group, cmd->value);
Holger Hans Peter Freyther2d99eeb2014-03-23 14:01:08 +0100164 if (!subscr) {
165 cmd->reply = "Failed to find subscriber";
166 return CTRL_CMD_ERROR;
167 }
168
169 if (subscr->use_count != 1) {
170 LOGP(DCTRL, LOGL_NOTICE, "Going to remove active subscriber.\n");
171 was_used = 1;
172 }
173
174 rc = db_subscriber_delete(subscr);
175 subscr_put(subscr);
176
177 if (rc != 0) {
178 cmd->reply = "Failed to remove subscriber";
179 return CTRL_CMD_ERROR;
180 }
181
182 cmd->reply = was_used ? "Removed active subscriber" : "Removed";
183 return CTRL_CMD_REPLY;
184}
Maxf6e51702017-01-11 18:37:55 +0100185CTRL_CMD_DEFINE_WO_NOVRF(subscriber_delete, "subscriber-delete-v1");
Holger Hans Peter Freyther2d99eeb2014-03-23 14:01:08 +0100186
Holger Hans Peter Freytherd883db02014-03-23 16:22:55 +0100187static void list_cb(struct gsm_subscriber *subscr, void *d)
188{
189 char **data = (char **) d;
190 *data = talloc_asprintf_append(*data, "%s,%s\n",
191 subscr->imsi, subscr->extension);
192}
193
194static int get_subscriber_list(struct ctrl_cmd *cmd, void *d)
195{
196 cmd->reply = talloc_strdup(cmd, "");
197
198 db_subscriber_list_active(list_cb, &cmd->reply);
199 printf("%s\n", cmd->reply);
200 return CTRL_CMD_REPLY;
201}
Max50eb6692017-05-02 16:44:43 +0200202CTRL_CMD_DEFINE_RO(subscriber_list, "subscriber-list-active-v1");
Holger Hans Peter Freytherd883db02014-03-23 16:22:55 +0100203
Holger Hans Peter Freyther9dbc3f82014-03-23 12:06:36 +0100204int msc_ctrl_cmds_install(void)
205{
206 int rc = 0;
207
208 rc |= ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_subscriber_modify);
Holger Hans Peter Freyther2d99eeb2014-03-23 14:01:08 +0100209 rc |= ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_subscriber_delete);
Holger Hans Peter Freytherd883db02014-03-23 16:22:55 +0100210 rc |= ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_subscriber_list);
Holger Hans Peter Freyther9dbc3f82014-03-23 12:06:36 +0100211 return rc;
212}