public function test_substr() { // test that a substring with a starting and ending value works correctly $this->assert_equal(MultiByte::substr($this->test_strings['international'], 1, 3), $this->test_strings['international_substr_1_3']); // test that a substring with only a starting value works correctly $this->assert_equal(MultiByte::substr($this->test_strings['international'], 5), $this->test_strings['international_substr_5']); }
function test_substr() { printf("Test string: %s <br>", self::$test_str); printf("Habari encoding: %s <br>", MultiByte::hab_encoding()); printf("mb_internal_encoding: %s <br>", mb_internal_encoding()); printf("MultiByte detected encoding of test string: %s <br>", MultiByte::detect_encoding(self::$test_str)); printf("mbstring detected encoding of test string: %s <br>", mb_detect_encoding(self::$test_str)); $this->assert_equal(MultiByte::substr(self::$test_str, 1, 3), mb_substr(self::$test_str, 1, 3)); $this->assert_equal(MultiByte::substr(self::$test_str, 1, 3), mb_substr(self::$test_str, 1, 3, mb_detect_encoding(self::$test_str))); $this->assert_equal(MultiByte::substr(self::$test_str, 5), mb_substr(self::$test_str, 5)); printf(" MultiByte substring (begin-1 end-3): %s <br>", MultiByte::substr(self::$test_str, 1, 3)); printf(" MultiByte substring 2 (begin-5 end-null): %s <br>", MultiByte::substr(self::$test_str, 5)); printf(" mbstring substring without encoding detected (begin-1 end-3): %s <br>", mb_substr(self::$test_str, 1, 3)); printf(" mbstring substring with encoding detected (begin-1 end-3): %s <br>", mb_substr(self::$test_str, 1, 3, mb_detect_encoding(self::$test_str))); printf(" mbstring substring 2 without encoding detected(begin-5 end-null): %s <br>", mb_substr(self::$test_str, 5)); }
public function filter_user_authenticate($user, $username, $password) { $passwdfile = Options::get('passwdlogins__file'); if (!$passwdfile) { EventLog::log(_t('No passwd file configured!'), 'err', 'passwdlogins', 'passwdlogins'); return false; } if (!file_exists($passwdfile)) { EventLog::log(_t('Passwd file does not exist: %1$s', array($passwdfile)), 'err', 'passwdlogins', 'passwdlogins'); return false; } // go ahead and trim the user and password $username = trim($username); $password = trim($password); // blank usernames and passwords are not allowed if ($username == '' || $password == '') { return false; } $users = $this->parse_htpasswd($passwdfile); if (isset($users[$username])) { $crypt_pass = $users[$username]; if ($crypt_pass[0] == '{') { // figure out the algorithm used for this password $algo = MultiByte::strtolower(MultiByte::substr($crypt_pass, 1, MultiByte::strpos($crypt_pass, '}', 1) - 1)); $passok = false; switch ($algo) { case 'ssha': $hash = base64_decode(MultiByte::substr($crypt_pass, 6)); $passok = MultiByte::substr($hash, 0, 20) == pack("H*", sha1($password . MultiByte::substr($hash, 20))); break; case 'sha': $passok = '{SHA}' . base64_encode(pack("H*", sha1($password))) == $crypt_pass; break; } } else { // it's plain crypt $passok = crypt($password, MultiByte::substr($crypt_pass, 0, CRYPT_SALT_LENGTH)) == $crypt_pass; } if ($passok == true) { return $this->get_user($username); } } // returning $user would continue the login check through other plugins and core - we want to force passwd logins return false; }
/** * Commit $_SESSION data to the database for this user. */ public static function write() { if (!isset(self::$session_id)) { self::create(); } $remote_address = Utils::get_ip(); // not always set, even by real browsers $user_agent = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : ''; $dowrite = self::changed(); if (isset($_SESSION)) { // get the data from the ArrayObject $data = $_SESSION; } else { $dowrite = false; $data = array(); } // but let a plugin make the final decision. we may want to ignore search spiders, for instance $dowrite = Plugins::filter('session_write', $dowrite, self::$session_id, $data); if ($dowrite) { // DB::update() checks if the record key exists, and inserts if not $record = array('ip' => self::get_subnet($remote_address), 'expires' => DateTime::create()->int + self::$lifetime, 'ua' => MultiByte::substr($user_agent, 0, 255), 'data' => serialize($data)); DB::update(DB::table('sessions'), $record, array('token' => self::$session_id)); } }
?> "><?php echo $action['label']; ?> </a></li> <?php } ?> <?php } ?> </ul> </div> <span class="content" ><?php echo MultiByte::substr(strip_tags($post->content), 0, 250); ?> …</span> </div> <?php } } else { ?> <div class="message none"> <p><?php _e('No posts could be found to match the query criteria.'); ?> </p> </div> <?php
/** * get_url returns a fully-qualified URL * 'host' returns http://www.habariproject.org * 'habari' returns http://www.habariproject.org/habari, if you * have Habari installed into a /habari/ sub-directory * 'site' returns http://www.habariproject.org/site if * you are installing with a subdirectory path * 'user' returns one of the following: * http://www.habariproject.org/user * http://www.habariproject.org/user/sites/x.y.z * 'theme' returns one of the following: * http://www.habariproject.org/user/themes/theme_name * http://www.habariproject.org/user/sites/x.y.z/themes/theme_name * 'admin' returns http://www.habariproject.org/admin * 'admin_theme' returns http://www.habariproject.org/system/admin * 'login' returns http://www.habariproject.org/auth/login * 'logout' returns http://www.habariproject.org/auth/logout * 'system' returns http://www.habariproject.org/system * 'vendor' returns http://www.habariproject.org/system/vendor * 'scripts' returns http://www.habariproject.org/system/vendor * '3rdparty' returns http://www.habariproject.org/3rdparty * if /3rdparty does not exists, /system/vendor will be returned * 'hostname' returns www.habariproject.org * @param string $name the name of the URL to return * @param bool|string $trail whether to include a trailing slash, or a string to use as the trailing value. Default: false * @return string URL */ public static function get_url($name, $trail = false) { $url = ''; switch (strtolower($name)) { case 'host': $protocol = 'http'; // If we're running on a port other than 80, i // add the port number to the value returned // from host_url $port = 80; // Default in case not set. $port = Config::get('custom_http_port', isset($_SERVER['SERVER_PORT']) ? $_SERVER['SERVER_PORT'] : $port); $portpart = ''; $host = Site::get_url('hostname'); // if the port isn't a standard port, and isn't part of $host already, add it if ($port != 80 && $port != 443 && MultiByte::substr($host, MultiByte::strlen($host) - strlen($port)) != $port) { $portpart = ':' . $port; } if (isset($_SERVER['HTTPS']) && !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off') { $protocol = 'https'; } $protocol = Config::get('custom_http_protocol', $protocol); $url = $protocol . '://' . $host . $portpart; break; case 'habari': if (self::$habari_url == null) { self::$habari_url = Site::get_url('host'); // Am I installed into a subdir? $path = trim(dirname(Site::script_name()), '/\\'); if ('' != $path) { self::$habari_url .= '/' . $path; } } $url = self::$habari_url; break; case 'site': $url = Site::get_url('habari'); // Am I in a Habari subdir site? if (self::$config_type == Site::CONFIG_SUBDIR) { $url = Utils::end_in_slash($url) . self::$config_urldir; } break; case 'user': $url = Site::get_url('habari', true) . Site::get_path('user'); break; case 'theme': $theme = Themes::get_theme_dir(); if (file_exists(Site::get_dir('config') . '/themes/' . $theme)) { $url = Site::get_url('user') . '/themes/' . $theme; } elseif (file_exists(HABARI_PATH . '/user/themes/' . $theme)) { $url = Site::get_url('habari') . '/user/themes/' . $theme; } elseif (file_exists(HABARI_PATH . '/3rdparty/themes/' . $theme)) { $url = Site::get_url('habari') . '/3rdparty/themes/' . $theme; } else { $url = Site::get_url('habari') . '/system/themes/' . $theme; } break; case 'admin': $url = Site::get_url('site') . '/admin'; break; case 'admin_theme': $url = Site::get_url('habari') . '/system/admin'; break; case 'login': $url = Site::get_url('site') . '/auth/login'; break; case 'logout': $url = Site::get_url('site') . '/auth/logout'; break; case 'system': $url = Site::get_url('habari') . '/system'; break; case 'vendor': case 'scripts': $url = Site::get_url('system') . '/vendor'; break; case '3rdparty': // this should be removed at a later date as it will cause problems // once 'vendor' is adopted, dump the condition! if (file_exists(HABARI_PATH . '/3rdparty')) { $url = Site::get_url('habari') . '/3rdparty'; } else { $url = Site::get_url('vendor'); } break; case 'hostname': // HTTP_HOST is not set for HTTP/1.0 requests $url = $_SERVER['SERVER_PROTOCOL'] == 'HTTP/1.0' || !isset($_SERVER['HTTP_HOST']) ? $_SERVER['SERVER_NAME'] : $_SERVER['HTTP_HOST']; break; } $url .= Utils::trail($trail); $url = Plugins::filter('site_url_' . $name, $url); return $url; }
/** * Static helper function to quickly fetch an URL, with semantics similar to * PHP's file_get_contents. Does not support * * Returns the content on success or FALSE if an error occurred. * * @param string $url The URL to fetch * @param bool $use_include_path whether to search the PHP include path first (unsupported) * @param resource $context a stream context to use (unsupported) * @param int $offset how many bytes to skip from the beginning of the result * @param int $maxlen how many bytes to return * @return string description */ public static function get_contents($url, $use_include_path = FALSE, $context = NULL, $offset = 0, $maxlen = -1) { $rr = new RemoteRequest($url); if ($rr->execute() === TRUE) { return $maxlen != -1 ? MultiByte::substr($rr->get_response_body(), $offset, $maxlen) : MultiByte::substr($rr->get_response_body(), $offset); } else { return FALSE; } }
/** * Trims longer phrases to shorter ones with elipsis in the middle * @param string $str The string to truncate * @param integer $len The length of the returned string * @param bool $middle Whether to place the ellipsis in the middle (true) or at the end (false) * @return string The truncated string */ public static function truncate($str, $len = 10, $middle = true) { // make sure $len is a positive integer if (!is_numeric($len) || 0 > $len) { return $str; } // if the string is less than the length specified, bail out if (MultiByte::strlen($str) <= $len) { return $str; } // okay. Shuold we place the ellipse in the middle? if ($middle) { // yes, so compute the size of each half of the string $len = round(($len - 3) / 2); // and place an ellipse in between the pieces return MultiByte::substr($str, 0, $len) . '…' . MultiByte::substr($str, -$len); } else { // no, the ellipse goes at the end $len = $len - 3; return MultiByte::substr($str, 0, $len) . '…'; } }
/** * get_dir returns a complete filesystem path to the requested item * 'config_file' returns the complete path to the config.php file, including the filename * 'config' returns the path of the directory containing config.php * 'user' returns the path of the user directory * 'theme' returns the path of the site's active theme * @param string the name of the path item to return * @param bool whether to include a trailing slash. Default: No * @return string Path */ public static function get_dir( $name, $trail = false ) { $path = ''; switch ( strtolower( $name ) ) { case 'config_file': $path = Site::get_dir( 'config' ) . '/config.php'; break; case 'config': if ( self::$config_path ) { return self::$config_path; } self::$config_path = HABARI_PATH; $config_dirs = preg_replace( '/^' . preg_quote( HABARI_PATH, '/' ) . '\/user\/sites\/(.*)\/config.php/', '$1', Utils::glob( HABARI_PATH . '/user/sites/*/config.php' ) ); if ( empty( $config_dirs ) ) { return self::$config_path; } $server = InputFilter::parse_url( Site::get_url( 'habari' ) ); $server = ( isset( $server['port'] ) ) ? $server['port'] . '.' . $server['host'] . '.' : $server['host'] . '.'; $request = explode( '/', trim( $_SERVER['REQUEST_URI'], '/' ) ); $match = trim( $server, '.' ); $x = count( $request ); do { if ( in_array( $match, $config_dirs ) ) { self::$config_dir = $match; self::$config_path = HABARI_PATH . '/user/sites/' . self::$config_dir; self::$config_type = ( $x > 0 ) ? Site::CONFIG_SUBDOMAIN : Site::CONFIG_SUBDIR; break; } $match = MultiByte::substr( $match, MultiByte::strpos( $match, '.' ) + 1 ); $x--; } while ( MultiByte::strpos( $match, '.' ) !== false ); $path = self::$config_path; break; case 'user': if ( Site::get_dir( 'config' ) == HABARI_PATH ) { $path = HABARI_PATH . '/user'; } else { $path = Site::get_dir( 'config' ); } break; case 'theme': $theme = Themes::get_theme_dir(); if ( file_exists( Site::get_dir( 'config' ) . '/themes/' . $theme ) ) { $path = Site::get_dir( 'user' ) . '/themes/' . $theme; } elseif ( file_exists( HABARI_PATH . '/user/themes/' . $theme ) ) { $path = HABARI_PATH . '/user/themes/' . $theme; } elseif ( file_exists( HABARI_PATH . '/3rdparty/themes/' . $theme ) ) { $url = Site::get_url( 'habari' ) . '/3rdparty/themes/' . $theme; } else { $path = HABARI_PATH . '/system/themes/' . $theme; } break; case 'admin_theme': $path = HABARI_PATH . '/system/admin'; break; case 'vendor': $path = HABARI_PATH . '/system/vendor'; break; } $path .= Utils::trail( $trail ); $path = Plugins::filter( 'site_dir_' . $name, $path ); return $path; }
/** * Get a fully-qualified URL from a filesystem path * * @param string $path The filesystem path * @param string|bool $trail If true, include a trailing slash. If string, append this to the requested url. Default: Add nothing. * @param bool $preserve_file If true, leave the filename on the URL. Default: Remove filename. * @return string URL */ public static function get_from_filesystem($path, $trail = false, $preserve_file = false) { if (!$preserve_file) { $path = dirname($path); } $url = Site::get_url('habari') . MultiByte::substr($path, MultiByte::strlen(HABARI_PATH)); // Replace windows paths with forward slashes $url = str_replace('\\', '/', $url); $url .= Utils::trail($trail); return $url; }
/** * Write the default options */ private function create_default_options() { // Create the default options Options::set('installed', true); Options::set('title', $this->handler_vars['blog_title']); Options::set('base_url', MultiByte::substr($_SERVER['REQUEST_URI'], 0, MultiByte::strrpos($_SERVER['REQUEST_URI'], '/') + 1)); Options::set('pagination', '5'); Options::set('atom_entries', '5'); Options::set('theme_name', 'k2'); Options::set('theme_dir', 'k2'); Options::set('comments_require_id', 1); Options::set('locale', $this->handler_vars['locale']); Options::set('timezone', 'UTC'); Options::set('dateformat', 'Y-m-d'); Options::set('timeformat', 'g:i a'); // generate a random-ish number to use as the salt for // a SHA1 hash that will serve as the unique identifier for // this installation. Also for use in cookies Options::set('GUID', sha1(Options::get('base_url') . Utils::nonce())); // Let's prepare the EventLog here, as well EventLog::register_type('default', 'habari'); EventLog::register_type('user', 'habari'); EventLog::register_type('authentication', 'habari'); EventLog::register_type('content', 'habari'); EventLog::register_type('comment', 'habari'); // Add the cronjob to truncate the log so that it doesn't get too big CronTab::add_daily_cron('truncate_log', array('Utils', 'truncate_log'), _t('Truncate the log table')); return true; }
/** * Stores the list of plugins that are present (not necessarily active) in * the Options table for future comparison. */ public static function set_present() { $plugin_files = Plugins::list_all(); // strip base path foreach ($plugin_files as $plugin_file) { $plugin_file = MultiByte::substr($plugin_file, MultiByte::strlen(HABARI_PATH)); } $plugin_data = array_map(function ($a) { return array('file' => $a, 'checksum' => md5_file($a)); }, $plugin_files); Options::set('plugins_present', $plugin_data); }
<span class="state pct10"><a href="<?php URL::out('admin', array('page' => 'posts', 'type' => $post->content_type, 'status' => $post->status ) ); ?>" title="<?php _e('Search for other %s items', array( MultiByte::ucfirst( Plugins::filter( "post_status_display", $post->statusname ) ) ) ); ?>"><?php echo MultiByte::ucfirst( Plugins::filter( "post_status_display", $post->statusname ) ); ?></a></span> <span class="author pct20"><span class="dim"><?php _e('by'); ?></span> <a href="<?php URL::out('admin', array('page' => 'posts', 'user_id' => $post->user_id, 'type' => $post->content_type, 'status' => 'any') ); ?>" title="<?php _e('Search for other items by %s', array( $post->author->displayname ) ) ?>"><?php echo $post->author->displayname; ?></a></span> <span class="date pct15"><span class="dim"><?php _e('on'); ?></span> <a href="<?php URL::out('admin', array('page' => 'posts', 'type' => $post->content_type, 'year_month' => $post->pubdate->get('Y-m') ) ); ?>" title="<?php _e('Search for other items from %s', array( $post->pubdate->get( 'M, Y' ) ) ); ?>"><?php $post->pubdate->out( HabariDateTime::get_default_date_format() ); ?></a></span> <span class="time pct10"><span class="dim"><?php _e('at'); ?> <?php $post->pubdate->out( HabariDateTime::get_default_time_format()); ?></span></span> <ul class="dropbutton"> <?php $actions = array( 'edit' => array('url' => URL::get('admin', 'page=publish&id=' . $post->id), 'title' => sprintf( _t('Edit \'%s\''), $post->title ), 'label' => _t('Edit'), 'permission' => 'edit' ), 'view' => array('url' => $post->permalink . '?preview=1', 'title' => sprintf( _t('View \'%s\''), $post->title ), 'label' => _t('View') ), 'remove' => array('url' => 'javascript:itemManage.remove('. $post->id . ', \'post\');', 'title' => _t('Delete this item'), 'label' => _t('Delete'), 'permission' => 'delete' ) ); $actions = Plugins::filter('post_actions', $actions, $post); foreach( $actions as $action ) : ?> <?php if ( !isset( $action['permission'] ) || ACL::access_check( $post_permissions, $action['permission'] ) ) { ?> <li><a href="<?php echo $action['url']; ?>" title="<?php echo $action['title']; ?>"><?php echo $action['label']; ?></a></li> <?php } ?> <?php endforeach; ?> </ul> </div> <span class="content" ><?php echo MultiByte::substr( strip_tags( $post->content ), 0, 250); ?>…</span> </div> <?php endforeach; else : ?> <div class="message none"> <p><?php _e('No posts could be found to match the query criteria.'); ?></p> </div> <?php endif; ?>
public function testSubstr() { $this->assertEquals(MultiByte::substr(self::$test_str, 1, 3), mb_substr(self::$test_str, 1, 3)); $this->assertEquals(MultiByte::substr(self::$test_str, 1, 3), mb_substr(self::$test_str, 1, 3, mb_detect_encoding(self::$test_str))); $this->assertEquals(MultiByte::substr(self::$test_str, 5), mb_substr(self::$test_str, 5)); }
/** * Parse tag parameters from a URL string * * @param String $tags The URL parameter string * * @return Array. Associative array of included and excluded tags */ public static function parse_url_tags($tags, $objectify = false) { $tags = explode(' ', $tags); $exclude_tag = array(); $include_tag = array(); foreach ($tags as $tag) { if (MultiByte::substr($tag, 0, 1) == '-') { $tag = MultiByte::substr($tag, 1); $exclude_tag[] = $objectify ? Tags::get_one(Utils::slugify($tag)) : Utils::slugify($tag); } else { $include_tag[] = $objectify ? Tags::get_one(Utils::slugify($tag)) : Utils::slugify($tag); } } return compact('include_tag', 'exclude_tag'); }
/** * Commit $_SESSION data to the database for this user. * * @param string $session_id The PHP-generated session id * @param string $data Data from session stored as a string */ public static function write($session_id, $data) { $remote_address = Utils::get_ip(); // not always set, even by real browsers $user_agent = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : ''; // default to writing the data only if it's changed if (self::$initial_data !== $data) { $dowrite = true; } else { $dowrite = false; } // but let a plugin make the final decision. we may want to ignore search spiders, for instance $dowrite = Plugins::filter('session_write', $dowrite, $session_id, $data); if ($dowrite) { // DB::update() checks if the record key exists, and inserts if not $record = array('ip' => self::get_subnet($remote_address), 'expires' => HabariDateTime::date_create()->int + self::$lifetime, 'ua' => MultiByte::substr($user_agent, 0, 255), 'data' => $data); DB::update(DB::table('sessions'), $record, array('token' => $session_id)); } }
/** * Handles AJAX requests from media silos. */ public function ajax_media($handler_vars) { Utils::check_request_method(array('POST')); $path = $handler_vars['path']; $rpath = $path; $silo = Media::get_silo($rpath, true); // get_silo sets $rpath by reference to the path inside the silo $assets = Media::dir($path); $output = array('ok' => 1, 'dirs' => array(), 'files' => array(), 'path' => $path); foreach ($assets as $asset) { if ($asset->is_dir) { $output['dirs'][$asset->basename] = $asset->get_props(); } else { $output['files'][$asset->basename] = $asset->get_props(); } } $rootpath = MultiByte::strpos($path, '/') !== false ? MultiByte::substr($path, 0, MultiByte::strpos($path, '/')) : $path; $controls = array('root' => '<a href="#" onclick="habari.media.fullReload();habari.media.showdir(\'' . $rootpath . '\');return false;">' . _t('Root') . '</a>'); $controls = Plugins::filter('media_controls', $controls, $silo, $rpath, ''); $controls_out = ''; foreach ($controls as $k => $v) { if (is_numeric($k)) { $controls_out .= "<li>{$v}</li>"; } else { $controls_out .= "<li class=\"{$k}\">{$v}</li>"; } } $output['controls'] = $controls_out; echo json_encode($output); }
/** * Stores the list of plugins that are present (not necessarily active) in * the Options table for future comparison. */ public static function set_present() { $plugin_files = Plugins::list_all(); // strip base path foreach ( $plugin_files as $plugin_file ) { $plugin_file = MultiByte::substr( $file, MultiByte::strlen( HABARI_PATH ) ); } $plugin_data = array_map( create_function( '$a', 'return array( "file" => $a, "checksum" => md5_file( $a ) );' ), $plugin_files ); Options::set( 'plugins_present', $plugin_data ); }
/** * Static helper function to quickly fetch an URL, with semantics similar to * PHP's file_get_contents. Does not support * * Returns the content on success or false if an error occurred. * * @param string $url The URL to fetch * @param bool $use_include_path whether to search the PHP include path first (unsupported) * @param resource $context a stream context to use (unsupported) * @param int $offset how many bytes to skip from the beginning of the result * @param int $maxlen how many bytes to return * @return string description */ public static function get_contents($url, $use_include_path = false, $context = null, $offset = 0, $maxlen = -1) { try { $rr = new RemoteRequest($url); if ($rr->execute() === true) { return $maxlen != -1 ? MultiByte::substr($rr->get_response_body(), $offset, $maxlen) : MultiByte::substr($rr->get_response_body(), $offset); } else { return false; } } catch (Exception $e) { // catch any exceptions to try and emulate file_get_contents() as closely as possible. // if you want more control over the errors, instantiate RemoteRequest manually return false; } }
private function _unchunk($body) { /* see <http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html> */ $result = ''; $chunk_size = 0; do { $chunk = explode("\r\n", $body, 2); list($chunk_size_str, ) = explode(';', $chunk[0], 2); $chunk_size = hexdec($chunk_size_str); if ($chunk_size > 0) { $result .= MultiByte::substr($chunk[1], 0, $chunk_size); $body = MultiByte::substr($chunk[1], $chunk_size + 1); } } while ($chunk_size > 0); // this ignores trailing header fields return $result; }
/** * Either just display the login form; or check a user's credentials, and * create a session for them; or handle a password reset request. */ public function act_login() { // If we're a reset password request, do that. if (isset($_POST['submit_button']) && $_POST['submit_button'] === _t('Reset password')) { Utils::check_request_method(array('POST')); $name = $this->handler_vars['habari_username']; if ($name !== NULL) { if (!is_numeric($name) && ($user = User::get($name))) { $hash = Utils::random_password(); $user->info->password_reset = md5($hash); $user->info->commit(); $message = _t('Please visit %1$s to reset your password.', array(URL::get('user', array('page' => 'password_reset', 'id' => $user->id, 'hash' => $hash)))); Utils::mail($user->email, _t('[%1$s] Password reset request for %2$s', array(Options::get('title'), $user->displayname)), $message); } // Moving this inside the check for user existence would allow attackers to test usernames, so don't Session::notice(_t('A password reset request has been sent to the user.')); } } else { Utils::check_request_method(array('GET', 'HEAD', 'POST')); $name = $_POST['habari_username']; $pass = $_POST['habari_password']; if (NULL != $name || NULL != $pass) { $user = User::authenticate($name, $pass); if ($user instanceof User && FALSE != $user) { /* Successfully authenticated. */ // Timestamp last login date and time. $user->info->authenticate_time = date('Y-m-d H:i:s'); $user->update(); // Remove left over expired session error message. if (Session::has_errors('expired_session')) { Session::remove_error('expired_session'); } $login_session = Session::get_set('login'); if (!empty($login_session)) { /* Now that we know we're dealing with the same user, transfer the form data so he does not lose his request */ if (!empty($login_session['post_data'])) { Session::add_to_set('last_form_data', $last_form_data['post'], 'post'); } if (!empty($login_session['get_data'])) { Session::add_to_set('last_form_data', $last_form_data['get'], 'get'); } /* Redirect to the correct admin page */ $dest = explode('/', MultiByte::substr($login_session['original'], MultiByte::strpos($login_session['original'], 'admin/'))); if ('' == $dest[0]) { $login_dest = Site::get_url('admin'); } else { // Replace '?' with '&' in $dest[1] before call URL::get() // Therefore calling URL::get() with a query string $dest[1] = str_replace('?', '&', $dest[1]); $login_dest = URL::get('admin', 'page=' . $dest[1]); } } else { $login_session = null; $login_dest = Site::get_url('admin'); } // filter the destination $login_dest = Plugins::filter('login_redirect_dest', $login_dest, $user, $login_session); // finally, redirect to the destination Utils::redirect($login_dest); return TRUE; } /* Authentication failed. */ // Remove submitted password, see, we're secure! $_POST['habari_password'] = ''; $this->handler_vars['error'] = _t('Bad credentials'); } } // Display the login form. $this->login_form($name); }
public function execute($method, $url, $headers, $body, $timeout) { $merged_headers = array(); foreach ($headers as $k => $v) { $merged_headers[] = $k . ': ' . $v; } $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); // The URL. curl_setopt($ch, CURLOPT_HEADERFUNCTION, array(&$this, '_headerfunction')); // The header of the response. curl_setopt($ch, CURLOPT_MAXREDIRS, $this->max_redirs); // Maximum number of redirections to follow. if ($this->can_followlocation) { curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); // Follow 302's and the like. } curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout); curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); curl_setopt($ch, CURLOPT_HTTPHEADER, $merged_headers); // headers to send if ($method === 'POST') { curl_setopt($ch, CURLOPT_POST, true); // POST mode. curl_setopt($ch, CURLOPT_POSTFIELDS, $body); } else { curl_setopt($ch, CURLOPT_CRLF, true); // Convert UNIX newlines to \r\n } /** * @todo Possibly find a way to generate a temp file without needing the user * to set write permissions on cache directory * * @todo Fallback to using the the old way if the cache directory isn't writable */ $tmp = tempnam(FILE_CACHE_LOCATION, 'RR'); if (!$tmp) { return Error::raise(_t(' %s: CURL Error. Unable to create temporary file name.', array(__CLASS__)), E_USER_WARNING); } $fh = @fopen($tmp, 'w+b'); if (!$fh) { return Error::raise(_t(' %s: CURL Error. Unable to open temporary file.', array(__CLASS__)), E_USER_WARNING); } curl_setopt($ch, CURLOPT_FILE, $fh); $success = curl_exec($ch); if ($success) { rewind($fh); $body = stream_get_contents($fh); } fclose($fh); unset($fh); if (isset($tmp) && file_exists($tmp)) { unlink($tmp); } if (curl_errno($ch) !== 0) { return Error::raise(sprintf(_t('%s: CURL Error %d: %s'), __CLASS__, curl_errno($ch), curl_error($ch)), E_USER_WARNING); } if (substr(curl_getinfo($ch, CURLINFO_HTTP_CODE), 0, 1) != 2) { return Error::raise(sprintf(_t('Bad return code (%1$d) for: %2$s'), curl_getinfo($ch, CURLINFO_HTTP_CODE), $url), E_USER_WARNING); } curl_close($ch); // this fixes an E_NOTICE in the array_pop $tmp_headers = explode("\r\n\r\n", MultiByte::substr($this->_headers, 0, -4)); $this->response_headers = array_pop($tmp_headers); $this->response_body = $body; $this->executed = true; return true; }