00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include <sys/types.h>
00029 #include <regex.h>
00030 #include <string.h>
00031 #include <arpa/inet.h>
00032
00033 #include "permissions.h"
00034 #include "hash.h"
00035 #include "../../config.h"
00036 #include "../../db/db.h"
00037 #include "../../ip_addr.h"
00038 #include "../../mem/shm_mem.h"
00039 #include "../../parser/msg_parser.h"
00040 #include "../../parser/parse_from.h"
00041 #include "../../usr_avp.h"
00042 #include "../../mod_fix.h"
00043 #include "../../ut.h"
00044 #include "../../resolve.h"
00045
00046 #define TABLE_VERSION 3
00047
00048 struct addr_list ***addr_hash_table;
00049 struct addr_list **addr_hash_table_1;
00050 struct addr_list **addr_hash_table_2;
00051
00052 struct subnet **subnet_table;
00053 struct subnet *subnet_table_1;
00054 struct subnet *subnet_table_2;
00055
00056 static db_con_t* db_handle = 0;
00057 static db_func_t perm_dbf;
00058
00059
00060
00061
00062
00063
00064 int reload_address_table(void)
00065 {
00066 db_key_t cols[4];
00067 db_res_t* res = NULL;
00068 db_row_t* row;
00069 db_val_t* val;
00070
00071 struct addr_list **new_hash_table;
00072 struct subnet *new_subnet_table;
00073 int i;
00074 struct in_addr ip_addr;
00075
00076 cols[0] = &grp_col;
00077 cols[1] = &ip_addr_col;
00078 cols[2] = &mask_col;
00079 cols[3] = &port_col;
00080
00081 if (perm_dbf.use_table(db_handle, &address_table) < 0) {
00082 LM_ERR("failed to use table\n");
00083 return -1;
00084 }
00085
00086 if (perm_dbf.query(db_handle, NULL, 0, NULL, cols, 0, 4, 0, &res) < 0) {
00087 LM_ERR("failed to query database\n");
00088 return -1;
00089 }
00090
00091
00092 if (*addr_hash_table == addr_hash_table_1) {
00093 empty_addr_hash_table(addr_hash_table_2);
00094 new_hash_table = addr_hash_table_2;
00095 } else {
00096 empty_addr_hash_table(addr_hash_table_1);
00097 new_hash_table = addr_hash_table_1;
00098 }
00099
00100
00101 if (*subnet_table == subnet_table_1) {
00102 empty_subnet_table(subnet_table_2);
00103 new_subnet_table = subnet_table_2;
00104 } else {
00105 empty_subnet_table(subnet_table_1);
00106 new_subnet_table = subnet_table_1;
00107 }
00108
00109 row = RES_ROWS(res);
00110
00111 LM_DBG("Number of rows in address table: %d\n", RES_ROW_N(res));
00112
00113 for (i = 0; i < RES_ROW_N(res); i++) {
00114 val = ROW_VALUES(row + i);
00115 if ((ROW_N(row + i) == 4) &&
00116 (VAL_TYPE(val) == DB_INT) && !VAL_NULL(val) &&
00117 (VAL_TYPE(val + 1) == DB_STRING) && !VAL_NULL(val + 1) &&
00118 inet_aton((char *)VAL_STRING(val + 1), &ip_addr) != 0 &&
00119 (VAL_TYPE(val + 2) == DB_INT) && !VAL_NULL(val + 2) &&
00120 ((unsigned int)VAL_INT(val + 2) > 0) &&
00121 ((unsigned int)VAL_INT(val + 2) <= 32) &&
00122 (VAL_TYPE(val + 3) == DB_INT) && !VAL_NULL(val + 3)) {
00123 if ((unsigned int)VAL_INT(val + 2) == 32) {
00124 if (addr_hash_table_insert(new_hash_table,
00125 (unsigned int)VAL_INT(val),
00126 (unsigned int)ip_addr.s_addr,
00127 (unsigned int)VAL_INT(val + 3))
00128 == -1) {
00129 LM_ERR("hash table problem\n");
00130 perm_dbf.free_result(db_handle, res);
00131 return -1;
00132 }
00133 LM_DBG("Tuple <%u, %s, %u> inserted into address hash "
00134 "table\n", (unsigned int)VAL_INT(val),
00135 (char *)VAL_STRING(val + 1),
00136 (unsigned int)VAL_INT(val + 2));
00137 } else {
00138 if (subnet_table_insert(new_subnet_table,
00139 (unsigned int)VAL_INT(val),
00140 (unsigned int)ip_addr.s_addr,
00141 (unsigned int)VAL_INT(val + 2),
00142 (unsigned int)VAL_INT(val + 3))
00143 == -1) {
00144 LM_ERR("subnet table problem\n");
00145 perm_dbf.free_result(db_handle, res);
00146 return -1;
00147 }
00148 LM_DBG("Tuple <%u, %s, %u, %u> inserted into subnet "
00149 "table\n", (unsigned int)VAL_INT(val),
00150 (char *)VAL_STRING(val + 1),
00151 (unsigned int)VAL_INT(val + 2),
00152 (unsigned int)VAL_INT(val + 3));
00153 }
00154 } else {
00155 LM_ERR("database problem\n");
00156 perm_dbf.free_result(db_handle, res);
00157 return -1;
00158 }
00159 }
00160
00161 perm_dbf.free_result(db_handle, res);
00162
00163 *addr_hash_table = new_hash_table;
00164 *subnet_table = new_subnet_table;
00165
00166 LM_DBG("address table reloaded successfully.\n");
00167
00168 return 1;
00169 }
00170
00171
00172
00173
00174
00175 int init_addresses(void)
00176 {
00177 if (!db_url.s) {
00178 LM_INFO("db_url parameter of permissions module not set, "
00179 "disabling allow_address\n");
00180 return 0;
00181 } else {
00182 if (db_bind_mod(&db_url, &perm_dbf) < 0) {
00183 LM_ERR("load a database support module\n");
00184 return -1;
00185 }
00186
00187 if (!DB_CAPABILITY(perm_dbf, DB_CAP_QUERY)) {
00188 LM_ERR("database module does not implement 'query' function\n");
00189 return -1;
00190 }
00191 }
00192
00193 addr_hash_table_1 = addr_hash_table_2 = 0;
00194 addr_hash_table = 0;
00195
00196 db_handle = perm_dbf.init(&db_url);
00197 if (!db_handle) {
00198 LM_ERR("unable to connect database\n");
00199 return -1;
00200 }
00201
00202 if(db_check_table_version(&perm_dbf, db_handle, &address_table, TABLE_VERSION) < 0) {
00203 LM_ERR("error during table version check.\n");
00204 perm_dbf.close(db_handle);
00205 return -1;
00206 }
00207
00208 addr_hash_table_1 = new_addr_hash_table();
00209 if (!addr_hash_table_1) return -1;
00210
00211 addr_hash_table_2 = new_addr_hash_table();
00212 if (!addr_hash_table_2) goto error;
00213
00214 addr_hash_table = (struct addr_list ***)shm_malloc
00215 (sizeof(struct addr_list **));
00216 if (!addr_hash_table) goto error;
00217
00218 *addr_hash_table = addr_hash_table_1;
00219
00220 subnet_table_1 = new_subnet_table();
00221 if (!subnet_table_1) goto error;
00222
00223 subnet_table_2 = new_subnet_table();
00224 if (!subnet_table_2) goto error;
00225
00226 subnet_table = (struct subnet **)shm_malloc(sizeof(struct subnet *));
00227 if (!subnet_table) goto error;
00228
00229 *subnet_table = subnet_table_1;
00230
00231 if (reload_address_table() == -1) {
00232 LM_CRIT("reload of address table failed\n");
00233 goto error;
00234 }
00235
00236 perm_dbf.close(db_handle);
00237 db_handle = 0;
00238
00239 return 0;
00240
00241 error:
00242 LM_ERR("no more shm memory\n");
00243 if (addr_hash_table_1) {
00244 free_addr_hash_table(addr_hash_table_1);
00245 addr_hash_table_1 = 0;
00246 }
00247 if (addr_hash_table_2) {
00248 free_addr_hash_table(addr_hash_table_2);
00249 addr_hash_table_2 = 0;
00250 }
00251 if (addr_hash_table) {
00252 shm_free(addr_hash_table);
00253 addr_hash_table = 0;
00254 }
00255 if (subnet_table_1) {
00256 free_subnet_table(subnet_table_1);
00257 subnet_table_1 = 0;
00258 }
00259 if (subnet_table_2) {
00260 free_subnet_table(subnet_table_2);
00261 subnet_table_2 = 0;
00262 }
00263 if (subnet_table) {
00264 shm_free(subnet_table);
00265 subnet_table = 0;
00266 }
00267 perm_dbf.close(db_handle);
00268 db_handle = 0;
00269 return -1;
00270 }
00271
00272
00273
00274
00275
00276
00277 int mi_init_addresses(void)
00278 {
00279 if (!db_url.s || db_handle) return 0;
00280 db_handle = perm_dbf.init(&db_url);
00281 if (!db_handle) {
00282 LM_ERR("unable to connect database\n");
00283 return -1;
00284 }
00285 return 0;
00286 }
00287
00288
00289
00290
00291
00292 void clean_addresses(void)
00293 {
00294 if (addr_hash_table_1) free_addr_hash_table(addr_hash_table_1);
00295 if (addr_hash_table_2) free_addr_hash_table(addr_hash_table_2);
00296 if (addr_hash_table) shm_free(addr_hash_table);
00297 if (subnet_table_1) free_subnet_table(subnet_table_1);
00298 if (subnet_table_2) free_subnet_table(subnet_table_2);
00299 if (subnet_table) shm_free(subnet_table);
00300 }
00301
00302
00303
00304
00305
00306
00307
00308 int allow_address(struct sip_msg* _msg, char* _addr_group, char* _addr_sp,
00309 char* _port_sp)
00310 {
00311 pv_spec_t *addr_sp, *port_sp;
00312 pv_value_t pv_val;
00313
00314 unsigned int addr, port;
00315 int addr_group;
00316 struct ip_addr *ip;
00317
00318 addr_sp = (pv_spec_t *)_addr_sp;
00319 port_sp = (pv_spec_t *)_port_sp;
00320
00321 if(fixup_get_ivalue(_msg, (gparam_p)_addr_group, &addr_group) !=0 ) {
00322 LM_ERR("cannot get group value\n");
00323 return -1;
00324 }
00325
00326 if (addr_sp && (pv_get_spec_value(_msg, addr_sp, &pv_val) == 0)) {
00327 if (pv_val.flags & PV_VAL_INT) {
00328 addr = pv_val.ri;
00329 } else if (pv_val.flags & PV_VAL_STR) {
00330 if ( (ip=str2ip( &pv_val.rs)) == NULL) {
00331 LM_ERR("failed to convert IP address string to in_addr\n");
00332 return -1;
00333 } else {
00334 addr = ip->u.addr32[0];
00335 }
00336 } else {
00337 LM_ERR("IP address PV empty value\n");
00338 return -1;
00339 }
00340 } else {
00341 LM_ERR("cannot get value of address pvar\n");
00342 return -1;
00343 }
00344
00345 if (port_sp && (pv_get_spec_value(_msg, port_sp, &pv_val) == 0)) {
00346 if (pv_val.flags & PV_VAL_INT) {
00347 port = pv_val.ri;
00348 } else if (pv_val.flags & PV_VAL_STR) {
00349 if (str2int(&(pv_val.rs), &port) == -1) {
00350 LM_ERR("failed to convert port string to int\n");
00351 return -1;
00352 }
00353 } else {
00354 LM_ERR("failed to convert port string to int\n");
00355 return -1;
00356 }
00357 } else {
00358 LM_ERR("cannot get value of port pvar\n");
00359 return -1;
00360 }
00361
00362 if (match_addr_hash_table(*addr_hash_table, addr_group, addr, port) == 1)
00363 return 1;
00364 else
00365 return match_subnet_table(*subnet_table, addr_group, addr, port);
00366 }
00367
00368
00369
00370
00371
00372
00373 int allow_source_address(struct sip_msg* _msg, char* _addr_group, char* _str2)
00374 {
00375 int addr_group = 0;
00376
00377 if(fixup_get_ivalue(_msg, (gparam_p)_addr_group, &addr_group) !=0 ) {
00378 LM_ERR("cannot get group value\n");
00379 return -1;
00380 }
00381
00382 LM_DBG("looking for <%u, %x, %u>\n",
00383 addr_group, _msg->rcv.src_ip.u.addr32[0], _msg->rcv.src_port);
00384
00385 if (match_addr_hash_table(*addr_hash_table, addr_group,
00386 _msg->rcv.src_ip.u.addr32[0],
00387 _msg->rcv.src_port) == 1)
00388 return 1;
00389 else
00390 return match_subnet_table(*subnet_table, addr_group,
00391 _msg->rcv.src_ip.u.addr32[0],
00392 _msg->rcv.src_port);
00393 }
00394
00395
00396
00397
00398
00399
00400
00401 int allow_source_address_group(struct sip_msg* _msg, char* _str1, char* _str2)
00402 {
00403 int group;
00404
00405 LM_DBG("looking for <%x, %u> in address table\n",
00406 _msg->rcv.src_ip.u.addr32[0], _msg->rcv.src_port);
00407 group = find_group_in_addr_hash_table(*addr_hash_table,
00408 _msg->rcv.src_ip.u.addr32[0],
00409 _msg->rcv.src_port);
00410 LM_DBG("Found <%d>\n", group);
00411
00412 if (group != -1) return group;
00413
00414 LM_DBG("looking for <%x, %u> in subnet table\n",
00415 _msg->rcv.src_ip.u.addr32[0], _msg->rcv.src_port);
00416 group = find_group_in_subnet_table(*subnet_table,
00417 _msg->rcv.src_ip.u.addr32[0],
00418 _msg->rcv.src_port);
00419 LM_DBG("Found <%d>\n", group);
00420 return group;
00421
00422 }