function iframe_alter_save($args)
{
    $elem = $args['elem'];
    $obj =& $args['obj'];
    if (!elem_has_class($elem, 'iframe')) {
        return false;
    }
    // parse children elements to find iframe
    $childs = html_parse(elem_val($elem));
    $i = false;
    foreach ($childs as $c) {
        if (elem_tag($c) == 'iframe') {
            $i = $c;
            break;
        }
    }
    if (!$i) {
        log_msg('warn', 'iframe_alter_save: no iframe element found, inner html is ' . var_dump_inl($childs));
        return false;
    }
    // url
    if (elem_attr($i, 'src') !== NULL) {
        $obj['iframe-url'] = elem_attr($i, 'src');
    } else {
        unset($obj['iframe-url']);
    }
    // scrolling
    if (elem_css($i, 'overflow') == 'hidden' || elem_css($i, 'overflow-x') == 'hidden' && elem_css($i, 'overflow-y') == 'hidden') {
        unset($obj['iframe-scroll']);
    } else {
        $obj['iframe-scroll'] = 'scroll';
    }
    return true;
}
Esempio n. 2
0
function video_alter_save($args)
{
    $elem = $args['elem'];
    $obj =& $args['obj'];
    if (!elem_has_class($elem, 'video')) {
        return false;
    }
    // parse children elements to find video
    $childs = html_parse(elem_val($elem));
    $v = false;
    foreach ($childs as $c) {
        if (elem_tag($c) == 'video') {
            $v = $c;
            break;
        }
    }
    if (!$v) {
        log_msg('warn', 'video_alter_save: no video element found, inner html is ' . var_dump_inl($childs));
        return false;
    }
    // autoplay
    if (elem_attr($v, 'autoplay') !== NULL) {
        $obj['video-autoplay'] = 'autoplay';
    } else {
        $obj['video-autoplay'] = '';
    }
    // loop
    if (elem_attr($v, 'loop') !== NULL) {
        $obj['video-loop'] = 'loop';
    } else {
        unset($obj['video-loop']);
    }
    // controls
    if (elem_attr($v, 'controls') !== NULL) {
        $obj['video-controls'] = 'controls';
    } else {
        unset($obj['video-controls']);
    }
    // volume
    if (elem_attr($v, 'audio') == 'muted') {
        $obj['video-volume'] = '0';
    } else {
        unset($obj['video-volume']);
    }
}
Esempio n. 3
0
/**
 *	try to turn a mixture of html code an plain text into valid html
 *
 *	@param string $html input
 *	@return string encoded output
 */
