Fixed Ipv6 address support
authorJamie Cameron <jcameron@webmin.com>
Fri, 13 Feb 2009 18:36:58 +0000 (18:36 +0000)
committerJamie Cameron <jcameron@webmin.com>
Fri, 13 Feb 2009 18:36:58 +0000 (18:36 +0000)
apache/CHANGELOG
apache/apache-lib.pl
apache/core.pl
apache/create_virt.cgi
apache/index.cgi
apache/save_vserv.cgi
apache/virt_index.cgi

index 798f437..2d65f44 100644 (file)
@@ -42,3 +42,5 @@ Added support for the funny ${APACHE_RUN_USER} and ${APACHE_PID_FILE} variables
 ---- Changes since 1.430 ----
 When a virtual host's base directory is changed, all <directory> blocks under it are updated too.
 When stopping and re-starting Apache, give it time to fully stop before continuing.
+---- Changes since 1.450 ----
+Fixed handling of IPv6 addresses so that Apache's [address] format is now fully supported.
index 289ce80..c5fcfa2 100644 (file)
@@ -1012,7 +1012,10 @@ if ($_[0]) {
                                                                  : $n);
                }
        else {
-               return &html_escape($_[0]->{'value'});
+               return &html_escape(
+                       $_[0]->{'value'} =~ /^\[(\S+)\]$/ ? $1 :
+                       $_[0]->{'value'} =~ /^\[(\S+)\]:(\d+)$/ ? "$1:$2" :
+                               $_[0]->{'value'});
                }
        }
 else { return $_[1] ? "*" : $text{'default_serv'}; }
@@ -1861,11 +1864,5 @@ else {
        }
 }
 
-sub check_apache_ip6address
-{
-local ($ip) = @_;
-return $ip =~ /^\[(\S+)\]$/ && &check_ip6address("$1");
-}
-
 1;
 
