/** * Handle the match */ function handle($match, $state, $pos, Doku_Handler $handler) { global $ID; $match = substr($match, 2, -4); $pos = strrpos($match, '$$'); $text = trim(substr($match, 0, $pos)); $sig = substr($match, $pos + 2, 32); $user = substr($match, $pos + 36); $check = md5($ID . $user . trim($text) . auth_cookiesalt()); return array('text' => $text, 'user' => $user, 'valid' => $sig == $check); }
/** * Authenticate using currently logged in user */ private function authenticate($secondAttempt = false) { global $auth, $INPUT; // Ok, this is evil. We read the login information of the current user and forward it to the HTTPClient list($this->user, $sticky, $this->pass) = auth_getCookie(); // Logged in in second attempt is now in Session. if ($secondAttempt && !isset($this->user) && $INPUT->str('u') && $INPUT->str('p')) { // We hacked directly into the login mechanism which provides the login information without encryption via $INPUT $this->user = $INPUT->str('u'); $this->pass = $INPUT->str('p'); $sticky = $INPUT->str('r'); } else { $secret = auth_cookiesalt(!$sticky, true); //bind non-sticky to session $this->pass = $this->auth_decrypt($this->pass, $secret); } return isset($this->user); }
/** * Gather all information * * @return array The popularity data as an array */ function _gather() { global $conf; /** @var $auth DokuWiki_Auth_Plugin */ global $auth; $data = array(); $phptime = ini_get('max_execution_time'); @set_time_limit(0); $pluginInfo = $this->getInfo(); // version $data['anon_id'] = md5(auth_cookiesalt()); $data['version'] = getVersion(); $data['popversion'] = $pluginInfo['date']; $data['language'] = $conf['lang']; $data['now'] = time(); $data['popauto'] = (int) $this->isAutoSubmitEnabled(); // some config values $data['conf_useacl'] = $conf['useacl']; $data['conf_authtype'] = $conf['authtype']; $data['conf_template'] = $conf['template']; // number and size of pages $list = array(); search($list, $conf['datadir'], array($this, '_search_count'), array('all' => false), ''); $data['page_count'] = $list['file_count']; $data['page_size'] = $list['file_size']; $data['page_biggest'] = $list['file_max']; $data['page_smallest'] = $list['file_min']; $data['page_nscount'] = $list['dir_count']; $data['page_nsnest'] = $list['dir_nest']; if ($list['file_count']) { $data['page_avg'] = $list['file_size'] / $list['file_count']; } $data['page_oldest'] = $list['file_oldest']; unset($list); // number and size of media $list = array(); search($list, $conf['mediadir'], array($this, '_search_count'), array('all' => true)); $data['media_count'] = $list['file_count']; $data['media_size'] = $list['file_size']; $data['media_biggest'] = $list['file_max']; $data['media_smallest'] = $list['file_min']; $data['media_nscount'] = $list['dir_count']; $data['media_nsnest'] = $list['dir_nest']; if ($list['file_count']) { $data['media_avg'] = $list['file_size'] / $list['file_count']; } unset($list); // number and size of cache $list = array(); search($list, $conf['cachedir'], array($this, '_search_count'), array('all' => true)); $data['cache_count'] = $list['file_count']; $data['cache_size'] = $list['file_size']; $data['cache_biggest'] = $list['file_max']; $data['cache_smallest'] = $list['file_min']; if ($list['file_count']) { $data['cache_avg'] = $list['file_size'] / $list['file_count']; } unset($list); // number and size of index $list = array(); search($list, $conf['indexdir'], array($this, '_search_count'), array('all' => true)); $data['index_count'] = $list['file_count']; $data['index_size'] = $list['file_size']; $data['index_biggest'] = $list['file_max']; $data['index_smallest'] = $list['file_min']; if ($list['file_count']) { $data['index_avg'] = $list['file_size'] / $list['file_count']; } unset($list); // number and size of meta $list = array(); search($list, $conf['metadir'], array($this, '_search_count'), array('all' => true)); $data['meta_count'] = $list['file_count']; $data['meta_size'] = $list['file_size']; $data['meta_biggest'] = $list['file_max']; $data['meta_smallest'] = $list['file_min']; if ($list['file_count']) { $data['meta_avg'] = $list['file_size'] / $list['file_count']; } unset($list); // number and size of attic $list = array(); search($list, $conf['olddir'], array($this, '_search_count'), array('all' => true)); $data['attic_count'] = $list['file_count']; $data['attic_size'] = $list['file_size']; $data['attic_biggest'] = $list['file_max']; $data['attic_smallest'] = $list['file_min']; if ($list['file_count']) { $data['attic_avg'] = $list['file_size'] / $list['file_count']; } $data['attic_oldest'] = $list['file_oldest']; unset($list); // user count if ($auth && $auth->canDo('getUserCount')) { $data['user_count'] = $auth->getUserCount(); } // calculate edits per day $list = @file($conf['metadir'] . '/_dokuwiki.changes'); $count = count($list); if ($count > 2) { $first = (int) substr(array_shift($list), 0, 10); $last = (int) substr(array_pop($list), 0, 10); $dur = ($last - $first) / (60 * 60 * 24); // number of days in the changelog $data['edits_per_day'] = $count / $dur; } unset($list); // plugins $data['plugin'] = plugin_list(); // pcre info if (defined('PCRE_VERSION')) { $data['pcre_version'] = PCRE_VERSION; } $data['pcre_backtrack'] = ini_get('pcre.backtrack_limit'); $data['pcre_recursion'] = ini_get('pcre.recursion_limit'); // php info $data['os'] = PHP_OS; $data['webserver'] = $_SERVER['SERVER_SOFTWARE']; $data['php_version'] = phpversion(); $data['php_sapi'] = php_sapi_name(); $data['php_memory'] = $this->_to_byte(ini_get('memory_limit')); $data['php_exectime'] = $phptime; $data['php_extension'] = get_loaded_extensions(); // plugin usage data $this->_add_plugin_usage_data($data); return $data; }
/** * Decrypt the given string with the cookie salt * * @param string $data * @return string */ public function decrypt($data) { $data = base64_decode($data); if (function_exists('auth_decrypt')) { return auth_decrypt($data, auth_cookiesalt()); // since binky } else { return PMA_blowfish_decrypt($data, auth_cookiesalt()); // deprecated } }
/** * Update user profile * * @author Christopher Smith <*****@*****.**> */ function updateprofile() { global $conf; global $lang; /* @var DokuWiki_Auth_Plugin $auth */ global $auth; /* @var Input $INPUT */ global $INPUT; if (!$INPUT->post->bool('save')) { return false; } if (!checkSecurityToken()) { return false; } if (!actionOK('profile')) { msg($lang['profna'], -1); return false; } $changes = array(); $changes['pass'] = $INPUT->post->str('newpass'); $changes['name'] = $INPUT->post->str('fullname'); $changes['mail'] = $INPUT->post->str('email'); // check misspelled passwords if ($changes['pass'] != $INPUT->post->str('passchk')) { msg($lang['regbadpass'], -1); return false; } // clean fullname and email $changes['name'] = trim(preg_replace('/[\\x00-\\x1f:<>&%,;]+/', '', $changes['name'])); $changes['mail'] = trim(preg_replace('/[\\x00-\\x1f:<>&%,;]+/', '', $changes['mail'])); // no empty name and email (except the backend doesn't support them) if (empty($changes['name']) && $auth->canDo('modName') || empty($changes['mail']) && $auth->canDo('modMail')) { msg($lang['profnoempty'], -1); return false; } if (!mail_isvalid($changes['mail']) && $auth->canDo('modMail')) { msg($lang['regbadmail'], -1); return false; } $changes = array_filter($changes); // check for unavailable capabilities if (!$auth->canDo('modName')) { unset($changes['name']); } if (!$auth->canDo('modMail')) { unset($changes['mail']); } if (!$auth->canDo('modPass')) { unset($changes['pass']); } // anything to do? if (!count($changes)) { msg($lang['profnochange'], -1); return false; } if ($conf['profileconfirm']) { if (!$auth->checkPass($INPUT->server->str('REMOTE_USER'), $INPUT->post->str('oldpass'))) { msg($lang['badpassconfirm'], -1); return false; } } if ($result = $auth->triggerUserMod('modify', array($INPUT->server->str('REMOTE_USER'), &$changes))) { // update cookie and session with the changed data if ($changes['pass']) { list(, $sticky, ) = auth_getCookie(); $pass = auth_encrypt($changes['pass'], auth_cookiesalt(!$sticky, true)); auth_setCookie($INPUT->server->str('REMOTE_USER'), $pass, (bool) $sticky); } return true; } return false; }
/** * Check for media for preconditions and return correct status code * * READ: MEDIA, MIME, EXT, CACHE * WRITE: MEDIA, FILE, array( STATUS, STATUSMESSAGE ) * * @author Gerry Weissbach <*****@*****.**> * @param $media reference to the media id * @param $file reference to the file variable * @returns array(STATUS, STATUSMESSAGE) */ function checkFileStatus(&$media, &$file) { global $MIME, $EXT, $CACHE; //media to local file if (preg_match('#^(https?)://#i', $media)) { //check hash if (substr(md5(auth_cookiesalt() . $media), 0, 6) != $_REQUEST['hash']) { return array(412, 'Precondition Failed'); } //handle external images if (strncmp($MIME, 'image/', 6) == 0) { $file = media_get_from_URL($media, $EXT, $CACHE); } if (!$file) { //download failed - redirect to original URL return array(302, $media); } } else { $media = cleanID($media); if (empty($media)) { return array(400, 'Bad request'); } //check permissions (namespace only) if (auth_quickaclcheck(getNS($media) . ':X') < AUTH_READ) { return array(403, 'Forbidden'); } $file = mediaFN($media); } //check file existance if (!@file_exists($file)) { return array(404, 'Not Found'); } return array(200, null); }
/** * Return a secret token to be used for CSRF attack prevention * * @author Andreas Gohr <*****@*****.**> * @link http://en.wikipedia.org/wiki/Cross-site_request_forgery * @link http://christ1an.blogspot.com/2007/04/preventing-csrf-efficiently.html * * @return string */ function getSecurityToken() { /** @var Input $INPUT */ global $INPUT; return PassHash::hmac('md5', session_id() . $INPUT->server->str('REMOTE_USER'), auth_cookiesalt()); }
/** * Send a new password * * This function handles both phases of the password reset: * * - handling the first request of password reset * - validating the password reset auth token * * @author Benoit Chesneau <*****@*****.**> * @author Chris Smith <*****@*****.**> * @author Andreas Gohr <*****@*****.**> * * @return bool true on success, false on any error */ function act_resendpwd() { global $lang; global $conf; global $auth; if (!actionOK('resendpwd')) { return false; } if (!$auth) { return false; } // should not be able to get here without modPass being possible... if (!$auth->canDo('modPass')) { msg($lang['resendna'], -1); return false; } $token = preg_replace('/[^a-f0-9]+/', '', $_REQUEST['pwauth']); if ($token) { // we're in token phase $tfile = $conf['cachedir'] . '/' . $token[0] . '/' . $token . '.pwauth'; if (!@file_exists($tfile)) { msg($lang['resendpwdbadauth'], -1); return false; } $user = io_readfile($tfile); @unlink($tfile); $userinfo = $auth->getUserData($user); if (!$userinfo['mail']) { msg($lang['resendpwdnouser'], -1); return false; } $pass = auth_pwgen(); if (!$auth->triggerUserMod('modify', array($user, array('pass' => $pass)))) { msg('error modifying user data', -1); return false; } if (auth_sendPassword($user, $pass)) { msg($lang['resendpwdsuccess'], 1); } else { msg($lang['regmailfail'], -1); } return true; } else { // we're in request phase if (!$_POST['save']) { return false; } if (empty($_POST['login'])) { msg($lang['resendpwdmissing'], -1); return false; } else { $user = trim($auth->cleanUser($_POST['login'])); } $userinfo = $auth->getUserData($user); if (!$userinfo['mail']) { msg($lang['resendpwdnouser'], -1); return false; } // generate auth token $token = md5(auth_cookiesalt() . $user); //secret but user based $tfile = $conf['cachedir'] . '/' . $token[0] . '/' . $token . '.pwauth'; $url = wl('', array('do' => 'resendpwd', 'pwauth' => $token), true, '&'); io_saveFile($tfile, $user); $text = rawLocale('pwconfirm'); $text = str_replace('@DOKUWIKIURL@', DOKU_URL, $text); $text = str_replace('@FULLNAME@', $userinfo['name'], $text); $text = str_replace('@LOGIN@', $user, $text); $text = str_replace('@TITLE@', $conf['title'], $text); $text = str_replace('@CONFIRM@', $url, $text); if (mail_send($userinfo['name'] . ' <' . $userinfo['mail'] . '>', $lang['regpwmail'], $text, $conf['mailfrom'])) { msg($lang['resendpwdconfirm'], 1); } else { msg($lang['regmailfail'], -1); } return true; } return false; // never reached }
<?php /** * CAPTCHA antispam plugin - Image generator * * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) * @author Andreas Gohr <*****@*****.**> */ if (!defined('DOKU_INC')) { define('DOKU_INC', dirname(__FILE__) . '/../../../'); } define('NOSESSION', true); define('DOKU_DISABLE_GZIP_OUTPUT', 1); require_once DOKU_INC . 'inc/init.php'; require_once DOKU_INC . 'inc/auth.php'; $ID = $_REQUEST['id']; $plugin = plugin_load('helper', 'captcha'); $rand = PMA_blowfish_decrypt($_REQUEST['secret'], auth_cookiesalt()); $code = $plugin->_generateCAPTCHA($plugin->_fixedIdent(), $rand); $plugin->_imageCAPTCHA($code); //Setup VIM: ex: et ts=4 enc=utf-8 :
/** * Build a semi-secret fixed string identifying the current page and user * * This string is always the same for the current user when editing the same * page revision, but only for one day. Editing a page before midnight and saving * after midnight will result in a failed CAPTCHA once, but makes sure it can * not be reused which is especially important for the registration form where the * $ID usually won't change. * * @return string */ public function _fixedIdent() { global $ID; $lm = @filemtime(wikiFN($ID)); $td = date('Y-m-d'); return auth_browseruid() . auth_cookiesalt() . $ID . $lm . $td; }
/** * Return a secret token to be used for CSRF attack prevention * * @author Andreas Gohr <*****@*****.**> * @link http://en.wikipedia.org/wiki/Cross-site_request_forgery * @link http://christ1an.blogspot.com/2007/04/preventing-csrf-efficiently.html * @return string */ function getSecurityToken() { return PassHash::hmac('md5', session_id() . $_SERVER['REMOTE_USER'], auth_cookiesalt()); }
/** * @param string $user * @param bool $inbind authldap specific, true if in bind phase * @return array containing user data or false */ protected function _getUserData($user, $inbind = false) { global $conf; if (!$this->_openLDAP()) { return false; } // force superuser bind if wanted and not bound as superuser yet if ($this->getConf('binddn') && $this->getConf('bindpw') && $this->bound < 2) { // use superuser credentials if (!@ldap_bind($this->con, $this->getConf('binddn'), $this->getConf('bindpw'))) { $this->_debug('LDAP bind as superuser: '******'user'] = $user; $info['server'] = $this->getConf('server'); //get info for given user $base = $this->_makeFilter($this->getConf('usertree'), $info); if ($this->getConf('userfilter')) { $filter = $this->_makeFilter($this->getConf('userfilter'), $info); } else { $filter = "(ObjectClass=*)"; } $sr = $this->_ldapsearch($this->con, $base, $filter, $this->getConf('userscope')); $result = @ldap_get_entries($this->con, $sr); $this->_debug('LDAP user search: ' . htmlspecialchars(ldap_error($this->con)), 0, __LINE__, __FILE__); $this->_debug('LDAP search at: ' . htmlspecialchars($base . ' ' . $filter), 0, __LINE__, __FILE__); // Don't accept more or less than one response if (!is_array($result) || $result['count'] != 1) { return false; //user not found } $user_result = $result[0]; ldap_free_result($sr); // general user info $info['dn'] = $user_result['dn']; $info['gid'] = $user_result['gidnumber'][0]; $info['mail'] = $user_result['mail'][0]; $info['name'] = $user_result['cn'][0]; $info['grps'] = array(); // overwrite if other attribs are specified. if (is_array($this->getConf('mapping'))) { foreach ($this->getConf('mapping') as $localkey => $key) { if (is_array($key)) { // use regexp to clean up user_result list($key, $regexp) = each($key); if ($user_result[$key]) { foreach ($user_result[$key] as $grpkey => $grp) { if ($grpkey !== 'count' && preg_match($regexp, $grp, $match)) { if ($localkey == 'grps') { $info[$localkey][] = $match[1]; } else { $info[$localkey] = $match[1]; } } } } } else { $info[$localkey] = $user_result[$key][0]; } } } $user_result = array_merge($info, $user_result); //get groups for given user if grouptree is given if ($this->getConf('grouptree') || $this->getConf('groupfilter')) { $base = $this->_makeFilter($this->getConf('grouptree'), $user_result); $filter = $this->_makeFilter($this->getConf('groupfilter'), $user_result); $sr = $this->_ldapsearch($this->con, $base, $filter, $this->getConf('groupscope'), array($this->getConf('groupkey'))); $this->_debug('LDAP group search: ' . htmlspecialchars(ldap_error($this->con)), 0, __LINE__, __FILE__); $this->_debug('LDAP search at: ' . htmlspecialchars($base . ' ' . $filter), 0, __LINE__, __FILE__); if (!$sr) { msg("LDAP: Reading group memberships failed", -1); $this->_debug('LDAP group search: ' . htmlspecialchars(ldap_error($this->con)), 0, __LINE__, __FILE__); return false; } $result = ldap_get_entries($this->con, $sr); ldap_free_result($sr); if (is_array($result)) { foreach ($result as $grp) { if (!empty($grp[$this->getConf('groupkey')])) { $group = $grp[$this->getConf('groupkey')]; if (is_array($group)) { $group = $group[0]; } else { $this->_debug('groupkey did not return a detailed result', 0, __LINE__, __FILE__); } if ($group === '') { continue; } $this->_debug('LDAP usergroup: ' . htmlspecialchars($group), 0, __LINE__, __FILE__); $info['grps'][] = $group; } } } } // merge local groups into group list if ($this->users === null) { $this->_loadUserData(); } if (is_array($this->users[$user]['grps'])) { foreach ($this->users[$user]['grps'] as $group) { if (in_array($group, $info['grps'])) { continue; } $info['grps'][] = $group; } } return $info; }
/** * Build a link to a media file * * Will return a link to the detail page if $direct is false * * The $more parameter should always be given as array, the function then * will strip default parameters to produce even cleaner URLs * * @param string $id the media file id or URL * @param mixed $more string or array with additional parameters * @param bool $direct link to detail page if false * @param string $sep URL parameter separator * @param bool $abs Create an absolute URL * @return string */ function ml($id = '', $more = '', $direct = true, $sep = '&', $abs = false) { global $conf; $isexternalimage = preg_match('#^(https?|ftp)://#i', $id); if (!$isexternalimage) { $id = cleanID($id); } if (is_array($more)) { // add token for resized images if ($more['w'] || $more['h']) { $more['tok'] = media_get_token($id, $more['w'], $more['h']); } // strip defaults for shorter URLs if (isset($more['cache']) && $more['cache'] == 'cache') { unset($more['cache']); } if (!$more['w']) { unset($more['w']); } if (!$more['h']) { unset($more['h']); } if (isset($more['id']) && $direct) { unset($more['id']); } $more = buildURLparams($more, $sep); } else { $matches = array(); if (preg_match_all('/\\b(w|h)=(\\d*)\\b/', $more, $matches, PREG_SET_ORDER)) { $resize = array('w' => 0, 'h' => 0); foreach ($matches as $match) { $resize[$match[1]] = $match[2]; } $more .= $sep . 'tok=' . media_get_token($id, $resize['w'], $resize['h']); } $more = str_replace('cache=cache', '', $more); //skip default $more = str_replace(',,', ',', $more); $more = str_replace(',', $sep, $more); } if ($abs) { $xlink = DOKU_URL; } else { $xlink = DOKU_BASE; } // external URLs are always direct without rewriting if ($isexternalimage) { $xlink .= 'lib/exe/fetch.php'; // add hash: $xlink .= '?hash=' . substr(md5(auth_cookiesalt() . $id), 0, 6); if ($more) { $xlink .= $sep . $more; $xlink .= $sep . 'media=' . rawurlencode($id); } else { $xlink .= $sep . 'media=' . rawurlencode($id); } return $xlink; } $id = idfilter($id); // decide on scriptname if ($direct) { if ($conf['userewrite'] == 1) { $script = '_media'; } else { $script = 'lib/exe/fetch.php'; } } else { if ($conf['userewrite'] == 1) { $script = '_detail'; } else { $script = 'lib/exe/detail.php'; } } // build URL based on rewrite mode if ($conf['userewrite']) { $xlink .= $script . '/' . $id; if ($more) { $xlink .= '?' . $more; } } else { if ($more) { $xlink .= $script . '?' . $more; $xlink .= $sep . 'media=' . $id; } else { $xlink .= $script . '?media=' . $id; } } return $xlink; }
<?php /** * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) * @author Andreas Gohr <*****@*****.**> * * Simple redirector script to avoid security warnings when embedding HTTP in SSL secured sites * * To avoid open redirects, a secret hash has to be provided */ if(!defined('DOKU_INC')) define('DOKU_INC', dirname(__FILE__) . '/../../../'); define('NOSESSION', true); require_once(DOKU_INC . 'inc/init.php'); global $INPUT; $url = $INPUT->str('url'); $hash = $INPUT->str('hash'); if(!$url) die('sorry. no url'); if(!$hash) die('sorry. no hash'); if($hash != md5(auth_cookiesalt() . 'vshare' . $url)) die('sorry. wrong hash'); send_redirect($url);
/** * Calculate a token to be used to verify fetch requests for resized or * cropped images have been internally generated - and prevent external * DDOS attacks via fetch * * @author Christopher Smith <*****@*****.**> * * @param string $id id of the image * @param int $w resize/crop width * @param int $h resize/crop height * @return string */ function media_get_token($id, $w, $h) { // token is only required for modified images if ($w || $h || media_isexternal($id)) { $token = $id; if ($w) { $token .= '.' . $w; } if ($h) { $token .= '.' . $h; } return substr(PassHash::hmac('md5', $token, auth_cookiesalt()), 0, 6); } return ''; }
/** * Checks if the CAPTCHA string submitted is valid * * @author Andreas Gohr <*****@*****.**> * @adaption Esther Brunner <*****@*****.**> */ function _captchaCheck() { if (plugin_isdisabled('captcha') || !($captcha = plugin_load('helper', 'captcha'))) { return; } // CAPTCHA is disabled or not available // do nothing if logged in user and no CAPTCHA required if (!$captcha->getConf('forusers') && $_SERVER['REMOTE_USER']) { return; } // compare provided string with decrypted captcha $rand = PMA_blowfish_decrypt($_REQUEST['plugin__captcha_secret'], auth_cookiesalt()); $code = $captcha->_generateCAPTCHA($captcha->_fixedIdent(), $rand); if (!$_REQUEST['plugin__captcha_secret'] || !$_REQUEST['plugin__captcha'] || strtoupper($_REQUEST['plugin__captcha']) != $code) { // CAPTCHA test failed! Continue to edit instead of saving msg($captcha->getLang('testfailed'), -1); if ($_REQUEST['comment'] == 'save') { $_REQUEST['comment'] = 'edit'; } elseif ($_REQUEST['comment'] == 'add') { $_REQUEST['comment'] = 'show'; } } // if we arrive here it was a valid save }
/** * Return a secret token to be used for CSRF attack prevention * * @author Andreas Gohr <*****@*****.**> * @link http://en.wikipedia.org/wiki/Cross-site_request_forgery * @link http://christ1an.blogspot.com/2007/04/preventing-csrf-efficiently.html * @return string */ function getSecurityToken() { return md5(auth_cookiesalt() . session_id()); }
/** * Render the flash player */ function render($mode, Doku_Renderer $R, $data) { if ($mode != 'xhtml') { return false; } if (is_null($data)) { return false; } if ($data['align'] == 0) { $align = 'none'; } if ($data['align'] == 1) { $align = 'right'; } if ($data['align'] == 2) { $align = 'left'; } if ($data['align'] == 3) { $align = 'center'; } if ($data['title']) { $title = ' title="' . hsc($data['title']) . '"'; } if (is_a($R, 'renderer_plugin_dw2pdf')) { // Output for PDF renderer $R->doc .= '<div class="vshare__' . $align . '" width="' . $data['width'] . '" height="' . $data['height'] . '">'; $R->doc .= '<a href="' . $data['url'] . '" class="vshare">'; $R->doc .= '<img src="' . DOKU_BASE . 'lib/plugins/vshare/video.png" />'; $R->doc .= '</a>'; $R->doc .= '<br />'; $R->doc .= '<a href="' . $data['url'] . '" class="vshare">'; $R->doc .= $data['title'] ? hsc($data['title']) : 'Video'; $R->doc .= '</a>'; $R->doc .= '</div>'; } else { // use redirector for HTTP embeds on SSL sites if (is_ssl() && substr($data['url'], 0, 7) == 'http://') { $data['url'] = DOKU_BASE . 'lib/plugins/vshare/redir.php' . '?url=' . rawurlencode($data['url']) . '&hash=' . md5(auth_cookiesalt() . 'vshare' . $data['url']); } // Normal output if ($data['type'] == 'flash') { // embed flash $R->doc .= '<div class="vshare__' . $align . '"' . $title . '>'; $R->doc .= html_flashobject($data['url'], $data['width'], $data['height'], $data['vars'], $data['vars']); $R->doc .= '</div>'; } else { // embed iframe $R->doc .= '<iframe '; $R->doc .= buildAttributes(array('src' => $data['url'], 'height' => $data['height'], 'width' => $data['width'], 'class' => 'vshare__' . $align, 'allowfullscreen' => '', 'frameborder' => 0, 'scrolling' => 'no')); $R->doc .= '>' . hsc($data['title']) . '</iframe>'; } } }
/** * Calculate a token to be used to verify fetch requests for resized or * cropped images have been internally generated - and prevent external * DDOS attacks via fetch * * @param string $id id of the image * @param int $w resize/crop width * @param int $h resize/crop height * * @author Christopher Smith <*****@*****.**> */ function media_get_token($id, $w, $h) { // token is only required for modified images if ($w || $h) { $token = auth_cookiesalt() . $id; if ($w) { $token .= '.' . $w; } if ($h) { $token .= '.' . $h; } return substr(md5($token), 0, 6); } return ''; }
/** * Build a link to a media file * * Will return a link to the detail page if $direct is false * * The $more parameter should always be given as array, the function then * will strip default parameters to produce even cleaner URLs * * @param string $id the media file id or URL * @param mixed $more string or array with additional parameters * @param bool $direct link to detail page if false * @param string $sep URL parameter separator * @param bool $abs Create an absolute URL * @return string */ function ml($id = '', $more = '', $direct = true, $sep = '&', $abs = false) { global $conf; if (is_array($more)) { // strip defaults for shorter URLs if (isset($more['cache']) && $more['cache'] == 'cache') { unset($more['cache']); } if (!$more['w']) { unset($more['w']); } if (!$more['h']) { unset($more['h']); } if (isset($more['id']) && $direct) { unset($more['id']); } $more = buildURLparams($more, $sep); } else { $more = str_replace('cache=cache', '', $more); //skip default $more = str_replace(',,', ',', $more); $more = str_replace(',', $sep, $more); } if ($abs) { $xlink = DOKU_URL; } else { $xlink = DOKU_BASE; } // external URLs are always direct without rewriting if (preg_match('#^(https?|ftp)://#i', $id)) { $xlink .= 'lib/exe/fetch.php'; // add hash: $xlink .= '?hash=' . substr(md5(auth_cookiesalt() . $id), 0, 6); if ($more) { $xlink .= $sep . $more; $xlink .= $sep . 'media=' . rawurlencode($id); } else { $xlink .= $sep . 'media=' . rawurlencode($id); } return $xlink; } $id = idfilter($id); // decide on scriptname if ($direct) { if ($conf['userewrite'] == 1) { $script = '_media'; } else { $script = 'lib/exe/fetch.php'; } } else { if ($conf['userewrite'] == 1) { $script = '_detail'; } else { $script = 'lib/exe/detail.php'; } } // build URL based on rewrite mode if ($conf['userewrite']) { $xlink .= $script . '/' . $id; if ($more) { $xlink .= '?' . $more; } } else { if ($more) { $xlink .= $script . '?' . $more; $xlink .= $sep . 'media=' . $id; } else { $xlink .= $script . '?media=' . $id; } } return $xlink; }
//get input $MEDIA = stripctl(getID('media', false)); // no cleaning except control chars - maybe external $CACHE = calc_cache($_REQUEST['cache']); $WIDTH = (int) $_REQUEST['w']; $HEIGHT = (int) $_REQUEST['h']; list($EXT, $MIME, $DL) = mimetype($MEDIA, false); if ($EXT === false) { $EXT = 'unknown'; $MIME = 'application/octet-stream'; $DL = true; } //media to local file if (preg_match('#^(https?)://#i', $MEDIA)) { //check hash if (substr(md5(auth_cookiesalt() . $MEDIA), 0, 6) != $_REQUEST['hash']) { header("HTTP/1.0 412 Precondition Failed"); print 'Precondition Failed'; exit; } //handle external images if (strncmp($MIME, 'image/', 6) == 0) { $FILE = media_get_from_URL($MEDIA, $EXT, $CACHE); } if (!$FILE) { //download failed - redirect to original URL header('Location: ' . $MEDIA); exit; } } else { $MEDIA = cleanID($MEDIA);
/** * Definition of the function modifyUser in order to modify the password * * @param string $user nick of the user to be changed * @param array $changes array of field/value pairs to be changed (password will be clear text) * @return bool true on success, false on error */ function modifyUser($user, $changes) { // open the connection to the ldap if (!$this->_openLDAP()) { $this->_debug('LDAP cannot connect: ' . htmlspecialchars(ldap_error($this->con)), 0, __LINE__, __FILE__); return false; } // find the information about the user, in particular the "dn" $info = $this->getUserData($user, true); if (empty($info['dn'])) { $this->_debug('LDAP cannot find your user dn', 0, __LINE__, __FILE__); return false; } $dn = $info['dn']; // find the old password of the user list($loginuser, $loginsticky, $loginpass) = auth_getCookie(); if ($loginuser !== null) { // the user is currently logged in $secret = auth_cookiesalt(!$loginsticky, true); $pass = auth_decrypt($loginpass, $secret); // bind with the ldap if (!@ldap_bind($this->con, $dn, $pass)) { $this->_debug('LDAP user bind failed: ' . htmlspecialchars($dn) . ': ' . htmlspecialchars(ldap_error($this->con)), 0, __LINE__, __FILE__); return false; } } elseif ($this->getConf('binddn') && $this->getConf('bindpw')) { // we are changing the password on behalf of the user (eg: forgotten password) // bind with the superuser ldap if (!@ldap_bind($this->con, $this->getConf('binddn'), conf_decodeString($this->getConf('bindpw')))) { $this->_debug('LDAP bind as superuser: '******'pass']); // change the password if (!@ldap_mod_replace($this->con, $dn, array('userpassword' => $hash))) { $this->_debug('LDAP mod replace failed: ' . htmlspecialchars($dn) . ': ' . htmlspecialchars(ldap_error($this->con)), 0, __LINE__, __FILE__); return false; } return true; }
<?php //fix for Opera XMLHttpRequests if (!count($_POST) && $HTTP_RAW_POST_DATA) { parse_str($HTTP_RAW_POST_DATA, $_POST); } if (!defined('DOKU_INC')) { define('DOKU_INC', dirname(__FILE__) . '/../../../'); } require_once DOKU_INC . 'inc/init.php'; require_once DOKU_INC . 'inc/common.php'; require_once DOKU_INC . 'inc/pageutils.php'; require_once DOKU_INC . 'inc/auth.php'; //close sesseion session_write_close(); header('Content-Type: text/plain; charset=utf-8'); $text = $_POST['text']; $id = $_POST['id']; $user = $_SERVER['REMOTE_USER']; $sig = md5($id . $user . trim($text) . auth_cookiesalt()); echo '{{', $text, ' $$', $sig, '--', $user, '$$}}';
function test_ml_imgresize_array_external() { global $conf; $conf['useslash'] = 0; $conf['userewrite'] = 0; $ids = array('https://example.com/lib/tpl/dokuwiki/images/logo.png', 'http://example.com/lib/tpl/dokuwiki/images/logo.png', 'ftp://example.com/lib/tpl/dokuwiki/images/logo.png'); $w = 80; $args = array('w' => $w); foreach ($ids as $id) { $tok = media_get_token($id, $w, 0); $hash = substr(PassHash::hmac('md5', $id, auth_cookiesalt()), 0, 6); $expect = DOKU_BASE . $this->script . '?w=' . $w . '&tok=' . $tok . '&media=' . rawurlencode($id); $this->assertEquals($expect, ml($id, $args)); } $h = 50; $args = array('h' => $h); $tok = media_get_token($id, $h, 0); $expect = DOKU_BASE . $this->script . '?h=' . $h . '&tok=' . $tok . '&media=' . rawurlencode($id); $this->assertEquals($expect, ml($id, $args)); $w = 80; $h = 50; $args = array('w' => $w, 'h' => $h); $tok = media_get_token($id, $w, $h); $expect = DOKU_BASE . $this->script . '?w=' . $w . '&h=' . $h . '&tok=' . $tok . '&media=' . rawurlencode($id); $this->assertEquals($expect, ml($id, $args)); }
function process_preregister_check(&$event, $param) { global $ACT, $INPUT; if ($ACT != 'preregistercheck') { return; } if ($_GET && $_GET['prereg']) { $md5 = $INPUT->str('prereg'); if (!preg_match("/^(\\w){32}\$/", $md5, $matches)) { return; } echo $this->getLang('registering') . $md5; $this->process_registration($md5); $event->preventDefault(); return; } $event->preventDefault(); if (!$_POST['login']) { msg('missing login: please fill out all fields'); return; } else { if (!$_POST['fullname']) { msg('missing Real Name: please fill out all fields'); return; } } if ($this->captcha == 'captcha') { $captcha = $this->loadHelper('captcha', true); if (!$captcha->check()) { return; } } if ($this->is_user($_REQUEST['login'])) { return; } // name already taken if ($this->captcha == 'builtin') { $failed = false; if (!isset($_REQUEST['card'])) { echo '<h4>' . $this->getLang('cards_nomatch') . '</h4>'; return; } foreach ($_REQUEST['card'] as $card) { if (strpos($_REQUEST['sel'], $card) === false) { $failed = true; break; } } if ($failed) { echo '<h4>' . $this->getLang('cards_nomatch') . '</h4>'; return; } } $t = time(); $salt = auth_cookiesalt(); $index = md5(microtime() . $salt); $url = DOKU_URL . 'doku.php?' . htmlentities($INPUT->str('id')) . '&do=preregistercheck&prereg=' . $index; if ($this->getConf('send_confirm')) { $valid_email = true; if ($this->send_link($_REQUEST['email'], $url, $valid_email)) { echo $this->getLang('confirmation'); } else { if ($valid_email) { echo $this->getLang('email_problem'); } } } else { echo "<a href='{$url}'>{$url}</a><br /><br />\n"; echo $this->getLang('screen_confirm'); } $data = unserialize(io_readFile($this->metaFn, false)); if (!$data) { $data = array(); } $data[$index] = $_POST; $data[$index]['savetime'] = $t; io_saveFile($this->metaFn, serialize($data)); }
/** * Return user info * * Returns info about the given user needs to contain * at least these fields: * * name string full name of the user * mail string email addres of the user * grps array list of groups the user is in * * This LDAP specific function returns the following * addional fields: * * dn string distinguished name (DN) * uid string Posix User ID * inbind bool for internal use - avoid loop in binding * * @author Andreas Gohr <*****@*****.**> * @author Trouble * @author Dan Allen <*****@*****.**> * @author <*****@*****.**> * @author Stephane Chazelas <*****@*****.**> * @return array containing user data or false */ function getUserData($user, $inbind = false) { global $conf; if (!$this->_openLDAP()) { return false; } // force superuser bind if wanted and not bound as superuser yet if ($this->cnf['binddn'] && $this->cnf['bindpw'] && $this->bound < 2) { // use superuser credentials if (!@ldap_bind($this->con, $this->cnf['binddn'], $this->cnf['bindpw'])) { if ($this->cnf['debug']) { msg('LDAP bind as superuser: '******'auth']['pass'], auth_cookiesalt()); $this->checkPass($_SESSION[DOKU_COOKIE]['auth']['user'], $pass); } $info['user'] = $user; $info['server'] = $this->cnf['server']; //get info for given user $base = $this->_makeFilter($this->cnf['usertree'], $info); if (!empty($this->cnf['userfilter'])) { $filter = $this->_makeFilter($this->cnf['userfilter'], $info); } else { $filter = "(ObjectClass=*)"; } $sr = $this->_ldapsearch($this->con, $base, $filter, $this->cnf['userscope']); $result = @ldap_get_entries($this->con, $sr); if ($this->cnf['debug']) { msg('LDAP user search: ' . htmlspecialchars(ldap_error($this->con)), 0, __LINE__, __FILE__); msg('LDAP search at: ' . htmlspecialchars($base . ' ' . $filter), 0, __LINE__, __FILE__); } // Don't accept more or less than one response if (!is_array($result) || $result['count'] != 1) { return false; //user not found } $user_result = $result[0]; ldap_free_result($sr); // general user info $info['dn'] = $user_result['dn']; $info['gid'] = $user_result['gidnumber'][0]; $info['mail'] = $user_result['mail'][0]; $info['name'] = $user_result['cn'][0]; $info['grps'] = array(); // overwrite if other attribs are specified. if (is_array($this->cnf['mapping'])) { foreach ($this->cnf['mapping'] as $localkey => $key) { if (is_array($key)) { // use regexp to clean up user_result list($key, $regexp) = each($key); if ($user_result[$key]) { foreach ($user_result[$key] as $grp) { if (preg_match($regexp, $grp, $match)) { if ($localkey == 'grps') { $info[$localkey][] = $match[1]; } else { $info[$localkey] = $match[1]; } } } } } else { $info[$localkey] = $user_result[$key][0]; } } } $user_result = array_merge($info, $user_result); //get groups for given user if grouptree is given if ($this->cnf['grouptree'] || $this->cnf['groupfilter']) { $base = $this->_makeFilter($this->cnf['grouptree'], $user_result); $filter = $this->_makeFilter($this->cnf['groupfilter'], $user_result); $sr = $this->_ldapsearch($this->con, $base, $filter, $this->cnf['groupscope'], array($this->cnf['groupkey'])); if ($this->cnf['debug']) { msg('LDAP group search: ' . htmlspecialchars(ldap_error($this->con)), 0, __LINE__, __FILE__); msg('LDAP search at: ' . htmlspecialchars($base . ' ' . $filter), 0, __LINE__, __FILE__); } if (!$sr) { msg("LDAP: Reading group memberships failed", -1); return false; } $result = ldap_get_entries($this->con, $sr); ldap_free_result($sr); if (is_array($result)) { foreach ($result as $grp) { if (!empty($grp[$this->cnf['groupkey']][0])) { if ($this->cnf['debug']) { msg('LDAP usergroup: ' . htmlspecialchars($grp[$this->cnf['groupkey']][0]), 0, __LINE__, __FILE__); } $info['grps'][] = $grp[$this->cnf['groupkey']][0]; } } } } // always add the default group to the list of groups if (!in_array($conf['defaultgroup'], $info['grps'])) { $info['grps'][] = $conf['defaultgroup']; } return $info; }
/** * Send a new password * * This function handles both phases of the password reset: * * - handling the first request of password reset * - validating the password reset auth token * * @author Benoit Chesneau <*****@*****.**> * @author Chris Smith <*****@*****.**> * @author Andreas Gohr <*****@*****.**> * * @return bool true on success, false on any error */ function act_resendpwd() { global $lang; global $conf; global $auth; if (!actionOK('resendpwd')) { msg($lang['resendna'], -1); return false; } $token = preg_replace('/[^a-f0-9]+/', '', $_REQUEST['pwauth']); if ($token) { // we're in token phase - get user info from token $tfile = $conf['cachedir'] . '/' . $token[0] . '/' . $token . '.pwauth'; if (!@file_exists($tfile)) { msg($lang['resendpwdbadauth'], -1); unset($_REQUEST['pwauth']); return false; } // token is only valid for 3 days if (time() - filemtime($tfile) > 3 * 60 * 60 * 24) { msg($lang['resendpwdbadauth'], -1); unset($_REQUEST['pwauth']); @unlink($tfile); return false; } $user = io_readfile($tfile); $userinfo = $auth->getUserData($user); if (!$userinfo['mail']) { msg($lang['resendpwdnouser'], -1); return false; } if (!$conf['autopasswd']) { // we let the user choose a password // password given correctly? if (!isset($_REQUEST['pass']) || $_REQUEST['pass'] == '') { return false; } if ($_REQUEST['pass'] != $_REQUEST['passchk']) { msg($lang['regbadpass'], -1); return false; } $pass = $_REQUEST['pass']; if (!$auth->triggerUserMod('modify', array($user, array('pass' => $pass)))) { msg('error modifying user data', -1); return false; } } else { // autogenerate the password and send by mail $pass = auth_pwgen(); if (!$auth->triggerUserMod('modify', array($user, array('pass' => $pass)))) { msg('error modifying user data', -1); return false; } if (auth_sendPassword($user, $pass)) { msg($lang['resendpwdsuccess'], 1); } else { msg($lang['regmailfail'], -1); } } @unlink($tfile); return true; } else { // we're in request phase if (!$_POST['save']) { return false; } if (empty($_POST['login'])) { msg($lang['resendpwdmissing'], -1); return false; } else { $user = trim($auth->cleanUser($_POST['login'])); } $userinfo = $auth->getUserData($user); if (!$userinfo['mail']) { msg($lang['resendpwdnouser'], -1); return false; } // generate auth token $token = md5(auth_cookiesalt() . $user); //secret but user based $tfile = $conf['cachedir'] . '/' . $token[0] . '/' . $token . '.pwauth'; $url = wl('', array('do' => 'resendpwd', 'pwauth' => $token), true, '&'); io_saveFile($tfile, $user); $text = rawLocale('pwconfirm'); $text = str_replace('@DOKUWIKIURL@', DOKU_URL, $text); $text = str_replace('@FULLNAME@', $userinfo['name'], $text); $text = str_replace('@LOGIN@', $user, $text); $text = str_replace('@TITLE@', $conf['title'], $text); $text = str_replace('@CONFIRM@', $url, $text); if (empty($conf['mailprefix'])) { $subject = $lang['regpwmail']; } else { $subject = '[' . $conf['mailprefix'] . '] ' . $lang['regpwmail']; } if (mail_send($userinfo['name'] . ' <' . $userinfo['mail'] . '>', $subject, $text, $conf['mailfrom'])) { msg($lang['resendpwdconfirm'], 1); } else { msg($lang['regmailfail'], -1); } return true; } return false; // never reached }
/** * Send a new password * * This function handles both phases of the password reset: * * - handling the first request of password reset * - validating the password reset auth token * * @author Benoit Chesneau <*****@*****.**> * @author Chris Smith <*****@*****.**> * @author Andreas Gohr <*****@*****.**> * * @return bool true on success, false on any error */ function act_resendpwd() { global $lang; global $conf; /* @var auth_basic $auth */ global $auth; /* @var Input $INPUT */ global $INPUT; if (!actionOK('resendpwd')) { msg($lang['resendna'], -1); return false; } $token = preg_replace('/[^a-f0-9]+/', '', $INPUT->str('pwauth')); if ($token) { // we're in token phase - get user info from token $tfile = $conf['cachedir'] . '/' . $token[0] . '/' . $token . '.pwauth'; if (!@file_exists($tfile)) { msg($lang['resendpwdbadauth'], -1); $INPUT->remove('pwauth'); return false; } // token is only valid for 3 days if (time() - filemtime($tfile) > 3 * 60 * 60 * 24) { msg($lang['resendpwdbadauth'], -1); $INPUT->remove('pwauth'); @unlink($tfile); return false; } $user = io_readfile($tfile); $userinfo = $auth->getUserData($user); if (!$userinfo['mail']) { msg($lang['resendpwdnouser'], -1); return false; } if (!$conf['autopasswd']) { // we let the user choose a password $pass = $INPUT->str('pass'); // password given correctly? if (!$pass) { return false; } if ($pass != $INPUT->str('passchk')) { msg($lang['regbadpass'], -1); return false; } // change it if (!$auth->triggerUserMod('modify', array($user, array('pass' => $pass)))) { msg('error modifying user data', -1); return false; } } else { // autogenerate the password and send by mail $pass = auth_pwgen(); if (!$auth->triggerUserMod('modify', array($user, array('pass' => $pass)))) { msg('error modifying user data', -1); return false; } if (auth_sendPassword($user, $pass)) { msg($lang['resendpwdsuccess'], 1); } else { msg($lang['regmailfail'], -1); } } @unlink($tfile); return true; } else { // we're in request phase if (!$INPUT->post->bool('save')) { return false; } if (!$INPUT->post->str('login')) { msg($lang['resendpwdmissing'], -1); return false; } else { $user = trim($auth->cleanUser($INPUT->post->str('login'))); } $userinfo = $auth->getUserData($user); if (!$userinfo['mail']) { msg($lang['resendpwdnouser'], -1); return false; } // generate auth token $token = md5(auth_cookiesalt() . $user); //secret but user based $tfile = $conf['cachedir'] . '/' . $token[0] . '/' . $token . '.pwauth'; $url = wl('', array('do' => 'resendpwd', 'pwauth' => $token), true, '&'); io_saveFile($tfile, $user); $text = rawLocale('pwconfirm'); $trep = array('FULLNAME' => $userinfo['name'], 'LOGIN' => $user, 'CONFIRM' => $url); $mail = new Mailer(); $mail->to($userinfo['name'] . ' <' . $userinfo['mail'] . '>'); $mail->subject($lang['regpwmail']); $mail->setBody($text, $trep); if ($mail->send()) { msg($lang['resendpwdconfirm'], 1); } else { msg($lang['regmailfail'], -1); } return true; } // never reached }
/** * Build a semi-secret fixed string identifying the current page and user * * This string is always the same for the current user when editing the same * page revision. */ function _fixedIdent() { global $ID; $lm = @filemtime(wikiFN($ID)); return auth_browseruid() . auth_cookiesalt() . $ID . $lm; }