function html_encode_str_smart($html)
{
    // TODO (later): remove debug code
    log_msg('debug', 'html_encode_str_smart: string is ' . quot(var_dump_inl($html)));
    // encode ampersand characters where needed
    $cur = 0;
    while ($cur < strlen($html)) {
        // check &
        if (substr($html, $cur, 1) == '&') {
            $replace = true;
            // DEBUG
            $reason = false;
            // check &#??
            if ($cur + 3 < strlen($html) && substr($html, $cur + 1, 1) == '#') {
                // check $#x or not
                if (strtolower(substr($html, $cur + 2, 1)) == 'x') {
                    // check for hexadecimal characters before ;
                    $ahead = $cur + 3;
                    while ($ahead < strlen($html)) {
                        $char = strtolower(substr($html, $ahead, 1));
                        if (48 <= ord($char) && ord($char) <= 57 || 97 <= ord($char) && ord($char) <= 102) {
                            // valid hexadecimal character
                            $ahead++;
                        } elseif ($char == ';') {
                            if ($cur + 3 < $ahead) {
                                // valid entitiy
                                $replace = false;
                                break;
                            } else {
                                // invalid entity
                                // DEBUG
                                $reason = 1;
                                break;
                            }
                        } else {
                            // invalid entity
                            // DEBUG
                            $reason = 2;
                            break;
                        }
                    }
                    if ($ahead == strlen($html)) {
                        // DEBUG
                        $reason = 3;
                    }
                } elseif (is_numeric(substr($html, $cur + 2, 1))) {
                    // check for for decimal characters before ;
                    $ahead = $cur + 3;
                    while ($ahead < strlen($html)) {
                        $char = substr($html, $ahead, 1);
                        if (48 <= ord($char) && ord($char) <= 57) {
                            // valid decimal character
                            $ahead++;
                        } elseif ($char == ';') {
                            // valid entity
                            $replace = false;
                            break;
                        } else {
                            // invalid entity
                            $reason = 4;
                            break;
                        }
                    }
                    if ($ahead == strlen($html)) {
                        // DEBUG
                        $reason = 5;
                    }
                } else {
                    // DEBUG
                    $reason = 6;
                }
            } else {
                // assume a named entity
                // it turns out we can't use get_html_translation_table()
                // for this as the HTML_ENTITIES table is not complete
                $ahead = $cur + 1;
                while ($ahead < strlen($html)) {
                    $char = strtolower(substr($html, $ahead, 1));
                    if (48 <= ord($char) && ord($char) <= 57 || 97 <= ord($char) && ord($char) <= 122) {
                        // valid alphanumeric character
                        $ahead++;
                    } elseif ($char == ';') {
                        if ($cur + 1 < $ahead) {
                            // (supposedly) valid entity
                            $replace = false;
                            break;
                        } else {
                            // invalid entity
                            // DEBUG
                            $reason = 7;
                            break;
                        }
                    } else {
                        // invalid entity
                        // DEBUG
                        $reason = 8;
                        break;
                    }
                }
                if ($ahead == strlen($html)) {
                    $reason = 9;
                    break;
                }
            }
            if ($replace) {
                log_msg('debug', 'html_encode_str_smart: replacing ampersand at ' . $cur . ' because of ' . $reason);
                $html = substr($html, 0, $cur) . '&amp;' . substr($html, $cur + 1);
                log_msg('debug', 'html_encode_str_smart: new string is ' . quot(var_dump_inl($html)));
                $cur += 5;
            } else {
                log_msg('debug', 'html_encode_str_smart: not replacing ampersand at ' . $cur);
                $cur++;
            }
        } else {
            $cur++;
        }
    }
    // encode < and > where needed
    $cur = 0;
    while ($cur < strlen($html)) {
        $char = substr($html, $cur, 1);
        $replace = true;
        if ($char == '<') {
            // a possible tag
            // search for a closing bracket
            $ahead = $cur + 1;
            while ($ahead < strlen($html)) {
                $c = strtolower(substr($html, $ahead, 1));
                if ($c == '<') {
                    // found another opening bracket
                    // the first one can't be legit
                    // DEBUG
                    $reason = 1;
                    break;
                } elseif ($c == '>') {
                    if ($cur + 1 < $ahead) {
                        // can be a valid tag
                        $replace = false;
                        // forward till after the closing bracket
                        $cur = $ahead;
                        break;
                    } else {
                        // invalid (empty) tag
                        // DEBUG
                        $reason = 2;
                        break;
                    }
                } elseif ($ahead == $cur + 1) {
                    if (48 <= ord($c) && ord($c) <= 57 || 97 <= ord($c) && ord($c) <= 122 || $c == '/') {
                        // starts with an alphanumeric character or a slash, can be valid
                    } else {
                        // DEBUG
                        $reason = 3;
                        break;
                    }
                }
                $ahead++;
            }
            if ($ahead == strlen($html)) {
                // DEBUG
                $reason = 4;
            }
        } else {
            if ($char == '>') {
                // we should be getting all valid tags through the code above
                // DEBUG
                $reason = 5;
            }
        }
        if ($replace && $char == '<') {
            log_msg('debug', 'html_encode_str_smart: replacing opening bracket at ' . $cur . ' because of ' . $reason);
            $html = substr($html, 0, $cur) . '&lt;' . substr($html, $cur + 1);
            log_msg('debug', 'html_encode_str_smart: new string is ' . quot(var_dump_inl($html)));
            $cur += 4;
        } elseif ($replace && $char == '>') {
            log_msg('debug', 'html_encode_str_smart: replacing closing bracket at ' . $cur . ' because of ' . $reason);
            $html = substr($html, 0, $cur) . '&gt;' . substr($html, $cur + 1);
            log_msg('debug', 'html_encode_str_smart: new string is ' . quot(var_dump_inl($html)));
            $cur += 4;
        } else {
            $cur++;
        }
    }
    return $html;
}
Esempio n. 4
0
<?php

/*
 *	index.php
 *	Main HTTP request handler
 *
 *	Copyright Gottfried Haider, Danja Vasiliev 2010.
 *	This source code is licensed under the GNU General Public License.
 *	See the file COPYING for more details.
 */
@(require_once 'config.inc.php');
require_once 'log.inc.php';
log_msg('info', '--- request ---');
require_once 'controller.inc.php';
require_once 'modules.inc.php';
$args = parse_query_string();
log_msg('info', 'index: query arguments ' . var_dump_inl($args));
log_msg('debug', 'index: base url is ' . quot(base_url()));
invoke_controller($args);
/**
 *	invoke a controller based on the query arguments given
 *
 *	this function does not return in case of an error.
 *	@param array $args query-arguments array
 *	@return mixed return value of controller that was called
 */
