diff options
Diffstat (limited to 'lib')
27 files changed, 524 insertions, 336 deletions
diff --git a/lib/base.php b/lib/base.php index 6ea77aa7a58..7098f480e27 100644 --- a/lib/base.php +++ b/lib/base.php @@ -213,6 +213,34 @@ class OC { } } + /* + * This function adds some security related headers to all requests served via base.php + * The implementation of this function has to happen here to ensure that all third-party + * components (e.g. SabreDAV) also benefit from this headers. + */ + public static function addSecurityHeaders() { + header('X-XSS-Protection: 1; mode=block'); // Enforce browser based XSS filters + header('X-Content-Type-Options: nosniff'); // Disable sniffing the content type for IE + + // iFrame Restriction Policy + $xFramePolicy = OC_Config::getValue('xframe_restriction', true); + if($xFramePolicy) { + header('X-Frame-Options: Sameorigin'); // Disallow iFraming from other domains + } + + // Content Security Policy + // If you change the standard policy, please also change it in config.sample.php + $policy = OC_Config::getValue('custom_csp_policy', + 'default-src \'self\'; ' + .'script-src \'self\' \'unsafe-eval\'; ' + .'style-src \'self\' \'unsafe-inline\'; ' + .'frame-src *; ' + .'img-src *; ' + .'font-src \'self\' data:; ' + .'media-src *'); + header('Content-Security-Policy:'.$policy); + } + public static function checkSSL() { // redirect to https site if configured if (OC_Config::getValue("forcessl", false)) { @@ -512,6 +540,7 @@ class OC { self::checkConfig(); self::checkInstalled(); self::checkSSL(); + self::addSecurityHeaders(); $errors = OC_Util::checkServer(); if (count($errors) > 0) { diff --git a/lib/l10n/ca.php b/lib/l10n/ca.php index 477cdf2925b..22d8c457f5e 100644 --- a/lib/l10n/ca.php +++ b/lib/l10n/ca.php @@ -67,6 +67,7 @@ $TRANSLATIONS = array( "_%n month ago_::_%n months ago_" => array("fa %n mes","fa %n mesos"), "last year" => "l'any passat", "years ago" => "anys enrere", +"Only the following characters are allowed in a username: \"a-z\", \"A-Z\", \"0-9\", and \"_.@-\"" => "Només els carà cters següents estan permesos en el nom d'usuari: \"a-z\", \"A-Z\", \"0-9\" i \"_.@-\"", "A valid username must be provided" => "Heu de facilitar un nom d'usuari và lid", "A valid password must be provided" => "Heu de facilitar una contrasenya và lida", "The username is already being used" => "El nom d'usuari ja està en ús" diff --git a/lib/private/appframework/dependencyinjection/dicontainer.php b/lib/private/appframework/dependencyinjection/dicontainer.php index 78224ea54c0..e478225a53d 100644 --- a/lib/private/appframework/dependencyinjection/dicontainer.php +++ b/lib/private/appframework/dependencyinjection/dicontainer.php @@ -92,8 +92,8 @@ class DIContainer extends SimpleContainer implements IAppContainer{ return new SecurityMiddleware($app, $c['Request']); }); - $middleWares = $this->middleWares; - $this['MiddlewareDispatcher'] = $this->share(function($c) use ($middleWares) { + $middleWares = &$this->middleWares; + $this['MiddlewareDispatcher'] = $this->share(function($c) use (&$middleWares) { $dispatcher = new MiddlewareDispatcher(); $dispatcher->registerMiddleware($c['SecurityMiddleware']); diff --git a/lib/private/appframework/http/request.php b/lib/private/appframework/http/request.php index 40f47a7bd2f..643fa685adc 100644 --- a/lib/private/appframework/http/request.php +++ b/lib/private/appframework/http/request.php @@ -60,7 +60,14 @@ class Request implements \ArrayAccess, \Countable, IRequest { * @param string|false 'requesttoken' the requesttoken or false when not available * @see http://www.php.net/manual/en/reserved.variables.php */ - public function __construct(array $vars=array()) { + public function __construct(array $vars=array(), $stream='php://input') { + + $this->inputStream = $stream; + $this->items['params'] = array(); + + if(!array_key_exists('method', $vars)) { + $vars['method'] = 'GET'; + } foreach($this->allowedKeys as $name) { $this->items[$name] = isset($vars[$name]) @@ -68,25 +75,32 @@ class Request implements \ArrayAccess, \Countable, IRequest { : array(); } - if (defined('PHPUNIT_RUN') && PHPUNIT_RUN - && in_array('fakeinput', stream_get_wrappers())) { - $this->inputStream = 'fakeinput://data'; - } else { - $this->inputStream = 'php://input'; - } - - // Only 'application/x-www-form-urlencoded' requests are automatically - // transformed by PHP, 'application/json' must be decoded manually. - if ($this->method === 'POST' - && strpos($this->getHeader('Content-Type'), 'application/json') !== false - ) { - $this->items['params'] = $this->items['post'] = json_decode(file_get_contents($this->inputStream), true); - } + // 'application/json' must be decoded manually. + if (strpos($this->getHeader('Content-Type'), 'application/json') !== false) { + $params = json_decode(file_get_contents($this->inputStream), true); + if(count($params) > 0) { + $this->items['params'] = $params; + if($vars['method'] === 'POST') { + $this->items['post'] = $params; + } + } + // Handle application/x-www-form-urlencoded for methods other than GET + // or post correctly + } elseif($vars['method'] !== 'GET' + && $vars['method'] !== 'POST' + && strpos($this->getHeader('Content-Type'), 'application/x-www-form-urlencoded') !== false) { + + parse_str(file_get_contents($this->inputStream), $params); + if(is_array($params)) { + $this->items['params'] = $params; + } + } $this->items['parameters'] = array_merge( $this->items['get'], $this->items['post'], - $this->items['urlParams'] + $this->items['urlParams'], + $this->items['params'] ); } @@ -313,47 +327,22 @@ class Request implements \ArrayAccess, \Countable, IRequest { * @throws \LogicException */ protected function getContent() { - if ($this->content === false && $this->method === 'PUT') { - throw new \LogicException( - '"put" can only be accessed once if not ' - . 'application/x-www-form-urlencoded or application/json.' - ); - } - // If the content can't be parsed into an array then return a stream resource. if ($this->method === 'PUT' && strpos($this->getHeader('Content-Type'), 'application/x-www-form-urlencoded') === false && strpos($this->getHeader('Content-Type'), 'application/json') === false ) { + if ($this->content === false) { + throw new \LogicException( + '"put" can only be accessed once if not ' + . 'application/x-www-form-urlencoded or application/json.' + ); + } $this->content = false; return fopen($this->inputStream, 'rb'); + } else { + return $this->parameters; } - - if (is_null($this->content)) { - $this->content = file_get_contents($this->inputStream); - - /* - * Normal jquery ajax requests are sent as application/x-www-form-urlencoded - * and in $_GET and $_POST PHP transformes the data into an array. - * The first condition mimics this. - * The second condition allows for sending raw application/json data while - * still getting the result as an array. - * - */ - if (strpos($this->getHeader('Content-Type'), 'application/x-www-form-urlencoded') !== false) { - parse_str($this->content, $content); - if(is_array($content)) { - $this->content = $content; - } - } elseif (strpos($this->getHeader('Content-Type'), 'application/json') !== false) { - $content = json_decode($this->content, true); - if(is_array($content)) { - $this->content = $content; - } - } - } - - return $this->content; } /** diff --git a/lib/private/connector/sabre/file.php b/lib/private/connector/sabre/file.php index ef6caaf22a7..750d646a8f5 100644 --- a/lib/private/connector/sabre/file.php +++ b/lib/private/connector/sabre/file.php @@ -205,10 +205,12 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D */ public function getContentType() { if (isset($this->fileinfo_cache['mimetype'])) { - return $this->fileinfo_cache['mimetype']; + $mimeType = $this->fileinfo_cache['mimetype']; + } else { + $mimeType = \OC\Files\Filesystem::getMimeType($this->path); } - return \OC\Files\Filesystem::getMimeType($this->path); + return \OC_Helper::getSecureMimeType($mimeType); } diff --git a/lib/private/davclient.php b/lib/private/davclient.php index afa4e1103b4..916dc11d17a 100644 --- a/lib/private/davclient.php +++ b/lib/private/davclient.php @@ -29,6 +29,8 @@ class OC_DAVClient extends \Sabre_DAV_Client { protected $requestTimeout; + protected $verifyHost; + /** * @brief Sets the request timeout or 0 to disable timeout. * @param integer $timeout in seconds or 0 to disable @@ -37,10 +39,21 @@ class OC_DAVClient extends \Sabre_DAV_Client { $this->requestTimeout = (int)$timeout; } + /** + * @brief Sets the CURLOPT_SSL_VERIFYHOST setting + * @param integer $value value to set CURLOPT_SSL_VERIFYHOST to + */ + public function setVerifyHost($value) { + $this->verifyHost = $value; + } + protected function curlRequest($url, $settings) { if ($this->requestTimeout > 0) { $settings[CURLOPT_TIMEOUT] = $this->requestTimeout; } + if (!is_null($this->verifyHost)) { + $settings[CURLOPT_SSL_VERIFYHOST] = $this->verifyHost; + } return parent::curlRequest($url, $settings); } } diff --git a/lib/private/files/type/detection.php b/lib/private/files/type/detection.php index 11e439032ce..8ee53917814 100644 --- a/lib/private/files/type/detection.php +++ b/lib/private/files/type/detection.php @@ -17,24 +17,40 @@ namespace OC\Files\Type; */ class Detection { protected $mimetypes = array(); + protected $secureMimeTypes = array(); /** - * add an extension -> mimetype mapping + * Add an extension -> mimetype mapping + * + * $mimetype is the assumed correct mime type + * The optional $secureMimeType is an alternative to send to send + * to avoid potential XSS. * * @param string $extension * @param string $mimetype + * @param string|null $secureMimeType */ - public function registerType($extension, $mimetype) { - $this->mimetypes[$extension] = $mimetype; + public function registerType($extension, $mimetype, $secureMimeType = null) { + $this->mimetypes[$extension] = array($mimetype, $secureMimeType); + $this->secureMimeTypes[$mimetype] = $secureMimeType ?: $mimetype; } /** - * add an array of extension -> mimetype mappings + * Add an array of extension -> mimetype mappings + * + * The mimetype value is in itself an array where the first index is + * the assumed correct mimetype and the second is either a secure alternative + * or null if the correct is considered secure. * * @param array $types */ public function registerTypeArray($types) { $this->mimetypes = array_merge($this->mimetypes, $types); + + // Update the alternative mimetypes to avoid having to look them up each time. + foreach ($this->mimetypes as $mimeType) { + $this->secureMimeTypes[$mimeType[0]] = $mimeType[1] ?: $mimeType[0]; + } } /** @@ -48,7 +64,9 @@ class Detection { //try to guess the type by the file extension $extension = strtolower(strrchr(basename($path), ".")); $extension = substr($extension, 1); //remove leading . - return (isset($this->mimetypes[$extension])) ? $this->mimetypes[$extension] : 'application/octet-stream'; + return (isset($this->mimetypes[$extension]) && isset($this->mimetypes[$extension][0])) + ? $this->mimetypes[$extension][0] + : 'application/octet-stream'; } else { return 'application/octet-stream'; } @@ -123,4 +141,16 @@ class Detection { return $mime; } } + + /** + * Get a secure mimetype that won't expose potential XSS. + * + * @param string $mimeType + * @return string + */ + public function getSecureMimeType($mimeType) { + return isset($this->secureMimeTypes[$mimeType]) + ? $this->secureMimeTypes[$mimeType] + : 'application/octet-stream'; + } } diff --git a/lib/private/files/view.php b/lib/private/files/view.php index 94be7114865..519ed250b1f 100644 --- a/lib/private/files/view.php +++ b/lib/private/files/view.php @@ -629,10 +629,21 @@ class View { } public function fromTmpFile($tmpFile, $path) { + if (Filesystem::isValidPath($path)) { + + // Get directory that the file is going into + $filePath = dirname($path); + + // Create the directories if any + if (!$this->file_exists($filePath)) { + $this->mkdir($filePath); + } + if (!$tmpFile) { debug_print_backtrace(); } + $source = fopen($tmpFile, 'r'); if ($source) { $this->file_put_contents($path, $source); diff --git a/lib/private/group/backend.php b/lib/private/group/backend.php index 2e17b5d0b7f..b0ed0d90d76 100644 --- a/lib/private/group/backend.php +++ b/lib/private/group/backend.php @@ -34,6 +34,7 @@ define('OC_GROUP_BACKEND_DELETE_GROUP', 0x00000010); define('OC_GROUP_BACKEND_ADD_TO_GROUP', 0x00000100); define('OC_GROUP_BACKEND_REMOVE_FROM_GOUP', 0x00001000); define('OC_GROUP_BACKEND_GET_DISPLAYNAME', 0x00010000); +define('OC_GROUP_BACKEND_COUNT_USERS', 0x00100000); /** * Abstract base class for user management @@ -45,6 +46,7 @@ abstract class OC_Group_Backend implements OC_Group_Interface { OC_GROUP_BACKEND_ADD_TO_GROUP => 'addToGroup', OC_GROUP_BACKEND_REMOVE_FROM_GOUP => 'removeFromGroup', OC_GROUP_BACKEND_GET_DISPLAYNAME => 'displayNamesInGroup', + OC_GROUP_BACKEND_COUNT_USERS => 'countUsersInGroup', ); /** diff --git a/lib/private/group/database.php b/lib/private/group/database.php index d0974685ff6..3815dcff2e5 100644 --- a/lib/private/group/database.php +++ b/lib/private/group/database.php @@ -212,6 +212,20 @@ class OC_Group_Database extends OC_Group_Backend { } /** + * @brief get the number of all users matching the search string in a group + * @param string $gid + * @param string $search + * @param int $limit + * @param int $offset + * @return int | false + */ + public function countUsersInGroup($gid, $search = '') { + $stmt = OC_DB::prepare('SELECT COUNT(`uid`) AS `count` FROM `*PREFIX*group_user` WHERE `gid` = ? AND `uid` LIKE ?'); + $result = $stmt->execute(array($gid, $search.'%')); + return $result->fetchOne(); + } + + /** * @brief get a list of all display names in a group * @param string $gid * @param string $search diff --git a/lib/private/group/dummy.php b/lib/private/group/dummy.php index da26e1b910e..94cbb607ad1 100644 --- a/lib/private/group/dummy.php +++ b/lib/private/group/dummy.php @@ -157,4 +157,14 @@ class OC_Group_Dummy extends OC_Group_Backend { } } + /** + * @brief get the number of all users in a group + * @returns int | bool + */ + public function countUsersInGroup($gid, $search = '', $limit = -1, $offset = 0) { + if(isset($this->groups[$gid])) { + return count($this->groups[$gid]); + } + } + } diff --git a/lib/private/group/group.php b/lib/private/group/group.php index 8d2aa87a788..3efbb6e7023 100644 --- a/lib/private/group/group.php +++ b/lib/private/group/group.php @@ -172,12 +172,6 @@ class Group { $users = array(); foreach ($this->backends as $backend) { $userIds = $backend->usersInGroup($this->gid, $search, $limit, $offset); - if (!is_null($limit)) { - $limit -= count($userIds); - } - if (!is_null($offset)) { - $offset -= count($userIds); - } $users += $this->getVerifiedUsers($userIds); if (!is_null($limit) and $limit <= 0) { return array_values($users); @@ -187,6 +181,27 @@ class Group { } /** + * returns the number of users matching the search string + * + * @param string $search + * @return int | bool + */ + public function count($search) { + $users = false; + foreach ($this->backends as $backend) { + if($backend->implementsActions(OC_GROUP_BACKEND_COUNT_USERS)) { + if($users === false) { + //we could directly add to a bool variable, but this would + //be ugly + $users = 0; + } + $users += $backend->countUsersInGroup($this->gid, $search); + } + } + return $users; + } + + /** * search for users in the group by displayname * * @param string $search @@ -202,12 +217,6 @@ class Group { } else { $userIds = $backend->usersInGroup($this->gid, $search, $limit, $offset); } - if (!is_null($limit)) { - $limit -= count($userIds); - } - if (!is_null($offset)) { - $offset -= count($userIds); - } $users = $this->getVerifiedUsers($userIds); if (!is_null($limit) and $limit <= 0) { return array_values($users); diff --git a/lib/private/group/manager.php b/lib/private/group/manager.php index 9b433b64fd4..f591bd32aba 100644 --- a/lib/private/group/manager.php +++ b/lib/private/group/manager.php @@ -134,12 +134,6 @@ class Manager extends PublicEmitter { $groups = array(); foreach ($this->backends as $backend) { $groupIds = $backend->getGroups($search, $limit, $offset); - if (!is_null($limit)) { - $limit -= count($groupIds); - } - if (!is_null($offset)) { - $offset -= count($groupIds); - } foreach ($groupIds as $groupId) { $groups[$groupId] = $this->getGroupObject($groupId); } diff --git a/lib/private/helper.php b/lib/private/helper.php index da3d3cd1c6e..d5214823de9 100644 --- a/lib/private/helper.php +++ b/lib/private/helper.php @@ -431,6 +431,16 @@ class OC_Helper { } /** + * Get a secure mimetype that won't expose potential XSS. + * + * @param string $mimeType + * @return string + */ + static function getSecureMimeType($mimeType) { + return self::getMimetypeDetector()->getSecureMimeType($mimeType); + } + + /** * get the mimetype form a data string * * @param string $data diff --git a/lib/private/json.php b/lib/private/json.php index 4ccdb490a6c..34f81c3b8cf 100644 --- a/lib/private/json.php +++ b/lib/private/json.php @@ -119,8 +119,6 @@ class OC_JSON{ * Encode and print $data in json format */ public static function encodedPrint($data, $setContentType=true) { - // Disable mimesniffing, don't move this to setContentTypeHeader! - header( 'X-Content-Type-Options: nosniff' ); if($setContentType) { self::setContentTypeHeader(); } diff --git a/lib/private/l10n.php b/lib/private/l10n.php index 175360e27a3..a397945b829 100644 --- a/lib/private/l10n.php +++ b/lib/private/l10n.php @@ -419,6 +419,14 @@ class OC_L10N implements \OCP\IL10N { } /** + * The given language is forced to be used while executing the current request + * @param string $lang + */ + public static function forceLanguage($lang) { + self::$language = $lang; + } + + /** * @brief find the best language * @param array|string $app details below * @returns string language diff --git a/lib/private/mimetypes.list.php b/lib/private/mimetypes.list.php index 91bcf584267..07e2391c116 100644 --- a/lib/private/mimetypes.list.php +++ b/lib/private/mimetypes.list.php @@ -22,111 +22,115 @@ /** * Array mapping file extensions to mimetypes (in alphabetical order). + * + * The first index in the mime type array is the assumed correct mimetype + * and the second is either a secure alternative or null if the correct + * is considered secure. */ return array( - '7z' => 'application/x-7z-compressed', - 'accdb' => 'application/msaccess', - 'ai' => 'application/illustrator', - 'avi' => 'video/x-msvideo', - 'bash' => 'text/x-shellscript', - 'blend' => 'application/x-blender', - 'bin' => 'application/x-bin', - 'bmp' => 'image/bmp', - 'cb7' => 'application/x-cbr', - 'cba' => 'application/x-cbr', - 'cbr' => 'application/x-cbr', - 'cbt' => 'application/x-cbr', - 'cbtc' => 'application/x-cbr', - 'cbz' => 'application/x-cbr', - 'cc' => 'text/x-c', - 'cdr' => 'application/coreldraw', - 'cpp' => 'text/x-c++src', - 'css' => 'text/css', - 'csv' => 'text/csv', - 'cvbdl' => 'application/x-cbr', - 'c' => 'text/x-c', - 'c++' => 'text/x-c++src', - 'deb' => 'application/x-deb', - 'doc' => 'application/msword', - 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', - 'dot' => 'application/msword', - 'dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.template', - 'dv' => 'video/dv', - 'eot' => 'application/vnd.ms-fontobject', - 'epub' => 'application/epub+zip', - 'exe' => 'application/x-ms-dos-executable', - 'flac' => 'audio/flac', - 'gif' => 'image/gif', - 'gz' => 'application/x-gzip', - 'gzip' => 'application/x-gzip', - 'html' => 'text/html', - 'htm' => 'text/html', - 'ical' => 'text/calendar', - 'ics' => 'text/calendar', - 'impress' => 'text/impress', - 'jpeg' => 'image/jpeg', - 'jpg' => 'image/jpeg', - 'js' => 'application/javascript', - 'json' => 'application/json', - 'keynote' => 'application/x-iwork-keynote-sffkey', - 'kra' => 'application/x-krita', - 'm2t' => 'video/mp2t', - 'm4v' => 'video/mp4', - 'markdown' => 'text/markdown', - 'mdown' => 'text/markdown', - 'md' => 'text/markdown', - 'mdb' => 'application/msaccess', - 'mdwn' => 'text/markdown', - 'mkv' => 'video/x-matroska', - 'mobi' => 'application/x-mobipocket-ebook', - 'mov' => 'video/quicktime', - 'mp3' => 'audio/mpeg', - 'mp4' => 'video/mp4', - 'mpeg' => 'video/mpeg', - 'mpg' => 'video/mpeg', - 'msi' => 'application/x-msi', - 'numbers' => 'application/x-iwork-numbers-sffnumbers', - 'odg' => 'application/vnd.oasis.opendocument.graphics', - 'odp' => 'application/vnd.oasis.opendocument.presentation', - 'ods' => 'application/vnd.oasis.opendocument.spreadsheet', - 'odt' => 'application/vnd.oasis.opendocument.text', - 'oga' => 'audio/ogg', - 'ogg' => 'audio/ogg', - 'ogv' => 'video/ogg', - 'otf' => 'font/opentype', - 'pages' => 'application/x-iwork-pages-sffpages', - 'pdf' => 'application/pdf', - 'php' => 'application/x-php', - 'pl' => 'application/x-perl', - 'png' => 'image/png', - 'ppt' => 'application/mspowerpoint', - 'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation', - 'psd' => 'application/x-photoshop', - 'py' => 'text/x-python', - 'rar' => 'application/x-rar-compressed', - 'reveal' => 'text/reveal', - 'sgf' => 'application/sgf', - 'sh-lib' => 'text/x-shellscript', - 'sh' => 'text/x-shellscript', - 'svg' => 'image/svg+xml', - 'swf' => 'application/x-shockwave-flash', - 'tar' => 'application/x-tar', - 'tar.gz' => 'application/x-compressed', - 'tex' => 'application/x-tex', - 'tgz' => 'application/x-compressed', - 'tiff' => 'image/tiff', - 'tif' => 'image/tiff', - 'ttf' => 'application/x-font-ttf', - 'txt' => 'text/plain', - 'vcard' => 'text/vcard', - 'vcf' => 'text/vcard', - 'wav' => 'audio/wav', - 'webm' => 'video/webm', - 'woff' => 'application/font-woff', - 'wmv' => 'video/x-ms-asf', - 'xcf' => 'application/x-gimp', - 'xls' => 'application/msexcel', - 'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', - 'xml' => 'application/xml', - 'zip' => 'application/zip', + '7z' => array('application/x-7z-compressed', null), + 'accdb' => array('application/msaccess', null), + 'ai' => array('application/illustrator', null), + 'avi' => array('video/x-msvideo', null), + 'bash' => array('text/x-shellscript', null), + 'blend' => array('application/x-blender', null), + 'bin' => array('application/x-bin', null), + 'bmp' => array('image/bmp', null), + 'cb7' => array('application/x-cbr', null), + 'cba' => array('application/x-cbr', null), + 'cbr' => array('application/x-cbr', null), + 'cbt' => array('application/x-cbr', null), + 'cbtc' => array('application/x-cbr', null), + 'cbz' => array('application/x-cbr', null), + 'cc' => array('text/x-c', null), + 'cdr' => array('application/coreldraw', null), + 'cpp' => array('text/x-c++src', null), + 'css' => array('text/css', null), + 'csv' => array('text/csv', null), + 'cvbdl' => array('application/x-cbr', null), + 'c' => array('text/x-c', null), + 'c++' => array('text/x-c++src', null), + 'deb' => array('application/x-deb', null), + 'doc' => array('application/msword', null), + 'docx' => array('application/vnd.openxmlformats-officedocument.wordprocessingml.document', null), + 'dot' => array('application/msword', null), + 'dotx' => array('application/vnd.openxmlformats-officedocument.wordprocessingml.template', null), + 'dv' => array('video/dv', null), + 'eot' => array('application/vnd.ms-fontobject', null), + 'epub' => array('application/epub+zip', null), + 'exe' => array('application/x-ms-dos-executable', null), + 'flac' => array('audio/flac', null), + 'gif' => array('image/gif', null), + 'gz' => array('application/x-gzip', null), + 'gzip' => array('application/x-gzip', null), + 'html' => array('text/html', 'text/plain'), + 'htm' => array('text/html', 'text/plain'), + 'ical' => array('text/calendar', null), + 'ics' => array('text/calendar', null), + 'impress' => array('text/impress', null), + 'jpeg' => array('image/jpeg', null), + 'jpg' => array('image/jpeg', null), + 'js' => array('application/javascript', 'text/plain'), + 'json' => array('application/json', 'text/plain'), + 'keynote' => array('application/x-iwork-keynote-sffkey', null), + 'kra' => array('application/x-krita', null), + 'm2t' => array('video/mp2t', null), + 'm4v' => array('video/mp4', null), + 'markdown' => array('text/markdown', null), + 'mdown' => array('text/markdown', null), + 'md' => array('text/markdown', null), + 'mdb' => array('application/msaccess', null), + 'mdwn' => array('text/markdown', null), + 'mkv' => array('video/x-matroska', null), + 'mobi' => array('application/x-mobipocket-ebook', null), + 'mov' => array('video/quicktime', null), + 'mp3' => array('audio/mpeg', null), + 'mp4' => array('video/mp4', null), + 'mpeg' => array('video/mpeg', null), + 'mpg' => array('video/mpeg', null), + 'msi' => array('application/x-msi', null), + 'numbers' => array('application/x-iwork-numbers-sffnumbers', null), + 'odg' => array('application/vnd.oasis.opendocument.graphics', null), + 'odp' => array('application/vnd.oasis.opendocument.presentation', null), + 'ods' => array('application/vnd.oasis.opendocument.spreadsheet', null), + 'odt' => array('application/vnd.oasis.opendocument.text', null), + 'oga' => array('audio/ogg', null), + 'ogg' => array('audio/ogg', null), + 'ogv' => array('video/ogg', null), + 'otf' => array('font/opentype', null), + 'pages' => array('application/x-iwork-pages-sffpages', null), + 'pdf' => array('application/pdf', null), + 'php' => array('application/x-php', null), + 'pl' => array('application/x-perl', null), + 'png' => array('image/png', null), + 'ppt' => array('application/mspowerpoint', null), + 'pptx' => array('application/vnd.openxmlformats-officedocument.presentationml.presentation', null), + 'psd' => array('application/x-photoshop', null), + 'py' => array('text/x-python', null), + 'rar' => array('application/x-rar-compressed', null), + 'reveal' => array('text/reveal', null), + 'sgf' => array('application/sgf', null), + 'sh-lib' => array('text/x-shellscript', null), + 'sh' => array('text/x-shellscript', null), + 'svg' => array('image/svg+xml', 'text/plain'), + 'swf' => array('application/x-shockwave-flash', 'application/octet-stream'), + 'tar' => array('application/x-tar', null), + 'tar.gz' => array('application/x-compressed', null), + 'tex' => array('application/x-tex', null), + 'tgz' => array('application/x-compressed', null), + 'tiff' => array('image/tiff', null), + 'tif' => array('image/tiff', null), + 'ttf' => array('application/x-font-ttf', null), + 'txt' => array('text/plain', null), + 'vcard' => array('text/vcard', null), + 'vcf' => array('text/vcard', null), + 'wav' => array('audio/wav', null), + 'webm' => array('video/webm', null), + 'woff' => array('application/font-woff', null), + 'wmv' => array('video/x-ms-asf', null), + 'xcf' => array('application/x-gimp', null), + 'xls' => array('application/msexcel', null), + 'xlsx' => array('application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', null), + 'xml' => array('application/xml', 'text/plain'), + 'zip' => array('application/zip', null), ); diff --git a/lib/private/preview.php b/lib/private/preview.php index 26016555a32..0187b4aacbb 100755 --- a/lib/private/preview.php +++ b/lib/private/preview.php @@ -13,6 +13,8 @@ */ namespace OC; +use OC\Preview\Provider; + require_once 'preview/image.php'; require_once 'preview/movies.php'; require_once 'preview/mp3.php'; @@ -39,15 +41,16 @@ class Preview { private $file; private $maxX; private $maxY; - private $scalingup; - private $mimetype; + private $scalingUp; + private $mimeType; //filemapper used for deleting previews // index is path, value is fileinfo static public $deleteFileMapper = array(); - //preview images object /** + * preview images object + * * @var \OC_Image */ private $preview; @@ -109,7 +112,7 @@ class Preview { * @brief returns the path of the file you want a thumbnail from * @return string */ - public function getFile() { + public function getFile() { return $this->file; } @@ -134,7 +137,7 @@ class Preview { * @return bool */ public function getScalingUp() { - return $this->scalingup; + return $this->scalingUp; } /** @@ -191,18 +194,18 @@ class Preview { if ($file !== '') { $this->getFileInfo(); if($this->info !== null && $this->info !== false) { - $this->mimetype = $this->info->getMimetype(); + $this->mimeType = $this->info->getMimetype(); } } return $this; } /** - * @brief set mimetype explicitely - * @param string $mimetype + * @brief set mime type explicitly + * @param string $mimeType */ - public function setMimetype($mimetype) { - $this->mimetype = $mimetype; + public function setMimetype($mimeType) { + $this->mimeType = $mimeType; } /** @@ -254,7 +257,7 @@ class Preview { if ($this->getMaxScaleFactor() === 1) { $scalingUp = false; } - $this->scalingup = $scalingUp; + $this->scalingUp = $scalingUp; return $this; } @@ -314,35 +317,68 @@ class Preview { /** * @brief check if thumbnail or bigger version of thumbnail of file is cached - * @return mixed (bool / string) - * false if thumbnail does not exist - * path to thumbnail if thumbnail exists + * @param int $fileId fileId of the original image + * @return string|false path to thumbnail if it exists or false */ - private function isCached() { - $file = $this->getFile(); + public function isCached($fileId) { + if (is_null($fileId)) { + return false; + } + $maxX = $this->getMaxX(); $maxY = $this->getMaxY(); - $scalingUp = $this->getScalingUp(); - $maxScaleFactor = $this->getMaxScaleFactor(); - $fileInfo = $this->getFileInfo($file); - $fileId = $fileInfo->getId(); + $previewPath = $this->getThumbnailsFolder() . '/' . $fileId . '/'; + + //does a preview with the wanted height and width already exist? + if ($this->userView->file_exists($previewPath . $maxX . '-' . $maxY . '.png')) { + return $previewPath . $maxX . '-' . $maxY . '.png'; + } + + return $this->isCachedBigger($fileId); + } + + /** + * @brief check if a bigger version of thumbnail of file is cached + * @param int $fileId fileId of the original image + * @return string|false path to bigger thumbnail if it exists or false + */ + private function isCachedBigger($fileId) { if (is_null($fileId)) { return false; } - $previewPath = $this->getThumbnailsFolder() . '/' . $fileId . '/'; - if (!$this->userView->is_dir($previewPath)) { - return false; + $maxX = $this->getMaxX(); + + //array for usable cached thumbnails + $possibleThumbnails = $this->getPossibleThumbnails($fileId); + + foreach ($possibleThumbnails as $width => $path) { + if ($width < $maxX) { + continue; + } else { + return $path; + } } - //does a preview with the wanted height and width already exist? - if ($this->userView->file_exists($previewPath . $maxX . '-' . $maxY . '.png')) { - return $previewPath . $maxX . '-' . $maxY . '.png'; + return false; + } + + /** + * @brief get possible bigger thumbnails of the given image + * @param int $fileId fileId of the original image + * @return array of paths to bigger thumbnails + */ + private function getPossibleThumbnails($fileId) { + + if (is_null($fileId)) { + return array(); } - $wantedAspectRatio = (float)($maxX / $maxY); + $previewPath = $this->getThumbnailsFolder() . '/' . $fileId . '/'; + + $wantedAspectRatio = (float) ($this->getMaxX() / $this->getMaxY()); //array for usable cached thumbnails $possibleThumbnails = array(); @@ -350,53 +386,47 @@ class Preview { $allThumbnails = $this->userView->getDirectoryContent($previewPath); foreach ($allThumbnails as $thumbnail) { $name = rtrim($thumbnail['name'], '.png'); - $size = explode('-', $name); - $x = (int)$size[0]; - $y = (int)$size[1]; + list($x, $y, $aspectRatio) = $this->getDimensionsFromFilename($name); - $aspectRatio = (float)($x / $y); - if ($aspectRatio !== $wantedAspectRatio) { + if (abs($aspectRatio - $wantedAspectRatio) >= 0.000001 + || $this->unscalable($x, $y) + ) { continue; } - - if ($x < $maxX || $y < $maxY) { - if ($scalingUp) { - $scalefactor = $maxX / $x; - if ($scalefactor > $maxScaleFactor) { - continue; - } - } else { - continue; - } - } $possibleThumbnails[$x] = $thumbnail['path']; } - if (count($possibleThumbnails) === 0) { - return false; - } - - if (count($possibleThumbnails) === 1) { - return current($possibleThumbnails); - } - ksort($possibleThumbnails); - if (key(reset($possibleThumbnails)) > $maxX) { - return current(reset($possibleThumbnails)); - } + return $possibleThumbnails; + } - if (key(end($possibleThumbnails)) < $maxX) { - return current(end($possibleThumbnails)); - } + private function getDimensionsFromFilename($name) { + $size = explode('-', $name); + $x = (int) $size[0]; + $y = (int) $size[1]; + $aspectRatio = (float) ($x / $y); + return array($x, $y, $aspectRatio); + } - foreach ($possibleThumbnails as $width => $path) { - if ($width < $maxX) { - continue; + private function unscalable($x, $y) { + + $maxX = $this->getMaxX(); + $maxY = $this->getMaxY(); + $scalingUp = $this->getScalingUp(); + $maxScaleFactor = $this->getMaxScaleFactor(); + + if ($x < $maxX || $y < $maxY) { + if ($scalingUp) { + $scalefactor = $maxX / $x; + if ($scalefactor > $maxScaleFactor) { + return true; + } } else { - return $path; + return true; } } + return false; } /** @@ -420,7 +450,7 @@ class Preview { } $fileId = $fileInfo->getId(); - $cached = $this->isCached(); + $cached = $this->isCached($fileId); if ($cached) { $stream = $this->userView->fopen($cached, 'r'); @@ -434,13 +464,14 @@ class Preview { if (is_null($this->preview)) { $preview = null; - foreach (self::$providers as $supportedMimetype => $provider) { - if (!preg_match($supportedMimetype, $this->mimetype)) { + foreach (self::$providers as $supportedMimeType => $provider) { + if (!preg_match($supportedMimeType, $this->mimeType)) { continue; } \OC_Log::write('core', 'Generating preview for "' . $file . '" with "' . get_class($provider) . '"', \OC_Log::DEBUG); + /** @var $provider Provider */ $preview = $provider->getThumbnail($file, $maxX, $maxY, $scalingUp, $this->fileView); if (!($preview instanceof \OC_Image)) { @@ -484,7 +515,6 @@ class Preview { $this->getPreview(); } $this->preview->show('image/png'); - return; } /** @@ -493,7 +523,6 @@ class Preview { */ public function show() { $this->showPreview(); - return; } /** @@ -505,7 +534,7 @@ class Preview { $x = $this->getMaxX(); $y = $this->getMaxY(); $scalingUp = $this->getScalingUp(); - $maxscalefactor = $this->getMaxScaleFactor(); + $maxScaleFactor = $this->getMaxScaleFactor(); if (!($image instanceof \OC_Image)) { \OC_Log::write('core', '$this->preview is not an instance of OC_Image', \OC_Log::DEBUG); @@ -514,16 +543,16 @@ class Preview { $image->fixOrientation(); - $realx = (int)$image->width(); - $realy = (int)$image->height(); + $realX = (int)$image->width(); + $realY = (int)$image->height(); - if ($x === $realx && $y === $realy) { + if ($x === $realX && $y === $realY) { $this->preview = $image; return; } - $factorX = $x / $realx; - $factorY = $y / $realy; + $factorX = $x / $realX; + $factorY = $y / $realY; if ($factorX >= $factorY) { $factor = $factorX; @@ -537,25 +566,25 @@ class Preview { } } - if (!is_null($maxscalefactor)) { - if ($factor > $maxscalefactor) { - \OC_Log::write('core', 'scalefactor reduced from ' . $factor . ' to ' . $maxscalefactor, \OC_Log::DEBUG); - $factor = $maxscalefactor; + if (!is_null($maxScaleFactor)) { + if ($factor > $maxScaleFactor) { + \OC_Log::write('core', 'scale factor reduced from ' . $factor . ' to ' . $maxScaleFactor, \OC_Log::DEBUG); + $factor = $maxScaleFactor; } } - $newXsize = (int)($realx * $factor); - $newYsize = (int)($realy * $factor); + $newXSize = (int)($realX * $factor); + $newYSize = (int)($realY * $factor); - $image->preciseResize($newXsize, $newYsize); + $image->preciseResize($newXSize, $newYSize); - if ($newXsize === $x && $newYsize === $y) { + if ($newXSize === $x && $newYSize === $y) { $this->preview = $image; return; } - if ($newXsize >= $x && $newYsize >= $y) { - $cropX = floor(abs($x - $newXsize) * 0.5); + if ($newXSize >= $x && $newYSize >= $y) { + $cropX = floor(abs($x - $newXSize) * 0.5); //don't crop previews on the Y axis, this sucks if it's a document. //$cropY = floor(abs($y - $newYsize) * 0.5); $cropY = 0; @@ -566,36 +595,36 @@ class Preview { return; } - if ($newXsize < $x || $newYsize < $y) { - if ($newXsize > $x) { - $cropX = floor(($newXsize - $x) * 0.5); - $image->crop($cropX, 0, $x, $newYsize); + if ($newXSize < $x || $newYSize < $y) { + if ($newXSize > $x) { + $cropX = floor(($newXSize - $x) * 0.5); + $image->crop($cropX, 0, $x, $newYSize); } - if ($newYsize > $y) { - $cropY = floor(($newYsize - $y) * 0.5); - $image->crop(0, $cropY, $newXsize, $y); + if ($newYSize > $y) { + $cropY = floor(($newYSize - $y) * 0.5); + $image->crop(0, $cropY, $newXSize, $y); } - $newXsize = (int)$image->width(); - $newYsize = (int)$image->height(); + $newXSize = (int)$image->width(); + $newYSize = (int)$image->height(); //create transparent background layer - $backgroundlayer = imagecreatetruecolor($x, $y); - $white = imagecolorallocate($backgroundlayer, 255, 255, 255); - imagefill($backgroundlayer, 0, 0, $white); + $backgroundLayer = imagecreatetruecolor($x, $y); + $white = imagecolorallocate($backgroundLayer, 255, 255, 255); + imagefill($backgroundLayer, 0, 0, $white); $image = $image->resource(); - $mergeX = floor(abs($x - $newXsize) * 0.5); - $mergeY = floor(abs($y - $newYsize) * 0.5); + $mergeX = floor(abs($x - $newXSize) * 0.5); + $mergeY = floor(abs($y - $newYSize) * 0.5); - imagecopy($backgroundlayer, $image, $mergeX, $mergeY, 0, 0, $newXsize, $newYsize); + imagecopy($backgroundLayer, $image, $mergeX, $mergeY, 0, 0, $newXSize, $newYSize); //$black = imagecolorallocate(0,0,0); //imagecolortransparent($transparentlayer, $black); - $image = new \OC_Image($backgroundlayer); + $image = new \OC_Image($backgroundLayer); $this->preview = $image; return; @@ -630,6 +659,7 @@ class Preview { $class = $provider['class']; $options = $provider['options']; + /** @var $object Provider */ $object = new $class($options); self::$providers[$object->getMimeType()] = $object; @@ -676,9 +706,9 @@ class Preview { } /** - * @param string $mimetype + * @param string $mimeType */ - public static function isMimeSupported($mimetype) { + public static function isMimeSupported($mimeType) { if (!\OC_Config::getValue('enable_previews', true)) { return false; } @@ -690,8 +720,8 @@ class Preview { //remove last element because it has the mimetype * $providers = array_slice(self::$providers, 0, -1); - foreach ($providers as $supportedMimetype => $provider) { - if (preg_match($supportedMimetype, $mimetype)) { + foreach ($providers as $supportedMimeType => $provider) { + if (preg_match($supportedMimeType, $mimeType)) { return true; } } diff --git a/lib/private/preview/movies.php b/lib/private/preview/movies.php index 7e0ff51ad2e..72ccfadc6e9 100644 --- a/lib/private/preview/movies.php +++ b/lib/private/preview/movies.php @@ -42,7 +42,6 @@ if (!\OC_Util::runningOnWindows()) { public function getThumbnail($path, $maxX, $maxY, $scalingup, $fileview) { // TODO: use proc_open() and stream the source file ? $absPath = \OC_Helper::tmpFile(); - $tmpPath = \OC_Helper::tmpFile(); $handle = $fileview->fopen($path, 'rb'); @@ -51,14 +50,39 @@ if (!\OC_Util::runningOnWindows()) { $firstmb = stream_get_contents($handle, 5242880); file_put_contents($absPath, $firstmb); + $result = $this->generateThumbNail($maxX, $maxY, $absPath, 5); + if ($result === false) { + $result = $this->generateThumbNail($maxX, $maxY, $absPath, 1); + if ($result === false) { + $result = $this->generateThumbNail($maxX, $maxY, $absPath, 0); + } + } + + unlink($absPath); + + + return $result; + } + + /** + * @param int $maxX + * @param int $maxY + * @param string $absPath + * @param string $tmpPath + * @param int $second + * @return bool|\OC_Image + */ + private function generateThumbNail($maxX, $maxY, $absPath, $second) + { + $tmpPath = \OC_Helper::tmpFile(); + if (self::$avconvBinary) { - $cmd = self::$avconvBinary . ' -an -y -ss 5'. + $cmd = self::$avconvBinary . ' -an -y -ss ' . escapeshellarg($second) . ' -i ' . escapeshellarg($absPath) . ' -f mjpeg -vframes 1 -vsync 1 ' . escapeshellarg($tmpPath) . ' > /dev/null 2>&1'; - } - else { - $cmd = self::$ffmpegBinary . ' -y -ss 5' . + } else { + $cmd = self::$ffmpegBinary . ' -y -ss ' . escapeshellarg($second) . ' -i ' . escapeshellarg($absPath) . ' -f mjpeg -vframes 1' . ' -s ' . escapeshellarg($maxX) . 'x' . escapeshellarg($maxY) . @@ -68,14 +92,13 @@ if (!\OC_Util::runningOnWindows()) { exec($cmd, $output, $returnCode); - unlink($absPath); - if ($returnCode === 0) { $image = new \OC_Image(); $image->loadFromFile($tmpPath); unlink($tmpPath); return $image->valid() ? $image : false; } + unlink($tmpPath); return false; } } diff --git a/lib/private/server.php b/lib/private/server.php index 3517d7b3548..5d90a0b19fc 100644 --- a/lib/private/server.php +++ b/lib/private/server.php @@ -35,6 +35,13 @@ class Server extends SimpleContainer implements IServerContainer { $requesttoken = false; } + if (defined('PHPUNIT_RUN') && PHPUNIT_RUN + && in_array('fakeinput', stream_get_wrappers())) { + $stream = 'fakeinput://data'; + } else { + $stream = 'php://input'; + } + return new Request( array( 'get' => $_GET, @@ -48,7 +55,7 @@ class Server extends SimpleContainer implements IServerContainer { : null, 'urlParams' => $urlParams, 'requesttoken' => $requesttoken, - ) + ), $stream ); }); $this->registerService('PreviewManager', function($c) { diff --git a/lib/private/share/share.php b/lib/private/share/share.php index 3bc07b43b4c..d4f08e8e016 100644 --- a/lib/private/share/share.php +++ b/lib/private/share/share.php @@ -431,6 +431,16 @@ class Share extends \OC\Share\Constants { $itemSourceName = $itemSource; } + // verify that the file exists before we try to share it + if ($itemType === 'file' or $itemType === 'folder') { + $path = \OC\Files\Filesystem::getPath($itemSource); + if (!$path) { + $message = 'Sharing ' . $itemSourceName . ' failed, because the file does not exist'; + \OC_Log::write('OCP\Share', $message, \OC_Log::ERROR); + throw new \Exception($message); + } + } + // Verify share type and sharing conditions are met if ($shareType === self::SHARE_TYPE_USER) { if ($shareWith == $uidOwner) { diff --git a/lib/private/template.php b/lib/private/template.php index c6851c6cc8d..610d5fbc8e5 100644 --- a/lib/private/template.php +++ b/lib/private/template.php @@ -64,29 +64,6 @@ class OC_Template extends \OC\Template\Base { $this->path = $path; parent::__construct($template, $requesttoken, $l10n, $themeDefaults); - - // Some headers to enhance security - header('X-XSS-Protection: 1; mode=block'); // Enforce browser based XSS filters - header('X-Content-Type-Options: nosniff'); // Disable sniffing the content type for IE - - // iFrame Restriction Policy - $xFramePolicy = OC_Config::getValue('xframe_restriction', true); - if($xFramePolicy) { - header('X-Frame-Options: Sameorigin'); // Disallow iFraming from other domains - } - - // Content Security Policy - // If you change the standard policy, please also change it in config.sample.php - $policy = OC_Config::getValue('custom_csp_policy', - 'default-src \'self\'; ' - .'script-src \'self\' \'unsafe-eval\'; ' - .'style-src \'self\' \'unsafe-inline\'; ' - .'frame-src *; ' - .'img-src *; ' - .'font-src \'self\' data:; ' - .'media-src *'); - header('Content-Security-Policy:'.$policy); // Standard - } /** diff --git a/lib/private/template/functions.php b/lib/private/template/functions.php index a72d41f72da..3c42d441efa 100644 --- a/lib/private/template/functions.php +++ b/lib/private/template/functions.php @@ -7,16 +7,17 @@ */ /** - * Prints an XSS escaped string - * @param string $string the string which will be escaped and printed + * Prints a sanitized string + * @param string|array $string the string which will be escaped and printed */ function p($string) { print(OC_Util::sanitizeHTML($string)); } /** - * Prints an unescaped string - * @param string $string the string which will be printed as it is + * Prints an unsanitized string - usage of this function may result into XSS. + * Consider using p() instead. + * @param string|array $string the string which will be printed as it is */ function print_unescaped($string) { print($string); diff --git a/lib/private/templatelayout.php b/lib/private/templatelayout.php index af17adb11c6..0c0c8d9c8d7 100644 --- a/lib/private/templatelayout.php +++ b/lib/private/templatelayout.php @@ -66,7 +66,7 @@ class OC_TemplateLayout extends OC_Template { } $versionParameter = '?v=' . md5(implode(OC_Util::getVersion())); - $useAssetPipeline = OC_Config::getValue('asset-pipeline.enabled', false); + $useAssetPipeline = $this->isAssetPipelineEnabled(); if ($useAssetPipeline) { $this->append( 'jsfiles', OC_Helper::linkToRoute('js_config') . $versionParameter); @@ -179,4 +179,33 @@ class OC_TemplateLayout extends OC_Template { sort($files); return hash('md5', implode('', $files)); } + + /** + * @return bool + */ + private function isAssetPipelineEnabled() { + // asset management enabled? + $useAssetPipeline = OC_Config::getValue('asset-pipeline.enabled', false); + if (!$useAssetPipeline) { + return false; + } + + // assets folder exists? + $assetDir = \OC::$SERVERROOT . '/assets'; + if (!is_dir($assetDir)) { + if (!mkdir($assetDir)) { + \OCP\Util::writeLog('assets', + "Folder <$assetDir> does not exist and/or could not be generated.", \OCP\Util::ERROR); + return false; + } + } + + // assets folder can be accessed? + if (!touch($assetDir."/.oc")) { + \OCP\Util::writeLog('assets', + "Folder <$assetDir> could not be accessed.", \OCP\Util::ERROR); + return false; + } + return $useAssetPipeline; + } } diff --git a/lib/private/user/manager.php b/lib/private/user/manager.php index a2ad9d17702..14698452e88 100644 --- a/lib/private/user/manager.php +++ b/lib/private/user/manager.php @@ -175,13 +175,6 @@ class Manager extends PublicEmitter { if (is_array($backendUsers)) { foreach ($backendUsers as $uid) { $users[] = $this->getUserObject($uid, $backend); - if (!is_null($limit)) { - $limit--; - } - if (!is_null($offset) and $offset > 0) { - $offset--; - } - } } } @@ -211,13 +204,6 @@ class Manager extends PublicEmitter { if (is_array($backendUsers)) { foreach ($backendUsers as $uid => $displayName) { $users[] = $this->getUserObject($uid, $backend); - if (!is_null($limit)) { - $limit--; - } - if (!is_null($offset) and $offset > 0) { - $offset--; - } - } } } diff --git a/lib/private/util.php b/lib/private/util.php index a744644b39c..e20de308e87 100755 --- a/lib/private/util.php +++ b/lib/private/util.php @@ -902,6 +902,8 @@ class OC_Util { // for this self test we don't care if the ssl certificate is self signed and the peer cannot be verified. $client->setVerifyPeer(false); + // also don't care if the host can't be verified + $client->setVerifyHost(0); $return = true; try { diff --git a/lib/public/appframework/http/jsonresponse.php b/lib/public/appframework/http/jsonresponse.php index 6628c4514d9..6d029b7464a 100644 --- a/lib/public/appframework/http/jsonresponse.php +++ b/lib/public/appframework/http/jsonresponse.php @@ -49,7 +49,6 @@ class JSONResponse extends Response { public function __construct($data=array(), $statusCode=Http::STATUS_OK) { $this->data = $data; $this->setStatus($statusCode); - $this->addHeader('X-Content-Type-Options', 'nosniff'); $this->addHeader('Content-type', 'application/json; charset=utf-8'); } |