Marius Burkard
2016-04-20 4569cae57f127afd093794310ccd290d2d9fdf36
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
dc8979 87         if(isset($app->remoting_lib->primary_id)) {
TB 88             $check_domain = $app->remoting_lib->dataRecord['domain'];
89         } else {
90             $check_domain = $_POST['domain'];
91         }
92         
7fe908 93         $app->uses('ini_parser,getconf');
MC 94         $settings = $app->getconf->get_global_config('domains');
95         if ($settings['use_domain_module'] == 'y') {
cc7a82 96             $sql = "SELECT domain_id, domain FROM domain WHERE domain_id = ?";
MC 97             $domain_check = $app->db->queryOneRecord($sql, $check_domain);
7fe908 98             if(!$domain_check) return;
MC 99             $check_domain = $domain_check['domain'];
100         }
101
102         $result = $this->_check_unique($field_value . '.' . $check_domain, true);
103         if(!$result) return $this->get_error('domain_error_autosub');
104     }
614b23 105     
TB 106     /* Check apache directives */
107     function web_apache_directives($field_name, $field_value, $validator) {
108         global $app;
109         
110         if(trim($field_value) != '') {
111             $security_config = $app->getconf->get_security_config('ids');
112         
113             if($security_config['apache_directives_scan_enabled'] == 'yes') {
114                 
115                 // Get blacklist
116                 $blacklist_path = '/usr/local/ispconfig/security/apache_directives.blacklist';
117                 if(is_file('/usr/local/ispconfig/security/apache_directives.blacklist.custom')) $blacklist_path = '/usr/local/ispconfig/security/apache_directives.blacklist.custom';
118                 if(!is_file($blacklist_path)) $blacklist_path = realpath(ISPC_ROOT_PATH.'/../security/apache_directives.blacklist');
119                 
120                 $directives = explode("\n",$field_value);
121                 $regex = explode("\n",file_get_contents($blacklist_path));
122                 $blocked = false;
123                 $blocked_line = '';
124                 
125                 if(is_array($directives) && is_array($regex)) {
126                     foreach($directives as $directive) {
127                         $directive = trim($directive);
128                         foreach($regex as $r) {
129                             if(preg_match(trim($r),$directive)) {
130                                 $blocked = true;
1f4d64 131                                 $blocked_line .= $directive.'<br />';
614b23 132                             };
TB 133                         }
134                     }
135                 }
136             }
137         }
138         
139         if($blocked === true) {
140             return $this->get_error('apache_directive_blocked_error').' '.$blocked_line;
141         }
142     }
143     
7fe908 144
MC 145     /* internal validator function to match regexp */
146     function _regex_validate($domain_name, $allow_wildcard = false) {
147         $pattern = '/^' . ($allow_wildcard == true ? '(\*\.)?' : '') . '[\w\.\-]{2,255}\.[a-zA-Z0-9\-]{2,30}$/';
148         return preg_match($pattern, $domain_name);
149     }
150
151     /* check if the domain hostname is unique (keep in mind the auto subdomains!) */
152     function _check_unique($domain_name, $only_domain = false) {
153         global $app, $page;
154
155         if(isset($app->remoting_lib->primary_id)) {
156             $primary_id = $app->remoting_lib->primary_id;
10b4c8 157             $domain = $app->remoting_lib->dataRecord;
7fe908 158         } else {
MC 159             $primary_id = $app->tform->primary_id;
10b4c8 160             $domain = $page->dataRecord;
7fe908 161         }
10b4c8 162
T 163         if($domain['ip_address'] == '' || $domain['ipv6_address'] == ''){
164             if($domain['parent_domain_id'] > 0){
cc7a82 165                 $parent_domain = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ?", $domain['parent_domain_id']);
a52337 166                 if(is_array($parent_domain) && !empty($parent_domain)){
MC 167                     $domain['ip_address'] = $parent_domain['ip_address'];
168                     $domain['ipv6_address'] = $parent_domain['ipv6_address'];
169                 }
10b4c8 170             }
T 171         }
7fe908 172
10b4c8 173         // check if domain has alias/subdomains - if we move a web to another IP, make sure alias/subdomains are checked as well
cc7a82 174         $aliassubdomains = $app->db->queryAllRecords("SELECT * FROM web_domain WHERE parent_domain_id = ? AND (type = 'alias' OR type = 'subdomain' OR type = 'vhostsubdomain')", $primary_id);
10b4c8 175         $additional_sql1 = '';
T 176         $additional_sql2 = '';
cc7a82 177         $domain_params = array();
10b4c8 178         if(is_array($aliassubdomains) && !empty($aliassubdomains)){
T 179             foreach($aliassubdomains as $aliassubdomain){
cc7a82 180                 $additional_sql1 .= " OR d.domain = ?";
MC 181                 $additional_sql2 .= " OR CONCAT(d.subdomain, '.', d.domain) = ?";
182                 $domain_params[] = $aliassubdomain['domain'];
10b4c8 183             }
T 184         }
f43ef9 185         
0b6b84 186         
cc7a82 187         $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 = ?" . $additional_sql1 . ") AND d.server_id = ? AND d.domain_id != ?" . ($primary_id ? " AND d.parent_domain_id != ?" : "");
8ae138 188         $params = array_merge(array($domain_name), $domain_params, array($domain['server_id'], $primary_id, $primary_id));
cc7a82 189         $checks = $app->db->queryAllRecords($qrystr, true, $params);
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         }
0b6b84 198         
7fe908 199         if($only_domain == false) {
8ae138 200             $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) = ?" . $additional_sql2 . ") AND d.server_id = ? AND d.domain_id != ?" . ($primary_id ? " AND d.parent_domain_id != ?" : "");
MC 201             $params = array_merge(array($domain_name), $domain_params, array($domain['server_id'], $primary_id, $primary_id));
a6e3ae 202             $checks = $app->db->queryAllRecords($qrystr, true, $params);
10b4c8 203             if(is_array($checks) && !empty($checks)){
T 204                 foreach($checks as $check){
205                     if($domain['ip_address'] == '*') return false;
206                     if($check['ip_address'] == '*') return false;
207                     if($domain['ip_address'] != '' && $check['ip_address'] == $domain['ip_address']) return false;
208                     if($domain['ipv6_address'] != '' && $check['ipv6_address'] == $domain['ipv6_address']) return false;
209                 }
210             }
7fe908 211         }
0b6b84 212         
7fe908 213         return true;
MC 214     }
215
216     /* check if the client may add wildcard domains */
217     function _wildcard_limit() {
218         global $app;
219
220         if($_SESSION["s"]["user"]["typ"] != 'admin') {
221             // Get the limits of the client
35509d 222             $client_group_id = $app->functions->intval($_SESSION["s"]["user"]["default_group"]);
cc7a82 223             $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);
7fe908 224
MC 225             if($client["limit_wildcard"] == 'y') return true;
226             else return false;
227         }
228         return true; // admin may always add wildcard domain
229     }
614b23 230     
7fe908 231
MC 232 }