function invoke_controller($args)
{
    global $controllers;
    // change query-arguments so that we always have a arg0 and arg1
    if (!isset($args[0])) {
        $args[0] = array('', '');
    } elseif (is_string($args[0])) {
        $args[0] = array($args[0], '');
    }
    // load all modules
    // TODO (later): fastpath for serving cached pages or files (the latter one
    // is only doable when we store in the object file which module to load)
    load_modules();
    $match = false;
    if (isset($controllers[$args[0][0] . '-' . $args[0][1]])) {
        // foo/bar would match controller for "foo/bar"
        $match = $controllers[$args[0][0] . '-' . $args[0][1]];
        $reason = $args[0][0] . '/' . $args[0][1];
    } elseif (isset($controllers[$args[0][0] . '-*'])) {
        // foo/bar would match "foo/*"
        $match = $controllers[$args[0][0] . '-*'];
        $reason = $args[0][0] . '/*';
    } elseif (isset($controllers['*-' . $args[0][1]])) {
        // foo/bar would match "*/bar"
        $match = $controllers['*-' . $args[0][1]];
        $reason = '*/' . $args[0][1];
    } elseif (isset($controllers['*-*'])) {
        // foo/bar would match "*/*"
        $match = $controllers['*-*'];
        $reason = '*/*';
    }
    if ($match !== false) {
        // check authentication for those controllers that require it
        if (isset($match['auth']) && $match['auth']) {
            if (!is_auth()) {
                prompt_auth();
            }
            // also check the referer to prevent against cross site request
            // forgery (xsrf)
            // this is not really optimal, since proxies can filter the referer
            // header, but as a first step..
            if (!empty($_SERVER['HTTP_REFERER'])) {
                $bu = base_url();
                if (substr($_SERVER['HTTP_REFERER'], 0, strlen($bu)) != $bu) {
                    log_msg('warn', 'controller: possible xsrf detected, referer is ' . quot($_SERVER['HTTP_REFERER']) . ', arguments ' . var_dump_inl($args));
                    hotglue_error(400);
                }
            }
        }
        log_msg('info', 'controller: invoking controller ' . quot($reason) . ' => ' . $match['func']);
        return $match['func']($args);
    } else {
        // normally we won't reach this as some default (*/*) controller will
        // be present
        log_msg('warn', 'controller: no match for ' . quot($args[0][0] . '/' . $args[0][1]));
        hotglue_error(400);
    }
}
Esempio n. 6
0
/**
 *	upload one or more files
 *
 *	@param array $args arguments
 *		key 'page' page to upload the files to (i.e. page.rev)
 *		key 'preferred_module' (optional) try first to invoke the upload method 
 *			on this module
 *	@return array response
 *		array of rendered, newly created objects
 */
function upload_files($args)
{
    if (empty($args['page'])) {
        return response('Required argument "page" missing or empty', 400);
    }
    if (!page_exists($args['page'])) {
        return response('Page ' . quot($args['page']) . ' does not exist', 404);
    }
    $ret = array();
    log_msg('debug', 'upload_files: $_FILES is ' . var_dump_inl($_FILES));
    foreach ($_FILES as $f) {
        $existed = false;
        $fn = upload_file($f['tmp_name'], $args['page'], $f['name'], $existed);
        if ($fn === false) {
            continue;
        } else {
            $args = array_merge($args, array('file' => $fn, 'mime' => $f['type'], 'size' => $f['size']));
            // clear mime type if set to default application/octet-stream
            if ($args['mime'] == 'application/octet-stream') {
                $args['mime'] = '';
            }
        }
        $s = false;
        // check preferred_module first
        if (!empty($args['preferred_module'])) {
            // make sure all modules are loaded
            load_modules();
            $func = $args['preferred_module'] . '_upload';
            if (is_callable($func)) {
                log_msg('debug', 'upload_files: invoking hook upload, calling ' . $func);
                $s = $func($args);
                if ($s !== false) {
                    log_msg('info', 'upload_object: ' . quot($fn) . ' was handled by ' . quot($args['preferred_module']));
                }
            }
        }
        // check all other modules next
        if ($s === false) {
            $r = invoke_hook_while('upload', false, $args);
            if (count($r) == 1) {
                $s = array_pop(array_values($r));
                log_msg('info', 'upload_object: ' . quot($fn) . ' was handled by ' . quot(array_pop(array_keys($r))));
            }
        }
        // check fallback hook last
        if ($s === false) {
            $r = invoke_hook_while('upload_fallback', false, $args);
            if (count($r) == 1) {
                $s = array_pop(array_values($r));
                log_msg('info', 'upload_object: ' . quot($fn) . ' was (fallback-) handled by ' . quot(array_pop(array_keys($r))));
            }
        }
        if ($s === false) {
            log_msg('warn', 'upload_files: nobody cared about file ' . quot($fn) . ', type ' . $f['type']);
            // delete file again unless it did already exist
            if (!$existed) {
                $a = expl('.', $args['page']);
                @unlink(CONTENT_DIR . '/' . $a[0] . '/shared/' . $fn);
            }
        } else {
            $ret[] = $s;
        }
    }
    return response($ret);
}
Esempio n. 7
0
/**
 *	check if the user is authenticated or not
 *
 *	@return true if authenticated, false if not
 */
