static bool config_filter_match_rest(const struct config_filter *mask, const struct config_filter *filter) { if (mask->local_name != NULL) { if (filter->local_name == NULL) return FALSE; if (strcmp(filter->local_name, mask->local_name) != 0) return FALSE; } /* FIXME: it's not comparing full masks */ if (mask->remote_bits != 0) { if (filter->remote_bits == 0) return FALSE; if (!net_is_in_network(&filter->remote_net, &mask->remote_net, mask->remote_bits)) return FALSE; } if (mask->local_bits != 0) { if (filter->local_bits == 0) return FALSE; if (!net_is_in_network(&filter->local_net, &mask->local_net, mask->local_bits)) return FALSE; } return TRUE; }
static bool mail_export_filter_match_ip(const struct mail_export_filter *filter, const struct mail_ip *ip) { struct mail_session *s; bool connected = FALSE, user_ok = FALSE, domain_ok = FALSE; if (filter->connected || filter->ip_bits > 0) { for (s = ip->sessions; s != NULL; s = s->ip_next) { if (!s->disconnected) connected = TRUE; if (filter->user != NULL && wildcard_match(s->user->name, filter->user)) user_ok = TRUE; if (filter->domain != NULL && wildcard_match(s->user->domain->name, filter->domain)) domain_ok = TRUE; } if (filter->connected && !connected) return FALSE; if (filter->user != NULL && !user_ok) return FALSE; if (filter->domain != NULL && !domain_ok) return FALSE; } if (filter->since > ip->last_update.tv_sec) return FALSE; if (filter->ip_bits > 0 && !net_is_in_network(&ip->ip, &filter->ip, filter->ip_bits)) return FALSE; return TRUE; }
static bool mail_export_filter_match_user_common(const struct mail_export_filter *filter, const struct mail_user *user) { struct mail_session *s; bool connected = FALSE, ip_ok = FALSE; if (filter->user != NULL && !wildcard_match(user->name, filter->user)) return FALSE; if (filter->connected || filter->ip_bits > 0) { for (s = user->sessions; s != NULL; s = s->user_next) { if (!s->disconnected) connected = TRUE; if (filter->ip_bits > 0 && net_is_in_network(&s->ip->ip, &filter->ip, filter->ip_bits)) ip_ok = TRUE; } if (filter->connected && !connected) return FALSE; if (filter->ip_bits > 0 && !ip_ok) return FALSE; } return TRUE; }
static bool config_filter_match_rest(const struct config_filter *mask, const struct config_filter *filter) { if (mask->local_name != NULL) { if (filter->local_name == NULL) return FALSE; /* Handle multiple names seperated by spaces in local_name * Ex: local_name "mail.domain.tld domain.tld mx.domain.tld" { ... } */ const char *const *local_name = t_strsplit_spaces(mask->local_name, " "); bool matched = FALSE; for (; *local_name != NULL; local_name++) { if (dns_match_wildcard(filter->local_name, *local_name) == 0) { matched = TRUE; break; } } if (!matched) return FALSE; } /* FIXME: it's not comparing full masks */ if (mask->remote_bits != 0) { if (filter->remote_bits == 0) return FALSE; if (!net_is_in_network(&filter->remote_net, &mask->remote_net, mask->remote_bits)) return FALSE; } if (mask->local_bits != 0) { if (filter->local_bits == 0) return FALSE; if (!net_is_in_network(&filter->local_net, &mask->local_net, mask->local_bits)) return FALSE; } return TRUE; }
static void penalty_print_line(struct penalty_context *ctx, const struct penalty_line *line) { const struct tm *tm; char buf[10]; if (ctx->net_bits > 0) { if (!net_is_in_network(&line->ip, &ctx->net_ip, ctx->net_bits)) return; } tm = localtime(&line->last_update); strftime(buf, sizeof(buf), "%H:%M:%S", tm); printf("%-16s %7u %s %s\n", net_ip2addr(&line->ip), line->penalty, unixdate2str(line->last_penalty), buf); }
static bool mail_export_filter_match_session(const struct mail_export_filter *filter, const struct mail_session *session) { if (filter->connected && session->disconnected) return FALSE; if (filter->since > session->last_update.tv_sec) return FALSE; if (filter->user != NULL && !wildcard_match(session->user->name, filter->user)) return FALSE; if (filter->domain != NULL && !wildcard_match(session->user->domain->name, filter->domain)) return FALSE; if (filter->ip_bits > 0 && !net_is_in_network(&session->ip->ip, &filter->ip, filter->ip_bits)) return FALSE; return TRUE; }
static bool client_is_trusted(struct client *client) { const char *const *net; struct ip_addr net_ip; unsigned int bits; if (client->set->login_trusted_networks == NULL) return FALSE; net = t_strsplit_spaces(client->set->login_trusted_networks, ", "); for (; *net != NULL; net++) { if (net_parse_range(*net, &net_ip, &bits) < 0) { i_error("login_trusted_networks: " "Invalid network '%s'", *net); break; } if (net_is_in_network(&client->ip, &net_ip, bits)) return TRUE; } return FALSE; }
static void test_net_is_in_network(void) { static struct test_net_is_in_network_input input[] = { { "1.2.3.4", "1.2.3.4", 32, TRUE }, { "1.2.3.4", "1.2.3.3", 32, FALSE }, { "1.2.3.4", "1.2.3.5", 32, FALSE }, { "1.2.3.4", "1.2.2.4", 32, FALSE }, { "1.2.3.4", "1.1.3.4", 32, FALSE }, { "1.2.3.4", "0.2.3.4", 32, FALSE }, { "1.2.3.253", "1.2.3.254", 31, FALSE }, { "1.2.3.254", "1.2.3.254", 31, TRUE }, { "1.2.3.255", "1.2.3.254", 31, TRUE }, { "1.2.3.255", "1.2.3.0", 24, TRUE }, { "1.2.255.255", "1.2.254.0", 23, TRUE }, { "255.255.255.255", "128.0.0.0", 1, TRUE }, { "255.255.255.255", "127.0.0.0", 1, FALSE } #ifdef HAVE_IPV6 , { "1234:5678::abcf", "1234:5678::abce", 127, TRUE }, { "1234:5678::abcd", "1234:5678::abce", 127, FALSE }, { "123e::ffff", "123e::0", 15, TRUE }, { "123d::ffff", "123e::0", 15, FALSE } #endif }; struct ip_addr ip, net_ip; unsigned int i; bool success; test_begin("net_is_in_network()"); for (i = 0; i < N_ELEMENTS(input); i++) { test_assert(net_addr2ip(input[i].ip, &ip) == 0); test_assert(net_addr2ip(input[i].net, &net_ip) == 0); success = net_is_in_network(&ip, &net_ip, input[i].bits) == input[i].ret; test_out(t_strdup_printf("net_is_in_network(%u)", i), success); } test_end(); }