int check_src_addr_3(struct sip_msg *msg, char *grp, char *info, char* pattern) { int group, hash_ret, subnet_ret, ret = 1; struct in_addr in; str str_ip, str_part_group; struct ip_addr *ip; str pattern_s; struct pm_part_struct *part_struct; struct part_var *pvar, *pvar_new; if (grp) { pvar = (struct part_var *) grp; if (pvar->type == TYPE_PV) { if (fixup_get_svalue(msg, pvar->u.gp, &str_part_group)) { LM_ERR("cannot get group value\n"); return -1; } pvar_new = pkg_malloc(sizeof(struct part_var)); if (pvar_new == NULL) { LM_ERR("no more pkg mem\n"); return -1; } if (check_addr_param1( &str_part_group, pvar_new)) { LM_ERR("failed to parse [%s]!", str_part_group.s); return -1; } group = pvar_new->u.parsed_part.v.ival; if (pvar_new->u.parsed_part.partition.s) part_struct = get_part_struct(&pvar_new->u.parsed_part.partition); else part_struct = get_part_struct(&def_part); pkg_free(pvar_new); } else { group = pvar->u.parsed_part.v.ival; if (pvar->u.parsed_part.partition.s) part_struct = get_part_struct(&pvar->u.parsed_part.partition); else part_struct = get_part_struct(&def_part); } if (group < 0) { LM_ERR("invalid group value\n"); return -1; } } else { group = 0; part_struct = get_part_struct(&def_part); } if (part_struct == NULL) { LM_ERR("no db_url defined or no (such) partition!\n"); return -1; } in.s_addr = msg->rcv.src_ip.u.addr32[0]; str_ip.s = inet_ntoa(in); if (!str_ip.s) { LM_ERR("error at inet_ntoa\n"); return -1; } str_ip.len = strlen(str_ip.s); ip = str2ip(&str_ip); LM_DBG("Looking for : <%d, %.*s, %d, %d> in tables\n", group, str_ip.len, str_ip.s, msg->rcv.src_port, msg->rcv.proto); if (pattern) { if (fixup_get_svalue(msg, (gparam_p)pattern, &pattern_s) < 0) { LM_ERR("cannot get pattern value\n"); return -1; } pattern = pkg_malloc(pattern_s.len + 1); if (!pattern) { LM_ERR("no more pkg mem\n"); return -1; } memcpy(pattern, pattern_s.s, pattern_s.len); pattern[pattern_s.len] = 0; } hash_ret = hash_match(msg, *part_struct->hash_table, group, ip, msg->rcv.src_port, msg->rcv.proto, pattern, info); if (hash_ret < 0) { subnet_ret = match_subnet_table(msg, *part_struct->subnet_table, group, ip, msg->rcv.src_port, msg->rcv.proto, pattern, info); ret = (hash_ret > subnet_ret) ? hash_ret : subnet_ret; } if (pattern) pkg_free(pattern); return ret; }
static int url_hash_match(const struct regex_matcher *rlist, const char *inurl, size_t len) { size_t j, k, ji, ki; char *host_begin; const char *path_begin; const char *component; size_t path_len; size_t host_len; char *p; int rc, prefix_matched=0; const char *lp[COMPONENTS+1]; size_t pp[COMPONENTS+2]; char urlbuff[URL_MAX_LEN+3];/* htmlnorm truncates at 1024 bytes + terminating null + slash + host end null */ unsigned count; if(!rlist || !rlist->sha256_hashes.bm_patterns) { /* no hashes loaded -> don't waste time canonicalizing and * looking up */ return CL_SUCCESS; } if(!inurl) return CL_EMEM; rc = cli_url_canon(inurl, len, urlbuff, sizeof(urlbuff), &host_begin, &host_len, &path_begin, &path_len); if (rc == CL_PHISH_CLEAN) return rc; /* get last 5 components of hostname */ j=COMPONENTS; component = strrchr(host_begin, '.'); while(component && j > 0) { do { --component; } while(*component != '.' && component > host_begin); if(*component != '.') component = NULL; if(component) lp[j--] = component + 1; } lp[j] = host_begin; /* get first 5 components of path */ pp[0] = path_len; if(path_len) { pp[1] = strcspn(path_begin, "?"); if(pp[1] != pp[0]) k = 2; else k = 1; pp[k++] = 0; while(k < COMPONENTS+2) { p = strchr(path_begin + pp[k-1] + 1, '/'); if(p && p > path_begin) { pp[k++] = p - path_begin; } else break; } } else k = 1; count = 0; for(ki=k;ki > 0;) { --ki; for(ji=COMPONENTS+1;ji > j;) { /* lookup last 2 and 3 components of host, as hostkey prefix, * if not matched, shortcircuit lookups */ int need_prefixmatch = (count<2 && !prefix_matched) && rlist->hostkey_prefix.bm_patterns; --ji; assert(pp[ki] <= path_len); /* lookup prefix/suffix hashes of URL */ rc = hash_match(rlist, lp[ji], host_begin + host_len - lp[ji] + 1, path_begin, pp[ki], need_prefixmatch ? &prefix_matched : NULL); if(rc) { return rc; } count++; #if 0 if (count == 2 && !prefix_matched && rlist->hostkey_prefix.bm_patterns) { /* if hostkey is not matched, don't bother calculating * hashes for other parts of the URL, they are not in the DB */ cli_dbgmsg("hostkey prefix not matched, short-circuiting lookups\n"); return CL_SUCCESS; } #endif } } return CL_SUCCESS; }
int check_addr_6(struct sip_msg* msg, char* grp_sgp, char* ip_sp, char* port_sp, char* proto_sp, char* info, char* pattern) { unsigned int port; int group, proto, hash_ret, subnet_ret, ret = 1; struct ip_addr *ip; str str_ip, str_proto, str_port, pattern_s, str_part_group; struct pm_part_struct *part_struct; struct part_var *pvar, *pvar_new; memset(&str_ip, 0, sizeof(str)); memset(&str_proto, 0, sizeof(str)); if (grp_sgp) { pvar = (struct part_var *) grp_sgp; if (pvar->type == TYPE_PV) { if (fixup_get_svalue(msg, pvar->u.gp, &str_part_group)) { LM_ERR("cannot get group value\n"); return -1; } pvar_new = pkg_malloc(sizeof(struct part_var)); if (pvar_new == NULL) { LM_ERR("no more pkg mem\n"); return -1; } if (check_addr_param1( &str_part_group, pvar_new)) { LM_ERR("failed to parse [%s]!", str_part_group.s); return -1; } group = pvar_new->u.parsed_part.v.ival; if (pvar_new->u.parsed_part.partition.s) part_struct = get_part_struct(&pvar_new->u.parsed_part.partition); else part_struct = get_part_struct(&def_part); pkg_free(pvar_new); } else { group = pvar->u.parsed_part.v.ival; if (pvar->u.parsed_part.partition.s) part_struct = get_part_struct(&pvar->u.parsed_part.partition); else part_struct = get_part_struct(&def_part); } if (group < 0) { LM_ERR("invalid group value\n"); return -1; } } else { group = 0; part_struct = get_part_struct(&def_part); } if (part_struct == NULL) { LM_ERR("no db_url defined or no (such) partition!\n"); return -1; } if (ip_sp) { if (fixup_get_svalue(msg, (gparam_p)ip_sp, &str_ip)) { LM_ERR("cannot get str_ip string\n"); return -1; } } else { LM_ERR("source ip not provided!\n"); return -1; } if (str_ip.len <= 0 || !str_ip.s) { LM_ERR("source ip is not set!\n"); return -1; } ip = str2ip(&str_ip); if (!ip) { LM_ERR("invalid ip set <%.*s>!\n", str_ip.len, str_ip.s); return -1; } if (proto_sp) { if (fixup_get_svalue(msg, (gparam_p) proto_sp, &str_proto)) { LM_ERR("cannot get str_proto string\n"); return -1; } } if (str_proto.len <= 0 || !str_proto.s) { str_proto.s = "any"; str_proto.len = strlen(str_proto.s); } if (!strncasecmp(str_proto.s, "UDP", str_proto.len)) proto = PROTO_UDP; else if (!strncasecmp(str_proto.s, "TCP", str_proto.len)) proto = PROTO_TCP; else if (!strncasecmp(str_proto.s, "TLS", str_proto.len)) proto = PROTO_TLS; else if (!strncasecmp(str_proto.s, "SCTP", str_proto.len)) proto = PROTO_SCTP; else if (!strncasecmp(str_proto.s, "ANY", str_proto.len)) proto = PROTO_NONE; else { LM_ERR("unknown protocol %.*s\n", str_proto.len, str_proto.s); return -1; } if (port_sp) { if (fixup_get_svalue(msg, (gparam_p)port_sp, &str_port)) { LM_ERR("cannot get port value\n"); return -1; } if (str2int(&str_port, &port) < 0) { LM_ERR("invalid port value\n"); return -1; } } else port = 0; if (pattern) { if (fixup_get_svalue(msg, (gparam_p)pattern, &pattern_s) < 0) { LM_ERR("cannot get pattern value\n"); return -1; } pattern = pkg_malloc(pattern_s.len + 1); if (!pattern) { LM_ERR("no more pkg mem\n"); return -1; } memcpy(pattern, pattern_s.s, pattern_s.len); pattern[pattern_s.len] = 0; } LM_DBG("Looking for : <%d, %.*s, %.*s, %d, %s>\n", group, str_ip.len, str_ip.s, str_proto.len, str_proto.s, port, ZSW(pattern) ); hash_ret = hash_match(msg, *part_struct->hash_table, group, ip, port, proto, pattern, info); if (hash_ret < 0) { subnet_ret = match_subnet_table(msg, *part_struct->subnet_table, group, ip, port, proto, pattern, info); ret = (hash_ret > subnet_ret) ? hash_ret : subnet_ret; } if (pattern) pkg_free(pattern); return ret; }