$_[$i] = $1."/".&prefix_to_mask($2);
}
if ($_[$i] =~ /^(\S+)\/(\S+)$/) {
- # Compare with network/mask
- # XXX IPv6 support
+ # Compare with IPv4 network/mask
@mo = split(/\./, $1); @ms = split(/\./, $2);
for($j=0; $j<4; $j++) {
if ((int($io[$j]) & int($ms[$j])) != int($mo[$j])) {
# Compare with hostname regexp
$mismatch = 1 if ($hn !~ /$1$/);
}
- elsif ($_[$i] eq 'LOCAL') {
- # Compare with local network
- # XXX IPv6 support
+ elsif ($_[$i] eq 'LOCAL' && &check_ipaddress($_[1])) {
+ # Compare with local IPv4 network
local @lo = split(/\./, $_[1]);
if ($lo[0] < 128) {
$mismatch = 1 if ($lo[0] != $io[0]);
$lo[2] != $io[2]);
}
}
+ elsif ($_[$i] eq 'LOCAL' && &check_ip6address($_[1])) {
+ # Compare with local IPv6 network, which is always first 4 words
+ local @lo = split(/:/, $_[1]);
+ for(my $i=0; $i<4; $i++) {
+ $mismatch = 1 if ($lo[$i] ne $io[$i]);
+ }
+ }
elsif ($_[$i] =~ /^[0-9\.]+$/) {
# Compare with IPv4 address or network
@mo = split(/\./, $_[$i]);
@mo = split(/:/, $_[$i]);
while(@mo && !$mo[$#mo]) { pop(@mo); }
for($j=0; $j<@mo; $j++) {
- if ($mo[$j] != $io[$j]) {
+ if ($mo[$j] ne $io[$j]) {
$mismatch = 1;
}
}
$raddr = $ENV{'REMOTE_ADDR'};
if ($in{"access"}) {
@hosts = split(/\s+/, $in{"ip"});
+ push(@hosts, "LOCAL") if ($in{'local'});
if (!@hosts) { &error($text{'access_enone'}); }
foreach $h (@hosts) {
$err = &valid_allow($h);
print &ui_table_start($text{'access_header'}, undef, 2, [ "width=30%" ]);
$access = $miniserv{"allow"} ? 1 : $miniserv{"deny"} ? 2 : 0;
+@list = $access == 1 ? split(/\s+/, $miniserv{"allow"}) :
+ $access == 2 ? split(/\s+/, $miniserv{"deny"}) : ( );
+$idx = &indexof("LOCAL", @list);
+splice(@list, $idx, 1) if ($idx >= 0);
print &ui_table_row($text{'access_ip'},
&ui_radio("access", $access,
[ [ 0, $text{'access_all'} ],
[ 1, $text{'access_allow'} ],
[ 2, $text{'access_deny'} ] ])."<br>\n".
- &ui_textarea("ip",
- $access == 1 ? join("\n", split(/\s+/, $miniserv{"allow"})) :
- $access == 2 ? join("\n", split(/\s+/, $miniserv{"deny"})) : "",
- 6, 30));
+ &ui_textarea("ip", join("\n", @list), 6, 30)."<br>\n".
+ &ui_checkbox("local", 1, $text{'access_local'}, $idx >= 0));
print &ui_table_row($text{'access_always'},
&ui_yesno_radio("alwaysresolve", int($miniserv{'alwaysresolve'})));
access_title=IP Access Control
access_desc=The Webmin server can be configured to deny or allow access only from certain IP addresses using this form. Hostnames (like foo.bar.com) and IP networks (like 10.254.3.0 or 10.254.1.0/255.255.255.128) can also be entered. You should limit access to your server to trusted addresses, especially if it is accessible from the Internet. Otherwise, anyone who guesses your password will have complete control of your system.
access_ip=Allowed IP addresses
+access_local=Include local network in list
access_header=Access control options
access_all=Allow from all addresses
access_allow=Only allow from listed addresses
access_emask='$1' is not a valid netmask
access_ecidr='$1' is not a valid CIDR number
access_eip='$1' is not a complete IP or network address
+access_eip6='$1' is not a complete IPv6 or network address
access_ehost=Failed to find IP address for '$1'
access_eself=Your current IP address ($1) would be denied
access_always=Resolve hostnames on every request?
$ip = $1."/".&prefix_to_mask($2);
}
if ($ip =~ /^(\S+)\/(\S+)$/) {
- # Compare with network/mask
- # XXX IPv6 support
+ # Compare with IPv4 network/mask
@mo = split(/\./, $1); @ms = split(/\./, $2);
for($j=0; $j<4; $j++) {
if ((int($io[$j]) & int($ms[$j])) != int($mo[$j])) {
@mo = split(/:/, $_[$i]);
while(@mo && !$mo[$#mo]) { pop(@mo); }
for($j=0; $j<@mo; $j++) {
- if ($mo[$j] != $io[$j]) {
+ if ($mo[$j] ne $io[$j]) {
$mismatch = 1;
}
}
sub valid_allow
{
local ($h) = @_;
-local $i;
if ($h =~ /^([0-9\.]+)\/(\d+)$/) {
&check_ipaddress($1) ||
return &text('access_enet', "$1");
&check_ipaddress($h) ||
return &text('access_eip', $h);
}
+elsif ($h =~ /^[a-f0-9:]+$/) {
+ &check_ip6address($h) ||
+ return &text('access_eip6', $h);
+ }
elsif ($h =~ /^\*\.(\S+)$/) {
# *.domain is OK
}
elsif ($h eq 'LOCAL') {
# Local means any on local nets
}
-elsif ($i = join('.', unpack("CCCC", inet_aton($h)))) {
- # Resolve a hostname
- $h = $i;
+elsif (&to_ipaddress($h) || &to_ip6address($h)) {
+ # Resolvable hostname
}
else {
return &text('access_ehost', $h);