Till Brehm
2014-08-25 1f4d646d3229aa4bdfe17b4653b2cd73d48b5f9a
commit | author | age
8ec1d8 1 <?php
M 2
3 /*
4 Copyright (c) 2007, Till Brehm, projektfarm Gmbh
5 Copyright (c) 2012, Marius Cramer, pixcept KG
6 All rights reserved.
7
8 Redistribution and use in source and binary forms, with or without modification,
9 are permitted provided that the following conditions are met:
10
11     * Redistributions of source code must retain the above copyright notice,
12       this list of conditions and the following disclaimer.
13     * Redistributions in binary form must reproduce the above copyright notice,
14       this list of conditions and the following disclaimer in the documentation
15       and/or other materials provided with the distribution.
16     * Neither the name of ISPConfig nor the names of its contributors
17       may be used to endorse or promote products derived from this software without
18       specific prior written permission.
19
20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
21 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23 IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
24 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
25 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
27 OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
29 EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 class validate_domain {
7fe908 33
MC 34     function get_error($errmsg) {
35         global $app;
36
37         if(isset($app->tform->wordbook[$errmsg])) {
38             return $app->tform->wordbook[$errmsg]."<br>\r\n";
39         } else {
40             return $errmsg."<br>\r\n";
41         }
42     }
43
44     /* Validator function for domain (website) */
45     function web_domain($field_name, $field_value, $validator) {
46         if(empty($field_value)) return $this->get_error('domain_error_empty');
47
48         // do not allow wildcards on website domains
49         $result = $this->_regex_validate($field_value);
50         if(!$result) return $this->get_error('domain_error_regex');
51
52         $result = $this->_check_unique($field_value);
53         if(!$result) return $this->get_error('domain_error_unique');
54     }
55
56     /* Validator function for sub domain */
57     function sub_domain($field_name, $field_value, $validator) {
58         if(empty($field_value)) return $this->get_error('domain_error_empty');
59
60         $allow_wildcard = $this->_wildcard_limit();
61         if($allow_wildcard == false && substr($field_value, 0, 2) === '*.') return $this->get_error('domain_error_wildcard');
62
63         $result = $this->_regex_validate($field_value, $allow_wildcard);
64         if(!$result) return $this->get_error('domain_error_regex');
65
66         $result = $this->_check_unique($field_value);
67         if(!$result) return $this->get_error('domain_error_unique');
68     }
69
70     /* Validator function for alias domain */
71     function alias_domain($field_name, $field_value, $validator) {
72         if(empty($field_value)) return $this->get_error('domain_error_empty');
73
74         // do not allow wildcards on alias domains
75         $result = $this->_regex_validate($field_value);
76         if(!$result) return $this->get_error('domain_error_regex');
77
78         $result = $this->_check_unique($field_value);
79         if(!$result) return $this->get_error('domain_error_unique');
80     }
81
82     /* Validator function for checking the auto subdomain of a web/aliasdomain */
83     function web_domain_autosub($field_name, $field_value, $validator) {
84         global $app;
85         if(empty($field_value) || $field_name != 'subdomain') return; // none set
86
87         $check_domain = $_POST['domain'];
88         $app->uses('ini_parser,getconf');
89         $settings = $app->getconf->get_global_config('domains');
90         if ($settings['use_domain_module'] == 'y') {
91             $sql = "SELECT domain_id, domain FROM domain WHERE domain_id = " . $app->functions->intval($check_domain);
92             $domain_check = $app->db->queryOneRecord($sql);
93             if(!$domain_check) return;
94             $check_domain = $domain_check['domain'];
95         }
96
97         $result = $this->_check_unique($field_value . '.' . $check_domain, true);
98         if(!$result) return $this->get_error('domain_error_autosub');
99     }
614b23 100     
TB 101     /* Check apache directives */
102     function web_apache_directives($field_name, $field_value, $validator) {
103         global $app;
104         
105         if(trim($field_value) != '') {
106             $security_config = $app->getconf->get_security_config('ids');
107         
108             if($security_config['apache_directives_scan_enabled'] == 'yes') {
109                 
110                 // Get blacklist
111                 $blacklist_path = '/usr/local/ispconfig/security/apache_directives.blacklist';
112                 if(is_file('/usr/local/ispconfig/security/apache_directives.blacklist.custom')) $blacklist_path = '/usr/local/ispconfig/security/apache_directives.blacklist.custom';
113                 if(!is_file($blacklist_path)) $blacklist_path = realpath(ISPC_ROOT_PATH.'/../security/apache_directives.blacklist');
114                 
115                 $directives = explode("\n",$field_value);
116                 $regex = explode("\n",file_get_contents($blacklist_path));
117                 $blocked = false;
118                 $blocked_line = '';
119                 
120                 if(is_array($directives) && is_array($regex)) {
121                     foreach($directives as $directive) {
122                         $directive = trim($directive);
123                         foreach($regex as $r) {
124                             if(preg_match(trim($r),$directive)) {
125                                 $blocked = true;
1f4d64 126                                 $blocked_line .= $directive.'<br />';
614b23 127                             };
TB 128                         }
129                     }
130                 }
131             }
132         }
133         
134         if($blocked === true) {
135             return $this->get_error('apache_directive_blocked_error').' '.$blocked_line;
136         }
137     }
138     
7fe908 139
MC 140     /* internal validator function to match regexp */
141     function _regex_validate($domain_name, $allow_wildcard = false) {
142         $pattern = '/^' . ($allow_wildcard == true ? '(\*\.)?' : '') . '[\w\.\-]{2,255}\.[a-zA-Z0-9\-]{2,30}$/';
143         return preg_match($pattern, $domain_name);
144     }
145
146     /* check if the domain hostname is unique (keep in mind the auto subdomains!) */
147     function _check_unique($domain_name, $only_domain = false) {
148         global $app, $page;
149
150         if(isset($app->remoting_lib->primary_id)) {
151             $primary_id = $app->remoting_lib->primary_id;
10b4c8 152             $domain = $app->remoting_lib->dataRecord;
7fe908 153         } else {
MC 154             $primary_id = $app->tform->primary_id;
10b4c8 155             $domain = $page->dataRecord;
7fe908 156         }
10b4c8 157
T 158         if($domain['ip_address'] == '' || $domain['ipv6_address'] == ''){
159             if($domain['parent_domain_id'] > 0){
35509d 160                 $parent_domain = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ".$app->functions->intval($domain['parent_domain_id']));
10b4c8 161             }
T 162         }
7fe908 163
10b4c8 164         // check if domain has alias/subdomains - if we move a web to another IP, make sure alias/subdomains are checked as well
0b6b84 165         $aliassubdomains = $app->db->queryAllRecords("SELECT * FROM web_domain WHERE parent_domain_id = ".$app->functions->intval($primary_id)." AND (type = 'alias' OR type = 'subdomain' OR type = 'vhostsubdomain')");
10b4c8 166         $additional_sql1 = '';
T 167         $additional_sql2 = '';
168         if(is_array($aliassubdomains) && !empty($aliassubdomains)){
169             foreach($aliassubdomains as $aliassubdomain){
0b6b84 170                 $additional_sql1 .= " OR d.domain = '".$app->db->quote($aliassubdomain['domain'])."'";
MC 171                 $additional_sql2 .= " OR CONCAT(d.subdomain, '.', d.domain) = '".$app->db->quote($aliassubdomain['domain'])."'";
10b4c8 172             }
T 173         }
f43ef9 174         
0b6b84 175         
31895e 176         $qrystr = "SELECT d.domain_id, IF(d.parent_domain_id != 0 AND p.domain_id IS NOT NULL, p.ip_address, d.ip_address) as `ip_address`, IF(d.parent_domain_id != 0 AND p.domain_id IS NOT NULL, p.ipv6_address, d.ipv6_address) as `ipv6_address` FROM `web_domain` as d LEFT JOIN `web_domain` as p ON (p.domain_id = d.parent_domain_id) WHERE (d.domain = '" . $app->db->quote($domain_name) . "'" . $additional_sql1 . ") AND d.server_id = " . $app->functions->intval($domain['server_id']) . " AND d.domain_id != " . $app->functions->intval($primary_id) . ($primary_id ? " AND d.parent_domain_id != " . $app->functions->intval($primary_id) : "");
0b6b84 177         $checks = $app->db->queryAllRecords($qrystr);
10b4c8 178         if(is_array($checks) && !empty($checks)){
T 179             foreach($checks as $check){
180                 if($domain['ip_address'] == '*') return false;
181                 if($check['ip_address'] == '*') return false;
182                 if($domain['ip_address'] != '' && $check['ip_address'] == $domain['ip_address']) return false;
183                 if($domain['ipv6_address'] != '' && $check['ipv6_address'] == $domain['ipv6_address']) return false;
184             }
185         }
0b6b84 186         
7fe908 187         if($only_domain == false) {
31895e 188             $qrystr = "SELECT d.domain_id, IF(d.parent_domain_id != 0 AND p.domain_id IS NOT NULL, p.ip_address, d.ip_address) as `ip_address`, IF(d.parent_domain_id != 0 AND p.domain_id IS NOT NULL, p.ipv6_address, d.ipv6_address) as `ipv6_address` FROM `web_domain` as d LEFT JOIN `web_domain` as p ON (p.domain_id = d.parent_domain_id) WHERE (CONCAT(d.subdomain, '.', d.domain)= '" . $app->db->quote($domain_name) . "'" . $additional_sql2 . ") AND d.server_id = " . $app->functions->intval($domain['server_id']) . " AND d.domain_id != " . $app->functions->intval($primary_id) . ($primary_id ? " AND d.parent_domain_id != " . $app->functions->intval($primary_id) : "");
0b6b84 189             $checks = $app->db->queryAllRecords($qrystr);
10b4c8 190             if(is_array($checks) && !empty($checks)){
T 191                 foreach($checks as $check){
192                     if($domain['ip_address'] == '*') return false;
193                     if($check['ip_address'] == '*') return false;
194                     if($domain['ip_address'] != '' && $check['ip_address'] == $domain['ip_address']) return false;
195                     if($domain['ipv6_address'] != '' && $check['ipv6_address'] == $domain['ipv6_address']) return false;
196                 }
197             }
7fe908 198         }
0b6b84 199         
7fe908 200         return true;
MC 201     }
202
203     /* check if the client may add wildcard domains */
204     function _wildcard_limit() {
205         global $app;
206
207         if($_SESSION["s"]["user"]["typ"] != 'admin') {
208             // Get the limits of the client
35509d 209             $client_group_id = $app->functions->intval($_SESSION["s"]["user"]["default_group"]);
7fe908 210             $client = $app->db->queryOneRecord("SELECT limit_wildcard FROM sys_group, client WHERE sys_group.client_id = client.client_id and sys_group.groupid = $client_group_id");
MC 211
212             if($client["limit_wildcard"] == 'y') return true;
213             else return false;
214         }
215         return true; // admin may always add wildcard domain
216     }
614b23 217     
7fe908 218
MC 219 }