📄 permissions.c
字号:
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"); return -1; } if (init_tag_avp( tag_avp_param) < 0) { LOG(L_ERR,"ERROR:permissions:mod_init: failed to process tag AVP\n"); return -1; } 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_F | HDR_CONTACT_F, 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);}/* * determines the permission to refer to given refer-to uri * return values: * -1: deny * 1: allow */static int check_refer_to(struct sip_msg* msg, int idx) { struct hdr_field *from, *refer_to; int len; static char from_str[EXPRESSION_LENGTH+1]; static char refer_to_str[EXPRESSION_LENGTH+1]; /* turn off control, allow any refer */ if ((!allow[idx].rules) && (!deny[idx].rules)) { DBG("check_refer_to(): No rules => allow any refer\n"); return 1; } /* looking for FROM HF */ if ((!msg->from) && (parse_headers(msg, HDR_FROM_F, 0) == -1)) { LOG(L_ERR, "check_refer_to(): Error while parsing message\n"); return -1; } if (!msg->from) { LOG(L_ERR, "check_refer_to(): FROM header field not found\n"); return -1; } /* we must call parse_from_header explicitly */ if ((!(msg->from)->parsed) && (parse_from_header(msg) < 0)) { LOG(L_ERR, "check_refer_to(): Error while parsing From body\n"); return -1; } from = msg->from; len = ((struct to_body*)from->parsed)->uri.len; if (len > EXPRESSION_LENGTH) { LOG(L_ERR, "check_refer_to(): From header field is too long: %d chars\n", len); return -1; } strncpy(from_str, ((struct to_body*)from->parsed)->uri.s, len); from_str[len] = '\0'; /* looking for REFER-TO HF */ if ((!msg->refer_to) && (parse_headers(msg, HDR_REFER_TO_F, 0) == -1)){ LOG(L_ERR, "check_refer_to(): Error while parsing message\n"); return -1; } if (!msg->refer_to) { LOG(L_ERR, "check_refer_to(): Refer-To header field not found\n"); return -1; } /* we must call parse_refer_to_header explicitly */ if ((!(msg->refer_to)->parsed) && (parse_refer_to_header(msg) < 0)) { LOG(L_ERR, "check_refer_to(): Error while parsing Refer-To body\n"); return -1; } refer_to = msg->refer_to; len = ((struct to_body*)refer_to->parsed)->uri.len; if (len > EXPRESSION_LENGTH) { LOG(L_ERR, "check_refer_to(): Refer-To header field is too long: %d chars\n", len); return -1; } strncpy(refer_to_str, ((struct to_body*)refer_to->parsed)->uri.s, len); refer_to_str[len] = '\0'; DBG("check_refer_to(): looking for From: %s Refer-To: %s\n", from_str, refer_to_str); /* rule exists in allow file */ if (search_rule(allow[idx].rules, from_str, refer_to_str)) { DBG("check_refer_to(): allow rule found => refer is allowed\n"); return 1; } /* rule exists in deny file */ if (search_rule(deny[idx].rules, from_str, refer_to_str)) { DBG("check_refer_to(): deny rule found => refer is denied\n"); return -1; } DBG("check_refer_to(): Neither allow nor deny rule found => refer_to is allowed\n"); return 1;}int allow_refer_to_1(struct sip_msg* msg, char* basename, char* s){ return check_refer_to(msg, (int)(long)basename);}int allow_refer_to_2(struct sip_msg* msg, char* allow_file, char* deny_file){ return check_refer_to(msg, (int)(long)allow_file);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -