From 95e8cecde56b679950d41444e8638b1acdb90a0c Mon Sep 17 00:00:00 2001
From: mcramer <m.cramer@pixcept.de>
Date: Thu, 13 Sep 2012 09:31:56 -0400
Subject: [PATCH] Fixed: Domain names in rewrite rules need the . and special chars to be escaped

---
 server/plugins-available/apache2_plugin.inc.php |  124 +++++++++++++++++++++++++++++++++--------
 1 files changed, 100 insertions(+), 24 deletions(-)

diff --git a/server/plugins-available/apache2_plugin.inc.php b/server/plugins-available/apache2_plugin.inc.php
index 188b12f..398b4ae 100644
--- a/server/plugins-available/apache2_plugin.inc.php
+++ b/server/plugins-available/apache2_plugin.inc.php
@@ -884,23 +884,23 @@
 
 			switch($data['new']['subdomain']) {
 				case 'www':
-					$rewrite_rules[] = array(	'rewrite_domain' 	=> '^'.$data['new']['domain'],
+					$rewrite_rules[] = array(	'rewrite_domain' 	=> '^'.$this->_rewrite_quote($data['new']['domain']),
 						'rewrite_type' 		=> ($data['new']['redirect_type'] == 'no')?'':'['.$data['new']['redirect_type'].']',
 						'rewrite_target' 	=> $rewrite_target,
 						'rewrite_target_ssl' => $rewrite_target_ssl);
-					$rewrite_rules[] = array(	'rewrite_domain' 	=> '^www.'.$data['new']['domain'],
+					$rewrite_rules[] = array(	'rewrite_domain' 	=> '^' . $this->_rewrite_quote('www.'.$data['new']['domain']),
 							'rewrite_type' 		=> ($data['new']['redirect_type'] == 'no')?'':'['.$data['new']['redirect_type'].']',
 							'rewrite_target' 	=> $rewrite_target,
 							'rewrite_target_ssl' => $rewrite_target_ssl);
 					break;
 				case '*':
-					$rewrite_rules[] = array(	'rewrite_domain' 	=> '(^|\.)'.$data['new']['domain'],
+					$rewrite_rules[] = array(	'rewrite_domain' 	=> '(^|\.)'.$this->_rewrite_quote($data['new']['domain']),
 						'rewrite_type' 		=> ($data['new']['redirect_type'] == 'no')?'':'['.$data['new']['redirect_type'].']',
 						'rewrite_target' 	=> $rewrite_target,
 						'rewrite_target_ssl' => $rewrite_target_ssl);
 					break;
 				default:
-					$rewrite_rules[] = array(	'rewrite_domain' 	=> '^'.$data['new']['domain'],
+					$rewrite_rules[] = array(	'rewrite_domain' 	=> '^'.$this->_rewrite_quote($data['new']['domain']),
 						'rewrite_type' 		=> ($data['new']['redirect_type'] == 'no')?'':'['.$data['new']['redirect_type'].']',
 						'rewrite_target' 	=> $rewrite_target,
 						'rewrite_target_ssl' => $rewrite_target_ssl);
@@ -920,7 +920,7 @@
 			unset($client);
 			unset($aa_search);
 			unset($aa_replace);
-			$server_alias[] .= $auto_alias;
+			$server_alias[] .= $auto_alias.' ';
 		}
 		
 		// get alias domains (co-domains and subdomains)
@@ -965,23 +965,25 @@
 					
 					switch($alias['subdomain']) {
 						case 'www':
-							$rewrite_rules[] = array(	'rewrite_domain' 	=> '^'.$alias['domain'],
+							$rewrite_rules[] = array(	'rewrite_domain' 	=> '^'.$this->_rewrite_quote($alias['domain']),
 								'rewrite_type' 		=> ($alias['redirect_type'] == 'no')?'':'['.$alias['redirect_type'].']',
 								'rewrite_target' 	=> $rewrite_target,
 								'rewrite_target_ssl' => $rewrite_target_ssl);
-							$rewrite_rules[] = array(	'rewrite_domain' 	=> '^www.'.$alias['domain'],
+							$rewrite_rules[] = array(	'rewrite_domain' 	=> '^' . $this->_rewrite_quote('www.'.$alias['domain']),
 									'rewrite_type' 		=> ($alias['redirect_type'] == 'no')?'':'['.$alias['redirect_type'].']',
 									'rewrite_target' 	=> $rewrite_target,
 									'rewrite_target_ssl' => $rewrite_target_ssl);
 							break;
 						case '*':
-							$rewrite_rules[] = array(	'rewrite_domain' 	=> '(^|\.)'.$alias['domain'],
+							$rewrite_rules[] = array(	'rewrite_domain' 	=> '(^|\.)'.$this->_rewrite_quote($alias['domain']),
 								'rewrite_type' 		=> ($alias['redirect_type'] == 'no')?'':'['.$alias['redirect_type'].']',
 								'rewrite_target' 	=> $rewrite_target,
 								'rewrite_target_ssl' => $rewrite_target_ssl);
 							break;
 						default:
-							$rewrite_rules[] = array(	'rewrite_domain' 	=> '^'.$alias['domain'],
+                            if(substr($alias['domain'], 0, 2) === '*.') $domain_rule = '(^|\.)'.$this->_rewrite_quote($alias['domain']);
+                            else $domain_rule = '^'.$this->_rewrite_quote($alias['domain']);
+							$rewrite_rules[] = array(	'rewrite_domain' 	=> $domain_rule,
 								'rewrite_type' 		=> ($alias['redirect_type'] == 'no')?'':'['.$alias['redirect_type'].']',
 								'rewrite_target' 	=> $rewrite_target,
 								'rewrite_target_ssl' => $rewrite_target_ssl);
@@ -1744,12 +1746,26 @@
 		
 		//* Create the .htaccess file
 		//if(!is_file($folder_path.'.htaccess')) {
-			$ht_file = "AuthType Basic\nAuthName \"Members Only\"\nAuthUserFile ".$folder_path.".htpasswd\nrequire valid-user";
-			$app->system->file_put_contents($folder_path.'.htaccess',$ht_file);
+			$begin_marker = '### ISPConfig folder protection begin ###';
+            $end_marker = "### ISPConfig folder protection end ###\n\n";
+            $ht_file = $begin_marker."\nAuthType Basic\nAuthName \"Members Only\"\nAuthUserFile ".$folder_path.".htpasswd\nrequire valid-user\n".$end_marker;
+			
+            if(file_exists($folder_path.'.htaccess')) {
+                $old_content = $app->system->file_get_contents($folder_path.'.htaccess');
+                
+                if(preg_match('/' . preg_quote($begin_marker, '/') . '(.*?)' . preg_quote($end_marker, '/') . '/s', $old_content, $matches)) {
+                    $ht_file = str_replace($matches[0], $ht_file, $old_content);
+                } else {
+                    $ht_file .= $old_content;
+                }
+            }
+            unset($old_content);
+            
+            $app->system->file_put_contents($folder_path.'.htaccess',$ht_file);
 			$app->system->chmod($folder_path.'.htaccess',0755);
 			$app->system->chown($folder_path.'.htaccess',$website['system_user']);
 			$app->system->chgrp($folder_path.'.htaccess',$website['system_group']);
-			$app->log('Created file '.$folder_path.'.htaccess',LOGLEVEL_DEBUG);
+			$app->log('Created/modified file '.$folder_path.'.htaccess',LOGLEVEL_DEBUG);
 		//}
 		
 	}
@@ -1791,8 +1807,24 @@
 		
 		//* Remove .htaccess file
 		if(is_file($folder_path.'.htaccess')) {
-			$app->system->unlink($folder_path.'.htaccess');
-			$app->log('Removed file '.$folder_path.'.htaccess',LOGLEVEL_DEBUG);
+            $begin_marker = '### ISPConfig folder protection begin ###';
+            $end_marker = "### ISPConfig folder protection end ###\n\n";
+            
+            $ht_file = $app->system->file_get_contents($folder_path.'.htaccess');
+            
+            if(preg_match('/' . preg_quote($begin_marker, '/') . '(.*?)' . preg_quote($end_marker, '/') . '/s', $ht_file, $matches)) {
+                $ht_file = str_replace($matches[0], '', $ht_file);
+            } else {
+                $ht_file = str_replace("AuthType Basic\nAuthName \"Members Only\"\nAuthUserFile ".$folder_path.".htpasswd\nrequire valid-user", '', $ht_file);
+            }
+            
+            if(trim($ht_file) == '') {
+                $app->system->unlink($folder_path.'.htaccess');
+                $app->log('Removed file '.$folder_path.'.htaccess',LOGLEVEL_DEBUG);
+            } else {
+                $app->system->file_put_contents($folder_path.'.htaccess', $ht_file);
+                $app->log('Removed protection content from file '.$folder_path.'.htaccess',LOGLEVEL_DEBUG);
+            }
 		}
 	}
 	
@@ -1844,6 +1876,9 @@
 		//* Create the folder path, if it does not exist
 		if(!is_dir($new_folder_path)) $app->system->mkdirpath($new_folder_path);
 		
+        $begin_marker = '### ISPConfig folder protection begin ###';
+        $end_marker = "### ISPConfig folder protection end ###\n\n";
+        
 		if($data['old']['path'] != $data['new']['path']) {
 
 		
@@ -1855,26 +1890,63 @@
 			
 			//* delete old .htaccess file
 			if(is_file($old_folder_path.'.htaccess')) {
-				$app->system->unlink($old_folder_path.'.htaccess');
-				$app->log('Deleted file '.$old_folder_path.'.htaccess',LOGLEVEL_DEBUG);
+                $ht_file = $app->system->file_get_contents($old_folder_path.'.htaccess');
+                
+                if(preg_match('/' . preg_quote($begin_marker, '/') . '(.*?)' . preg_quote($end_marker, '/') . '/s', $ht_file, $matches)) {
+                    $ht_file = str_replace($matches[0], '', $ht_file);
+                } else {
+                    $ht_file = str_replace("AuthType Basic\nAuthName \"Members Only\"\nAuthUserFile ".$old_folder_path.".htpasswd\nrequire valid-user", '', $ht_file);
+                }
+                
+                if(trim($ht_file) == '') {
+                    $app->system->unlink($old_folder_path.'.htaccess');
+                    $app->log('Removed file '.$old_folder_path.'.htaccess',LOGLEVEL_DEBUG);
+                } else {
+                    $app->system->file_put_contents($old_folder_path.'.htaccess', $ht_file);
+                    $app->log('Removed protection content from file '.$old_folder_path.'.htaccess',LOGLEVEL_DEBUG);
+                }
 			}
 		
 		}
 		
 		//* Create the .htaccess file
 		if($data['new']['active'] == 'y') {
-			$ht_file = "AuthType Basic\nAuthName \"Members Only\"\nAuthUserFile ".$new_folder_path.".htpasswd\nrequire valid-user";
-			$app->system->file_put_contents($new_folder_path.'.htaccess',$ht_file);
-			$app->system->chmod($new_folder_path.'.htpasswd',0755);
-			$app->system->chown($folder_path.'.htpasswd',$website['system_user']);
-			$app->system->chgrp($folder_path.'.htpasswd',$website['system_group']);
-			$app->log('Created file '.$new_folder_path.'.htpasswd',LOGLEVEL_DEBUG);
+            $ht_file = $begin_marker."\nAuthType Basic\nAuthName \"Members Only\"\nAuthUserFile ".$new_folder_path.".htpasswd\nrequire valid-user\n".$end_marker;
+			
+            if(file_exists($new_folder_path.'.htaccess')) {
+                $old_content = $app->system->file_get_contents($new_folder_path.'.htaccess');
+                
+                if(preg_match('/' . preg_quote($begin_marker, '/') . '(.*?)' . preg_quote($end_marker, '/') . '/s', $old_content, $matches)) {
+                    $ht_file = str_replace($matches[0], $ht_file, $old_content);
+                } else {
+                    $ht_file .= $old_content;
+                }
+            }
+            
+            $app->system->file_put_contents($new_folder_path.'.htaccess',$ht_file);
+			$app->system->chmod($new_folder_path.'.htaccess',0755);
+			$app->system->chown($new_folder_path.'.htaccess',$website['system_user']);
+			$app->system->chgrp($new_folder_path.'.htaccess',$website['system_group']);
+			$app->log('Created/modified file '.$new_folder_path.'.htaccess',LOGLEVEL_DEBUG);
 		}
 		
 		//* Remove .htaccess file
 		if($data['new']['active'] == 'n' && is_file($new_folder_path.'.htaccess')) {
-			$app->system->unlink($new_folder_path.'.htaccess');
-			$app->log('Removed file '.$new_folder_path.'.htaccess',LOGLEVEL_DEBUG);
+            $ht_file = $app->system->file_get_contents($new_folder_path.'.htaccess');
+            
+            if(preg_match('/' . preg_quote($begin_marker, '/') . '(.*?)' . preg_quote($end_marker, '/') . '/s', $ht_file, $matches)) {
+                $ht_file = str_replace($matches[0], '', $ht_file);
+            } else {
+                $ht_file = str_replace("AuthType Basic\nAuthName \"Members Only\"\nAuthUserFile ".$new_folder_path.".htpasswd\nrequire valid-user", '', $ht_file);
+            }
+            
+            if(trim($ht_file) == '') {
+                $app->system->unlink($new_folder_path.'.htaccess');
+                $app->log('Removed file '.$new_folder_path.'.htaccess',LOGLEVEL_DEBUG);
+            } else {
+                $app->system->file_put_contents($new_folder_path.'.htaccess', $ht_file);
+                $app->log('Removed protection content from file '.$new_folder_path.'.htaccess',LOGLEVEL_DEBUG);
+            }
 		}
 		
 		
@@ -2491,6 +2563,10 @@
 		return symlink($cfrom, $to);
 	}
 
+    private function _rewrite_quote($string) {
+        return str_replace(array('.', '*', '?', '+'), array('\\.', '\\*', '\\?', '\\+'), $string);
+    }
+    
 } // end class
 
 ?>

--
Gitblit v1.9.1