]> git.ipfire.org Git - people/amarx/ipfire-2.x.git/commitdiff
CCD Extension 0.1
authorAlexander Marx <amarx@ipfire.org>
Mon, 5 Nov 2012 11:50:09 +0000 (12:50 +0100)
committerAlexander Marx <amarx@ipfire.org>
Mon, 5 Nov 2012 11:50:09 +0000 (12:50 +0100)
Implementierung der CCD Extension für OpenVPN Server. Es können mehrere statische NEtze angelegt werden, aus denen
Clients fixe IP-Adressen zugewiesen werden. Weiterhin können je Client Routen gesetzt werden. Diese Routen können
Netze hinter dem Client (iroute) oder hinter dem IPFIRE (push route) sein.
Ausserdem ist es möglich, je CLient Nameserver und WINS Server zu konfigurieren, die
dann in den entspr. CCD Dateien hinterlegt werden.

html/cgi-bin/ovpnmain.cgi [changed mode: 0644->0755]

old mode 100644 (file)
new mode 100755 (executable)
index 990fe66..1b1069b
@@ -77,8 +77,12 @@ $cgiparams{'DHCP_WINS'} = '';
 $cgiparams{'ROUTES_PUSH'} = '';
 $cgiparams{'DCOMPLZO'} = 'off';
 $cgiparams{'MSSFIX'} = '';
+$cgiparams{'number'} = '';
 $routes_push_file = "${General::swroot}/ovpn/routes_push";
 unless (-e $routes_push_file)    { system("touch $routes_push_file"); }
+unless (-e "${General::swroot}/ovpn/ccd.conf")    { system("touch ${General::swroot}/ovpn/ccd.conf"); }
+unless (-e "${General::swroot}/ovpn/ccdroute")    { system("touch ${General::swroot}/ovpn/ccdroute"); }
+unless (-e "${General::swroot}/ovpn/ccdroute2")    { system("touch ${General::swroot}/ovpn/ccdroute2"); }
 
 &Header::getcgihash(\%cgiparams, {'wantfile' => 1, 'filevar' => 'FH'});
 
