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
00029 #include <sys/types.h>
00030 #include <regex.h>
00031 #include <string.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
00043 #define TABLE_VERSION 4
00044
00045 struct trusted_list ***hash_table;
00046 struct trusted_list **hash_table_1;
00047 struct trusted_list **hash_table_2;
00048
00049
00050 static db_con_t* db_handle = 0;
00051 static db_func_t perm_dbf;
00052
00053
00054
00055
00056
00057
00058 int reload_trusted_table(void)
00059 {
00060 db_key_t cols[4];
00061 db_res_t* res = NULL;
00062 db_row_t* row;
00063 db_val_t* val;
00064
00065 struct trusted_list **new_hash_table;
00066 int i;
00067
00068 char *pattern, *tag;
00069
00070 cols[0] = &source_col;
00071 cols[1] = &proto_col;
00072 cols[2] = &from_col;
00073 cols[3] = &tag_col;
00074
00075 if (perm_dbf.use_table(db_handle, &trusted_table) < 0) {
00076 LM_ERR("failed to use trusted table\n");
00077 return -1;
00078 }
00079
00080 if (perm_dbf.query(db_handle, NULL, 0, NULL, cols, 0, 4, 0, &res) < 0) {
00081 LM_ERR("failed to query database\n");
00082 return -1;
00083 }
00084
00085
00086 if (*hash_table == hash_table_1) {
00087 empty_hash_table(hash_table_2);
00088 new_hash_table = hash_table_2;
00089 } else {
00090 empty_hash_table(hash_table_1);
00091 new_hash_table = hash_table_1;
00092 }
00093
00094 row = RES_ROWS(res);
00095
00096 LM_DBG("number of rows in trusted table: %d\n", RES_ROW_N(res));
00097
00098 for (i = 0; i < RES_ROW_N(res); i++) {
00099 val = ROW_VALUES(row + i);
00100 if ((ROW_N(row + i) == 4) &&
00101 (VAL_TYPE(val) == DB_STRING) && !VAL_NULL(val) &&
00102 (VAL_TYPE(val + 1) == DB_STRING) && !VAL_NULL(val + 1) &&
00103 (VAL_NULL(val + 2) ||
00104 ((VAL_TYPE(val + 2) == DB_STRING) && !VAL_NULL(val + 2))) &&
00105 (VAL_NULL(val + 3) ||
00106 ((VAL_TYPE(val + 3) == DB_STRING) && !VAL_NULL(val + 3)))) {
00107 if (VAL_NULL(val + 2)) {
00108 pattern = 0;
00109 } else {
00110 pattern = (char *)VAL_STRING(val + 2);
00111 }
00112 if (VAL_NULL(val + 3)) {
00113 tag = 0;
00114 } else {
00115 tag = (char *)VAL_STRING(val + 3);
00116 }
00117 if (hash_table_insert(new_hash_table,
00118 (char *)VAL_STRING(val),
00119 (char *)VAL_STRING(val + 1),
00120 pattern, tag) == -1) {
00121 LM_ERR("hash table problem\n");
00122 perm_dbf.free_result(db_handle, res);
00123 return -1;
00124 }
00125 LM_DBG("tuple <%s, %s, %s, %s> inserted into trusted hash "
00126 "table\n", VAL_STRING(val), VAL_STRING(val + 1),
00127 pattern, tag);
00128 } else {
00129 LM_ERR("database problem\n");
00130 perm_dbf.free_result(db_handle, res);
00131 return -1;
00132 }
00133 }
00134
00135 perm_dbf.free_result(db_handle, res);
00136
00137 *hash_table = new_hash_table;
00138
00139 LM_DBG("trusted table reloaded successfully.\n");
00140
00141 return 1;
00142 }
00143
00144
00145
00146
00147
00148 int init_trusted(void)
00149 {
00150
00151 if (!db_url.s) {
00152 LM_INFO("db_url parameter of permissions module not set, "
00153 "disabling allow_trusted\n");
00154 return 0;
00155 } else {
00156 if (db_bind_mod(&db_url, &perm_dbf) < 0) {
00157 LM_ERR("load a database support module\n");
00158 return -1;
00159 }
00160
00161 if (!DB_CAPABILITY(perm_dbf, DB_CAP_QUERY)) {
00162 LM_ERR("database module does not implement 'query' function\n");
00163 return -1;
00164 }
00165 }
00166
00167 hash_table_1 = hash_table_2 = 0;
00168 hash_table = 0;
00169
00170 if (db_mode == ENABLE_CACHE) {
00171 db_handle = perm_dbf.init(&db_url);
00172 if (!db_handle) {
00173 LM_ERR("unable to connect database\n");
00174 return -1;
00175 }
00176
00177 if(db_check_table_version(&perm_dbf, db_handle, &trusted_table, TABLE_VERSION) < 0) {
00178 LM_ERR("error during table version check.\n");
00179 perm_dbf.close(db_handle);
00180 return -1;
00181 }
00182
00183 hash_table_1 = new_hash_table();
00184 if (!hash_table_1) return -1;
00185
00186 hash_table_2 = new_hash_table();
00187 if (!hash_table_2) goto error;
00188
00189 hash_table = (struct trusted_list ***)shm_malloc
00190 (sizeof(struct trusted_list **));
00191 if (!hash_table) goto error;
00192
00193 *hash_table = hash_table_1;
00194
00195 if (reload_trusted_table() == -1) {
00196 LM_CRIT("reload of trusted table failed\n");
00197 goto error;
00198 }
00199
00200 perm_dbf.close(db_handle);
00201 db_handle = 0;
00202 }
00203 return 0;
00204
00205 error:
00206 if (hash_table_1) {
00207 free_hash_table(hash_table_1);
00208 hash_table_1 = 0;
00209 }
00210 if (hash_table_2) {
00211 free_hash_table(hash_table_2);
00212 hash_table_2 = 0;
00213 }
00214 if (hash_table) {
00215 shm_free(hash_table);
00216 hash_table = 0;
00217 }
00218 perm_dbf.close(db_handle);
00219 db_handle = 0;
00220 return -1;
00221 }
00222
00223
00224
00225
00226
00227 int init_child_trusted(int rank)
00228 {
00229 if (!db_url.s) {
00230 return 0;
00231 }
00232
00233
00234 if (db_mode==DISABLE_CACHE && rank>0) {
00235 db_handle = perm_dbf.init(&db_url);
00236 if (!db_handle) {
00237 LM_ERR("unable to connect database\n");
00238 return -1;
00239 }
00240
00241 if(db_check_table_version(&perm_dbf, db_handle, &trusted_table, TABLE_VERSION) < 0) {
00242 LM_ERR("error during table version check.\n");
00243 perm_dbf.close(db_handle);
00244 return -1;
00245 }
00246
00247 }
00248
00249 return 0;
00250 }
00251
00252
00253
00254
00255
00256 int mi_init_trusted(void)
00257 {
00258 if (!db_url.s || db_handle) return 0;
00259 db_handle = perm_dbf.init(&db_url);
00260 if (!db_handle) {
00261 LM_ERR("unable to connect database\n");
00262 return -1;
00263 }
00264 return 0;
00265 }
00266
00267
00268
00269
00270
00271 void clean_trusted(void)
00272 {
00273 if (hash_table_1) free_hash_table(hash_table_1);
00274 if (hash_table_2) free_hash_table(hash_table_2);
00275 if (hash_table) shm_free(hash_table);
00276 }
00277
00278
00279
00280
00281
00282
00283 static inline int match_proto(const char *proto_string, int proto_int)
00284 {
00285 if (strcasecmp(proto_string, "any") == 0) return 1;
00286
00287 if (proto_int == PROTO_UDP) {
00288 if (strcasecmp(proto_string, "udp") == 0) {
00289 return 1;
00290 } else {
00291 return 0;
00292 }
00293 }
00294
00295 if (proto_int == PROTO_TCP) {
00296 if (strcasecmp(proto_string, "tcp") == 0) {
00297 return 1;
00298 } else {
00299 return 0;
00300 }
00301 }
00302
00303 if (proto_int == PROTO_TLS) {
00304 if (strcasecmp(proto_string, "tls") == 0) {
00305 return 1;
00306 } else {
00307 return 0;
00308 }
00309 }
00310
00311 if (proto_int == PROTO_SCTP) {
00312 if (strcasecmp(proto_string, "sctp") == 0) {
00313 return 1;
00314 } else {
00315 return 0;
00316 }
00317 }
00318
00319 LM_ERR("unknown request protocol\n");
00320
00321 return 0;
00322 }
00323
00324
00325
00326
00327
00328 static int match_res(struct sip_msg* msg, int proto, db_res_t* _r)
00329 {
00330 int i, tag_avp_type;
00331 str uri;
00332 char uri_string[MAX_URI_SIZE+1];
00333 db_row_t* row;
00334 db_val_t* val;
00335 regex_t preg;
00336 int_str tag_avp, avp_val;
00337
00338 if (parse_from_header(msg) < 0) return -1;
00339 uri = get_from(msg)->uri;
00340 if (uri.len > MAX_URI_SIZE) {
00341 LM_ERR("message has From URI too large\n");
00342 return -1;
00343 }
00344 memcpy(uri_string, uri.s, uri.len);
00345 uri_string[uri.len] = (char)0;
00346
00347 row = RES_ROWS(_r);
00348
00349 for(i = 0; i < RES_ROW_N(_r); i++) {
00350 val = ROW_VALUES(row + i);
00351 if ((ROW_N(row + i) == 3) &&
00352 (VAL_TYPE(val) == DB_STRING) && !VAL_NULL(val) &&
00353 match_proto(VAL_STRING(val), proto) &&
00354 (VAL_NULL(val + 1) ||
00355 ((VAL_TYPE(val + 1) == DB_STRING) && !VAL_NULL(val + 1))) &&
00356 (VAL_NULL(val + 2) ||
00357 ((VAL_TYPE(val + 2) == DB_STRING) && !VAL_NULL(val + 2))))
00358 {
00359 if (VAL_NULL(val + 1)) goto found;
00360 if (regcomp(&preg, (char *)VAL_STRING(val + 1), REG_NOSUB)) {
00361 LM_ERR("invalid regular expression\n");
00362 continue;
00363 }
00364 if (regexec(&preg, uri_string, 0, (regmatch_t *)0, 0)) {
00365 regfree(&preg);
00366 continue;
00367 } else {
00368 regfree(&preg);
00369 goto found;
00370 }
00371 }
00372 }
00373 return -1;
00374
00375 found:
00376 get_tag_avp(&tag_avp, &tag_avp_type);
00377 if (tag_avp.n && !VAL_NULL(val + 2)) {
00378 avp_val.s.s = (char *)VAL_STRING(val + 2);
00379 avp_val.s.len = strlen(avp_val.s.s);
00380 if (add_avp(tag_avp_type|AVP_VAL_STR, tag_avp, avp_val) != 0) {
00381 LM_ERR("failed to set of tag_avp failed\n");
00382 return -1;
00383 }
00384 }
00385 return 1;
00386 }
00387
00388
00389
00390
00391
00392
00393 int allow_trusted(struct sip_msg* msg, char *src_ip, int proto)
00394 {
00395 int result;
00396 db_res_t* res = NULL;
00397
00398 db_key_t keys[1];
00399 db_val_t vals[1];
00400 db_key_t cols[3];
00401
00402 if (!db_url.s) {
00403 LM_ERR("db_url parameter has not been set\n");
00404 return -1;
00405 }
00406
00407 if (db_mode == DISABLE_CACHE) {
00408 keys[0] = &source_col;
00409 cols[0] = &proto_col;
00410 cols[1] = &from_col;
00411 cols[2] = &tag_col;
00412
00413 if (perm_dbf.use_table(db_handle, &trusted_table) < 0) {
00414 LM_ERR("failed to use trusted table\n");
00415 return -1;
00416 }
00417
00418 VAL_TYPE(vals) = DB_STRING;
00419 VAL_NULL(vals) = 0;
00420 VAL_STRING(vals) = src_ip;
00421
00422 if (perm_dbf.query(db_handle, keys, 0, vals, cols, 1, 3, 0,
00423 &res) < 0){
00424 LM_ERR("failed to query database\n");
00425 perm_dbf.close(db_handle);
00426 return -1;
00427 }
00428
00429 if (RES_ROW_N(res) == 0) {
00430 perm_dbf.free_result(db_handle, res);
00431 return -1;
00432 }
00433
00434 result = match_res(msg, proto, res);
00435 perm_dbf.free_result(db_handle, res);
00436 return result;
00437 } else {
00438 return match_hash_table(*hash_table, msg, src_ip, proto);
00439 }
00440 }
00441
00442
00443
00444
00445
00446
00447 int allow_trusted_0(struct sip_msg* _msg, char* str1, char* str2)
00448 {
00449 return allow_trusted(_msg, ip_addr2a(&(_msg->rcv.src_ip)),
00450 _msg->rcv.proto);
00451 }
00452
00453
00454
00455
00456
00457
00458 int allow_trusted_2(struct sip_msg* _msg, char* _src_ip_sp, char* _proto_sp)
00459 {
00460 pv_spec_t *src_ip_sp, *proto_sp;
00461 pv_value_t pv_val;
00462 char *src_ip, *proto;
00463 int proto_int;
00464
00465 src_ip_sp = (pv_spec_t *)_src_ip_sp;
00466 proto_sp = (pv_spec_t *)_proto_sp;
00467
00468 if (src_ip_sp && (pv_get_spec_value(_msg, src_ip_sp, &pv_val) == 0)) {
00469 if (pv_val.flags & PV_VAL_STR) {
00470 src_ip = pv_val.rs.s;
00471 } else {
00472 LM_ERR("src_ip pvar value is not string\n");
00473 return -1;
00474 }
00475 } else {
00476 LM_ERR("src_ip pvar does not exist or has no value\n");
00477 return -1;
00478 }
00479
00480 if (proto_sp && (pv_get_spec_value(_msg, proto_sp, &pv_val) == 0)) {
00481 if (pv_val.flags & PV_VAL_STR) {
00482 proto = pv_val.rs.s;
00483 } else {
00484 LM_ERR("proto pvar value is not string\n");
00485 return -1;
00486 }
00487 } else {
00488 LM_ERR("proto pvar does not exist or has no value\n");
00489 return -1;
00490 }
00491
00492 if (strcmp(proto, "UDP") == 0) {
00493 proto_int = PROTO_UDP;
00494 } else if (strcmp(proto, "TCP") == 0) {
00495 proto_int = PROTO_TCP;
00496 } else if (strcmp(proto, "TLS") == 0) {
00497 proto_int = PROTO_TLS;
00498 } else if (strcmp(proto, "SCTP") == 0) {
00499 proto_int = PROTO_SCTP;
00500 } else {
00501 LM_ERR("unknown protocol %s\n", proto);
00502 return -1;
00503 }
00504
00505 return allow_trusted(_msg, src_ip, proto_int);
00506 }