function is_auth()
{
    if (AUTH_METHOD == 'none') {
        log_msg('debug', 'common: auth success (auth_method none)');
        return true;
    } elseif (AUTH_METHOD == 'basic') {
        if (isset($_SERVER['PHP_AUTH_USER']) && isset($_SERVER['PHP_AUTH_PW'])) {
            if ($_SERVER['PHP_AUTH_USER'] == AUTH_USER && $_SERVER['PHP_AUTH_PW'] == AUTH_PASSWORD) {
                log_msg('debug', 'common: auth success (auth_method basic)');
                return true;
            } else {
                log_msg('info', 'common: auth failure (auth_method basic)');
                return false;
            }
        } else {
            if (!empty($_SERVER['HTTP_AUTHORIZATION'])) {
                log_msg('warn', 'common: no auth data (auth_method basic) but HTTP_AUTHORIZATION is ' . quot(var_dump_inl($_SERVER['HTTP_AUTHORIZATION'])));
            } else {
                log_msg('debug', 'common: no auth data (auth_method basic)');
            }
            return false;
        }
    } elseif (AUTH_METHOD == 'digest') {
        if (isset($_SERVER['PHP_AUTH_DIGEST'])) {
            log_msg('debug', 'common: auth digest ' . var_dump_inl($_SERVER['PHP_AUTH_DIGEST']));
            $res = http_digest_check(array(AUTH_USER => AUTH_PASSWORD), SITE_NAME);
            if ($res == 0) {
                log_msg('debug', 'common: auth success (auth_method digest)');
                return true;
            } else {
                log_msg('info', 'common: auth failure ' . $res . ' (auth_method digest)');
                return false;
            }
        } else {
            if (!empty($_SERVER['HTTP_AUTHORIZATION'])) {
                log_msg('warn', 'common: no auth data (auth_method digest) but HTTP_AUTHORIZATION is ' . quot(var_dump_inl($_SERVER['HTTP_AUTHORIZATION'])));
            } else {
                log_msg('debug', 'common: no auth data (auth_method digest)');
            }
            return false;
        }
    } else {
        log_msg('error', 'common: invalid or missing AUTH_METHOD config setting');
        return false;
    }
}
Esempio n. 8
0
/**
 *	invoke a hook while the returned result is $while
 *
 *	this function also takes care of loading all modules.
 *	@param string $hook hook to invoke
 *	@param mixed $while value to compare the returned result with
 *	@param array $args arguments-array
 *	@return array with result (module=>result) or empty result if there was none
 */
function invoke_hook_while($hook, $while, $args = array())
{
    global $modules;
    // make sure all modules are loaded
    load_modules();
    foreach ($modules as $m) {
        if (is_callable($m . '_' . $hook)) {
            $func = $m . '_' . $hook;
            // DEBUG
            log_msg('debug', 'modules: invoking hook ' . $hook . ', calling ' . $func);
            $cur = $func($args);
            if ($cur !== $while) {
                $ret = array($m => $cur);
                // DEBUG
                //log_msg('debug', 'modules: invoke_hook_while on '.$hook.' returned '.var_dump_inl($ret));
                return $ret;
            }
        }
    }
    log_msg('debug', 'modules: invoke_hook_while on ' . $hook . ' returned ' . var_dump_inl(array()));
    return array();
}
Esempio n. 9
0
    log_msg('warn', 'json: ' . $err['#data']);
    die;
}
// check authentication
if (isset($m['auth']) && $m['auth']) {
    if (!is_auth()) {
        prompt_auth(true);
    }
}
if (isset($m['cross-origin']) && $m['cross-origin']) {
    // output cross-origin header if requested
    header('Access-Controll-Allow-Origin: *');
} else {
    // otherwise check the referer to make xsrf harder
    if (!empty($_SERVER['HTTP_REFERER'])) {
        $bu = base_url();
        if (substr($_SERVER['HTTP_REFERER'], 0, strlen($bu)) != $bu) {
            echo json_encode(response('Cross-origin requests not supported for this method', 400));
            log_msg('warn', 'json: possible xsrf detected, referer is ' . quot($_SERVER['HTTP_REFERER']) . ', arguments ' . var_dump_inl($args));
            die;
        }
    }
}
// run service and output result
$ret = run_service($method, $args);
if (is_array($ret) && isset($ret['#error']) && $ret['#error']) {
    log_msg('warn', 'json: service ' . $method . ' returned error ' . quot($ret['#data']));
} elseif (is_array($ret) && isset($ret['#data'])) {
    log_msg('debug', 'json: service returned ' . var_dump_inl($ret['#data']));
}
echo json_encode($ret);