@@ -345,15 +349,35 @@ sub writeserverconf {
     print CONF "push \"route $netsettings{'GREEN_NETADDRESS'} $netsettings{'GREEN_NETMASK'}\"\n";
     
     if ($vpnsettings{'ROUTES_PUSH'} ne '') {
-       @temp = split(/\n/,$vpnsettings{'ROUTES_PUSH'});
-       foreach (@temp)
-       {
-               @tempovpnsubnet = split("\/",&General::ipcidr2msk($_));
-               print CONF "push \"route " . $tempovpnsubnet[0]. " " .  $tempovpnsubnet[1] . "\"\n";
+               @temp = split(/\n/,$vpnsettings{'ROUTES_PUSH'});
+               foreach (@temp)
+               {
+                       @tempovpnsubnet = split("\/",&General::ipcidr2msk($_));
+                       print CONF "push \"route " . $tempovpnsubnet[0]. " " .  $tempovpnsubnet[1] . "\"\n";
+               }
        }
-    }
-
-    if ($sovpnsettings{CLIENT2CLIENT} eq 'on') {
+###########
+#A.Marx CCD---add route into server.conf
+###########    
+       my %ccdconfhash=();
+       &General::readhasharray("${General::swroot}/ovpn/ccd.conf", \%ccdconfhash);
+       foreach my $key (keys %ccdconfhash) {
+               my $a=$ccdconfhash{$key}[1];
+               my ($b,$c) = split (/\//, $a);
+               print CONF "route $b ".&General::cidrtosub($c)."\n";
+       }
+       my %ccdroutehash=();
+       &General::readhasharray("${General::swroot}/ovpn/ccdroute", \%ccdroutehash);
+       foreach my $key (keys %ccdroutehash) {
+               foreach my $i ( 1 .. $#{$ccdroutehash{$key}}){
+                       my ($a,$b)=split (/\//,$ccdroutehash{$key}[$i]);
+                       print CONF "route $a $b\n";
+               }
+       }
+###########
+#CCD END
+###########
+       if ($sovpnsettings{CLIENT2CLIENT} eq 'on') {
        print CONF "client-to-client\n";
     }
     if ($sovpnsettings{MSSFIX} eq 'on') {
@@ -417,6 +441,266 @@ sub emptyserverlog{
 
 }
 
+#####################
+#A.Marx CCD functions
+#####################
+sub delccdnet 
+{
+       my %ccdconfhash = ();
+       my %ccdhash = ();
+       my $ccdnetname=$_[0];
+       if (-f "${General::swroot}/ovpn/ovpnconfig"){
+               &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%ccdhash);
+               foreach my $key (keys %ccdhash) {
+                       if ($ccdhash{$key}[32] eq $ccdnetname) {
+                               $errormessage=$Lang::tr{'ccd err hostinnet'};
+                               return;
+                       }
+               }
+       }
+       if (!open(CCDCONF,'<',"${General::swroot}/ovpn/ccd.conf")){
+               $errormessage="Unable to open /var/ipfire/ovpn/ccd.conf! for READING";
+       }else{
+               
+                       &General::readhasharray("${General::swroot}/ovpn/ccd.conf", \%ccdconfhash);
+                       foreach my $key (keys %ccdconfhash) {
+                                       if ($ccdconfhash{$key}[0] eq $ccdnetname){
+                                               delete $ccdconfhash{$key};
+                                       }
+                       }
+                       &General::writehasharray("${General::swroot}/ovpn/ccd.conf", \%ccdconfhash);
+       }
+       &writeserverconf;
+       return 0;
+}
+
+sub addccdnet
+{
+       my %ccdconfhash=();
+       my @ccdconf=();
+       my $ccdname=$_[0];
+       my $ccdnet=$_[1];
+       my $ovpnsubnet=$_[2];
+       my $subcidr;
+       my @ip2=();
+       my $checkup;
+       my $ccdip;
+       if (&General::validip2($ccdnet)){
+                       $ccdnet=&General::iporsubtocidr($ccdnet);       
+       }else{
+               $errormessage="Address invalid!";
+               return;
+       }
+       ($ccdip,$subcidr) = split (/\//,$ccdnet);
+       if ($ccdname eq '') {
+                       $errormessage=$errormessage.$Lang::tr{'ccd err name'}."<br>";
+       }
+       if (&General::iporsubtocidr($ccdnet) eq &General::iporsubtocidr($ovpnsubnet)) {
+                       $errormessage=$errormessage.$Lang::tr{'ccd err isovpnnet'}."<br>";
+       }
+       my $baseaddress=&General::getnetworkip($ccdip,$subcidr);
+       &General::readhasharray("${General::swroot}/ovpn/ccd.conf", \%ccdconfhash);
+       foreach my $key (keys %ccdconfhash) {
+                       @ccdconf=split(/\//,$ccdconfhash{$key}[1]);
+                       if ($ccdname eq $ccdconfhash{$key}[0]) {$errormessage=$errormessage.$Lang::tr{'ccd err nameexist'}."<br>";}
+                       if ($ccdnet eq $ccdconfhash{$key}[1]) {$errormessage=$errormessage.$Lang::tr{'ccd err netadrexist'}."<br>";}
+       }
+       if (!$errormessage) {
+               my %ccdconfhash=();
+               &General::readhasharray("${General::swroot}/ovpn/ccd.conf", \%ccdconfhash);
+               my $key = &General::findhasharraykey (\%ccdconfhash);
+               foreach my $i (0 .. 1) { $ccdconfhash{$key}[$i] = "";}
+               $ccdconfhash{$key}[0] = $ccdname;
+               $ccdconfhash{$key}[1] = $baseaddress."/".$subcidr;
+               &General::writehasharray("${General::swroot}/ovpn/ccd.conf", \%ccdconfhash);
+               &writeserverconf;
+               return 0;
+       }
+}
+
+sub modccdnet
+{
+       
+       my $newname=$_[0];
+       my $oldname=$_[1];
+       my %ccdconfhash=();
+       my %ccdhash=();
+       &General::readhasharray("${General::swroot}/ovpn/ccd.conf", \%ccdconfhash);
+       foreach my $key (keys %ccdconfhash) {
+               if ($ccdconfhash{$key}[0] eq $oldname) {
+                       foreach my $key1 (keys %ccdconfhash) {
+                               if ($ccdconfhash{$key1}[0] eq $newname){
+                                       $errormessage=$errormessage.$Lang::tr{'ccd err netadrexist'};
+                                       return;
+                               }else{
+                                       $ccdconfhash{$key}[0]= $newname;
+                                       &General::writehasharray("${General::swroot}/ovpn/ccd.conf", \%ccdconfhash);
+                                       last;
+                               }
+                       }
+               }
+       }
+       
+       &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%ccdhash);
+               foreach my $key (keys %ccdhash) {
+                       if ($ccdhash{$key}[32] eq $oldname) {
+                               $ccdhash{$key}[32]=$newname;
+                               last;
+                       }
+               }
+       &General::writehasharray("${General::swroot}/ovpn/ovpnconfig", \%ccdhash);
+       return 0;
+}
+sub ccdmaxclients
+{
+       my $ccdnetwork=$_[0];
+       my @octets=();
+       my @subnet=();
+       @octets=split("\/",$ccdnetwork);
+       @subnet= split /\./, &General::cidrtosub($octets[1]);
+       my ($a,$b,$c,$d,$e);
+       $a=256-$subnet[0];
+       $b=256-$subnet[1];
+       $c=256-$subnet[2];
+       $d=256-$subnet[3];
+       $e=($a*$b*$c*$d)/4;
+       return $e;
+}
+
+sub getccdadresses 
+{
+       my $ipin=$_[0];
+       my ($ip1,$ip2,$ip3,$ip4)=split  /\./, $ipin;
+       my $cidr=$_[1];
+       chomp($cidr);
+       my $count=$_[2];
+       my $hasip=$_[3];
+       chomp($hasip);
+       my @iprange=();
+       my %ccdhash=();
+       &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%ccdhash);
+       $iprange[0]=$ip1.".".$ip2.".".$ip3.".".2;
+       for (my $i=0;$i<=$count-1;$i++) {
+               my $tmpip=$iprange[$i-1];
+               my $stepper=$i*4;
+               $iprange[$i]= &General::getnextip($tmpip,4);
+       }
+       my $r=0;
+       foreach my $key (keys %ccdhash) {
+               $r=0;
+               foreach  my $tmp (@iprange){
+                       my ($net,$sub) = split (/\//,$ccdhash{$key}[33]);
+                       if ($net eq $tmp) {
+                               if ( $hasip ne  $ccdhash{$key}[33] ){
+                                       splice (@iprange,$r,1);
+                               }
+                       }
+                       $r++;
+               }
+               #goto VPNCONF_ERROR;
+       }
+       return @iprange;
+}
+
+sub fillselectbox
+{
+       my $boxname=$_[1];
+       my ($ccdip,$subcidr) = split("/",$_[0]); 
+       my $tz=$_[2];
+       my @allccdips=&getccdadresses($ccdip,$subcidr,&ccdmaxclients($ccdip."/".$subcidr),$tz);
+       print"<select name='$boxname' STYLE='font-family : arial; font-size : 9pt; width:120px;' >";
+       foreach (@allccdips) {
+               my $ip=$_."/30";
+               chomp($ip);
+               print "<option value='$ip' ";
+               if ( $ip eq $cgiparams{$boxname} ){
+                       print"selected";
+               }
+               print ">$ip</option>";
+       }
+       print "</select>";
+}
+
+sub hostsinnet
+{
+       my $name=$_[0];
+       my %ccdhash=();
+       my $i=0;
+       &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%ccdhash);
+       foreach my $key (keys %ccdhash) {
+               if ($ccdhash{$key}[32] eq $name){ $i++;}
+       }
+       return $i;
+}
+
+sub check_routes_push
+{
+                       my $val=$_[0];
+                       my ($ip,$cidr) = split (/\//, $val);
+                       ##check for existing routes in routes_push
+                       if (-e "${General::swroot}/ovpn/routes_push") {
+                               open(FILE,"${General::swroot}/ovpn/routes_push");
+                               while (<FILE>) {
+                                       $_=~s/\s*$//g;
+                                       my $val2=&General::iporsubtodec($_);
+                                       my ($ip2,$cidr2) = split (/\//,$val2);
+                                       if($val eq $val2){
+                                               return 0;
+                                       }
+                                       #subnetcheck
+                                       if (&General::IpInSubnet ($ip,$ip2,$cidr2)){
+                                               return 0;
+                                       }
+                               };
+                               close(FILE);
+                       }
+       return 1;
+}
+
+sub check_ccdroute
+{
+       my %ccdroutehash=();
+       my $val=$_[0];
+       my ($ip,$cidr) = split (/\//, $val);
+       #check for existing routes in ccdroute
+       &General::readhasharray("${General::swroot}/ovpn/ccdroute", \%ccdroutehash);
+       foreach my $key (keys %ccdroutehash) {
+               foreach my $i (1 .. $#{$ccdroutehash{$key}}) {
+                       if (&General::iporsubtodec($val) eq $ccdroutehash{$key}[$i] && $ccdroutehash{$key}[0] ne $cgiparams{'NAME'}){
+                               return 0;
+                       }
+                       my ($ip2,$cidr2) = split (/\//,$ccdroutehash{$key}[$i]);
+                       #subnetcheck
+                       if (&General::IpInSubnet ($ip,$ip2,$cidr2)&& $ccdroutehash{$key}[0] ne $cgiparams{'NAME'} ){
+                               return 0;
+                       }
+               }
+       }
+       return 1;
+}
+sub check_ccdconf
+{
+       my %ccdconfhash=();
+       my $val=$_[0];
+       my ($ip,$cidr) = split (/\//, $val);
+       #check for existing routes in ccdroute
+       &General::readhasharray("${General::swroot}/ovpn/ccd.conf", \%ccdconfhash);
+       foreach my $key (keys %ccdconfhash) {
+               if (&General::iporsubtocidr($val) eq $ccdconfhash{$key}[1]){
+                               return 0;
+                       }
+                       my ($ip2,$cidr2) = split (/\//,$ccdconfhash{$key}[1]);
+                       #subnetcheck
+                       if (&General::IpInSubnet ($ip,$ip2,&General::cidrtosub($cidr2))){
+                               return 0;
+                       }
+               
+       }
+       return 1;
+}
+#A.Marx CCD functions end
+#########################
+
 ###
 # m.a.d net2net
 ###
@@ -451,6 +735,7 @@ sub read_routepushfile
                while (<FILE>) { $vpnsettings{'ROUTES_PUSH'} .= $_ };
                close(FILE);
                $cgiparams{'ROUTES_PUSH'} = $vpnsettings{'ROUTES_PUSH'};
+               
        }
 }
 
@@ -490,11 +775,11 @@ if ($cgiparams{'ACTION'} eq $Lang::tr{'start ovpn server'} ||
        &emptyserverlog();      
     }   
 #    #restart openvpn server
-    if ($cgiparams{'ACTION'} eq $Lang::tr{'restart ovpn server'}){
+#    if ($cgiparams{'ACTION'} eq $Lang::tr{'restart ovpn server'}){
 #workarund, till SIGHUP also works when running as nobody    
-       system('/usr/local/bin/openvpnctrl', '-r');     
-       &emptyserverlog();      
-    }       
+#      system('/usr/local/bin/openvpnctrl', '-r');     
+#      &emptyserverlog();      
+#    }       
 }
 
 ###
@@ -554,24 +839,51 @@ if ($cgiparams{'ACTION'} eq $Lang::tr{'save-adv-options'}) {
     if ($cgiparams{'ROUTES_PUSH'} ne ''){
        @temp = split(/\n/,$cgiparams{'ROUTES_PUSH'});
        undef $vpnsettings{'ROUTES_PUSH'};
-       foreach (@temp)
+       
+       foreach my $tmpip (@temp)
        {
                s/^\s+//g; s/\s+$//g;
-               if ($_)
+               
+               if ($tmpip)
                {
-                       unless (&General::validipandmask($_)) {
-                               $errormessage = $Lang::tr{'ovpn errmsg invalid ip or mask'};
-                       goto ADV_ERROR;
+                       $tmpip=~s/\s*$//g; 
+                       unless (&General::validipandmask($tmpip)) {
+                               $errormessage = "$tmpip ".$Lang::tr{'ovpn errmsg invalid ip or mask'};
+                               goto ADV_ERROR;
                        }
-                       my ($ip, $cidr) = split("\/",&General::ipcidr2msk($_));
+                       my ($ip, $cidr) = split("\/",&General::ipcidr2msk($tmpip));
+                       
                        if ($ip eq $netsettings{'GREEN_NETADDRESS'} && $cidr eq $netsettings{'GREEN_NETMASK'}) {
                                $errormessage = $Lang::tr{'ovpn errmsg green already pushed'};
-  goto ADV_ERROR;
+                               goto ADV_ERROR;
+                       }
+#########
+#A.Marx CCD
+#########                              
+                       my %ccdroutehash=();
+                       &General::readhasharray("${General::swroot}/ovpn/ccdroute", \%ccdroutehash);
+                       foreach my $key (keys %ccdroutehash) {
+                               foreach my $i (1 .. $#{$ccdroutehash{$key}}) { 
+                                       if ( $ip."/".$cidr eq $ccdroutehash{$key}[$i] ){
+                                               $errormessage="Route $ip\/$cidr ".$Lang::tr{'ccd err inuse'}." $ccdroutehash{$key}[0]" ;
+                                               goto ADV_ERROR;
+                                       }
+                                       my ($ip2,$cidr2) = split(/\//,$ccdroutehash{$key}[$i]);
+                                       if (&General::IpInSubnet ($ip,$ip2,$cidr2)){
+                                               $errormessage="Route $ip\/$cidr ".$Lang::tr{'ccd err inuse'}." $ccdroutehash{$key}[0]" ;
+                                               goto ADV_ERROR;
+                                       }
+                               }
                        }
-                       $vpnsettings{'ROUTES_PUSH'} .= $_."\n";
+                       
+##########
+#CCD End
+##########     
+                       
+                       $vpnsettings{'ROUTES_PUSH'} .= $tmpip."\n";
                }
-       }
-       &write_routepushfile;
+       }
+    &write_routepushfile;
        undef $vpnsettings{'ROUTES_PUSH'};
     }
        else {
@@ -1571,29 +1883,26 @@ END
     my $n2nactive = `/bin/ps ax|grep $confighash{$cgiparams{'KEY'}}[1]|grep -v grep|awk \'{print \$1}\'`;
     
     if ($confighash{$cgiparams{'KEY'}}) {
+               if ($confighash{$cgiparams{'KEY'}}[0] eq 'off') {
+                       $confighash{$cgiparams{'KEY'}}[0] = 'on';
+                       &General::writehasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
 
-
-       if ($confighash{$cgiparams{'KEY'}}[0] eq 'off') {
-           $confighash{$cgiparams{'KEY'}}[0] = 'on';
-           &General::writehasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
-
-     if ($confighash{$cgiparams{'KEY'}}[3] eq 'net'){
+                       if ($confighash{$cgiparams{'KEY'}}[3] eq 'net'){
                  system('/usr/local/bin/openvpnctrl', '-sn2n', $confighash{$cgiparams{'KEY'}}[1]);
-          }
-  } else {
+                       }
+               } else {
 
-           $confighash{$cgiparams{'KEY'}}[0] = 'off';
-      &General::writehasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
+                       $confighash{$cgiparams{'KEY'}}[0] = 'off';
+                       &General::writehasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
 
-          if ($confighash{$cgiparams{'KEY'}}[3] eq 'net'){
+                       if ($confighash{$cgiparams{'KEY'}}[3] eq 'net'){
                     if ($n2nactive ne ''){                             
-                    system('/usr/local/bin/openvpnctrl', '-kn2n', $confighash{$cgiparams{'KEY'}}[1]);
-           }
+                                               system('/usr/local/bin/openvpnctrl', '-kn2n', $confighash{$cgiparams{'KEY'}}[1]);
+                                       }
  
-          } else {
+                       } else {
                  $errormessage = $Lang::tr{'invalid key'};
-          }
+                       }
       }
   }
 
@@ -1718,9 +2027,10 @@ else
     
     my $zip = Archive::Zip->new();
     
-    print CLIENTCONF "#OpenVPN Server conf\r\n";
+    print CLIENTCONF "#OpenVPN Client conf\r\n";
     print CLIENTCONF "tls-client\r\n";
     print CLIENTCONF "client\r\n";
+    print CLIENTCONF "nobind\n";
     print CLIENTCONF "dev $vpnsettings{'DDEVICE'}\r\n";
     print CLIENTCONF "proto $vpnsettings{'DPROTOCOL'}\r\n";
     print CLIENTCONF "$vpnsettings{'DDEVICE'}-mtu $vpnsettings{'DMTU'}\r\n";
@@ -1814,10 +2124,41 @@ else
 }
 
   unlink ("${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1]cert.pem");
-       unlink ("${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1].p12");
+  unlink ("${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1].p12");
+############
+#A.Marx CCD#  delete ccd files and routes
+############   
+       
+       if (-f "${General::swroot}/ovpn/ccd/$confighash{$cgiparams{'KEY'}}[2]")
+       {
+               unlink "${General::swroot}/ovpn/ccd/$confighash{$cgiparams{'KEY'}}[2]";
+       }
+       my %ccdroutehash=();
+       &General::readhasharray("${General::swroot}/ovpn/ccdroute", \%ccdroutehash);
+       foreach my $key (keys %ccdroutehash) {
+               if ($ccdroutehash{$key}[0] eq $confighash{$cgiparams{'KEY'}}[1]){
+                       delete $ccdroutehash{$key};
+               }
+       }
+       &General::writehasharray("${General::swroot}/ovpn/ccdroute", \%ccdroutehash);
+       my %ccdroute2hash=();
+       &General::readhasharray("${General::swroot}/ovpn/ccdroute2", \%ccdroute2hash);
+       foreach my $key (keys %ccdroute2hash) {
+               if ($ccdroute2hash{$key}[0] eq $confighash{$cgiparams{'KEY'}}[1]){
+                       delete $ccdroute2hash{$key};
+               }
+       }
+       &General::writehasharray("${General::swroot}/ovpn/ccdroute2", \%ccdroute2hash);
+       
+       
+       
+#CCD END
+###########
+       
        delete $confighash{$cgiparams{'KEY'}};
        my $temp2 = `/usr/bin/openssl ca -gencrl -out ${General::swroot}/ovpn/crls/cacrl.pem -config ${General::swroot}/ovpn/openssl/ovpn.cnf`;
        &General::writehasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
+
        #&writeserverconf();
     } else {
        $errormessage = $Lang::tr{'invalid key'};
@@ -1941,7 +2282,7 @@ ADV_ERROR:
     &Header::openbox('100%', 'LEFT', $Lang::tr{'advanced server'});
     print <<END
     <form method='post' enctype='multipart/form-data'>
-    <table width='100%'>
+    <table width='100%' border=0>
     <tr>
        <td colspan='4'><b>$Lang::tr{'dhcp-options'}</b></td>
     </tr>
@@ -2077,6 +2418,119 @@ END
     &Header::closepage();
     exit(0);
        
+###########
+#A.Marx CCD   Add,delete CCD net
+###########
+} elsif ($cgiparams{'ACTION'} eq $Lang::tr{'ccd net'} || 
+               $cgiparams{'ACTION'} eq $Lang::tr{'ccd add'} ||  
+               $cgiparams{'ACTION'} eq "kill" || 
+               $cgiparams{'ACTION'} eq "edit" ||
+               $cgiparams{'ACTION'} eq $Lang::tr{'ccd modify'}){
+       &Header::showhttpheaders();
+       &Header::openpage($Lang::tr{'ccd net'}, 1, '');
+       &Header::openbigbox('100%', 'LEFT', '', '');
+
+       if ($cgiparams{'ACTION'} eq "kill"){
+               &delccdnet($cgiparams{'net'});
+       }
+       
+       if ($cgiparams{'ACTION'} eq $Lang::tr{'ccd modify'}){
+               my ($a,$b) =split (/\|/,$cgiparams{'ccdname'});
+               if ( $a ne $b){ &modccdnet($a,$b);}
+       }
+       
+       if ($cgiparams{'ACTION'} eq $Lang::tr{'ccd add'}) {
+               &addccdnet($cgiparams{'ccdname'},$cgiparams{'ccdsubnet'},$cgiparams{'DOVPN_SUBNET'});
+       }
+       if ($errormessage) {
+           &Header::openbox('100%', 'LEFT', $Lang::tr{'error messages'});
+           print "<class name='base'>$errormessage";
+           print "&nbsp;</class>";
+           &Header::closebox();                
+       }
+if ($cgiparams{'ACTION'} eq "edit"){
+       &Header::openbox('100%', 'LEFT', $Lang::tr{'ccd modify'});
+       print <<END
+    <table width='100%' border=0>
+    <tr><form method='post'>
+       <td width='10%'>$Lang::tr{'ccd name'}:</td><td><input type='TEXT' name='ccdname' value='$cgiparams{'ccdname'}' /></td>
+       <td width='8%'>$Lang::tr{'ccd subnet'}:</td><td><input type='TEXT' name='ccdsubnet' value='$cgiparams{'ccdsubnet'}' readonly /></td></tr>
+       
+       <tr><td colspan='4' align='right'><hr><input type='submit' name='ACTION' value='$Lang::tr{'ccd modify'}' />
+       <input type='hidden' name='ccdname' value='$cgiparams{'ccdname'}'/>
+       </td></tr>
+       </table></form>
+END
+;
+       &Header::closebox();
+       &Header::openbox('100%', 'LEFT', );
+       print <<END
+    <table width='100%' border='0'  cellpadding='0' cellspacing='1'>
+    <tr>
+       <td class='boldbase' align='center'><b>$Lang::tr{'ccd name'}</td><td></td><td class='boldbase' align='center'><b>$Lang::tr{'ccd net'}</td><td class='boldbase' width='15%' align='center'><b>$Lang::tr{'ccd maxclients'}</td><td class='boldbase' width='15%' align='center'><b>$Lang::tr{'ccd used'}</td><td width='3%'></td><td width='3%'></td></tr>
+END
+;
+}
+else{
+       $cgiparams{'ccdname'}='';
+       $cgiparams{'ccdsubnet'}='';
+       &Header::openbox('100%', 'LEFT', $Lang::tr{'ccd add'});
+       print <<END
+    <table width='100%' border='0'>
+    <tr><form method='post'>
+       <td colspan='4'>$Lang::tr{'ccd hint'}<br><br></td></tr>
+       <tr>
+       <td width='10%'>$Lang::tr{'ccd name'}:</td><td><input type='TEXT' name='ccdname' value='$cgiparams{'ccdname'}' /></td>
+       <td width='8%'>$Lang::tr{'ccd subnet'}:</td><td><input type='TEXT' name='ccdsubnet' value='$cgiparams{'ccdsubnet'}' /></td></tr>
+       <tr><td colspan=4><hr /></td></tr><tr>
+       <td colspan='4' align='right'><input type='hidden' name='ACTION' value='$Lang::tr{'ccd add'}' /><input type='submit' value='$Lang::tr{'add'}' /><input type='hidden' name='DOVPN_SUBNET' value='$cgiparams{'DOVPN_SUBNET'}'/></td></tr>
+       </table></form>
+END
+;
+       &Header::closebox();
+       &Header::openbox('100%', 'LEFT', );
+       print <<END
+    <table width='100%' border='0'  cellpadding='0' cellspacing='1'>
+    <tr>
+       <td class='boldbase' align='center'><b>$Lang::tr{'ccd name'}</td><td></td><td class='boldbase' align='center'><b>$Lang::tr{'ccd net'}</td><td class='boldbase' width='15%' align='center'><b>$Lang::tr{'ccd maxclients'}</td><td class='boldbase' width='15%' align='center'><b>$Lang::tr{'ccd used'}</td><td width='3%'></td><td width='3%'></td></tr>
+END
+;
+}
+       my %ccdconfhash=();     
+       &General::readhasharray("${General::swroot}/ovpn/ccd.conf", \%ccdconfhash);     
+       my @ccdconf=();
+       my $count=0;
+       foreach my $key (keys %ccdconfhash) {
+               @ccdconf=($ccdconfhash{$key}[0],$ccdconfhash{$key}[1]);
+               $count++;
+               my $ccdhosts = &hostsinnet($ccdconf[0]);
+               if ($count % 2){ print" <tr bgcolor='$color{'color22'}'>";}
+               else{            print" <tr bgcolor='$color{'color20'}'>";}
+               print"<td>$ccdconf[0]</td><td></td><td>$ccdconf[1]</td><td align='center'>".&ccdmaxclients($ccdconf[1])."</td><td align='center'>$ccdhosts</td><td>";
+print <<END
+               <form method='post' />
+               <input type='image' src='/images/edit.gif' align='middle' alt=$Lang::tr{'edit'} title=$Lang::tr{'edit'} />
+               <input type='hidden' name='ACTION' value='edit'/>
+               <input type='hidden' name='ccdname' value='$ccdconf[0]' />
+               <input type='hidden' name='ccdsubnet' value='$ccdconf[1]' />
+               </form></td>
+               <form method='post' />
+               <td><input type='hidden' name='ACTION' value='kill'/>
+               <input type='hidden' name='number' value='$count' />
+               <input type='hidden' name='net' value='$ccdconf[0]' />
+               <input type='image' src='/images/delete.gif' align='middle' alt=$Lang::tr{'remove'} title=$Lang::tr{'remove'} /></form></td></tr>
+END
+;
+       }       
+       print "</table></form>";
+       &Header::closebox();
+       print "<div align='center'><a href='/cgi-bin/ovpnmain.cgi'>$Lang::tr{'back'}</a></div>";
+       &Header::closebigbox();
+       &Header::closepage();
+       exit(0);
+       
+#END CCD----------------------------------------------------------------
+
 ###
 ### Openvpn Connections Statistics
 ###
@@ -2284,7 +2738,7 @@ if ( -s "${General::swroot}/ovpn/settings") {
 
        print <<END
            <b>$Lang::tr{'connection type'}:</b><br />
-           <table><form method='post' ENCTYPE="multipart/form-data">
+           <table border='0' width='100%'><form method='post' ENCTYPE="multipart/form-data">
            <tr><td><input type='radio' name='TYPE' value='host' checked /></td>
                <td class='base'>$Lang::tr{'host to net vpn'}</td></tr>
            <tr><td><input type='radio' name='TYPE' value='net' /></td>
@@ -2293,21 +2747,21 @@ if ( -s "${General::swroot}/ovpn/settings") {
                <td class='base'>$Lang::tr{'net to net vpn'} (Upload Client Package)</td></tr>
          <tr><td>&nbsp;</td><td class='base'><input type='file' name='FH' size='30'></td></tr>
          <tr><td>&nbsp;</td><td>Import Connection Name <img src='/blob.gif' /></td></tr>
-    <tr><td>&nbsp;</td><td class='base'><input type='text' name='n2nname' size='30'><td class='base'>Default : Client Packagename</td></td></tr>
+    <tr><td>&nbsp;</td><td class='base'><input type='text' name='n2nname' size='30'>Default : Client Packagename</td></tr>
          <tr><td colspan='3'><hr /></td></tr>
-    <tr><td align='center'><input type='submit' name='ACTION' value='$Lang::tr{'add'}' /></td></tr>
-         <tr><td>&nbsp;</td></tr>
+    <tr><td align='right' colspan='3'><input type='submit' name='ACTION' value='$Lang::tr{'add'}' /></td></tr>
          <tr><td class='base' colspan='3' align='left'><img src='/blob.gif' alt='*' />&nbsp;$Lang::tr{'this field may be blank'}</td></tr>
            </form></table>
 END
        ;
+       
 
 } else {
        print <<END
                    <b>$Lang::tr{'connection type'}:</b><br />
-           <table><form method='post' ENCTYPE="multipart/form-data">
+           <table border='0' width='100%'><form method='post' ENCTYPE="multipart/form-data">
            <tr><td><input type='radio' name='TYPE' value='host' checked /></td> <td class='base'>$Lang::tr{'host to net vpn'}</td></tr>
-           <tr><td align='center'><input type='submit' name='ACTION' value='$Lang::tr{'add'}' /></td></tr>
+           <tr><td align='right' colspan'3'><input type='submit' name='ACTION' value='$Lang::tr{'add'}' /></td></tr>
            </form></table>
 END
        ;
@@ -2540,23 +2994,23 @@ foreach my $dkey (keys %confighash) {
        foreach my $i (0 .. 31) { $confighash{$key}[$i] = "";}
        $confighash{$key}[0] = 'off';
        $confighash{$key}[1] = $n2nname[0];
-  $confighash{$key}[2] = $n2nname[0];  
+    $confighash{$key}[2] = $n2nname[0];        
        $confighash{$key}[3] = 'net';
        $confighash{$key}[4] = 'cert';  
        $confighash{$key}[6] = 'client';                
        $confighash{$key}[8] =  $n2nlocalsub[2];
-  $confighash{$key}[10] = $n2nremote[1];
-  $confighash{$key}[11] = "$n2nremsub[1]/$n2nremsub[2]";               
+    $confighash{$key}[10] = $n2nremote[1];
+    $confighash{$key}[11] = "$n2nremsub[1]/$n2nremsub[2]";             
        $confighash{$key}[22] = $n2nmgmt[2];
-  $confighash{$key}[23] = $mssfixactive;
+    $confighash{$key}[23] = $mssfixactive;
        $confighash{$key}[24] = $n2nfragment[1];
-  $confighash{$key}[25] = 'IPFire n2n Client';
+    $confighash{$key}[25] = 'IPFire n2n Client';
        $confighash{$key}[26] = 'red';
-  $confighash{$key}[27] = "$n2novpnsub[0].$n2novpnsub[1].$n2novpnsub[2].0/255.255.255.0";
-  $confighash{$key}[28] = $n2nproto[0];
-  $confighash{$key}[29] = $n2nport[1];
-  $confighash{$key}[30] = $complzoactive;
-  $confighash{$key}[31] = $n2ntunmtu[1];
+    $confighash{$key}[27] = "$n2novpnsub[0].$n2novpnsub[1].$n2novpnsub[2].0/255.255.255.0";
+    $confighash{$key}[28] = $n2nproto[0];
+    $confighash{$key}[29] = $n2nport[1];
+    $confighash{$key}[30] = $complzoactive;
+    $confighash{$key}[31] = $n2ntunmtu[1];
 
 
   &General::writehasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
@@ -2655,7 +3109,7 @@ if ($confighash{$cgiparams{'KEY'}}) {
 } elsif (($cgiparams{'ACTION'} eq $Lang::tr{'add'}) ||
         ($cgiparams{'ACTION'} eq $Lang::tr{'edit'}) ||
         ($cgiparams{'ACTION'} eq $Lang::tr{'save'} && $cgiparams{'ADVANCED'} eq '')) {
-
+           
     &General::readhash("${General::swroot}/ovpn/settings", \%vpnsettings);
     &General::readhasharray("${General::swroot}/ovpn/caconfig", \%cahash);
     &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
@@ -2665,35 +3119,165 @@ if ($confighash{$cgiparams{'KEY'}}) {
            $errormessage = $Lang::tr{'invalid key'};
            goto VPNCONF_END;
        }
-       $cgiparams{'ENABLED'}   = $confighash{$cgiparams{'KEY'}}[0];
-       $cgiparams{'NAME'}      = $confighash{$cgiparams{'KEY'}}[1];
-       $cgiparams{'TYPE'}      = $confighash{$cgiparams{'KEY'}}[3];
-       $cgiparams{'AUTH'}      = $confighash{$cgiparams{'KEY'}}[4];
-       $cgiparams{'PSK'}       = $confighash{$cgiparams{'KEY'}}[5];
-       $cgiparams{'SIDE'}      = $confighash{$cgiparams{'KEY'}}[6];
-       $cgiparams{'LOCAL_SUBNET'} = $confighash{$cgiparams{'KEY'}}[8];
-  $cgiparams{'REMOTE'} = $confighash{$cgiparams{'KEY'}}[10];
-  $cgiparams{'REMOTE_SUBNET'} = $confighash{$cgiparams{'KEY'}}[11];
+       $cgiparams{'ENABLED'}                   = $confighash{$cgiparams{'KEY'}}[0];
+       $cgiparams{'NAME'}                              = $confighash{$cgiparams{'KEY'}}[1];
+       $cgiparams{'TYPE'}                              = $confighash{$cgiparams{'KEY'}}[3];
+       $cgiparams{'AUTH'}                              = $confighash{$cgiparams{'KEY'}}[4];
+       $cgiparams{'PSK'}                               = $confighash{$cgiparams{'KEY'}}[5];
+       $cgiparams{'SIDE'}                              = $confighash{$cgiparams{'KEY'}}[6];
+       $cgiparams{'LOCAL_SUBNET'}              = $confighash{$cgiparams{'KEY'}}[8];
+       $cgiparams{'REMOTE'}                    = $confighash{$cgiparams{'KEY'}}[10];
+       $cgiparams{'REMOTE_SUBNET'}     = $confighash{$cgiparams{'KEY'}}[11];
 # n2n m.a.d new fields
-  $cgiparams{'OVPN_MGMT'} = $confighash{$cgiparams{'KEY'}}[22];
-  $cgiparams{'MSSFIX'} = $confighash{$cgiparams{'KEY'}}[23];
-  $cgiparams{'FRAGMENT'} = $confighash{$cgiparams{'KEY'}}[24];
-       $cgiparams{'REMARK'}    = $confighash{$cgiparams{'KEY'}}[25];
-       $cgiparams{'INTERFACE'} = $confighash{$cgiparams{'KEY'}}[26];
+       $cgiparams{'OVPN_MGMT'}                 = $confighash{$cgiparams{'KEY'}}[22];
+       $cgiparams{'MSSFIX'}                    = $confighash{$cgiparams{'KEY'}}[23];
+       $cgiparams{'FRAGMENT'}                  = $confighash{$cgiparams{'KEY'}}[24];
+       $cgiparams{'REMARK'}                    = $confighash{$cgiparams{'KEY'}}[25];
+       $cgiparams{'INTERFACE'}                 = $confighash{$cgiparams{'KEY'}}[26];
 #new fields    
-       $cgiparams{'OVPN_SUBNET'} = $confighash{$cgiparams{'KEY'}}[27];
-       $cgiparams{'PROTOCOL'}    = $confighash{$cgiparams{'KEY'}}[28];
-       $cgiparams{'DEST_PORT'}   = $confighash{$cgiparams{'KEY'}}[29];
-       $cgiparams{'COMPLZO'}     = $confighash{$cgiparams{'KEY'}}[30];
-       $cgiparams{'MTU'}         = $confighash{$cgiparams{'KEY'}}[31];
-
-#new fields
-#ab hiere error uebernehmen
-
-    } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'save'}) {
+       $cgiparams{'OVPN_SUBNET'}               = $confighash{$cgiparams{'KEY'}}[27];
+       $cgiparams{'PROTOCOL'}                  = $confighash{$cgiparams{'KEY'}}[28];
+       $cgiparams{'DEST_PORT'}                 = $confighash{$cgiparams{'KEY'}}[29];
+       $cgiparams{'COMPLZO'}                   = $confighash{$cgiparams{'KEY'}}[30];
+       $cgiparams{'MTU'}                               = $confighash{$cgiparams{'KEY'}}[31];
+############
+#A.Marx CCD
+############   
+       $cgiparams{'CHECK1'}                    = $confighash{$cgiparams{'KEY'}}[32];
+       my $name=$cgiparams{'CHECK1'}   ;
+       $cgiparams{$name}                               = $confighash{$cgiparams{'KEY'}}[33];
+       $cgiparams{'RG'}                                = $confighash{$cgiparams{'KEY'}}[34];
+       $cgiparams{'CCD_DNS1'}                  = $confighash{$cgiparams{'KEY'}}[35];
+       $cgiparams{'CCD_DNS2'}                  = $confighash{$cgiparams{'KEY'}}[36];
+       $cgiparams{'CCD_WINS'}                  = $confighash{$cgiparams{'KEY'}}[37];
+#########
+#CCD End
+#########      
+               
+       } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'save'}) {
        $cgiparams{'REMARK'} = &Header::cleanhtml($cgiparams{'REMARK'});
        
-  if ($cgiparams{'TYPE'} !~ /^(host|net)$/) {
+       
+###########
+#A.Marx CCD--check iroute field and convert it to decimal
+###########
+       
+       my @temp=();
+       my %ccdroutehash=();
+       my $keypoint=0;
+       if ($cgiparams{'IR'} ne ''){
+               @temp = split("\n",$cgiparams{'IR'});
+               &General::readhasharray("${General::swroot}/ovpn/ccdroute", \%ccdroutehash);
+               #find key to use
+               foreach my $key (keys %ccdroutehash) {
+                       if ($ccdroutehash{$key}[0] eq $cgiparams{'NAME'}) {
+                               $keypoint=$key;
+                               delete $ccdroutehash{$key};
+                       }else{
+                               $keypoint = &General::findhasharraykey (\%ccdroutehash);
+                       }
+               }
+               $ccdroutehash{$keypoint}[0]=$cgiparams{'NAME'};
+               my $i=1;
+               my $val=0;
+               foreach $val (@temp){
+                       chomp($val);
+                       $val=~s/\s*$//g; 
+                       $val=&General::iporsubtodec($val);
+                       my ($ip,$cidr) = split (/\//, $val);
+                       
+                       if (! &check_routes_push($val)){$errormessage="Route $val ".$Lang::tr{'ccd err routeovpn'};goto VPNCONF_ERROR;}
+                       if (! &check_ccdroute($val)){$errormessage=$errormessage."<br>Route $val ".$Lang::tr{'ccd err inuse'};goto VPNCONF_ERROR;}
+                                                                       
+                       #check for existing network IP's
+                       if ((&General::IpInSubnet ($ip,$netsettings{GREEN_NETADDRESS},$netsettings{GREEN_NETMASK}) && $netsettings{GREEN_NETADDRESS} ne '0.0.0.0')|| 
+                               (&General::IpInSubnet ($ip,$netsettings{RED_NETADDRESS},$netsettings{RED_NETMASK}) && $netsettings{RED_NETADDRESS} ne '0.0.0.0')||
+                               (&General::IpInSubnet ($ip,$netsettings{BLUE_NETADDRESS},$netsettings{BLUE_NETMASK}) && $netsettings{BLUE_NETADDRESS} ne '0.0.0.0' && $netsettings{BLUE_NETADDRESS} gt '')||
+                               (&General::IpInSubnet ($ip,$netsettings{ORANGE_NETADDRESS},$netsettings{ORANGE_NETMASK}) && $netsettings{ORANGE_NETADDRESS} ne '0.0.0.0' && $netsettings{ORANGE_NETADDRESS} gt '' )){
+                               $errormessage="$ip USED FOR SYSTEM!";
+                               goto VPNCONF_ERROR;
+                       }
+                       #if (! &check_ccdconf($val)){$errormessage=$errormessage."<br>                          Route $val ".$Lang::tr{'ccd err routeovpn'};goto VPNCONF_ERROR;}
+                       if (&General::validip2($val)){
+                               $ccdroutehash{$keypoint}[$i] = &General::iporsubtodec($val);
+                       }else{
+                               $errormessage="Route ".$Lang::tr{'ccd invalid'};
+                               goto VPNCONF_ERROR;
+                       }
+                       $i++;
+               }
+               &General::writehasharray("${General::swroot}/ovpn/ccdroute", \%ccdroutehash);
+               &writeserverconf;
+       }       
+       undef @temp;
+               #check route field and convert it to decimal
+       my %ccdroute2hash=();
+       my $val=0;
+       my $i=1;
+       if ($cgiparams{'IFROUTE'} ne ''){
+               &General::readhasharray("${General::swroot}/ovpn/ccdroute2", \%ccdroute2hash);
+               #find key to use
+               foreach my $key (keys %ccdroute2hash) {
+                       if ($ccdroute2hash{$key}[0] eq $cgiparams{'NAME'}) {
+                               $keypoint=$key;
+                               delete $ccdroute2hash{$key};
+                       }else{
+                               $keypoint = &General::findhasharraykey (\%ccdroute2hash);
+                       }
+               }
+               $ccdroute2hash{$keypoint}[0]=$cgiparams{'NAME'};
+               @temp = split("\n",$cgiparams{'IFROUTE'});
+               foreach $val (@temp){
+                       chomp($val);
+                       $val=~s/\s*$//g; 
+                       my ($ip,$cidr) = split (/\//, $val);
+                       if (! &check_routes_push($val)){$errormessage="Route $val ".$Lang::tr{'ccd err routeovpn2'};goto VPNCONF_ERROR;}
+                       if (! &check_ccdroute($val)){$errormessage=$errormessage."<br>Route $val ".$Lang::tr{'ccd err inuse'};goto VPNCONF_ERROR;}
+                       if ((&General::IpInSubnet ($ip,$netsettings{GREEN_NETADDRESS},$netsettings{GREEN_NETMASK}) && $netsettings{GREEN_NETADDRESS} ne '0.0.0.0')|| 
+                               (&General::IpInSubnet ($ip,$netsettings{RED_NETADDRESS},$netsettings{RED_NETMASK}) && $netsettings{RED_NETADDRESS} ne '0.0.0.0')||
+                               (&General::IpInSubnet ($ip,$netsettings{BLUE_NETADDRESS},$netsettings{BLUE_NETMASK}) && $netsettings{BLUE_NETADDRESS} ne '0.0.0.0' && $netsettings{BLUE_NETADDRESS} gt '')||
+                               (&General::IpInSubnet ($ip,$netsettings{ORANGE_NETADDRESS},$netsettings{ORANGE_NETMASK}) && $netsettings{ORANGE_NETADDRESS} ne '0.0.0.0' && $netsettings{ORANGE_NETADDRESS} gt '' )){
+                               $errormessage="$ip ".$Lang::tr{'ccd err routeovpn2'};
+                               goto VPNCONF_ERROR;
+                       }
+                       if (! &check_ccdconf($val)){$errormessage=$errormessage."<br>Route $val ".$Lang::tr{'ccd err routeovpn'};goto VPNCONF_ERROR;}
+                       if (&General::validip2($val)){
+                               $ccdroute2hash{$keypoint}[$i] = &General::iporsubtodec($val);
+                       }else{
+                               $errormessage="Route ".$Lang::tr{'ccd invalid'};
+                               goto VPNCONF_ERROR;
+                       }
+                       $i++;
+               }       
+               &General::writehasharray("${General::swroot}/ovpn/ccdroute2", \%ccdroute2hash);
+       }
+       
+       if ($cgiparams{'CCD_DNS1'} ne '' &&  ! &General::validip($cgiparams{'CCD_DNS1'})) {
+                       $errormessage=$errormessage."<br>".$Lang::tr{'invalid input for dhcp dns'}." 1";
+                       goto VPNCONF_ERROR;
+       }
+       if ($cgiparams{'CCD_DNS1'} ne ''){
+               
+       }
+       if ($cgiparams{'CCD_DNS2'} ne '' &&  ! &General::validip($cgiparams{'CCD_DNS2'})) {
+                       $errormessage=$errormessage."<br>".$Lang::tr{'invalid input for dhcp dns'}." 2";
+                       goto VPNCONF_ERROR;
+       }
+       if ($cgiparams{'CCD_DNS2'} ne ''){
+               
+       }
+       
+       
+       if ($cgiparams{'CCD_WINS'} ne '' &&  ! &General::validip($cgiparams{'CCD_WINS'})) {
+                       $errormessage=$errormessage."<br>".$Lang::tr{'invalid input for dhcp wins'};
+                       goto VPNCONF_ERROR;
+       }
+       
+###########
+#CCD End
+###########    
+       
+ if ($cgiparams{'TYPE'} !~ /^(host|net)$/) {
            $errormessage = $Lang::tr{'connection type is invalid'};
            if ($cgiparams{'TYPE'} eq 'net') {
       unlink ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}/$cgiparams{'NAME'}.conf") or die "Removing Configfile fail: $!";
@@ -3143,45 +3727,129 @@ if ($cgiparams{'TYPE'} eq 'net') {
 
         # Save the config
        my $key = $cgiparams{'KEY'};
+       
        if (! $key) {
            $key = &General::findhasharraykey (\%confighash);
-           foreach my $i (0 .. 31) { $confighash{$key}[$i] = "";}
+           foreach my $i (0 .. 36) { $confighash{$key}[$i] = "";}
        }
-       $confighash{$key}[0] = $cgiparams{'ENABLED'};
-       $confighash{$key}[1] = $cgiparams{'NAME'};
+       $confighash{$key}[0]            = $cgiparams{'ENABLED'};
+       $confighash{$key}[1]            = $cgiparams{'NAME'};
        if ((! $cgiparams{'KEY'}) && $cgiparams{'AUTH'} ne 'psk') {
-           $confighash{$key}[2] = $cgiparams{'CERT_NAME'};
+           $confighash{$key}[2]        = $cgiparams{'CERT_NAME'};
        }
-       $confighash{$key}[3] = $cgiparams{'TYPE'};
+       
+       $confighash{$key}[3]            = $cgiparams{'TYPE'};
        if ($cgiparams{'AUTH'} eq 'psk') {
-           $confighash{$key}[4] = 'psk';
-           $confighash{$key}[5] = $cgiparams{'PSK'};
+           $confighash{$key}[4]        = 'psk';
+           $confighash{$key}[5]        = $cgiparams{'PSK'};
        } else {
-           $confighash{$key}[4] = 'cert';
+           $confighash{$key}[4]        = 'cert';
        }
        if ($cgiparams{'TYPE'} eq 'net') {
-           $confighash{$key}[6] = $cgiparams{'SIDE'};
-           $confighash{$key}[11] = $cgiparams{'REMOTE_SUBNET'};
+           $confighash{$key}[6]        = $cgiparams{'SIDE'};
+           $confighash{$key}[11]       = $cgiparams{'REMOTE_SUBNET'};
        }
-       $confighash{$key}[8] = $cgiparams{'LOCAL_SUBNET'};
-       $confighash{$key}[10] = $cgiparams{'REMOTE'};
+       $confighash{$key}[8]            = $cgiparams{'LOCAL_SUBNET'};
+       $confighash{$key}[10]           = $cgiparams{'REMOTE'};
   if ($cgiparams{'OVPN_MGMT'} eq '') {
-  $confighash{$key}[22] = $confighash{$key}[29];
+       $confighash{$key}[22]           = $confighash{$key}[29];
   } else {
-  $confighash{$key}[22] = $cgiparams{'OVPN_MGMT'};
+       $confighash{$key}[22]           = $cgiparams{'OVPN_MGMT'};
   }
-  $confighash{$key}[23] = $cgiparams{'MSSFIX'};
-  $confighash{$key}[24] = $cgiparams{'FRAGMENT'};
-       $confighash{$key}[25] = $cgiparams{'REMARK'};
-       $confighash{$key}[26] = $cgiparams{'INTERFACE'};
+       $confighash{$key}[23]           = $cgiparams{'MSSFIX'};
+       $confighash{$key}[24]           = $cgiparams{'FRAGMENT'};
+       $confighash{$key}[25]           = $cgiparams{'REMARK'};
+       $confighash{$key}[26]           = $cgiparams{'INTERFACE'};
 # new fields   
-       $confighash{$key}[27] = $cgiparams{'OVPN_SUBNET'};
-       $confighash{$key}[28] = $cgiparams{'PROTOCOL'};
-       $confighash{$key}[29] = $cgiparams{'DEST_PORT'};
-       $confighash{$key}[30] = $cgiparams{'COMPLZO'};
-       $confighash{$key}[31] = $cgiparams{'MTU'};
+       $confighash{$key}[27]           = $cgiparams{'OVPN_SUBNET'};
+       $confighash{$key}[28]           = $cgiparams{'PROTOCOL'};
+       $confighash{$key}[29]           = $cgiparams{'DEST_PORT'};
+       $confighash{$key}[30]           = $cgiparams{'COMPLZO'};
+       $confighash{$key}[31]           = $cgiparams{'MTU'};
 # new fileds   
+       
+       
+###########
+#A.Marx CCD new fields
+###########
+       $confighash{$key}[32]           = $cgiparams{'CHECK1'};
+       my $name=$cgiparams{'CHECK1'};
+       $confighash{$key}[33]           = $cgiparams{$name};
+       $confighash{$key}[34]           = $cgiparams{'RG'};
+       $confighash{$key}[35]           = $cgiparams{'CCD_DNS1'};
+       $confighash{$key}[36]           = $cgiparams{'CCD_DNS2'};
+       $confighash{$key}[37]           = $cgiparams{'CCD_WINS'};
+       
+       #-----------------------------------------
+       # Attention: Workaround for "6 comma Bug".
+       # The last field has to contain something
+       # to be sure that each line has a fixed 
+       # number of elements
+       #-----------------------------------------
+       $confighash{$key}[38]           = "END";
+               
        &General::writehasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
+       
+       if ($cgiparams{'CHECK1'} ){
+               
+               my ($ccdip,$ccdsub)=split "/",$cgiparams{$name};
+               my ($a,$b,$c,$d) = split (/\./,$ccdip);
+                       if ( -e "${General::swroot}/ovpn/ccd/$confighash{$key}[2]"){unlink "${General::swroot}/ovpn/ccd/$cgiparams{'CERT_NAME'}";}
+                       open ( CCDRWCONF,'>',"${General::swroot}/ovpn/ccd/$confighash{$key}[2]") or die "Unable to create clientconfigfile $!";
+                       print CCDRWCONF "# OpenVPN Clientconfig from CCD extension by Copymaster#\n\n";
+                       if($cgiparams{'CHECK1'} eq 'dynamic'){
+                               print CCDRWCONF "#This client uses the dynamic pool\n";
+                       }else{
+                               print CCDRWCONF "#Ip address client and Server\n";
+                               print CCDRWCONF "ifconfig-push $ccdip ".&General::getlastip($ccdip,1)."\n";
+                       }
+                       if ($confighash{$key}[34] eq 'on'){
+                               print CCDRWCONF "\n#Redirect Gateway: \n#All IP traffic is redirected through the vpn \n";
+                               print CCDRWCONF "push redirect-gateway\n";
+                       }
+                       my %ccdroute=();
+                       if ($cgiparams{'IR'} ne ''){
+                               print CCDRWCONF "\n#Client routes these Networks (behind Client)\n";
+                               &General::writehasharray("${General::swroot}/ovpn/ccdroute", \%ccdroutehash);
+                               foreach my $key (keys %ccdroutehash){
+                                       if ($ccdroutehash{$key}[0] eq $cgiparams{'NAME'}){
+                                               foreach my $i ( 1 .. $#{$ccdroutehash{$key}}){
+                                                       my ($a,$b)=split (/\//,$ccdroutehash{$key}[$i]);
+                                                       print CCDRWCONF "iroute $a $b\n";
+                                               }
+                                       }
+                               }
+                       }
+                       if ($cgiparams{'IFROUTE'} ne ''){
+                               print CCDRWCONF "\n#Client gets routes to these Networks (behind IPFIRE)\n";
+                               &General::writehasharray("${General::swroot}/ovpn/ccdroute2", \%ccdroute2hash);
+                               foreach my $key (keys %ccdroute2hash){
+                                       if ($ccdroute2hash{$key}[0] eq $cgiparams{'NAME'}){
+                                               foreach my $i ( 1 .. $#{$ccdroute2hash{$key}}){
+                                                       my ($a,$b)=split (/\//,$ccdroute2hash{$key}[$i]);
+                                                       print CCDRWCONF "push \"route $a $b\"\n";
+                                               }
+                                       }
+                               }
+                       }
+                       if(($cgiparams{'CCD_DNS1'} eq '') && ($cgiparams{'CCD_DNS1'} ne '')){ $cgiparams{'CCD_DNS1'} = $cgiparams{'CCD_DNS2'};$cgiparams{'CCD_DNS2'}='';}
+                       if($cgiparams{'CCD_DNS1'} ne ''){
+                               print CCDRWCONF "\n#Client gets these Nameservers\n";
+                               print CCDRWCONF "push \"dhcp-option DNS $cgiparams{'CCD_DNS1'}\" \n";
+                       }
+                       if($cgiparams{'CCD_DNS2'} ne ''){
+                               print CCDRWCONF "push \"dhcp-option DNS $cgiparams{'CCD_DNS2'}\" \n";
+                       }
+                       if($cgiparams{'CCD_WINS'} ne ''){
+                               print CCDRWCONF "\n#Client gets this WINS server\n";
+                               print CCDRWCONF "push \"dhcp-option WINS $cgiparams{'CCD_WINS'}\" \n";
+                       }
+                       close CCDRWCONF;
+       }
+########
+#CCD End
+########
+       
 
 ###
 # m.a.d n2n begin
@@ -3308,12 +3976,17 @@ if ($cgiparams{'TYPE'} eq 'net') {
        }
 
        &Header::openbox('100%', 'LEFT', "$Lang::tr{'connection'}:");
-       print "<table width='100%'>\n";
-       print "<tr><td width='25%' class='boldbase'>$Lang::tr{'name'}:</td>";
+       print "<table width='100%'  border='0'>\n";
+       
+       
+       
+       print "<tr><td width='14%' class='boldbase'>$Lang::tr{'name'}: </td>";
+       
        if ($cgiparams{'TYPE'} eq 'host') {
            if ($cgiparams{'KEY'}) {
-               print "<td width='35%' class='base'><input type='hidden' name='NAME' value='$cgiparams{'NAME'}' />$cgiparams{'NAME'}</td>\n";
+               print "<td width='35%' class='base'><input type='hidden' name='NAME' value='$cgiparams{'NAME'}' />$cgiparams{'NAME'}</td>";
            } else {
+                       
                print "<td width='35%'><input type='text' name='NAME' value='$cgiparams{'NAME'}' maxlength='20' size='30' /></td>";
            }
 #          print "<tr><td>$Lang::tr{'interface'}</td>";
@@ -3333,6 +4006,9 @@ if ($cgiparams{'TYPE'} eq 'net') {
            } else {
                print "<td width='25%'><input type='text' name='NAME' value='$cgiparams{'NAME'}' maxlength='20' /></td>";
            }
+           
+           
+           
            print <<END
                    <td width='25%'>&nbsp;</td>
                    <td width='25%'>&nbsp;</td></tr>
@@ -3374,30 +4050,117 @@ if ($cgiparams{'TYPE'} eq 'net') {
         <td colspan='2'>$Lang::tr{'openvpn default'}: <span class="base">$Lang::tr{'destination port'}</span></td>
 
 END
-           ;
+;
        }
 
        print "<tr><td class='boldbase'>$Lang::tr{'remark title'}&nbsp;<img src='/blob.gif' /></td>";
-       print "<td colspan='3'><input type='text' name='REMARK' value='$cgiparams{'REMARK'}' size='55' maxlength='50' /></td></tr>";
+       print "<td colspan='3'><input type='text' name='REMARK' value='$cgiparams{'REMARK'}' size='55' maxlength='50' /></td></tr></table>";
        
        if ($cgiparams{'TYPE'} eq 'host') {
 
-      print "<tr><td>$Lang::tr{'enabled'} <input type='checkbox' name='ENABLED' $checked{'ENABLED'}{'on'} /></td>\n";
-         }     
+      print "<tr><td>$Lang::tr{'enabled'} <input type='checkbox' name='ENABLED' $checked{'ENABLED'}{'on'} /></td>";
+###########
+#A.Marx CCD---neuer client
+###########
+       print"</tr></table><br><br>";
+    print "<table border='0' width='100%' cellspacing='1' cellpadding='0'><tr><td colspan='3'><hr><br><b>$Lang::tr{'ccd choose net'}</td></tr><tr><td height='20' colspan='3'></td></tr>";
+    my %ccdconfhash=();
+    my %ccdroutehash=();
+    my %ccdroute2hash=();
+    &General::readhasharray("${General::swroot}/ovpn/ccd.conf", \%ccdconfhash);
+    my @ccdconf=();
+       my $count=0;
+       my $checked;
+       $checked{'check1'}{'off'} = '';
+    $checked{'check1'}{'on'} = '';
+    $checked{'check1'}{$cgiparams{'CHECK1'}} = 'CHECKED';
+    print"<tr><td align='center' width='1%' valign='top'><input type='radio' name='CHECK1' value='dynamic' checked /></td><td align='left' valign='top' width='35%'>$Lang::tr{'ccd dynrange'}</td><td width='30%'>";
+    print"</td></tr></table><br><br>";
+       my $name=$cgiparams{'CHECK1'};
+       $checked{'RG'}{$cgiparams{'RG'}} = 'CHECKED';
+       print"<table border='0' width='100%' cellspacing='1' cellpadding='0'><tr><td width='1%'></td><td width='30%' class='boldbase' align='center'><b>$Lang::tr{'ccd name'}</td><td width='15%' class='boldbase' align='center'><b>$Lang::tr{'ccd net'}</td><td class='boldbase' align='center' width='18%'><b>$Lang::tr{'ccd clientip'}</td></tr>";
+       foreach my $key (keys %ccdconfhash) {
+               $count++;
+               @ccdconf=($ccdconfhash{$key}[0],$ccdconfhash{$key}[1]);
+               if ($count % 2){print"<tr bgcolor='$color{'color22'}'>";}else{print"<tr bgcolor='$color{'color20'}'>";}
+               print"<td align='center' width='1%'><input type='radio' name='CHECK1' value='$ccdconf[0]' $checked{'check1'}{$ccdconf[0]}/></td><td>$ccdconf[0]</td><td width='40%'>$ccdconf[1]</td><td align='left' width='10%'>";
+               &fillselectbox($ccdconf[1],$ccdconf[0],$cgiparams{$name});
+               print"</td></tr>";
+       }
+       print "</table><br><br>";
+print <<END
+<table border='0' width='100%'>
+<tr><td colspan='4'><hr><br><b>$Lang::tr{'ccd client options'}</td></tr>
+<tr><td colspan='4' height='20'></td></tr>
+<tr><td width='20%'>Redirect Gateway:</td><td colspan='3'><input type='checkbox' name='RG' $checked{'RG'}{'on'} /></td></tr>
+<tr><td colspan='4'>&nbsp</td></tr>
+<tr><td valign='top'>$Lang::tr{'ccd iroute'}<br>$Lang::tr{'ccd iroute2'}</td><td align='left' width='30%'><textarea name='IR' cols='26' rows='6' wrap='off'>
+END
+;
+
+if ($cgiparams{'IR'} ne ''){
+       print $cgiparams{'IR'};
+}else{
+       &General::readhasharray ("${General::swroot}/ovpn/ccdroute", \%ccdroutehash);
+       foreach my $key (keys %ccdroutehash) {
+               if( $cgiparams{'NAME'} eq $ccdroutehash{$key}[0]){
+                       foreach my $i (1 .. $#{$ccdroutehash{$key}}) {
+                                       $ccdroutehash{$key}[$i].="\n";
+                                       print $ccdroutehash{$key}[$i];
+                                       $cgiparams{'IR'} .= $ccdroutehash{$key}[$i];
+                       }
+               }
+       }
+}
+print <<END
+</textarea></td><td valign='top' colspan='2'>$Lang::tr{'ccd iroutehint'}</td></tr>
+<tr><td colspan='4'><br></td></tr>
+<tr><td valign='top' rowspan='3'>$Lang::tr{'ccd iroute'}<br>$Lang::tr{'ccd iroute3'}</td><td align='left' width='30%' rowspan='3'><textarea name='IFROUTE' cols='26' rows='6' wrap='off'>
+END
+;
+if ($cgiparams{'IFROUTE'} ne ''){
+       print $cgiparams{'IFROUTE'};
+}else{
+       &General::readhasharray ("${General::swroot}/ovpn/ccdroute2", \%ccdroute2hash);
+       foreach my $key (keys %ccdroute2hash) {
+               if( $cgiparams{'NAME'} eq $ccdroute2hash{$key}[0]){
+                       foreach my $i (1 .. $#{$ccdroute2hash{$key}}) {
+                                       $ccdroute2hash{$key}[$i].="\n";
+                                       print $ccdroute2hash{$key}[$i];
+                                       $cgiparams{'IFROUTE'} .= $ccdroutehash{$key}[$i];
+                       }
+               }
+       }
+}
+
+
+print<<END
+</textarea></td><td valign='top'>DNS1:</td><td valign='top'><input type='TEXT' name='CCD_DNS1' value='$cgiparams{'CCD_DNS1'}' size='30' /></td></tr>
+<tr valign='top'><td>DNS2:</td><td><input type='TEXT' name='CCD_DNS2' value='$cgiparams{'CCD_DNS2'}' size='30' /></td></tr>
+<tr valign='top'><td valign='top'>WINS:</td><td><input type='TEXT' name='CCD_WINS' value='$cgiparams{'CCD_WINS'}' size='30' /></td></tr>
 
+</table><br><hr>
+
+
+END
+;
+
+   
+#CCD End
+#########      
+         
+         
+         }     
 #          if ($cgiparams{'KEY'}) {
 #              print "<td colspan='3'>&nbsp;</td></tr></table>";
 #          } else {
 #              print "<td colspan='3'><input type='checkbox' name='EDIT_ADVANCED' $checked{'EDIT_ADVANCED'}{'on'} /> $Lang::tr{'edit advanced settings when done'}</tr></table>";
 #          }
 #      }else{
-           print "<td colspan='3'>&nbsp;</td></tr></table>";
+          
 #      }    
-           
-       
-
        &Header::closebox();
-       
        if ($cgiparams{'KEY'} && $cgiparams{'AUTH'} eq 'psk') {
        #    &Header::openbox('100%', 'LEFT', $Lang::tr{'authentication'});
        #    print <<END
@@ -3405,15 +4168,17 @@ END
        #    <tr><td class='base' width='50%'>$Lang::tr{'use a pre-shared key'}</td>
        #       <td class='base' width='50%'><input type='text' name='PSK' size='30' value='$cgiparams{'PSK'}' /></td></tr>
        #    </table>
-END
        #    ;
        #    &Header::closebox();
        } elsif (! $cgiparams{'KEY'}) {
+               
+               
            my $disabled='';
            my $cakeydisabled='';
            my $cacrtdisabled='';
            if ( ! -f "${General::swroot}/ovpn/ca/cakey.pem" ) { $cakeydisabled = "disabled='disabled'" } else { $cakeydisabled = "" };
            if ( ! -f "${General::swroot}/ovpn/ca/cacert.pem" ) { $cacrtdisabled = "disabled='disabled'" } else { $cacrtdisabled = "" };
+           
            &Header::openbox('100%', 'LEFT', $Lang::tr{'authentication'});
  
  
@@ -3438,6 +4203,10 @@ print <<END
 END
 ;
 
+
+
+
+       
 ###
 # m.a.d net2net
 ###
@@ -3627,7 +4396,7 @@ END
     }  
     &Header::openbox('100%', 'LEFT', $Lang::tr{'global settings'});    
     print <<END        
-    <table width='100%'>
+    <table width='100%' border=0>
     <form method='post'>
     <td width='25%'>&nbsp;</td>
     <td width='25%'>&nbsp;</td>
@@ -3674,18 +4443,25 @@ END
                                   <option value='CAST5-CBC' $selected{'DCIPHER'}{'CAST5-CBC'}>CAST5-CBC</option>
                                   <option value='AES-128-CBC' $selected{'DCIPHER'}{'AES-128-CBC'}>AES-128-CBC</option>
                                   <option value='AES-192-CBC' $selected{'DCIPHER'}{'AES-192-CBC'}>AES-192-CBC</option>
-                                  <option value='AES-256-CBC' $selected{'DCIPHER'}{'AES-256-CBC'}>AES-256-CBC</option></select></td>
+                                  <option value='AES-256-CBC' $selected{'DCIPHER'}{'AES-256-CBC'}>AES-256-CBC</option></select></td></tr>
+                                  <tr><td colspan='4'><hr /></td></tr>
 END
 ;                                 
     
     if ( $srunning eq "yes" ) {
-       print "<tr><td align='left'><input type='submit' name='ACTION' value='$Lang::tr{'save'}' disabled='disabled' /></td>";
-       print "<td><input type='submit' name='ACTION' value='$Lang::tr{'advanced server'}' disabled='disabled'/></td>"; 
-       print "<td><input type='submit' name='ACTION' value='$Lang::tr{'stop ovpn server'}' /></td>";
-       print "<td><input type='submit' name='ACTION' value='$Lang::tr{'restart ovpn server'}' /></td></tr>";   
+       print "<tr><td align='right' colspan='4'><input type='submit' name='ACTION' value='$Lang::tr{'save'}' disabled='disabled' />";
+#A.Marx CCD
+       print "<input type='submit' name='ACTION' value='$Lang::tr{'ccd net'}' disabled='disabled'/>";
+###########    
+       print "<input type='submit' name='ACTION' value='$Lang::tr{'advanced server'}' disabled='disabled'/>";  
+       print "<input type='submit' name='ACTION' value='$Lang::tr{'stop ovpn server'}' /></td></tr>";
+       #print "<td><input type='submit' name='ACTION' value='$Lang::tr{'restart ovpn server'}' /></td></tr>";  
     } else{
-       print "<tr><td align='left'><input type='submit' name='ACTION' value='$Lang::tr{'save'}' /></td>";
-       print "<td><input type='submit' name='ACTION' value='$Lang::tr{'advanced server'}' /></td>";
+       print "<tr><td align='right' colspan='4'><input type='submit' name='ACTION' value='$Lang::tr{'save'}' />";
+#A.Marx CCD    
+       print "<input type='submit' name='ACTION' value='$Lang::tr{'ccd net'}' />";
+###########
+       print "<input type='submit' name='ACTION' value='$Lang::tr{'advanced server'}' />";
        if (( -e "${General::swroot}/ovpn/ca/cacert.pem" &&
             -e "${General::swroot}/ovpn/ca/dh1024.pem" &&
             -e "${General::swroot}/ovpn/certs/servercert.pem" &&
@@ -3693,11 +4469,11 @@ END
            (( $cgiparams{'ENABLED'} eq 'on') || 
            ( $cgiparams{'ENABLED_BLUE'} eq 'on') ||
            ( $cgiparams{'ENABLED_ORANGE'} eq 'on'))){
-           print "<td><input type='submit' name='ACTION' value='$Lang::tr{'start ovpn server'}' /></td>";
-           print "<td><input type='submit' name='ACTION' value='$Lang::tr{'restart ovpn server'}' /></td></tr>";       
+           print "<input type='submit' name='ACTION' value='$Lang::tr{'start ovpn server'}' /></td></tr>";
+           #print "<td><input type='submit' name='ACTION' value='$Lang::tr{'restart ovpn server'}' /></td></tr>";      
        } else {
-           print "<td><input type='submit' name='ACTION' value='$Lang::tr{'start ovpn server'}' disabled='disabled' /></td>";    
-           print "<td><input type='submit' name='ACTION' value='$Lang::tr{'restart ovpn server'}' disabled='disabled' /></td></tr>";               
+           print "<input type='submit' name='ACTION' value='$Lang::tr{'start ovpn server'}' disabled='disabled' /></td></tr>";    
+           #print "<td><input type='submit' name='ACTION' value='$Lang::tr{'restart ovpn server'}' disabled='disabled' /></td></tr>";              
        }    
     }
     print "</form></table>";
@@ -3829,18 +4605,19 @@ END
     </tr>
     </table>
 END
-    ;
+;
     }
-    print <<END
-    <form method='post' enctype='multipart/form-data'>
-    <table width='100%' border='0' cellspacing='1' cellpadding='0'>
-    <tr><td class='base' nowrap='nowrap'>$Lang::tr{'ca name'}:</td>
-    <td nowrap='nowrap'><input type='text' name='CA_NAME' value='$cgiparams{'CA_NAME'}' size='15' />
-    <td nowrap='nowrap'><input type='file' name='FH' size='30' /></td>
-    <td nowrap='nowrap'><input type='submit' name='ACTION' value='$Lang::tr{'upload ca certificate'}' /><br /><input type='submit' name='ACTION' value='$Lang::tr{'show crl'}' /></td>    
-    </tr></table></form>
+    
+print <<END
+<form method='post' enctype='multipart/form-data'>
+<table width='100%' border='0'>
+<tr><td class='base' nowrap='nowrap'>$Lang::tr{'ca name'}:</td><td nowrap='nowrap' ><input type='text' name='CA_NAME' value='$cgiparams{'CA_NAME'}' size='15' /></td><td nowrap='nowrap' colspan='2' align='right'><input type='file' name='FH' size='34' /></td></tr>
+<tr><td colspan='4'><hr /></td></tr>
+<tr align='right'><td colspan='4' align='right' width='80%'><input type='submit' name='ACTION' value='$Lang::tr{'upload ca certificate'}' /><input type='submit' name='ACTION' value='$Lang::tr{'show crl'}' /></td></tr>
+</table>
 END
-    ;
+;
 
     &Header::closebox();
     if ( $srunning eq "yes" ) {    
@@ -3864,7 +4641,7 @@ END
     <td width='10%' class='boldbase' align='center'><b>$Lang::tr{'name'}</b></td>
     <td width='15%' class='boldbase' align='center'><b>$Lang::tr{'type'}</b></td>
     <td width='18%' class='boldbase' align='center'><b>$Lang::tr{'common name'}</b></td>
-    <td width='22%' class='boldbase' align='center'><b>$Lang::tr{'valid till'}</b></td>
+    <td width='22%' class='boldbase' align='center'><b>$Lang::tr{'ccd name'}</b></td>
     <td width='20%' class='boldbase' align='center'><b>$Lang::tr{'remark'}</b></td>
     <td width='10%' class='boldbase' align='center'><b>$Lang::tr{'status'}</b></td>
     <td width='5%' class='boldbase' colspan='6' align='center'><b>$Lang::tr{'action'}</b></td>
@@ -3891,7 +4668,9 @@ END
        my $cavalid = `/usr/bin/openssl x509 -text -in ${General::swroot}/ovpn/certs/$confighash{$key}[1]cert.pem`;
        $cavalid    =~ /Not After : (.*)[\n]/;
        $cavalid    = $1;
-       print "<td align='center'>$cavalid</td>";
+       if ($confighash{$key}[32] eq "" && $confighash{$key}[3] eq 'net' ){$confighash{$key}[32]="net-2-net";}
+       if ($confighash{$key}[32] eq "" && $confighash{$key}[3] eq 'host' ){$confighash{$key}[32]="dynamic";}
+       print "<td align='center'>$confighash{$key}[32]</td>";
        print "<td align='center'>$confighash{$key}[25]</td>";
 
        my $active = "<table cellpadding='2' cellspacing='0' bgcolor='${Header::colourred}' width='100%'><tr><td align='center'><b><font color='#FFFFFF'>$Lang::tr{'capsclosed'}</font></b></td></tr></table>";
@@ -4029,7 +4808,7 @@ END
     # If the config file contains entries, print Key to action icons
     if ( $id ) {
     print <<END
-    <table>
+    <table border='0'>
     <tr>
        <td class='boldbase'>&nbsp; <b>$Lang::tr{'legend'}:</b></td>
        <td>&nbsp; <img src='/images/on.gif' alt='$Lang::tr{'click to disable'}' /></td>
@@ -4050,7 +4829,7 @@ END
        <td> <img src='/images/openvpn.png' alt='?RELOAD'/></td>
        <td class='base'>$Lang::tr{'dl client arch'}</td>
     </tr>
-    </table>
+    </table><hr>
 END
     ;
     }
@@ -4058,8 +4837,8 @@ END
     print <<END
     <table width='100%'>
     <form method='post'>
-    <tr><td width='50%' ><input type='submit' name='ACTION' value='$Lang::tr{'add'}' /></td>
-       <td width='50%' ><input type='submit' name='ACTION' value='$Lang::tr{'ovpn con stat'}' $activeonrun /></td></tr>
+    <tr><td align='right'><input type='submit' name='ACTION' value='$Lang::tr{'add'}' />
+    <input type='submit' name='ACTION' value='$Lang::tr{'ovpn con stat'}' $activeonrun /></td></tr>
     </form>
     </table>
 END