📄 permissions.c
字号:
DBG("check_routing(): allow rule found => routing is allowed\n"); return 1; } /* rule exists in deny file */ if (search_rule(deny[idx].rules, from_str, ruri_str)) { DBG("check_routing(): deny rule found => routing is denied\n"); return -1; } if (!check_all_branches) { DBG("check_routing(): Neither allow nor deny rule found => routing is allowed\n"); return 1; } check_branches: init_branch_iterator(); while((branch.s = next_branch(&branch.len, &q, 0, 0))) { uri_str = get_plain_uri(&branch); if (!uri_str) { LOG(L_ERR, "check_uri(): Error while extracting plain URI\n"); return -1; } DBG("check_routing: Looking for From: %s Branch: %s\n", from_str, uri_str); if (search_rule(allow[idx].rules, from_str, uri_str)) { continue; } if (search_rule(deny[idx].rules, from_str, uri_str)) { LOG(LOG_INFO, "check_routing(): Deny rule found for one of branches => routing is denied\n"); return -1; } } LOG(LOG_INFO, "check_routing(): Check of branches passed => routing is allowed\n"); return 1;}/* * Convert the name of the files into table index */static int load_fixup(void** param, int param_no){ char* pathname; int idx; rule_file_t* table; if (param_no == 1) { table = allow; } else { table = deny; } pathname = get_pathname(*param); idx = find_index(table, pathname); if (idx == -1) { /* Not opened yet, open the file and parse it */ table[rules_num].filename = pathname; table[rules_num].rules = parse_config_file(pathname); if (table[rules_num].rules) { LOG(L_INFO, "load_fixup(): File (%s) parsed\n", pathname); } else { LOG(L_WARN, "load_fixup(): File (%s) not found => empty rule set\n", pathname); } *param = (void*)(long)rules_num; if (param_no == 2) rules_num++; } else { /* File already parsed, re-use it */ LOG(L_INFO, "load_fixup(): File (%s) already loaded, re-using\n", pathname); pkg_free(pathname); *param = (void*)(long)idx; } return 0;}/* * Convert the name of the file into table index */static int single_fixup(void** param, int param_no){ char* buffer; void* tmp; int param_len, ret, suffix_len; if (param_no != 1) return 0; param_len = strlen((char*)*param); if (strlen(allow_suffix) > strlen(deny_suffix)) { suffix_len = strlen(allow_suffix); } else { suffix_len = strlen(deny_suffix); } buffer = pkg_malloc(param_len + suffix_len + 1); if (!buffer) { LOG(L_ERR, "single_fixup(): No memory left\n"); return -1; } strcpy(buffer, (char*)*param); strcat(buffer, allow_suffix); tmp = buffer; ret = load_fixup(&tmp, 1); strcpy(buffer + param_len, deny_suffix); tmp = buffer; ret |= load_fixup(&tmp, 2); *param = tmp; pkg_free(buffer); return ret;}/* * module initialization function */static int mod_init(void){ LOG(L_INFO, "permissions - initializing\n"); allow[0].filename = get_pathname(DEFAULT_ALLOW_FILE); allow[0].rules = parse_config_file(allow[0].filename); if (allow[0].rules) { LOG(L_INFO, "Default allow file (%s) parsed\n", allow[0].filename); } else { LOG(L_WARN, "Default allow file (%s) not found => empty rule set\n", allow[0].filename); } deny[0].filename = get_pathname(DEFAULT_DENY_FILE); deny[0].rules = parse_config_file(deny[0].filename); if (deny[0].rules) { LOG(L_INFO, "Default deny file (%s) parsed\n", deny[0].filename); } else { LOG(L_WARN, "Default deny file (%s) not found => empty rule set\n", deny[0].filename); } if (init_trusted() != 0) { LOG(L_ERR, "Error while initializing allow_trusted function\n"); } rules_num = 1; return 0;}static int child_init(int rank){ return init_child_trusted(rank);}/* * destroy function */static void mod_exit(void) { int i; for(i = 0; i < rules_num; i++) { free_rule(allow[i].rules); pkg_free(allow[i].filename); free_rule(deny[i].rules); pkg_free(deny[i].filename); } clean_trusted();}/* * Uses default rule files from the module parameters */int allow_routing_0(struct sip_msg* msg, char* str1, char* str2){ return check_routing(msg, 0);}int allow_routing_1(struct sip_msg* msg, char* basename, char* s){ return check_routing(msg, (int)(long)basename);}/* * Accepts allow and deny files as parameters */int allow_routing_2(struct sip_msg* msg, char* allow_file, char* deny_file){ /* Index converted by load_lookup */ return check_routing(msg, (int)(long)allow_file);}/* * Test of REGISTER messages. Creates To-Contact pairs and compares them * against rules in allow and deny files passed as parameters. The function * iterates over all Contacts and creates a pair with To for each contact * found. That allows to restrict what IPs may be used in registrations, for * example */static int check_register(struct sip_msg* msg, int idx){ int len; static char to_str[EXPRESSION_LENGTH + 1]; char* contact_str; contact_t* c; /* turn off control, allow any routing */ if ((!allow[idx].rules) && (!deny[idx].rules)) { DBG("check_register(): No rules => allow any registration\n"); return 1; } /* * Note: We do not parse the whole header field here although the message can * contain multiple Contact header fields. We try contacts one by one and if one * of them causes reject then we don't look at others, this could improve performance * a little bit in some situations */ if (parse_headers(msg, HDR_TO | HDR_CONTACT, 0) == -1) { LOG(L_ERR, "check_register(): Error while parsing headers\n"); return -1; } if (!msg->to) { LOG(L_ERR, "check_register(): To or Contact not found\n"); return -1; } if (!msg->contact) { /* REGISTER messages that contain no Contact header field * are allowed. Such messages do not modify the contents of * the user location database anyway and thus are not harmful */ DBG("check_register(): No Contact found, allowing\n"); return 1; } /* Check if the REGISTER message contains start Contact and if * so then allow it */ if (parse_contact(msg->contact) < 0) { LOG(L_ERR, "check_register(): Error while parsing Contact HF\n"); return -1; } if (((contact_body_t*)msg->contact->parsed)->star) { DBG("check_register(): * Contact found, allowing\n"); return 1; } len = ((struct to_body*)msg->to->parsed)->uri.len; if (len > EXPRESSION_LENGTH) { LOG(L_ERR, "check_register(): To header field is too long: %d chars\n", len); return -1; } strncpy(to_str, ((struct to_body*)msg->to->parsed)->uri.s, len); to_str[len] = '\0'; if (contact_iterator(&c, msg, 0) < 0) { return -1; } while(c) { contact_str = get_plain_uri(&c->uri); if (!contact_str) { LOG(L_ERR, "check_register(): Can't extract plain Contact URI\n"); return -1; } DBG("check_register(): Looking for To: %s Contact: %s\n", to_str, contact_str); /* rule exists in allow file */ if (search_rule(allow[idx].rules, to_str, contact_str)) { if (check_all_branches) goto skip_deny; } /* rule exists in deny file */ if (search_rule(deny[idx].rules, to_str, contact_str)) { DBG("check_register(): Deny rule found => Register denied\n"); return -1; } skip_deny: if (contact_iterator(&c, msg, c) < 0) { return -1; } } DBG("check_register(): No contact denied => Allowed\n"); return 1;}int allow_register_1(struct sip_msg* msg, char* basename, char* s){ return check_register(msg, (int)(long)basename);}int allow_register_2(struct sip_msg* msg, char* allow_file, char* deny_file){ return check_register(msg, (int)(long)allow_file);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -