inc/base.php
defbfa55
 <?php
c208bd90
 /*
 This file belongs to the Webinterface of schokokeks.org Hosting
 
cf54502a
 Written 2008-2018 by schokokeks.org Hosting, namely
c208bd90
   Bernd Wurst <bernd@schokokeks.org>
   Hanno Böck <hanno@schokokeks.org>
 
 To the extent possible under law, the author(s) have dedicated all copyright and related and neighboring rights to this software to the public domain worldwide. This software is distributed without any warranty.
 
2626dd47
 You should have received a copy of the CC0 Public Domain Dedication along with this software. If not, see
c208bd90
 http://creativecommons.org/publicdomain/zero/1.0/
 
 Nevertheless, in case you use a significant part of this code, we ask (but not require, see the license) that you keep the authors' names in place and return your changes to the public. We would be especially happy if you tell us what you're going to do with this code.
 */
defbfa55
 
f1f231f5
 require_once('class/database.php');
a1bdbea8
 require_once('inc/debug.php');
27f758e4
 
f53efe18
 function config($key, $localonly = false)
d96a86aa
 {
2626dd47
     global $config;
 
     if ($key == "modules") {
         // Stelle sicher, dass das "index"-Modul immer aktiv ist!
         if (! in_array("index", $config['modules'])) {
             $config['modules'][] = "index";
         }
         // Stelle sicher, dass das "about"-Modul immer aktiv ist!
         if (! in_array("about", $config['modules'])) {
             $config['modules'][] = "about";
         }
5effc2bd
     }
 
2626dd47
     if ($key == 'modules' && isset($_SESSION['restrict_modules'])) {
         $modules = array();
         foreach ($config['modules'] as $mod) {
             if (in_array($mod, $_SESSION['restrict_modules'])) {
                 $modules[] = $mod;
             }
         }
         return $modules;
ff0f9b9b
     }
 
2626dd47
     if (array_key_exists($key, $config)) {
         return $config[$key];
     }
9086c9ad
 
2626dd47
     if ($localonly) {
         return null;
     }
f53efe18
 
2626dd47
     /* read configuration from database */
     $result = db_query("SELECT `key`, value FROM misc.config");
9086c9ad
 
2626dd47
     while ($object = $result->fetch()) {
         if (!array_key_exists($object['key'], $config)) {
             $config[$object['key']]=$object['value'];
         }
     }
     // Sonst wird das Passwort des webadmin-Users mit ausgegeben
     $debug_config = $config;
     unset($debug_config['db_pass']);
     DEBUG($debug_config);
     if (array_key_exists($key, $config)) {
         return $config[$key];
     } else {
         logger(LOG_ERR, "inc/base", "config", "Request to read nonexistant config option »{$key}«.");
     }
     return null;
d96a86aa
 }
 
2626dd47
 function have_role($role)
 {
29c4531a
     $have = $_SESSION['role'] & $role;
     if ($have) {
         DEBUG("Current user has role ".$role);
     } else {
         DEBUG("Current user does not have role ".$role);
     }
     return $have;
 }
 
2626dd47
 function get_server_by_id($id)
 {
     $id = (int) $id;
     $result = db_query("SELECT hostname FROM system.servers WHERE id=?", array($id));
     $ret = $result->fetch();
     return $ret['hostname'];
8561dcc4
 }
 
d96a86aa
 
a1bdbea8
 function redirect($target)
 {
2626dd47
     global $debugmode;
     if ($target == '') {
         $target = $_SERVER['REQUEST_URI'];
     }
     if (! $debugmode) {
         header("Location: {$target}");
     } else {
         if (strpos($target, '?') === false) {
             print 'REDIRECT: '.internal_link($target, $target);
         } else {
             list($file, $qs) = explode('?', $target, 2);
             print 'REDIRECT: '.internal_link($file, $target, $qs);
         }
     }
     die();
a1bdbea8
 }
 
 
978a7d07
 function my_server_id()
 {
2626dd47
     $uid = (int) $_SESSION['userinfo']['uid'];
     $result = db_query("SELECT server FROM system.useraccounts WHERE uid=?", array($uid));
     $r = $result->fetch();
     DEBUG($r);
     return $r['server'];
978a7d07
 }
 
 
 function additional_servers()
 {
2626dd47
     $uid = (int) $_SESSION['userinfo']['uid'];
     $result = db_query("SELECT server FROM system.user_server WHERE uid=?", array($uid));
     $servers = array();
     while ($s = $result->fetch()) {
         $servers[] = $s['server'];
     }
     DEBUG($servers);
     return $servers;
978a7d07
 }
 
 
 function server_names()
 {
2626dd47
     $result = db_query("SELECT id, hostname FROM system.servers");
     $servers = array();
     while ($s = $result->fetch()) {
         $servers[$s['id']] = $s['hostname'];
     }
     DEBUG($servers);
     return $servers;
978a7d07
 }
 
 
0d1b7607
 function maybe_null($value)
 {
2626dd47
     if (! $value) {
         return null;
     }
771febac
 
2626dd47
     if (strlen((string) $value) > 0) {
         return (string) $value;
     } else {
         return null;
     }
0d1b7607
 }
 
f1f231f5
 
3048f62f
 #define('LOG_ERR', 3);
 #define('LOG_WARNING', 4);
 #define('LOG_INFO', 6);
0d1b7607
 
3048f62f
 function logger($severity, $scriptname, $scope, $message)
fb92f399
 {
2626dd47
     if (config('logging') < $severity) {
         DEBUG("NOT LOGGING $scriptname:$scope:$message");
         return;
     }
 
     DEBUG("LOGGING $scriptname:$scope:$message");
     $user = null;
     if (array_key_exists("role", $_SESSION)) {
         if ($_SESSION['role'] & ROLE_SYSTEMUSER) {
             $user = $_SESSION['userinfo']['username'];
         } elseif ($_SESSION['role'] & ROLE_CUSTOMER) {
             $user = $_SESSION['customerinfo']['customerno'];
         }
     }
 
     $args = array(":user" => $user,
8132c40e
                 ":remote" => $_SERVER['REMOTE_ADDR'],
                 ":scriptname" => $scriptname,
                 ":scope" => $scope,
                 ":message" => $message);
fb92f399
 
2626dd47
     db_query("INSERT INTO misc.scriptlog (remote, user,scriptname,scope,message) VALUES (:remote, :user, :scriptname, :scope, :message)", $args);
fb92f399
 }
 
ede58dec
 function html_header($arg)
 {
2626dd47
     global $html_header;
     $html_header .= $arg;
ede58dec
 }
fb92f399
 
d73051da
 function title($arg)
 {
2626dd47
     global $title;
     $title = $arg;
d73051da
 }
 
 function headline($arg)
 {
2626dd47
     global $headline;
     $headline = $arg;
d73051da
 }
 
defbfa55
 function output($arg)
 {
2626dd47
     global $output;
     $output .= $arg;
defbfa55
 }
 
d189d815
 function footnote($explaination)
 {
     global $footnotes;
     if (!isset($footnotes) || !is_array($footnotes)) {
         $footnotes = array();
     }
     $fnid = array_search($explaination, $footnotes);
59b12098
     DEBUG($footnotes);
2626dd47
     if ($fnid === false) {
59b12098
         DEBUG("Footnote »{$explaination}« is not in footnotes!");
d189d815
         $footnotes[] = $explaination;
     }
     $fnid = array_search($explaination, $footnotes);
     return str_repeat('*', ($fnid+1));
 }
defbfa55
 
2626dd47
 function random_string($len)
5a11bf46
 {
2626dd47
     $s = str_replace('+', '.', base64_encode(random_bytes(ceil($len*3/4))));
     return substr($s, 0, $len);
5a11bf46
 }
defbfa55
 
 
 function are_you_sure($query_string, $question)
 {
2626dd47
     $query_string = encode_querystring($query_string);
     $token = random_string(20);
     $_SESSION['are_you_sure_token'] = $token;
     title('Sicherheitsabfrage');
     output("
d5f2f3f4
     <form action=\"{$query_string}\" method=\"post\">
33986238
     <div class=\"confirmation\">
       <div class=\"question\">{$question}</div>
       <p class=\"buttons\">
         <input type=\"hidden\" name=\"random_token\" value=\"{$token}\" />
         <input type=\"submit\" name=\"really\" value=\"Ja\" />
ec0c81a8
         &#160; &#160;
33986238
         <input type=\"submit\" name=\"not_really\" value=\"Nein\" />
       </p>
     </div>");
2626dd47
     output("</form>\n");
defbfa55
 }
 
 
 function user_is_sure()
 {
2626dd47
     if (isset($_POST['really'])) {
         if ($_POST['random_token'] == $_SESSION['are_you_sure_token']) {
             return true;
         } else {
             system_failure("Possible Cross-site-request-forgery detected!");
         }
     } elseif (isset($_POST['not_really'])) {
         return false;
     } else {
         return null;
     }
defbfa55
 }
 
 
 
74a5d992
 function generate_form_token($form_id)
 {
2626dd47
     require_once("inc/debug.php");
     $sessid = session_id();
     if ($sessid == "") {
         DEBUG("Uh? Session not running? Wtf?");
         system_failure("Internal error!");
     }
     if (! isset($_SESSION['session_token'])) {
         $_SESSION['session_token'] = random_string(10);
     }
     return hash('sha256', $sessid.$form_id.$_SESSION['session_token']);
74a5d992
 }
 
 
2626dd47
 function check_form_token($form_id, $formtoken = null)
74a5d992
 {
2626dd47
     if ($formtoken == null) {
         $formtoken = $_REQUEST['formtoken'];
     }
     $sessid = session_id();
     if ($sessid == "") {
         DEBUG("Uh? Session not running? Wtf?");
         system_failure("Internal error! (Session not running)");
     }
 
     $correct_formtoken = hash('sha256', $sessid.$form_id.$_SESSION['session_token']);
 
     if (! ($formtoken == $correct_formtoken)) {
         system_failure("Possible cross-site-request-forgery!");
     }
74a5d992
 }
 
dcee94d9
 
3d979297
 function have_module($modname)
 {
2626dd47
     return in_array($modname, config('modules'));
3d979297
 }
 
 
2626dd47
 function use_module($modname)
6f5cde19
 {
b7ec211c
     global $prefix, $needed_modules;
     if (! isset($needed_modules)) {
         $needed_modules = array();
     }
     if (in_array($modname, $needed_modules)) {
         return;
     }
     $needed_modules[] = $modname;
6f5cde19
     if (! have_module($modname)) {
         system_failure("Soll nicht verfügbares Modul laden!");
     }
     /* setup module include path */
2626dd47
     ini_set('include_path', ini_get('include_path').':./modules/'.$modname.'/include:');
6f5cde19
     $style = 'modules/'.$modname.'/style.css';
     if (file_exists($style)) {
         html_header('<link rel="stylesheet" href="'.$prefix.$style.'" type="text/css" />'."\n");
     }
 }
 
 
d5f2f3f4
 function encode_querystring($querystring)
dcee94d9
 {
2626dd47
     global $debugmode;
     if ($debugmode) {
         $querystring = 'debug&'.$querystring;
     }
     $query = explode('&', $querystring);
     $new_query = array();
     foreach ($query as $item) {
         if ($item != '') {
             $split = explode('=', $item, 2);
             if (count($split) == 1) {
                 $new_query[] = $split[0];
             } else {
                 $new_query[] = $split[0].'='.urlencode($split[1]);
             }
         }
     }
     $querystring = implode('&amp;', $new_query);
     if ($querystring) {
         $querystring = '?'.$querystring;
     }
     return $querystring;
d5f2f3f4
 }
dcee94d9
 
d5f2f3f4
 
019e071b
 function beta_notice()
 {
     output('<div class="beta"><h4>Achtung: Testbetrieb</h4><p>Diese Funktion ist im Testbetrieb. Bei Fehlfunktionen, Unklarheiten oder Verbesserungsvorschlägen bitten wir um kurze Nachricht an <a href="mailto:root@schokokeks.org">root@schokokeks.org</a></p></div>');
 }
 
 
b7bc5c81
 function addnew($file, $label, $querystring = '', $attribs = '')
45e40a07
 {
2626dd47
     output('<p class="addnew">'.internal_link($file, $label, $querystring, $attribs).'</p>');
45e40a07
 }
 
d5f2f3f4
 
 function internal_link($file, $label, $querystring = '', $attribs = '')
 {
2626dd47
     global $prefix;
     if (strpos($file, '/') === 0) {
         $file = $prefix.substr($file, 1);
     }
     $querystring = encode_querystring($querystring);
     return "<a href=\"{$file}{$querystring}\" {$attribs} >{$label}</a>";
dcee94d9
 }
 
 
 function html_form($form_id, $scriptname, $querystring, $content)
 {
2626dd47
     $querystring = encode_querystring($querystring);
     $ret = '';
     $ret .= '<form id="'.$form_id.'" action="'.$scriptname.$querystring.'" method="post">'."\n";
     $ret .= '<p style="display: none;"><input type="hidden" name="formtoken" value="'.generate_form_token($form_id).'" /></p>'."\n";
     $ret .= $content;
     $ret .= '</form>';
     return $ret;
dcee94d9
 }
 
 
547266d9
 function html_select($name, $options, $default='', $free='')
0d1b7607
 {
2626dd47
     require_once('inc/security.php');
     $ret = "<select name=\"{$name}\" id=\"{$name}\" size=\"1\" {$free} >\n";
     foreach ($options as $key => $value) {
         $selected = '';
         if ($default == $key) {
             $selected = ' selected="selected" ';
         }
         $key = filter_input_general($key);
         $value = filter_input_general($value);
         $ret .= "  <option value=\"{$key}\"{$selected}>{$value}</option>\n";
     }
     $ret .= '</select>';
     return $ret;
0d1b7607
 }
 
dcee94d9
 
cec6f676
 function html_datepicker($nameprefix, $timestamp)
 {
2626dd47
     $valid_days = array( 1 =>  1,  2 =>  2,  3 =>  3,  4 =>  4,  5 =>  5,
cec6f676
                        6 =>  6,  7 =>  7,  8 =>  8,  9 =>  9, 10 => 10,
                       11 => 11, 12 => 12, 13 => 13, 14 => 14, 15 => 15,
                       16 => 16, 17 => 17, 18 => 18, 19 => 19, 20 => 20,
                       21 => 21, 22 => 22, 23 => 23, 24 => 24, 25 => 25,
                       26 => 26, 27 => 27, 28 => 28, 29 => 29, 30 => 30,
                       31 => 31);
2626dd47
     $valid_months = array( 1 =>  1,  2 =>  2,  3 =>  3,  4 =>  4,  5 =>  5,
cec6f676
                          6 =>  6,  7 =>  7,  8 =>  8,  9 =>  9, 10 => 10,
                         11 => 11, 12 => 12);
2626dd47
     $current_year = (int) date('Y');
     $valid_years = array($current_year => $current_year,
65aab10c
                        $current_year+1 => $current_year+1,
                        $current_year+2 => $current_year+2,
                        $current_year+3 => $current_year+3,
                        $current_year+4 => $current_year+4);
9086c9ad
 
2626dd47
     $selected_day = date('d', $timestamp);
     $selected_month = date('m', $timestamp);
     $selected_year = date('Y', $timestamp);
     $ret = '';
     $ret .= html_select($nameprefix.'_day', $valid_days, $selected_day, 'style="text-align: right;"').". ";
     $ret .= html_select($nameprefix.'_month', $valid_months, $selected_month, 'style="text-align: right;"').". ";
     $ret .= html_select($nameprefix.'_year', $valid_years, $selected_year);
     return $ret;
cec6f676
 }
 
2626dd47
 function get_modules_info()
c12c27e9
 {
2626dd47
     $modules = config('modules');
     $modconfig = array();
     foreach ($modules as $name) {
         $modconfig[$name] = null;
         if (file_exists('modules/'.$name.'/module.info')) {
             $modconfig[$name] = parse_ini_file('modules/'.$name.'/module.info');
         }
     }
     return $modconfig;
c12c27e9
 }