base.php 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957
  1. <?php
  2. /**
  3. * ownCloud
  4. *
  5. * @author Frank Karlitschek
  6. * @copyright 2012 Frank Karlitschek frank@owncloud.org
  7. *
  8. * This library is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
  10. * License as published by the Free Software Foundation; either
  11. * version 3 of the License, or any later version.
  12. *
  13. * This library is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
  17. *
  18. * You should have received a copy of the GNU Affero General Public
  19. * License along with this library. If not, see <http://www.gnu.org/licenses/>.
  20. *
  21. */
  22. require_once 'public/constants.php';
  23. /**
  24. * Class that is a namespace for all global OC variables
  25. * No, we can not put this class in its own file because it is used by
  26. * OC_autoload!
  27. */
  28. class OC {
  29. /**
  30. * Associative array for autoloading. classname => filename
  31. */
  32. public static $CLASSPATH = array();
  33. /**
  34. * The installation path for owncloud on the server (e.g. /srv/http/owncloud)
  35. */
  36. public static $SERVERROOT = '';
  37. /**
  38. * the current request path relative to the owncloud root (e.g. files/index.php)
  39. */
  40. private static $SUBURI = '';
  41. /**
  42. * the owncloud root path for http requests (e.g. owncloud/)
  43. */
  44. public static $WEBROOT = '';
  45. /**
  46. * The installation path of the 3rdparty folder on the server (e.g. /srv/http/owncloud/3rdparty)
  47. */
  48. public static $THIRDPARTYROOT = '';
  49. /**
  50. * the root path of the 3rdparty folder for http requests (e.g. owncloud/3rdparty)
  51. */
  52. public static $THIRDPARTYWEBROOT = '';
  53. /**
  54. * The installation path array of the apps folder on the server (e.g. /srv/http/owncloud) 'path' and
  55. * web path in 'url'
  56. */
  57. public static $APPSROOTS = array();
  58. /*
  59. * requested app
  60. */
  61. public static $REQUESTEDAPP = '';
  62. /*
  63. * requested file of app
  64. */
  65. public static $REQUESTEDFILE = '';
  66. /**
  67. * check if owncloud runs in cli mode
  68. */
  69. public static $CLI = false;
  70. /**
  71. * @var OC_Router
  72. */
  73. protected static $router = null;
  74. /**
  75. * @var \OC\Session\Session
  76. */
  77. public static $session = null;
  78. /**
  79. * @var \OC\Autoloader $loader
  80. */
  81. public static $loader = null;
  82. /**
  83. * @var \OC\Server
  84. */
  85. public static $server = null;
  86. public static function initPaths() {
  87. // calculate the root directories
  88. OC::$SERVERROOT = str_replace("\\", '/', substr(__DIR__, 0, -4));
  89. // ensure we can find OC_Config
  90. set_include_path(
  91. OC::$SERVERROOT . '/lib' . PATH_SEPARATOR .
  92. get_include_path()
  93. );
  94. OC::$SUBURI = str_replace("\\", "/", substr(realpath($_SERVER["SCRIPT_FILENAME"]), strlen(OC::$SERVERROOT)));
  95. $scriptName = OC_Request::scriptName();
  96. if (substr($scriptName, -1) == '/') {
  97. $scriptName .= 'index.php';
  98. //make sure suburi follows the same rules as scriptName
  99. if (substr(OC::$SUBURI, -9) != 'index.php') {
  100. if (substr(OC::$SUBURI, -1) != '/') {
  101. OC::$SUBURI = OC::$SUBURI . '/';
  102. }
  103. OC::$SUBURI = OC::$SUBURI . 'index.php';
  104. }
  105. }
  106. OC::$WEBROOT = substr($scriptName, 0, strlen($scriptName) - strlen(OC::$SUBURI));
  107. if (OC::$WEBROOT != '' and OC::$WEBROOT[0] !== '/') {
  108. OC::$WEBROOT = '/' . OC::$WEBROOT;
  109. }
  110. // search the 3rdparty folder
  111. if (OC_Config::getValue('3rdpartyroot', '') <> '' and OC_Config::getValue('3rdpartyurl', '') <> '') {
  112. OC::$THIRDPARTYROOT = OC_Config::getValue('3rdpartyroot', '');
  113. OC::$THIRDPARTYWEBROOT = OC_Config::getValue('3rdpartyurl', '');
  114. } elseif (file_exists(OC::$SERVERROOT . '/3rdparty')) {
  115. OC::$THIRDPARTYROOT = OC::$SERVERROOT;
  116. OC::$THIRDPARTYWEBROOT = OC::$WEBROOT;
  117. } elseif (file_exists(OC::$SERVERROOT . '/../3rdparty')) {
  118. OC::$THIRDPARTYWEBROOT = rtrim(dirname(OC::$WEBROOT), '/');
  119. OC::$THIRDPARTYROOT = rtrim(dirname(OC::$SERVERROOT), '/');
  120. } else {
  121. throw new Exception('3rdparty directory not found! Please put the ownCloud 3rdparty'
  122. .' folder in the ownCloud folder or the folder above.'
  123. .' You can also configure the location in the config.php file.');
  124. }
  125. // search the apps folder
  126. $config_paths = OC_Config::getValue('apps_paths', array());
  127. if (!empty($config_paths)) {
  128. foreach ($config_paths as $paths) {
  129. if (isset($paths['url']) && isset($paths['path'])) {
  130. $paths['url'] = rtrim($paths['url'], '/');
  131. $paths['path'] = rtrim($paths['path'], '/');
  132. OC::$APPSROOTS[] = $paths;
  133. }
  134. }
  135. } elseif (file_exists(OC::$SERVERROOT . '/apps')) {
  136. OC::$APPSROOTS[] = array('path' => OC::$SERVERROOT . '/apps', 'url' => '/apps', 'writable' => true);
  137. } elseif (file_exists(OC::$SERVERROOT . '/../apps')) {
  138. OC::$APPSROOTS[] = array(
  139. 'path' => rtrim(dirname(OC::$SERVERROOT), '/') . '/apps',
  140. 'url' => '/apps',
  141. 'writable' => true
  142. );
  143. }
  144. if (empty(OC::$APPSROOTS)) {
  145. throw new Exception('apps directory not found! Please put the ownCloud apps folder in the ownCloud folder'
  146. .' or the folder above. You can also configure the location in the config.php file.');
  147. }
  148. $paths = array();
  149. foreach (OC::$APPSROOTS as $path) {
  150. $paths[] = $path['path'];
  151. }
  152. // set the right include path
  153. set_include_path(
  154. OC::$SERVERROOT . '/lib/private' . PATH_SEPARATOR .
  155. OC::$SERVERROOT . '/config' . PATH_SEPARATOR .
  156. OC::$THIRDPARTYROOT . '/3rdparty' . PATH_SEPARATOR .
  157. implode($paths, PATH_SEPARATOR) . PATH_SEPARATOR .
  158. get_include_path() . PATH_SEPARATOR .
  159. OC::$SERVERROOT
  160. );
  161. }
  162. public static function checkConfig() {
  163. if (file_exists(OC::$SERVERROOT . "/config/config.php")
  164. and !is_writable(OC::$SERVERROOT . "/config/config.php")) {
  165. $defaults = new OC_Defaults();
  166. if (self::$CLI) {
  167. echo "Can't write into config directory!\n";
  168. echo "This can usually be fixed by giving the webserver write access to the config directory\n";
  169. echo "\n";
  170. echo "See " . \OC_Helper::linkToDocs('admin-dir_permissions') . "\n";
  171. exit;
  172. } else {
  173. OC_Template::printErrorPage(
  174. "Can't write into config directory!",
  175. 'This can usually be fixed by '
  176. .'<a href="' . \OC_Helper::linkToDocs('admin-dir_permissions') . '" target="_blank">giving the webserver write access to the config directory</a>.'
  177. );
  178. }
  179. }
  180. }
  181. public static function checkInstalled() {
  182. // Redirect to installer if not installed
  183. if (!OC_Config::getValue('installed', false) && OC::$SUBURI != '/index.php') {
  184. if (!OC::$CLI) {
  185. $url = 'http://' . $_SERVER['SERVER_NAME'] . OC::$WEBROOT . '/index.php';
  186. header("Location: $url");
  187. }
  188. exit();
  189. }
  190. }
  191. public static function checkSSL() {
  192. // redirect to https site if configured
  193. if (OC_Config::getValue("forcessl", false)) {
  194. header('Strict-Transport-Security: max-age=31536000');
  195. ini_set("session.cookie_secure", "on");
  196. if (OC_Request::serverProtocol() <> 'https' and !OC::$CLI) {
  197. $url = "https://" . OC_Request::serverHost() . OC_Request::requestUri();
  198. header("Location: $url");
  199. exit();
  200. }
  201. } else {
  202. // Invalidate HSTS headers
  203. if (OC_Request::serverProtocol() === 'https') {
  204. header('Strict-Transport-Security: max-age=0');
  205. }
  206. }
  207. }
  208. public static function checkMaintenanceMode() {
  209. // Allow ajax update script to execute without being stopped
  210. if (OC_Config::getValue('maintenance', false) && OC::$SUBURI != '/core/ajax/update.php') {
  211. // send http status 503
  212. header('HTTP/1.1 503 Service Temporarily Unavailable');
  213. header('Status: 503 Service Temporarily Unavailable');
  214. header('Retry-After: 120');
  215. // render error page
  216. $tmpl = new OC_Template('', 'update.user', 'guest');
  217. $tmpl->printPage();
  218. die();
  219. }
  220. }
  221. public static function checkSingleUserMode() {
  222. $user = OC_User::getUserSession()->getUser();
  223. $group = OC_Group::getManager()->get('admin');
  224. if ($user && OC_Config::getValue('singleuser', false) && !$group->inGroup($user)) {
  225. // send http status 503
  226. header('HTTP/1.1 503 Service Temporarily Unavailable');
  227. header('Status: 503 Service Temporarily Unavailable');
  228. header('Retry-After: 120');
  229. // render error page
  230. $tmpl = new OC_Template('', 'singleuser.user', 'guest');
  231. $tmpl->printPage();
  232. die();
  233. }
  234. }
  235. public static function checkUpgrade($showTemplate = true) {
  236. if (OC_Config::getValue('installed', false)) {
  237. $installedVersion = OC_Config::getValue('version', '0.0.0');
  238. $currentVersion = implode('.', OC_Util::getVersion());
  239. if (version_compare($currentVersion, $installedVersion, '>')) {
  240. if ($showTemplate && !OC_Config::getValue('maintenance', false)) {
  241. OC_Config::setValue('theme', '');
  242. $minimizerCSS = new OC_Minimizer_CSS();
  243. $minimizerCSS->clearCache();
  244. $minimizerJS = new OC_Minimizer_JS();
  245. $minimizerJS->clearCache();
  246. OC_Util::addScript('update');
  247. $tmpl = new OC_Template('', 'update.admin', 'guest');
  248. $tmpl->assign('version', OC_Util::getVersionString());
  249. $tmpl->printPage();
  250. exit();
  251. } else {
  252. return true;
  253. }
  254. }
  255. return false;
  256. }
  257. }
  258. public static function initTemplateEngine() {
  259. // Add the stuff we need always
  260. OC_Util::addScript("jquery-1.10.0.min");
  261. OC_Util::addScript("jquery-migrate-1.2.1.min");
  262. OC_Util::addScript("jquery-ui-1.10.0.custom");
  263. OC_Util::addScript("jquery-showpassword");
  264. OC_Util::addScript("jquery.infieldlabel");
  265. OC_Util::addScript("jquery.placeholder");
  266. OC_Util::addScript("jquery-tipsy");
  267. OC_Util::addScript("compatibility");
  268. OC_Util::addScript("jquery.ocdialog");
  269. OC_Util::addScript("oc-dialogs");
  270. OC_Util::addScript("js");
  271. OC_Util::addScript("octemplate");
  272. OC_Util::addScript("eventsource");
  273. OC_Util::addScript("config");
  274. //OC_Util::addScript( "multiselect" );
  275. OC_Util::addScript('search', 'result');
  276. OC_Util::addScript('router');
  277. OC_Util::addScript("oc-requesttoken");
  278. // avatars
  279. if (\OC_Config::getValue('enable_avatars', true) === true) {
  280. \OC_Util::addScript('placeholder');
  281. \OC_Util::addScript('3rdparty', 'md5/md5.min');
  282. \OC_Util::addScript('jquery.avatar');
  283. \OC_Util::addScript('avatar');
  284. }
  285. OC_Util::addStyle("styles");
  286. OC_Util::addStyle("apps");
  287. OC_Util::addStyle("fixes");
  288. OC_Util::addStyle("multiselect");
  289. OC_Util::addStyle("jquery-ui-1.10.0.custom");
  290. OC_Util::addStyle("jquery-tipsy");
  291. OC_Util::addStyle("jquery.ocdialog");
  292. }
  293. public static function initSession() {
  294. // prevents javascript from accessing php session cookies
  295. ini_set('session.cookie_httponly', '1;');
  296. // set the cookie path to the ownCloud directory
  297. $cookie_path = OC::$WEBROOT ? : '/';
  298. ini_set('session.cookie_path', $cookie_path);
  299. //set the session object to a dummy session so code relying on the session existing still works
  300. self::$session = new \OC\Session\Memory('');
  301. try {
  302. // set the session name to the instance id - which is unique
  303. self::$session = new \OC\Session\Internal(OC_Util::getInstanceId());
  304. // if session cant be started break with http 500 error
  305. } catch (Exception $e) {
  306. //show the user a detailed error page
  307. OC_Response::setStatus(OC_Response::STATUS_INTERNAL_SERVER_ERROR);
  308. OC_Template::printExceptionErrorPage($e);
  309. }
  310. $sessionLifeTime = self::getSessionLifeTime();
  311. // regenerate session id periodically to avoid session fixation
  312. if (!self::$session->exists('SID_CREATED')) {
  313. self::$session->set('SID_CREATED', time());
  314. } else if (time() - self::$session->get('SID_CREATED') > $sessionLifeTime / 2) {
  315. session_regenerate_id(true);
  316. self::$session->set('SID_CREATED', time());
  317. }
  318. // session timeout
  319. if (self::$session->exists('LAST_ACTIVITY') && (time() - self::$session->get('LAST_ACTIVITY') > $sessionLifeTime)) {
  320. if (isset($_COOKIE[session_name()])) {
  321. setcookie(session_name(), '', time() - 42000, $cookie_path);
  322. }
  323. session_unset();
  324. session_destroy();
  325. session_start();
  326. }
  327. self::$session->set('LAST_ACTIVITY', time());
  328. }
  329. /**
  330. * @return int
  331. */
  332. private static function getSessionLifeTime() {
  333. return OC_Config::getValue('session_lifetime', 60 * 60 * 24);
  334. }
  335. /**
  336. * @return OC_Router
  337. */
  338. public static function getRouter() {
  339. if (!isset(OC::$router)) {
  340. OC::$router = new OC_Router();
  341. OC::$router->loadRoutes();
  342. }
  343. return OC::$router;
  344. }
  345. public static function loadAppClassPaths() {
  346. foreach (OC_APP::getEnabledApps() as $app) {
  347. $file = OC_App::getAppPath($app) . '/appinfo/classpath.php';
  348. if (file_exists($file)) {
  349. require_once $file;
  350. }
  351. }
  352. }
  353. public static function init() {
  354. // register autoloader
  355. require_once __DIR__ . '/autoloader.php';
  356. self::$loader = new \OC\Autoloader();
  357. self::$loader->registerPrefix('Doctrine\\Common', 'doctrine/common/lib');
  358. self::$loader->registerPrefix('Doctrine\\DBAL', 'doctrine/dbal/lib');
  359. self::$loader->registerPrefix('Symfony\\Component\\Routing', 'symfony/routing');
  360. self::$loader->registerPrefix('Symfony\\Component\\Console', 'symfony/console');
  361. self::$loader->registerPrefix('Sabre\\VObject', '3rdparty');
  362. self::$loader->registerPrefix('Sabre_', '3rdparty');
  363. self::$loader->registerPrefix('Patchwork', '3rdparty');
  364. spl_autoload_register(array(self::$loader, 'load'));
  365. // set some stuff
  366. //ob_start();
  367. error_reporting(E_ALL | E_STRICT);
  368. if (defined('DEBUG') && DEBUG) {
  369. ini_set('display_errors', 1);
  370. }
  371. self::$CLI = (php_sapi_name() == 'cli');
  372. date_default_timezone_set('UTC');
  373. ini_set('arg_separator.output', '&amp;');
  374. // try to switch magic quotes off.
  375. if (get_magic_quotes_gpc() == 1) {
  376. ini_set('magic_quotes_runtime', 0);
  377. }
  378. //try to configure php to enable big file uploads.
  379. //this doesn´t work always depending on the webserver and php configuration.
  380. //Let´s try to overwrite some defaults anyways
  381. //try to set the maximum execution time to 60min
  382. @set_time_limit(3600);
  383. @ini_set('max_execution_time', 3600);
  384. @ini_set('max_input_time', 3600);
  385. //try to set the maximum filesize to 10G
  386. @ini_set('upload_max_filesize', '10G');
  387. @ini_set('post_max_size', '10G');
  388. @ini_set('file_uploads', '50');
  389. //copy http auth headers for apache+php-fcgid work around
  390. if (isset($_SERVER['HTTP_XAUTHORIZATION']) && !isset($_SERVER['HTTP_AUTHORIZATION'])) {
  391. $_SERVER['HTTP_AUTHORIZATION'] = $_SERVER['HTTP_XAUTHORIZATION'];
  392. }
  393. //set http auth headers for apache+php-cgi work around
  394. if (isset($_SERVER['HTTP_AUTHORIZATION'])
  395. && preg_match('/Basic\s+(.*)$/i', $_SERVER['HTTP_AUTHORIZATION'], $matches)
  396. ) {
  397. list($name, $password) = explode(':', base64_decode($matches[1]), 2);
  398. $_SERVER['PHP_AUTH_USER'] = strip_tags($name);
  399. $_SERVER['PHP_AUTH_PW'] = strip_tags($password);
  400. }
  401. //set http auth headers for apache+php-cgi work around if variable gets renamed by apache
  402. if (isset($_SERVER['REDIRECT_HTTP_AUTHORIZATION'])
  403. && preg_match('/Basic\s+(.*)$/i', $_SERVER['REDIRECT_HTTP_AUTHORIZATION'], $matches)
  404. ) {
  405. list($name, $password) = explode(':', base64_decode($matches[1]), 2);
  406. $_SERVER['PHP_AUTH_USER'] = strip_tags($name);
  407. $_SERVER['PHP_AUTH_PW'] = strip_tags($password);
  408. }
  409. self::initPaths();
  410. if (OC_Config::getValue('instanceid', false)) {
  411. // \OC\Memcache\Cache has a hidden dependency on
  412. // OC_Util::getInstanceId() for namespacing. See #5409.
  413. try {
  414. self::$loader->setMemoryCache(\OC\Memcache\Factory::createLowLatency('Autoloader'));
  415. } catch(\Exception $ex) {
  416. }
  417. }
  418. OC_Util::isSetLocaleWorking();
  419. // set debug mode if an xdebug session is active
  420. if (!defined('DEBUG') || !DEBUG) {
  421. if (isset($_COOKIE['XDEBUG_SESSION'])) {
  422. define('DEBUG', true);
  423. }
  424. }
  425. if (!defined('PHPUNIT_RUN')) {
  426. if (defined('DEBUG') and DEBUG) {
  427. set_exception_handler(array('OC_Template', 'printExceptionErrorPage'));
  428. } else {
  429. OC\Log\ErrorHandler::register();
  430. OC\Log\ErrorHandler::setLogger(OC_Log::$object);
  431. }
  432. }
  433. // register the stream wrappers
  434. stream_wrapper_register('fakedir', 'OC\Files\Stream\Dir');
  435. stream_wrapper_register('static', 'OC\Files\Stream\StaticStream');
  436. stream_wrapper_register('close', 'OC\Files\Stream\Close');
  437. stream_wrapper_register('quota', 'OC\Files\Stream\Quota');
  438. stream_wrapper_register('oc', 'OC\Files\Stream\OC');
  439. // setup the basic server
  440. self::$server = new \OC\Server();
  441. self::initTemplateEngine();
  442. if (!self::$CLI) {
  443. self::initSession();
  444. } else {
  445. self::$session = new \OC\Session\Memory('');
  446. }
  447. self::checkConfig();
  448. self::checkInstalled();
  449. self::checkSSL();
  450. $errors = OC_Util::checkServer();
  451. if (count($errors) > 0) {
  452. if (self::$CLI) {
  453. foreach ($errors as $error) {
  454. echo $error['error']."\n";
  455. echo $error['hint'] . "\n\n";
  456. }
  457. } else {
  458. OC_Template::printGuestPage('', 'error', array('errors' => $errors));
  459. }
  460. exit;
  461. }
  462. //try to set the session lifetime
  463. $sessionLifeTime = self::getSessionLifeTime();
  464. @ini_set('gc_maxlifetime', (string)$sessionLifeTime);
  465. // User and Groups
  466. if (!OC_Config::getValue("installed", false)) {
  467. self::$session->set('user_id', '');
  468. }
  469. OC_User::useBackend(new OC_User_Database());
  470. OC_Group::useBackend(new OC_Group_Database());
  471. if (isset($_SERVER['PHP_AUTH_USER']) && self::$session->exists('user_id')
  472. && $_SERVER['PHP_AUTH_USER'] != self::$session->get('user_id')) {
  473. $sessionUser = self::$session->get('user_id');
  474. $serverUser = $_SERVER['PHP_AUTH_USER'];
  475. OC_Log::write('core',
  476. "Session user-id ($sessionUser) doesn't match SERVER[PHP_AUTH_USER] ($serverUser).",
  477. OC_Log::WARN);
  478. OC_User::logout();
  479. }
  480. // Load Apps
  481. // This includes plugins for users and filesystems as well
  482. global $RUNTIME_NOAPPS;
  483. global $RUNTIME_APPTYPES;
  484. if (!$RUNTIME_NOAPPS && !self::checkUpgrade(false)) {
  485. if ($RUNTIME_APPTYPES) {
  486. OC_App::loadApps($RUNTIME_APPTYPES);
  487. } else {
  488. OC_App::loadApps();
  489. }
  490. }
  491. //setup extra user backends
  492. OC_User::setupBackends();
  493. self::registerCacheHooks();
  494. self::registerFilesystemHooks();
  495. self::registerPreviewHooks();
  496. self::registerShareHooks();
  497. self::registerLogRotate();
  498. //make sure temporary files are cleaned up
  499. register_shutdown_function(array('OC_Helper', 'cleanTmp'));
  500. //parse the given parameters
  501. self::$REQUESTEDAPP = (isset($_GET['app']) && trim($_GET['app']) != '' && !is_null($_GET['app']) ? OC_App::cleanAppId(strip_tags($_GET['app'])) : OC_Config::getValue('defaultapp', 'files'));
  502. if (substr_count(self::$REQUESTEDAPP, '?') != 0) {
  503. $app = substr(self::$REQUESTEDAPP, 0, strpos(self::$REQUESTEDAPP, '?'));
  504. $param = substr($_GET['app'], strpos($_GET['app'], '?') + 1);
  505. parse_str($param, $get);
  506. $_GET = array_merge($_GET, $get);
  507. self::$REQUESTEDAPP = $app;
  508. $_GET['app'] = $app;
  509. }
  510. self::$REQUESTEDFILE = (isset($_GET['getfile']) ? $_GET['getfile'] : null);
  511. if (substr_count(self::$REQUESTEDFILE, '?') != 0) {
  512. $file = substr(self::$REQUESTEDFILE, 0, strpos(self::$REQUESTEDFILE, '?'));
  513. $param = substr(self::$REQUESTEDFILE, strpos(self::$REQUESTEDFILE, '?') + 1);
  514. parse_str($param, $get);
  515. $_GET = array_merge($_GET, $get);
  516. self::$REQUESTEDFILE = $file;
  517. $_GET['getfile'] = $file;
  518. }
  519. if (!is_null(self::$REQUESTEDFILE)) {
  520. $subdir = OC_App::getAppPath(OC::$REQUESTEDAPP) . '/' . self::$REQUESTEDFILE;
  521. $parent = OC_App::getAppPath(OC::$REQUESTEDAPP);
  522. if (!OC_Helper::issubdirectory($subdir, $parent)) {
  523. self::$REQUESTEDFILE = null;
  524. header('HTTP/1.0 404 Not Found');
  525. exit;
  526. }
  527. }
  528. if (OC_Config::getValue('installed', false) && !self::checkUpgrade(false)) {
  529. if (OC_Appconfig::getValue('core', 'backgroundjobs_mode', 'ajax') == 'ajax') {
  530. OC_Util::addScript('backgroundjobs');
  531. }
  532. }
  533. }
  534. /**
  535. * register hooks for the cache
  536. */
  537. public static function registerCacheHooks() {
  538. if (OC_Config::getValue('installed', false)) { //don't try to do this before we are properly setup
  539. // register cache cleanup jobs
  540. try { //if this is executed before the upgrade to the new backgroundjob system is completed it will throw an exception
  541. \OCP\BackgroundJob::registerJob('OC\Cache\FileGlobalGC');
  542. } catch (Exception $e) {
  543. }
  544. // NOTE: This will be replaced to use OCP
  545. $userSession = \OC_User::getUserSession();
  546. $userSession->listen('postLogin', '\OC\Cache\File', 'loginListener');
  547. }
  548. }
  549. /**
  550. * register hooks for the cache
  551. */
  552. public static function registerLogRotate() {
  553. if (OC_Config::getValue('installed', false) && OC_Config::getValue('log_rotate_size', false)) {
  554. //don't try to do this before we are properly setup
  555. // register cache cleanup jobs
  556. try { //if this is executed before the upgrade to the new backgroundjob system is completed it will throw an exception
  557. \OCP\BackgroundJob::registerJob('OC\Log\Rotate', OC_Config::getValue("datadirectory", OC::$SERVERROOT.'/data').'/owncloud.log');
  558. } catch (Exception $e) {
  559. }
  560. }
  561. }
  562. /**
  563. * register hooks for the filesystem
  564. */
  565. public static function registerFilesystemHooks() {
  566. // Check for blacklisted files
  567. OC_Hook::connect('OC_Filesystem', 'write', 'OC_Filesystem', 'isBlacklisted');
  568. OC_Hook::connect('OC_Filesystem', 'rename', 'OC_Filesystem', 'isBlacklisted');
  569. }
  570. /**
  571. * register hooks for previews
  572. */
  573. public static function registerPreviewHooks() {
  574. OC_Hook::connect('OC_Filesystem', 'post_write', 'OC\Preview', 'post_write');
  575. OC_Hook::connect('OC_Filesystem', 'delete', 'OC\Preview', 'post_delete');
  576. OC_Hook::connect('\OCP\Versions', 'delete', 'OC\Preview', 'post_delete');
  577. OC_Hook::connect('\OCP\Trashbin', 'delete', 'OC\Preview', 'post_delete');
  578. }
  579. /**
  580. * register hooks for sharing
  581. */
  582. public static function registerShareHooks() {
  583. if(\OC_Config::getValue('installed')) {
  584. OC_Hook::connect('OC_User', 'post_deleteUser', 'OCP\Share', 'post_deleteUser');
  585. OC_Hook::connect('OC_User', 'post_addToGroup', 'OCP\Share', 'post_addToGroup');
  586. OC_Hook::connect('OC_User', 'post_removeFromGroup', 'OCP\Share', 'post_removeFromGroup');
  587. OC_Hook::connect('OC_User', 'post_deleteGroup', 'OCP\Share', 'post_deleteGroup');
  588. }
  589. }
  590. /**
  591. * @brief Handle the request
  592. */
  593. public static function handleRequest() {
  594. // load all the classpaths from the enabled apps so they are available
  595. // in the routing files of each app
  596. OC::loadAppClassPaths();
  597. // Check if ownCloud is installed or in maintenance (update) mode
  598. if (!OC_Config::getValue('installed', false)) {
  599. require_once 'core/setup.php';
  600. exit();
  601. }
  602. $request = OC_Request::getPathInfo();
  603. if(substr($request, -3) !== '.js') {// we need these files during the upgrade
  604. self::checkMaintenanceMode();
  605. self::checkUpgrade();
  606. }
  607. // Test it the user is already authenticated using Apaches AuthType Basic... very usable in combination with LDAP
  608. OC::tryBasicAuthLogin();
  609. if (!self::$CLI and (!isset($_GET["logout"]) or ($_GET["logout"] !== 'true'))) {
  610. try {
  611. if (!OC_Config::getValue('maintenance', false)) {
  612. OC_App::loadApps();
  613. }
  614. self::checkSingleUserMode();
  615. OC::getRouter()->match(OC_Request::getRawPathInfo());
  616. return;
  617. } catch (Symfony\Component\Routing\Exception\ResourceNotFoundException $e) {
  618. //header('HTTP/1.0 404 Not Found');
  619. } catch (Symfony\Component\Routing\Exception\MethodNotAllowedException $e) {
  620. OC_Response::setStatus(405);
  621. return;
  622. }
  623. }
  624. $app = OC::$REQUESTEDAPP;
  625. $file = OC::$REQUESTEDFILE;
  626. $param = array('app' => $app, 'file' => $file);
  627. // Handle app css files
  628. if (substr($file, -3) == 'css') {
  629. self::loadCSSFile($param);
  630. return;
  631. }
  632. // Handle redirect URL for logged in users
  633. if (isset($_REQUEST['redirect_url']) && OC_User::isLoggedIn()) {
  634. $location = OC_Helper::makeURLAbsolute(urldecode($_REQUEST['redirect_url']));
  635. // Deny the redirect if the URL contains a @
  636. // This prevents unvalidated redirects like ?redirect_url=:user@domain.com
  637. if (strpos($location, '@') === false) {
  638. header('Location: ' . $location);
  639. return;
  640. }
  641. }
  642. // Handle WebDAV
  643. if ($_SERVER['REQUEST_METHOD'] == 'PROPFIND') {
  644. // not allowed any more to prevent people
  645. // mounting this root directly.
  646. // Users need to mount remote.php/webdav instead.
  647. header('HTTP/1.1 405 Method Not Allowed');
  648. header('Status: 405 Method Not Allowed');
  649. return;
  650. }
  651. // Someone is logged in :
  652. if (OC_User::isLoggedIn()) {
  653. OC_App::loadApps();
  654. OC_User::setupBackends();
  655. if (isset($_GET["logout"]) and ($_GET["logout"])) {
  656. if (isset($_COOKIE['oc_token'])) {
  657. OC_Preferences::deleteKey(OC_User::getUser(), 'login_token', $_COOKIE['oc_token']);
  658. }
  659. OC_User::logout();
  660. header("Location: " . OC::$WEBROOT . '/');
  661. } else {
  662. if (is_null($file)) {
  663. $param['file'] = 'index.php';
  664. }
  665. $file_ext = substr($param['file'], -3);
  666. if ($file_ext != 'php'
  667. || !self::loadAppScriptFile($param)
  668. ) {
  669. header('HTTP/1.0 404 Not Found');
  670. }
  671. }
  672. return;
  673. }
  674. // Not handled and not logged in
  675. self::handleLogin();
  676. }
  677. public static function loadAppScriptFile($param) {
  678. OC_App::loadApps();
  679. $app = $param['app'];
  680. $file = $param['file'];
  681. $app_path = OC_App::getAppPath($app);
  682. if (OC_App::isEnabled($app) && $app_path !== false) {
  683. $file = $app_path . '/' . $file;
  684. unset($app, $app_path);
  685. if (file_exists($file)) {
  686. require_once $file;
  687. return true;
  688. }
  689. }
  690. header('HTTP/1.0 404 Not Found');
  691. return false;
  692. }
  693. public static function loadCSSFile($param) {
  694. $app = $param['app'];
  695. $file = $param['file'];
  696. $app_path = OC_App::getAppPath($app);
  697. if (file_exists($app_path . '/' . $file)) {
  698. $app_web_path = OC_App::getAppWebPath($app);
  699. $filepath = $app_web_path . '/' . $file;
  700. $minimizer = new OC_Minimizer_CSS();
  701. $info = array($app_path, $app_web_path, $file);
  702. $minimizer->output(array($info), $filepath);
  703. }
  704. }
  705. protected static function handleLogin() {
  706. OC_App::loadApps(array('prelogin'));
  707. $error = array();
  708. // auth possible via apache module?
  709. if (OC::tryApacheAuth()) {
  710. $error[] = 'apacheauthfailed';
  711. }
  712. // remember was checked after last login
  713. elseif (OC::tryRememberLogin()) {
  714. $error[] = 'invalidcookie';
  715. }
  716. // logon via web form
  717. elseif (OC::tryFormLogin()) {
  718. $error[] = 'invalidpassword';
  719. if ( OC_Config::getValue('log_authfailip', false) ) {
  720. OC_Log::write('core', 'Login failed: user \''.$_POST["user"].'\' , wrong password, IP:'.$_SERVER['REMOTE_ADDR'],
  721. OC_Log::WARN);
  722. } else {
  723. OC_Log::write('core', 'Login failed: user \''.$_POST["user"].'\' , wrong password, IP:set log_authfailip=true in conf',
  724. OC_Log::WARN);
  725. }
  726. }
  727. OC_Util::displayLoginPage(array_unique($error));
  728. }
  729. protected static function cleanupLoginTokens($user) {
  730. $cutoff = time() - OC_Config::getValue('remember_login_cookie_lifetime', 60 * 60 * 24 * 15);
  731. $tokens = OC_Preferences::getKeys($user, 'login_token');
  732. foreach ($tokens as $token) {
  733. $time = OC_Preferences::getValue($user, 'login_token', $token);
  734. if ($time < $cutoff) {
  735. OC_Preferences::deleteKey($user, 'login_token', $token);
  736. }
  737. }
  738. }
  739. protected static function tryApacheAuth() {
  740. $return = OC_User::handleApacheAuth();
  741. // if return is true we are logged in -> redirect to the default page
  742. if ($return === true) {
  743. $_REQUEST['redirect_url'] = \OC_Request::requestUri();
  744. OC_Util::redirectToDefaultPage();
  745. exit;
  746. }
  747. // in case $return is null apache based auth is not enabled
  748. return is_null($return) ? false : true;
  749. }
  750. protected static function tryRememberLogin() {
  751. if (!isset($_COOKIE["oc_remember_login"])
  752. || !isset($_COOKIE["oc_token"])
  753. || !isset($_COOKIE["oc_username"])
  754. || !$_COOKIE["oc_remember_login"]
  755. || !OC_Util::rememberLoginAllowed()
  756. ) {
  757. return false;
  758. }
  759. OC_App::loadApps(array('authentication'));
  760. if (defined("DEBUG") && DEBUG) {
  761. OC_Log::write('core', 'Trying to login from cookie', OC_Log::DEBUG);
  762. }
  763. // confirm credentials in cookie
  764. if (isset($_COOKIE['oc_token']) && OC_User::userExists($_COOKIE['oc_username'])) {
  765. // delete outdated cookies
  766. self::cleanupLoginTokens($_COOKIE['oc_username']);
  767. // get stored tokens
  768. $tokens = OC_Preferences::getKeys($_COOKIE['oc_username'], 'login_token');
  769. // test cookies token against stored tokens
  770. if (in_array($_COOKIE['oc_token'], $tokens, true)) {
  771. // replace successfully used token with a new one
  772. OC_Preferences::deleteKey($_COOKIE['oc_username'], 'login_token', $_COOKIE['oc_token']);
  773. $token = OC_Util::generateRandomBytes(32);
  774. OC_Preferences::setValue($_COOKIE['oc_username'], 'login_token', $token, time());
  775. OC_User::setMagicInCookie($_COOKIE['oc_username'], $token);
  776. // login
  777. OC_User::setUserId($_COOKIE['oc_username']);
  778. OC_Util::redirectToDefaultPage();
  779. // doesn't return
  780. }
  781. // if you reach this point you have changed your password
  782. // or you are an attacker
  783. // we can not delete tokens here because users may reach
  784. // this point multiple times after a password change
  785. OC_Log::write('core', 'Authentication cookie rejected for user ' . $_COOKIE['oc_username'], OC_Log::WARN);
  786. }
  787. OC_User::unsetMagicInCookie();
  788. return true;
  789. }
  790. protected static function tryFormLogin() {
  791. if (!isset($_POST["user"]) || !isset($_POST['password'])) {
  792. return false;
  793. }
  794. OC_App::loadApps();
  795. //setup extra user backends
  796. OC_User::setupBackends();
  797. if (OC_User::login($_POST["user"], $_POST["password"])) {
  798. // setting up the time zone
  799. if (isset($_POST['timezone-offset'])) {
  800. self::$session->set('timezone', $_POST['timezone-offset']);
  801. }
  802. $userid = OC_User::getUser();
  803. self::cleanupLoginTokens($userid);
  804. if (!empty($_POST["remember_login"])) {
  805. if (defined("DEBUG") && DEBUG) {
  806. OC_Log::write('core', 'Setting remember login to cookie', OC_Log::DEBUG);
  807. }
  808. $token = OC_Util::generateRandomBytes(32);
  809. OC_Preferences::setValue($userid, 'login_token', $token, time());
  810. OC_User::setMagicInCookie($userid, $token);
  811. } else {
  812. OC_User::unsetMagicInCookie();
  813. }
  814. OC_Util::redirectToDefaultPage();
  815. exit();
  816. }
  817. return true;
  818. }
  819. protected static function tryBasicAuthLogin() {
  820. if (!isset($_SERVER["PHP_AUTH_USER"])
  821. || !isset($_SERVER["PHP_AUTH_PW"])
  822. ) {
  823. return false;
  824. }
  825. OC_App::loadApps(array('authentication'));
  826. if (OC_User::login($_SERVER["PHP_AUTH_USER"], $_SERVER["PHP_AUTH_PW"])) {
  827. //OC_Log::write('core',"Logged in with HTTP Authentication", OC_Log::DEBUG);
  828. OC_User::unsetMagicInCookie();
  829. $_SERVER['HTTP_REQUESTTOKEN'] = OC_Util::callRegister();
  830. }
  831. return true;
  832. }
  833. }
  834. // define runtime variables - unless this already has been done
  835. if (!isset($RUNTIME_NOAPPS)) {
  836. $RUNTIME_NOAPPS = false;
  837. }
  838. if (!function_exists('get_temp_dir')) {
  839. function get_temp_dir() {
  840. if ($temp = ini_get('upload_tmp_dir')) return $temp;
  841. if ($temp = getenv('TMP')) return $temp;
  842. if ($temp = getenv('TEMP')) return $temp;
  843. if ($temp = getenv('TMPDIR')) return $temp;
  844. $temp = tempnam(__FILE__, '');
  845. if (file_exists($temp)) {
  846. unlink($temp);
  847. return dirname($temp);
  848. }
  849. if ($temp = sys_get_temp_dir()) return $temp;
  850. return null;
  851. }
  852. }
  853. OC::init();