index aa40880..33eb9f6 100644 (file)
@@ -251,13 +251,24 @@ $bref = $_[0]; $lref = $_[1]; $pref = $_[2];
 if (@$lref) {
        # listen directives in use.. so BindAddress and Port are unused
        foreach $l (@$lref) {
-               if ($l->{'value'} =~ /^(\S+):(\d+)$/) {
+               if ($l->{'value'} =~ /^\[(\S+)\]:(\d+)$/) {
+                       # IPv6 address and port
+                       push(@blist, $1); push(@plist, $2);
+                       }
+               elsif ($l->{'value'} =~ /^\[(\S+)\]$/) {
+                       # IPv6 address only
+                       push(@blist, $1); push(@plist, undef);
+                       }
+               elsif ($l->{'value'} =~ /^(\S+):(\d+)$/) {
+                       # IPv4 address and port
                        push(@blist, $1); push(@plist, $2);
                        }
                elsif ($l->{'value'} =~ /^(\d+)$/) {
+                       # Port only
                        push(@blist, "*"); push(@plist, $1);
                        }
                elsif ($l->{'value'} =~ /^(\S+)$/) {
+                       # IPv4 address or hostname only
                        push(@blist, $1); push(@plist, undef);
                        }
                }
@@ -305,7 +316,9 @@ for($i=0; defined($in{"Port_$i"}); $i++) {
        if ($bdef == 2) { next; }
 
        if ($bdef) { push(@blist, "*"); }
-       elsif ($b =~ /^\S+$/ && gethostbyname($b)) { push(@blist, $b); }
+       elsif ($b =~ /^\S+$/ &&
+              (gethostbyname($b) || &check_ipaddress($b) ||
+               &check_ip6address($b))) { push(@blist, $b); }
        else { &error(&text('core_eaddress', $b)); }
 
        if ($pdef) { push(@plist, undef); }
@@ -339,6 +352,9 @@ if ($_[0]->{'version'} < 2.0) {
 else {
        # Apache 2.0 just uses Listen directives
        for($i=0; $i<@blist; $i++) {
+               if (&check_ip6address($blist[$i])) {
+                       $blist[$i] = "[".$blist[$i]."]";
+                       }
                if ($blist[$i] ne "*" && $plist[$i]) {
                        push(@l, "$blist[$i]:$plist[$i]");
                        }
@@ -539,6 +555,7 @@ sub edit_NameVirtualHost
 local(@nv, $nv, $star);
 foreach $nv (@{$_[0]}) {
        if ($nv->{'value'} eq "*" && $_[1]->{'version'} >= 1.312) { $star++; }
+       elsif ($nv->{'value'} =~ /^\[(\S+)\]$/) { push(@nv, $1); }
        else { push(@nv, $nv->{'value'}); }
        }
 if ($_[1]->{'version'} >= 1.312) {
@@ -559,9 +576,16 @@ local(@nv, $nv, $addr);
 foreach $nv (@nv) {
        if ($nv =~ /^(\S+):(\d+|\*)$/) { $addr = $1; }
        else { $addr = $nv; }
-       if (!gethostbyname($addr) && $addr ne '*') {
+       if (!gethostbyname($addr) && !&check_ipaddress($addr) &&
+           !&check_ip6address($addr) && $addr ne '*') {
                &error(&text('core_evirtaddr', $addr));
                }
+       if ($nv =~ /^(\S+):(\d+|\*)$/ && &check_ip6address($1)) {
+               $nv = "[$1]:$2";
+               }
+       elsif (&check_ip6address($nv)) {
+               $nv = "[$nv]";
+               }
        }
 if (@nv) { return ( \@nv ); }
 else { return ( [ ] ); }
index 392503b..8c6191b 100755 (executable)
@@ -29,13 +29,13 @@ elsif ($in{'addr'} !~ /\S/) {
        &error($text{'cvirt_eaddr1'});
        }
 else {
-       @addrs = split(/\s+/, $in{'addr'});
-       foreach $a (@addrs) {
+       foreach $a (split(/\s+/, $in{'addr'})) {
                gethostbyname($a) || &check_ipaddress($a) ||
-                   &check_apache_ip6address($a) ||
+                   &check_ip6address($a) ||
                        &error(&text('cvirt_eaddr2', $a));
+               push(@addrs, &check_ip6address($a) ? "[$a]" : $a);
                }
-       $addr = $in{'addr'};
+       $addr = join(" ", @addrs);
        }
 
 # Parse and find the specified port
index 3369a73..6bb7f80 100755 (executable)
@@ -131,12 +131,20 @@ elsif ($config{'show_order'} == 2) {
        }
 foreach $v (@virt) {
        $vm = $v->{'members'};
-       if ($v->{'words'}->[0] =~ /^(\S+):(\S+)$/) {
+       if ($v->{'words'}->[0] =~ /^\[(\S+)\]:(\d+)$/) {
+               # IPv6 address and port
+               $addr = $1;
+               $port = $2;
+               }
+       elsif ($v->{'words'}->[0] =~ /^(\S+):(\d+)$/) {
+               # IPv4 address and port
                $addr = $1;
                $port = $2;
                }
        else {
+               # Address, perhaps v6, with default port
                $addr = $v->{'words'}->[0];
+               $addr = $1 if ($addr =~ /^\[(\S+)\]$/);
                if ($httpd_modules{'core'} < 2.0) {
                        $port = &def(&find_directive("Port", $conf), 80);
                        }
@@ -393,7 +401,7 @@ if ($access{'create'}) {
                  [ [ 1, "$text{'index_any1'}<br>" ],
                    [ 2, "$text{'index_any2'}<br>" ],
                    [ 0, $text{'index_any0'}." ".
-                        &ui_textbox("addr", undef, 20) ] ])."<br>\n".
+                        &ui_textbox("addr", undef, 40) ] ])."<br>\n".
                &ui_checkbox("nv", 1, $text{'index_nv'}, 1)."<br>".
                &ui_checkbox("listen", 1, $text{'index_listen'}, 1));
 
@@ -453,7 +461,7 @@ local $addr = $_[0]->{'words'}->[0] =~ /^(\S+):(\S+)/ ? $1 :
                $_[0]->{'words'}->[0];
 return $addr eq '_default_' || $addr eq '*' ? undef :
        &check_ipaddress($addr) ? $addr :
-       &check_apache_ip6address($addr) ? $addr :
+       $addr =~ /^\[(\S+)\]$/ && &check_ip6address($1) ? $1 :
                                 &to_ipaddress($addr);
 }
 
index ea603e3..6f7c93f 100755 (executable)
@@ -40,6 +40,7 @@ else {
 
        # Check address
        if (defined($in{'addrs'})) {
+               # Multiple addresses
                local @addrs = split(/\s+/, $in{'addrs'});
                @addrs || &error($text{'vserv_eaddrs'});
                foreach $a (@addrs) {
@@ -52,6 +53,7 @@ else {
                $addr = join(" ", @addrs);
                }
        else {
+               # One address
                if ($in{'addr_def'} == 1) {
                        if ($httpd_modules{'core'} >= 1.2)
                                { $addr = "_default_"; }
@@ -63,10 +65,17 @@ else {
                elsif ($in{'addr'} !~ /\S/) {
                        &error($text{'vserv_eaddr1'});
                        }
-               elsif (!gethostbyname($in{'addr'})) {
+               elsif (!gethostbyname($in{'addr'}) &&
+                      !&check_ipaddress($in{'addr'}) &&
+                      !&check_ip6address($in{'addr'})) {
                        &error(&text('vserv_eaddr2', $in{'addr'}));
                        }
+               elsif (&check_ip6address($in{'addr'})) {
+                       # IPv6 address
+                       $addr = "[$in{'addr'}]";
+                       }
                else {
+                       # IPv4 address or hostname
                        $addr = $in{'addr'};
                        }
                }
index 7ea87f2..9cb82f9 100755 (executable)
@@ -96,10 +96,22 @@ if ($in{'virt'} && $access{'vaddr'}) {
        if ($val =~ /\s/) {
                $addrs = $val;
                }
-       if ($val =~ /^(\S+):(\S+)$/) {
+       if ($val =~ /^\[(\S+)\]:(\d+)$/) {
+               # IPv6 address and port
                $addr = $1; $port = $2;
                }
-       else { $addr = $val; }
+       elsif ($val =~ /^\[(\S+)\]$/) {
+               # IPv6 address
+               $addr = $1;
+               }
+       elsif ($val =~ /^(\S+):(\d+)$/) {
+               # IPv4 address or hostname and port
+               $addr = $1; $port = $2;
+               }
+       else {
+               # IPv4 address or hostname
+               $addr = $val;
+               }
 
        if ($addrs) {
                # Multiple addresses and ports
@@ -116,7 +128,7 @@ if ($in{'virt'} && $access{'vaddr'}) {
                            [ 2, $text{'vserv_any'} ],
                            [ 0, &ui_textbox("addr",
                                        $addr eq "*" || $addr eq "_default_" ?
-                                               "" : $addr, 20) ] ]));
+                                               "" : $addr, 40) ] ]));
 
                print &ui_table_row($text{'vserv_port'},
                     &choice_input($port eq "*" ? 1 : $port > 0 ? 2 : 0,