diff --git a/etc/inc/filter.inc b/etc/inc/filter.inc index ba71d04..17acae3 100644 --- a/etc/inc/filter.inc +++ b/etc/inc/filter.inc @@ -415,7 +415,13 @@ function filter_generate_aliases() { $extraalias = ""; $ip = find_interface_ip($alias['address']); $extraalias = " " . link_ip_to_carp_interface($ip); - $aliases .= "{$alias['name']} = \"{ {$alias['address']}{$extralias} }\"\n"; + if ($alias['type'] != 'urltable') + $aliases .= "{$alias['name']} = \"{ {$alias['address']}{$extralias} }\"\n"; + else { + $urlfn = alias_expand_urltable($alias['name']); + if ($urlfn) + $aliases .= "table <{$alias['name']}> persist file \"{$urlfn}\"\n"; + } } } @@ -2013,7 +2019,8 @@ function generate_user_filter_rule($rule, $ngcounter) { } else { if ($g['debug']) echo "{$src_table} NOT found in cache...adding\n"; - $table_cache[$src_table] = $src_table_line; + if (strpos($src_table_line, 'http://') === false) + $table_cache[$src_table] = $src_table_line; } if (isset($dst_table)) if (isset($table_cache[$dst_table])) { @@ -2022,7 +2029,8 @@ function generate_user_filter_rule($rule, $ngcounter) { } else { if ($g['debug']) echo "{$dst_table} NOT found in cache...adding\n"; - $table_cache[$dst_table] = $dst_table_line; + if (strpos($dst_table_line, 'http://') === false) + $table_cache[$dst_table] = $dst_table_line; } /* exception(s) to a user rules can go here. */ diff --git a/etc/inc/pfsense-utils.inc b/etc/inc/pfsense-utils.inc index c45def5..2f0f6fb 100644 --- a/etc/inc/pfsense-utils.inc +++ b/etc/inc/pfsense-utils.inc @@ -3905,4 +3905,47 @@ function update_alias_names_upon_change($section, $subsection, $fielda, $fieldb, } +function process_alias_urltable($name, $url, $freq, $forceupdate=false) { + $aliastable_prefix = "/var/db/aliastables/"; + $aliastable_filename = $aliastable_prefix . $name . ".txt"; + + // Make the aliases directory if it doesn't exist + if (!file_exists($aliastable_prefix)) { + mkdir($aliastable_prefix); + } elseif (!is_dir($aliastable_prefix)) { + unlink($aliastable_prefix); + mkdir($aliastable_prefix); + } + + // If the file doesn't exist or is older than update_freq days, fetch a new copy. + if (!file_exists($aliastable_filename) + || ((time() - filemtime($aliastable_filename)) > ($freq * 86400)) + || $forceupdate) { + + // Try to fetch the URL supplied + conf_mount_rw(); + unlink_if_exists($aliastable_filename . ".tmp"); + mwexec("/usr/bin/fetch -q -o " . escapeshellarg($aliastable_filename) . ".tmp " . escapeshellarg($url)); + mwexec("/usr/bin/grep -v '^#' " . escapeshellarg($aliastable_filename) . ".tmp > " . escapeshellarg($aliastable_filename)); + unlink_if_exists($aliastable_filename . ".tmp"); + conf_mount_ro(); + if (filesize($aliastable_filename)) { + return true; + } else { + // If it's unfetchable or an empty file, bail + return false; + } + } else { + // File exists, and it doesn't need updated. + return -1; + } +} + +function is_valid_http_url($url) { + $parsed = parse_url($url); + if (($parsed['scheme'] == 'http') && (is_fqdn($parsed['host']) || is_ipaddr($parsed['host']))) + return true; + else + return false; +} ?> diff --git a/etc/inc/util.inc b/etc/inc/util.inc index 61d2e55..efeaf01 100644 --- a/etc/inc/util.inc +++ b/etc/inc/util.inc @@ -487,6 +487,21 @@ function alias_expand_net($name) { return null; } +function alias_expand_urltable($name) { + global $aliastable; + $aliastable_prefix = "/var/db/aliastables/"; + $aliastable_filename = $aliastable_prefix . $name . ".txt"; + + if (isset($aliastable[$name]) + && (is_valid_http_url($aliastable[$name])) + && file_exists($aliastable_filename)) + return $aliastable_filename; + elseif (process_alias_urltable($name, $aliastable[$name], 0, true)) + return $aliastable_filename; + else + return null; +} + /* find out whether two subnets overlap */ function check_subnets_overlap($subnet1, $bits1, $subnet2, $bits2) { diff --git a/etc/rc.update_urltables b/etc/rc.update_urltables new file mode 100755 index 0000000..506a5b0 --- /dev/null +++ b/etc/rc.update_urltables @@ -0,0 +1,49 @@ +#!/usr/local/bin/php -q + 0) { + log_error("{$argv[0]}: Starting up."); + + if ($argv[1] != "now") { + // Wait a little before updating. + $wait = mt_rand(5, 60); + log_error("{$argv[0]}: Sleeping for {$wait} seconds."); + sleep($wait); + } + + log_error("{$argv[0]}: Starting URL table alias updates"); + + foreach ($todo as $t) { + $r = process_alias_urltable($t['name'], $t['url'], $t['freq']); + if ($r == 1) { + $result = ""; + exec("/sbin/pfctl -t " . escapeshellarg($t['name']) . " -T replace -f /var/db/aliastables/" . escapeshellarg($t['name']) . ".txt 2>&1", $result); + log_error("{$argv[0]}: Updated {$t['name']} content from {$t['url']}: {$result[0]}"); + } elseif ($r == -1) { + log_error("{$argv[0]}: {$t['name']} does not need updated."); + } else { + log_error("{$argv[0]}: ERROR: could not update {$t['name']} content from {$t['url']}"); + } + } +} +?> \ No newline at end of file diff --git a/usr/local/www/firewall_aliases.php b/usr/local/www/firewall_aliases.php index e453200..9be52a4 100755 --- a/usr/local/www/firewall_aliases.php +++ b/usr/local/www/firewall_aliases.php @@ -85,7 +85,7 @@ if ($_GET['act'] == "del") { $referenced_by = $rule['descr']; break; } - if($rule['source']['address'] == $alias_name) { + if($rule['destination']['address'] == $alias_name) { $is_alias_referenced = true; $referenced_by = $rule['descr']; break; @@ -177,11 +177,10 @@ include("head.inc");