Pascal Dreissen
2016-07-05 fbfdc438eaf2a70d5fefda74c919edc76e82d0fd
commit | author | age
532ae5 1 <?php
L 2
3 /*
4 Copyright (c) 2010, Till Brehm, projektfarm Gmbh
5 All rights reserved.
6
7 Redistribution and use in source and binary forms, with or without modification,
8 are permitted provided that the following conditions are met:
9
10     * Redistributions of source code must retain the above copyright notice,
11       this list of conditions and the following disclaimer.
12     * Redistributions in binary form must reproduce the above copyright notice,
13       this list of conditions and the following disclaimer in the documentation
14       and/or other materials provided with the distribution.
15     * Neither the name of ISPConfig nor the names of its contributors
16       may be used to endorse or promote products derived from this software without
17       specific prior written permission.
18
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
23 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
26 OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
28 EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 //* The purpose of this library is to provide some general functions.
32 //* This class is loaded automatically by the ispconfig framework.
33
34 class functions {
8c1761 35     var $idn_converter = null;
b1a6a5 36     var $idn_converter_name = '';
532ae5 37
120cce 38     public function mail($to, $subject, $text, $from, $filepath = '', $filetype = 'application/pdf', $filename = '', $cc = '', $bcc = '', $from_name = '') {
b1a6a5 39         global $app, $conf;
MC 40
532ae5 41         if($conf['demo_mode'] == true) $app->error("Mail sending disabled in demo mode.");
b1a6a5 42
MC 43         $app->uses('getconf,ispcmail');
a59498 44         $mail_config = $app->getconf->get_global_config('mail');
M 45         if($mail_config['smtp_enabled'] == 'y') {
46             $mail_config['use_smtp'] = true;
47             $app->ispcmail->setOptions($mail_config);
48         }
120cce 49         $app->ispcmail->setSender($from, $from_name);
a59498 50         $app->ispcmail->setSubject($subject);
M 51         $app->ispcmail->setMailText($text);
b1a6a5 52
a59498 53         if($filepath != '') {
M 54             if(!file_exists($filepath)) $app->error("Mail attachement does not exist ".$filepath);
55             $app->ispcmail->readAttachFile($filepath);
56         }
b1a6a5 57
a59498 58         if($cc != '') $app->ispcmail->setHeader('Cc', $cc);
M 59         if($bcc != '') $app->ispcmail->setHeader('Bcc', $bcc);
b1a6a5 60
a59498 61         $app->ispcmail->send($to);
M 62         $app->ispcmail->finish();
b1a6a5 63
532ae5 64         return true;
L 65     }
b1a6a5 66
MC 67     public function array_merge($array1, $array2) {
532ae5 68         $out = $array1;
L 69         foreach($array2 as $key => $val) {
70             $out[$key] = $val;
71         }
72         return $out;
73     }
b1a6a5 74
36d487 75     public function currency_format($number, $view = '') {
532ae5 76         global $app;
36d487 77         if($view != '') $number_format_decimals = (int)$app->lng('number_format_decimals_'.$view);
b1a6a5 78         if(!$number_format_decimals) $number_format_decimals = (int)$app->lng('number_format_decimals');
MC 79
532ae5 80         $number_format_dec_point = $app->lng('number_format_dec_point');
L 81         $number_format_thousands_sep = $app->lng('number_format_thousands_sep');
82         if($number_format_thousands_sep == 'number_format_thousands_sep') $number_format_thousands_sep = '';
83         return number_format((double)$number, $number_format_decimals, $number_format_dec_point, $number_format_thousands_sep);
84     }
b1a6a5 85
2d2fd1 86     //* convert currency formatted number back to floating number
FT 87     public function currency_unformat($number) {
88         global $app;
b1a6a5 89
2d2fd1 90         $number_format_dec_point = $app->lng('number_format_dec_point');
FT 91         $number_format_thousands_sep = $app->lng('number_format_thousands_sep');
92         if($number_format_thousands_sep == 'number_format_thousands_sep') $number_format_thousands_sep = '';
b1a6a5 93
2d2fd1 94         if($number_format_thousands_sep != '') $number = str_replace($number_format_thousands_sep, '', $number);
FT 95         if($number_format_dec_point != '.' && $number_format_dec_point != '') $number = str_replace($number_format_dec_point, '.', $number);
b1a6a5 96
2d2fd1 97         return (double)$number;
FT 98     }
b1a6a5 99
532ae5 100     public function get_ispconfig_url() {
615a0a 101         global $app;
b1a6a5 102
MC 103         $url = (stristr($_SERVER['SERVER_PROTOCOL'], 'HTTPS') || stristr($_SERVER['HTTPS'], 'on'))?'https':'http';
615a0a 104         if($_SERVER['SERVER_NAME'] != '_') {
T 105             $url .= '://'.$_SERVER['SERVER_NAME'];
106             if($_SERVER['SERVER_PORT'] != 80 && $_SERVER['SERVER_PORT'] != 443) {
107                 $url .= ':'.$_SERVER['SERVER_PORT'];
108             }
109         } else {
110             $app->uses("getconf");
b1a6a5 111             $server_config = $app->getconf->get_server_config(1, 'server');
615a0a 112             $url .= '://'.$server_config['hostname'];
T 113             if($_SERVER['SERVER_PORT'] != 80 && $_SERVER['SERVER_PORT'] != 443) {
114                 $url .= ':'.$_SERVER['SERVER_PORT'];
115             }
532ae5 116         }
L 117         return $url;
118     }
b1a6a5 119
MC 120     public function json_encode($data) {
4c28d9 121         if(!function_exists('json_encode')){
221340 122             if(is_array($data) || is_object($data)){
b1a6a5 123                 $islist = is_array($data) && (empty($data) || array_keys($data) === range(0, count($data)-1));
221340 124
F 125                 if($islist){
126                     $json = '[' . implode(',', array_map(array($this, "json_encode"), $data) ) . ']';
127                 } else {
b1a6a5 128                     $items = array();
221340 129                     foreach( $data as $key => $value ) {
F 130                         $items[] = $this->json_encode("$key") . ':' . $this->json_encode($value);
4c28d9 131                     }
221340 132                     $json = '{' . implode(',', $items) . '}';
F 133                 }
134             } elseif(is_string($data)){
b1a6a5 135                 // Escape non-printable or Non-ASCII characters.
MC 136                 // I also put the \\ character first, as suggested in comments on the 'addclashes' page.
221340 137                 $string = '"'.addcslashes($data, "\\\"\n\r\t/".chr(8).chr(12)).'"';
F 138                 $json = '';
139                 $len = strlen($string);
b1a6a5 140                 // Convert UTF-8 to Hexadecimal Codepoints.
221340 141                 for($i = 0; $i < $len; $i++){
F 142                     $char = $string[$i];
143                     $c1 = ord($char);
144
b1a6a5 145                     // Single byte;
221340 146                     if($c1 <128){
F 147                         $json .= ($c1 > 31) ? $char : sprintf("\\u%04x", $c1);
148                         continue;
4c28d9 149                     }
221340 150
b1a6a5 151                     // Double byte
221340 152                     $c2 = ord($string[++$i]);
F 153                     if(($c1 & 32) === 0){
154                         $json .= sprintf("\\u%04x", ($c1 - 192) * 64 + $c2 - 128);
155                         continue;
156                     }
157
b1a6a5 158                     // Triple
221340 159                     $c3 = ord($string[++$i]);
F 160                     if(($c1 & 16) === 0){
161                         $json .= sprintf("\\u%04x", (($c1 - 224) <<12) + (($c2 - 128) << 6) + ($c3 - 128));
162                         continue;
163                     }
164
b1a6a5 165                     // Quadruple
221340 166                     $c4 = ord($string[++$i]);
F 167                     if(($c1 & 8) === 0){
168                         $u = (($c1 & 15) << 2) + (($c2>>4) & 3) - 1;
169
170                         $w1 = (54<<10) + ($u<<6) + (($c2 & 15) << 2) + (($c3>>4) & 3);
171                         $w2 = (55<<10) + (($c3 & 15)<<6) + ($c4-128);
172                         $json .= sprintf("\\u%04x\\u%04x", $w1, $w2);
173                     }
174                 }
175             } else {
b1a6a5 176                 // int, floats, bools, null
221340 177                 $json = strtolower(var_export($data, true));
4c28d9 178             }
221340 179             return $json;
4c28d9 180         } else {
F 181             return json_encode($data);
182         }
b1a6a5 183     }
MC 184
5672cd 185     public function suggest_ips($type = 'IPv4'){
F 186         global $app;
b1a6a5 187
5672cd 188         if($type == 'IPv4'){
2df8c0 189 //            $regex = "/^[0-9]{1,3}(\.)[0-9]{1,3}(\.)[0-9]{1,3}(\.)[0-9]{1,3}$/";
FS 190             $regex = "/^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/";
5672cd 191         } else {
F 192             // IPv6
fbfdc4 193             $regex = "/(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))/";
5672cd 194         }
b1a6a5 195
391e05 196         $server_by_id = array();
FT 197         $server_by_ip = array();
198         $servers = $app->db->queryAllRecords("SELECT * FROM server");
199         if(is_array($servers) && !empty($servers)){
200             foreach($servers as $server){
201                 $server_by_id[$server['server_id']] = $server['server_name'];
202             }
203         }
b1a6a5 204
5672cd 205         $ips = array();
cc7a82 206         $results = $app->db->queryAllRecords("SELECT ip_address AS ip, server_id FROM server_ip WHERE ip_type = ?", $type);
5672cd 207         if(!empty($results) && is_array($results)){
F 208             foreach($results as $result){
391e05 209                 if(preg_match($regex, $result['ip'])){
FT 210                     $ips[] = $result['ip'];
211                     $server_by_ip[$result['ip']] = $server_by_id[$result['server_id']];
212                 }
5672cd 213             }
F 214         }
215         $results = $app->db->queryAllRecords("SELECT ip_address AS ip FROM openvz_ip");
216         if(!empty($results) && is_array($results)){
217             foreach($results as $result){
218                 if(preg_match($regex, $result['ip'])) $ips[] = $result['ip'];
219             }
220         }
221         $results = $app->db->queryAllRecords("SELECT data AS ip FROM dns_rr WHERE type = 'A' OR type = 'AAAA'");
222         if(!empty($results) && is_array($results)){
223             foreach($results as $result){
224                 if(preg_match($regex, $result['ip'])) $ips[] = $result['ip'];
225             }
226         }
227         $results = $app->db->queryAllRecords("SELECT ns AS ip FROM dns_slave");
228         if(!empty($results) && is_array($results)){
229             foreach($results as $result){
230                 if(preg_match($regex, $result['ip'])) $ips[] = $result['ip'];
231             }
232         }
374e5a 233         
5672cd 234         $results = $app->db->queryAllRecords("SELECT remote_ips FROM web_database WHERE remote_ips != ''");
F 235         if(!empty($results) && is_array($results)){
236             foreach($results as $result){
237                 $tmp_ips = explode(',', $result['remote_ips']);
238                 foreach($tmp_ips as $tmp_ip){
239                     $tmp_ip = trim($tmp_ip);
240                     if(preg_match($regex, $tmp_ip)) $ips[] = $tmp_ip;
241                 }
242             }
243         }
244         $ips = array_unique($ips);
245         sort($ips, SORT_NUMERIC);
246
247         $result_array = array('cheader' => array(), 'cdata' => array());
b1a6a5 248
5672cd 249         if(!empty($ips)){
F 250             $result_array['cheader'] = array('title' => 'IPs',
b1a6a5 251                 'total' => count($ips),
MC 252                 'limit' => count($ips)
253             );
254
5672cd 255             foreach($ips as $ip){
b1a6a5 256                 $result_array['cdata'][] = array( 'title' => $ip,
MC 257                     'description' => $type.($server_by_ip[$ip] != ''? ' &gt; '.$server_by_ip[$ip] : ''),
258                     'onclick' => '',
259                     'fill_text' => $ip
260                 );
5672cd 261             }
F 262         }
b1a6a5 263
5672cd 264         return $result_array;
F 265     }
4c28d9 266
b1a6a5 267     public function intval($string, $force_numeric = false) {
MC 268         if(intval($string) == 2147483647 || ($string > 0 && intval($string) < 0)) {
269             if($force_numeric == true) return floatval($string);
270             elseif(preg_match('/^([-]?)[0]*([1-9][0-9]*)([^0-9].*)*$/', $string, $match)) return $match[1].$match[2];
271             else return 0;
272         } else {
273             return intval($string);
274         }
275     }
71accc 276
b1a6a5 277     /**
MC 278      * Function to change bytes to kB, MB, GB or TB
279      * @param int $size - size in bytes
280      * @param int precicion - after-comma-numbers (default: 2)
281      * @return string - formated bytes
282      */
283     public function formatBytes($size, $precision = 2) {
284         $base=log($size)/log(1024);
5561eb 285         $suffixes=array('', ' kB', ' MB', ' GB', ' TB');
b1a6a5 286         return round(pow(1024, $base-floor($base)), $precision).$suffixes[floor($base)];
MC 287     }
288
289     /** IDN converter wrapper.
290      * all converter classes should be placed in ISPC_CLASS_PATH.'/idn/'
291      */
292     private function _idn_encode_decode($domain, $encode = true) {
293         if($domain == '') return '';
294         if(preg_match('/^[0-9\.]+$/', $domain)) return $domain; // may be an ip address - anyway does not need to bee encoded
295
296         // get domain and user part if it is an email
297         $user_part = false;
298         if(strpos($domain, '@') !== false) {
299             $user_part = substr($domain, 0, strrpos($domain, '@'));
300             $domain = substr($domain, strrpos($domain, '@') + 1);
301         }
302
303         if($encode == true) {
304             if(function_exists('idn_to_ascii')) {
e9d5c9 305                 $domain = idn_to_ascii($domain, IDNA_NONTRANSITIONAL_TO_ASCII, INTL_IDNA_VARIANT_UTS46);
b1a6a5 306             } elseif(file_exists(ISPC_CLASS_PATH.'/idn/idna_convert.class.php')) {
MC 307                 /* use idna class:
d6363b 308                  * @author  Matthias Sommerfeld <mso@phlylabs.de>
M 309                  * @copyright 2004-2011 phlyLabs Berlin, http://phlylabs.de
310                  * @version 0.8.0 2011-03-11
311                  */
b1a6a5 312
MC 313                 if(!is_object($this->idn_converter) || $this->idn_converter_name != 'idna_convert.class') {
314                     include_once ISPC_CLASS_PATH.'/idn/idna_convert.class.php';
315                     $this->idn_converter = new idna_convert(array('idn_version' => 2008));
316                     $this->idn_converter_name = 'idna_convert.class';
317                 }
318                 $domain = $this->idn_converter->encode($domain);
319             }
320         } else {
321             if(function_exists('idn_to_utf8')) {
e9d5c9 322                 $domain = idn_to_utf8($domain, IDNA_NONTRANSITIONAL_TO_ASCII, INTL_IDNA_VARIANT_UTS46);
b1a6a5 323             } elseif(file_exists(ISPC_CLASS_PATH.'/idn/idna_convert.class.php')) {
MC 324                 /* use idna class:
d6363b 325                  * @author  Matthias Sommerfeld <mso@phlylabs.de>
M 326                  * @copyright 2004-2011 phlyLabs Berlin, http://phlylabs.de
327                  * @version 0.8.0 2011-03-11
328                  */
b1a6a5 329
MC 330                 if(!is_object($this->idn_converter) || $this->idn_converter_name != 'idna_convert.class') {
331                     include_once ISPC_CLASS_PATH.'/idn/idna_convert.class.php';
332                     $this->idn_converter = new idna_convert(array('idn_version' => 2008));
333                     $this->idn_converter_name = 'idna_convert.class';
334                 }
335                 $domain = $this->idn_converter->decode($domain);
336             }
337         }
338
339         if($user_part !== false) return $user_part . '@' . $domain;
340         else return $domain;
341     }
342
343     public function idn_encode($domain) {
344         $domains = explode("\n", $domain);
345         for($d = 0; $d < count($domains); $d++) {
346             $domains[$d] = $this->_idn_encode_decode($domains[$d], true);
347         }
348         return implode("\n", $domains);
349     }
350
351     public function idn_decode($domain) {
352         $domains = explode("\n", $domain);
353         for($d = 0; $d < count($domains); $d++) {
354             $domains[$d] = $this->_idn_encode_decode($domains[$d], false);
355         }
356         return implode("\n", $domains);
357     }
358
64ea56 359     public function is_allowed_user($username, $restrict_names = false) {
MC 360         global $app;
361         
f2fc77 362         $name_blacklist = array('root','ispconfig','vmail','getmail');
TB 363         if(in_array($username,$name_blacklist)) return false;
364         
373e88 365         if(preg_match('/^[a-zA-Z0-9\.\-_]{1,32}$/', $username) == false) return false;
f2fc77 366         
64ea56 367         if($restrict_names == true && preg_match('/^web\d+$/', $username) == false) return false;
MC 368         
369         return true;
370     }
371     
372     public function is_allowed_group($groupname, $restrict_names = false) {
373         global $app;
374         
f2fc77 375         $name_blacklist = array('root','ispconfig','vmail','getmail');
TB 376         if(in_array($groupname,$name_blacklist)) return false;
377         
373e88 378         if(preg_match('/^[a-zA-Z0-9\.\-_]{1,32}$/', $groupname) == false) return false;
f2fc77 379         
64ea56 380         if($restrict_names == true && preg_match('/^client\d+$/', $groupname) == false) return false;
MC 381         
382         return true;
383     }
61f1f5 384     
MC 385     public function getimagesizefromstring($string){
386         if (!function_exists('getimagesizefromstring')) {
387             $uri = 'data://application/octet-stream;base64,' . base64_encode($string);
388             return getimagesize($uri);
389         } else {
390             return getimagesizefromstring($string);
391         }        
392     }
d22277 393     
MB 394     public function password($minLength = 10, $special = false){
395         global $app;
396     
397         $iteration = 0;
398         $password = "";
399         $maxLength = $minLength + 5;
400         $length = $this->getRandomInt($minLength, $maxLength);
401
402         while($iteration < $length){
403             $randomNumber = (floor(((mt_rand() / mt_getrandmax()) * 100)) % 94) + 33;
404             if(!$special){
405                 if (($randomNumber >=33) && ($randomNumber <=47)) { continue; }
406                 if (($randomNumber >=58) && ($randomNumber <=64)) { continue; }
407                 if (($randomNumber >=91) && ($randomNumber <=96)) { continue; }
408                 if (($randomNumber >=123) && ($randomNumber <=126)) { continue; }
409             }
410             $iteration++;
411             $password .= chr($randomNumber);
412         }
413         $app->uses('validate_password');
414         if($app->validate_password->password_check('', $password, '') !== false) $password = $this->password($minLength, $special);
415         return $password;
416     }
417
418     public function getRandomInt($min, $max){
419         return floor((mt_rand() / mt_getrandmax()) * ($max - $min + 1)) + $min;
420     }
421     
422     public function generate_customer_no(){
423         global $app;
424         // generate customer no.
425         $customer_no = mt_rand(100000, 999999);
18093f 426         while($app->db->queryOneRecord("SELECT client_id FROM client WHERE customer_no = ?", $customer_no)) {
d22277 427             $customer_no = mt_rand(100000, 999999);
MB 428         }
429         
430         return $customer_no;
431     }
532ae5 432 }
L 433
71accc 434 ?>