base.php 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758
  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. /**
  31. * Assoziative array for autoloading. classname => filename
  32. */
  33. public static $CLASSPATH = array();
  34. /**
  35. * The installation path for owncloud on the server (e.g. /srv/http/owncloud)
  36. */
  37. public static $SERVERROOT = '';
  38. /**
  39. * the current request path relative to the owncloud root (e.g. files/index.php)
  40. */
  41. private static $SUBURI = '';
  42. /**
  43. * the owncloud root path for http requests (e.g. owncloud/)
  44. */
  45. public static $WEBROOT = '';
  46. /**
  47. * The installation path of the 3rdparty folder on the server (e.g. /srv/http/owncloud/3rdparty)
  48. */
  49. public static $THIRDPARTYROOT = '';
  50. /**
  51. * the root path of the 3rdparty folder for http requests (e.g. owncloud/3rdparty)
  52. */
  53. public static $THIRDPARTYWEBROOT = '';
  54. /**
  55. * The installation path array of the apps folder on the server (e.g. /srv/http/owncloud) 'path' and
  56. * web path in 'url'
  57. */
  58. public static $APPSROOTS = array();
  59. /*
  60. * requested app
  61. */
  62. public static $REQUESTEDAPP = '';
  63. /*
  64. * requested file of app
  65. */
  66. public static $REQUESTEDFILE = '';
  67. /**
  68. * check if owncloud runs in cli mode
  69. */
  70. public static $CLI = false;
  71. /*
  72. * OC router
  73. */
  74. protected static $router = null;
  75. /**
  76. * SPL autoload
  77. */
  78. public static function autoload($className)
  79. {
  80. if (array_key_exists($className, OC::$CLASSPATH)) {
  81. $path = OC::$CLASSPATH[$className];
  82. /** @TODO: Remove this when necessary
  83. Remove "apps/" from inclusion path for smooth migration to mutli app dir
  84. */
  85. if (strpos($path, 'apps/') === 0) {
  86. OC_Log::write('core', 'include path for class "' . $className . '" starts with "apps/"', OC_Log::DEBUG);
  87. $path = str_replace('apps/', '', $path);
  88. }
  89. } elseif (strpos($className, 'OC_') === 0) {
  90. $path = strtolower(str_replace('_', '/', substr($className, 3)) . '.php');
  91. } elseif (strpos($className, 'OC\\') === 0) {
  92. $path = strtolower(str_replace('\\', '/', substr($className, 3)) . '.php');
  93. } elseif (strpos($className, 'OCP\\') === 0) {
  94. $path = 'public/' . strtolower(str_replace('\\', '/', substr($className, 3)) . '.php');
  95. } elseif (strpos($className, 'OCA\\') === 0) {
  96. $path = 'apps/' . strtolower(str_replace('\\', '/', substr($className, 3)) . '.php');
  97. } elseif (strpos($className, 'Sabre_') === 0) {
  98. $path = str_replace('_', '/', $className) . '.php';
  99. } elseif (strpos($className, 'Symfony\\Component\\Routing\\') === 0) {
  100. $path = 'symfony/routing/' . str_replace('\\', '/', $className) . '.php';
  101. } elseif (strpos($className, 'Sabre\\VObject') === 0) {
  102. $path = str_replace('\\', '/', $className) . '.php';
  103. } elseif (strpos($className, 'Test_') === 0) {
  104. $path = 'tests/lib/' . strtolower(str_replace('_', '/', substr($className, 5)) . '.php');
  105. } else {
  106. return false;
  107. }
  108. if ($fullPath = stream_resolve_include_path($path)) {
  109. require_once $fullPath;
  110. }
  111. return false;
  112. }
  113. public static function initPaths()
  114. {
  115. // calculate the root directories
  116. OC::$SERVERROOT = str_replace("\\", '/', substr(__DIR__, 0, -4));
  117. OC::$SUBURI = str_replace("\\", "/", substr(realpath($_SERVER["SCRIPT_FILENAME"]), strlen(OC::$SERVERROOT)));
  118. $scriptName = $_SERVER["SCRIPT_NAME"];
  119. if (substr($scriptName, -1) == '/') {
  120. $scriptName .= 'index.php';
  121. //make sure suburi follows the same rules as scriptName
  122. if (substr(OC::$SUBURI, -9) != 'index.php') {
  123. if (substr(OC::$SUBURI, -1) != '/') {
  124. OC::$SUBURI = OC::$SUBURI . '/';
  125. }
  126. OC::$SUBURI = OC::$SUBURI . 'index.php';
  127. }
  128. }
  129. OC::$WEBROOT = substr($scriptName, 0, strlen($scriptName) - strlen(OC::$SUBURI));
  130. if (OC::$WEBROOT != '' and OC::$WEBROOT[0] !== '/') {
  131. OC::$WEBROOT = '/' . OC::$WEBROOT;
  132. }
  133. // ensure we can find OC_Config
  134. set_include_path(
  135. OC::$SERVERROOT . '/lib' . PATH_SEPARATOR .
  136. get_include_path()
  137. );
  138. // search the 3rdparty folder
  139. if (OC_Config::getValue('3rdpartyroot', '') <> '' and OC_Config::getValue('3rdpartyurl', '') <> '') {
  140. OC::$THIRDPARTYROOT = OC_Config::getValue('3rdpartyroot', '');
  141. OC::$THIRDPARTYWEBROOT = OC_Config::getValue('3rdpartyurl', '');
  142. } elseif (file_exists(OC::$SERVERROOT . '/3rdparty')) {
  143. OC::$THIRDPARTYROOT = OC::$SERVERROOT;
  144. OC::$THIRDPARTYWEBROOT = OC::$WEBROOT;
  145. } elseif (file_exists(OC::$SERVERROOT . '/../3rdparty')) {
  146. OC::$THIRDPARTYWEBROOT = rtrim(dirname(OC::$WEBROOT), '/');
  147. OC::$THIRDPARTYROOT = rtrim(dirname(OC::$SERVERROOT), '/');
  148. } else {
  149. echo("3rdparty directory not found! Please put the ownCloud 3rdparty folder in the ownCloud folder or the folder above. You can also configure the location in the config.php file.");
  150. exit;
  151. }
  152. // search the apps folder
  153. $config_paths = OC_Config::getValue('apps_paths', array());
  154. if (!empty($config_paths)) {
  155. foreach ($config_paths as $paths) {
  156. if (isset($paths['url']) && isset($paths['path'])) {
  157. $paths['url'] = rtrim($paths['url'], '/');
  158. $paths['path'] = rtrim($paths['path'], '/');
  159. OC::$APPSROOTS[] = $paths;
  160. }
  161. }
  162. } elseif (file_exists(OC::$SERVERROOT . '/apps')) {
  163. OC::$APPSROOTS[] = array('path' => OC::$SERVERROOT . '/apps', 'url' => '/apps', 'writable' => true);
  164. } elseif (file_exists(OC::$SERVERROOT . '/../apps')) {
  165. OC::$APPSROOTS[] = array('path' => rtrim(dirname(OC::$SERVERROOT), '/') . '/apps', 'url' => '/apps', 'writable' => true);
  166. }
  167. if (empty(OC::$APPSROOTS)) {
  168. echo("apps directory not found! Please put the ownCloud apps folder in the ownCloud folder or the folder above. You can also configure the location in the config.php file.");
  169. exit;
  170. }
  171. $paths = array();
  172. foreach (OC::$APPSROOTS as $path)
  173. $paths[] = $path['path'];
  174. // set the right include path
  175. set_include_path(
  176. OC::$SERVERROOT . '/lib' . PATH_SEPARATOR .
  177. OC::$SERVERROOT . '/config' . PATH_SEPARATOR .
  178. OC::$THIRDPARTYROOT . '/3rdparty' . PATH_SEPARATOR .
  179. implode($paths, PATH_SEPARATOR) . PATH_SEPARATOR .
  180. get_include_path() . PATH_SEPARATOR .
  181. OC::$SERVERROOT
  182. );
  183. }
  184. public static function checkInstalled()
  185. {
  186. // Redirect to installer if not installed
  187. if (!OC_Config::getValue('installed', false) && OC::$SUBURI != '/index.php') {
  188. if (!OC::$CLI) {
  189. $url = 'http://' . $_SERVER['SERVER_NAME'] . OC::$WEBROOT . '/index.php';
  190. header("Location: $url");
  191. }
  192. exit();
  193. }
  194. }
  195. public static function checkSSL()
  196. {
  197. // redirect to https site if configured
  198. if (OC_Config::getValue("forcessl", false)) {
  199. header('Strict-Transport-Security: max-age=31536000');
  200. ini_set("session.cookie_secure", "on");
  201. if (OC_Request::serverProtocol() <> 'https' and !OC::$CLI) {
  202. $url = "https://" . OC_Request::serverHost() . $_SERVER['REQUEST_URI'];
  203. header("Location: $url");
  204. exit();
  205. }
  206. }
  207. }
  208. public static function checkUpgrade()
  209. {
  210. if (OC_Config::getValue('installed', false)) {
  211. $installedVersion = OC_Config::getValue('version', '0.0.0');
  212. $currentVersion = implode('.', OC_Util::getVersion());
  213. if (version_compare($currentVersion, $installedVersion, '>')) {
  214. // Check if the .htaccess is existing - this is needed for upgrades from really old ownCloud versions
  215. if (isset($_SERVER['SERVER_SOFTWARE']) && strstr($_SERVER['SERVER_SOFTWARE'], 'Apache')) {
  216. if (!OC_Util::ishtaccessworking()) {
  217. if (!file_exists(OC::$SERVERROOT . '/data/.htaccess')) {
  218. OC_Setup::protectDataDirectory();
  219. }
  220. }
  221. }
  222. OC_Log::write('core', 'starting upgrade from ' . $installedVersion . ' to ' . $currentVersion, OC_Log::DEBUG);
  223. $result = OC_DB::updateDbFromStructure(OC::$SERVERROOT . '/db_structure.xml');
  224. if (!$result) {
  225. echo 'Error while upgrading the database';
  226. die();
  227. }
  228. if (file_exists(OC::$SERVERROOT . "/config/config.php") and !is_writable(OC::$SERVERROOT . "/config/config.php")) {
  229. $tmpl = new OC_Template('', 'error', 'guest');
  230. $tmpl->assign('errors', array(1 => array('error' => "Can't write into config directory 'config'", 'hint' => "You can usually fix this by giving the webserver user write access to the config directory in owncloud")));
  231. $tmpl->printPage();
  232. exit;
  233. }
  234. $minimizerCSS = new OC_Minimizer_CSS();
  235. $minimizerCSS->clearCache();
  236. $minimizerJS = new OC_Minimizer_JS();
  237. $minimizerJS->clearCache();
  238. OC_Config::setValue('version', implode('.', OC_Util::getVersion()));
  239. OC_App::checkAppsRequirements();
  240. // load all apps to also upgrade enabled apps
  241. OC_App::loadApps();
  242. }
  243. }
  244. }
  245. public static function initTemplateEngine()
  246. {
  247. // Add the stuff we need always
  248. OC_Util::addScript("jquery-1.7.2.min");
  249. OC_Util::addScript("jquery-ui-1.8.16.custom.min");
  250. OC_Util::addScript("jquery-showpassword");
  251. OC_Util::addScript("jquery.infieldlabel");
  252. OC_Util::addScript("jquery-tipsy");
  253. OC_Util::addScript("oc-dialogs");
  254. OC_Util::addScript("js");
  255. OC_Util::addScript("eventsource");
  256. OC_Util::addScript("config");
  257. //OC_Util::addScript( "multiselect" );
  258. OC_Util::addScript('search', 'result');
  259. OC_Util::addScript('router');
  260. if (OC_Config::getValue('installed', false)) {
  261. if (OC_Appconfig::getValue('core', 'backgroundjobs_mode', 'ajax') == 'ajax') {
  262. OC_Util::addScript('backgroundjobs');
  263. }
  264. }
  265. OC_Util::addStyle("styles");
  266. OC_Util::addStyle("multiselect");
  267. OC_Util::addStyle("jquery-ui-1.8.16.custom");
  268. OC_Util::addStyle("jquery-tipsy");
  269. }
  270. public static function initSession()
  271. {
  272. // prevents javascript from accessing php session cookies
  273. ini_set('session.cookie_httponly', '1;');
  274. // set the session name to the instance id - which is unique
  275. session_name(OC_Util::getInstanceId());
  276. // (re)-initialize session
  277. session_start();
  278. // regenerate session id periodically to avoid session fixation
  279. if (!isset($_SESSION['SID_CREATED'])) {
  280. $_SESSION['SID_CREATED'] = time();
  281. } else if (time() - $_SESSION['SID_CREATED'] > 900) {
  282. session_regenerate_id(true);
  283. $_SESSION['SID_CREATED'] = time();
  284. }
  285. // session timeout
  286. if (isset($_SESSION['LAST_ACTIVITY']) && (time() - $_SESSION['LAST_ACTIVITY'] > 3600)) {
  287. if (isset($_COOKIE[session_name()])) {
  288. setcookie(session_name(), '', time() - 42000, '/');
  289. }
  290. session_unset();
  291. session_destroy();
  292. session_start();
  293. }
  294. $_SESSION['LAST_ACTIVITY'] = time();
  295. }
  296. public static function getRouter()
  297. {
  298. if (!isset(OC::$router)) {
  299. OC::$router = new OC_Router();
  300. OC::$router->loadRoutes();
  301. }
  302. return OC::$router;
  303. }
  304. public static function init()
  305. {
  306. // register autoloader
  307. spl_autoload_register(array('OC', 'autoload'));
  308. setlocale(LC_ALL, 'en_US.UTF-8');
  309. // set some stuff
  310. //ob_start();
  311. error_reporting(E_ALL | E_STRICT);
  312. if (defined('DEBUG') && DEBUG) {
  313. ini_set('display_errors', 1);
  314. }
  315. self::$CLI = (php_sapi_name() == 'cli');
  316. date_default_timezone_set('UTC');
  317. ini_set('arg_separator.output', '&amp;');
  318. // try to switch magic quotes off.
  319. if (get_magic_quotes_gpc()) {
  320. @set_magic_quotes_runtime(false);
  321. }
  322. //try to configure php to enable big file uploads.
  323. //this doesn´t work always depending on the webserver and php configuration.
  324. //Let´s try to overwrite some defaults anyways
  325. //try to set the maximum execution time to 60min
  326. @set_time_limit(3600);
  327. @ini_set('max_execution_time', 3600);
  328. @ini_set('max_input_time', 3600);
  329. //try to set the maximum filesize to 10G
  330. @ini_set('upload_max_filesize', '10G');
  331. @ini_set('post_max_size', '10G');
  332. @ini_set('file_uploads', '50');
  333. //try to set the session lifetime to 60min
  334. @ini_set('gc_maxlifetime', '3600');
  335. //copy http auth headers for apache+php-fcgid work around
  336. if (isset($_SERVER['HTTP_XAUTHORIZATION']) && !isset($_SERVER['HTTP_AUTHORIZATION'])) {
  337. $_SERVER['HTTP_AUTHORIZATION'] = $_SERVER['HTTP_XAUTHORIZATION'];
  338. }
  339. //set http auth headers for apache+php-cgi work around
  340. if (isset($_SERVER['HTTP_AUTHORIZATION']) && preg_match('/Basic\s+(.*)$/i', $_SERVER['HTTP_AUTHORIZATION'], $matches)) {
  341. list($name, $password) = explode(':', base64_decode($matches[1]), 2);
  342. $_SERVER['PHP_AUTH_USER'] = strip_tags($name);
  343. $_SERVER['PHP_AUTH_PW'] = strip_tags($password);
  344. }
  345. //set http auth headers for apache+php-cgi work around if variable gets renamed by apache
  346. if (isset($_SERVER['REDIRECT_HTTP_AUTHORIZATION']) && preg_match('/Basic\s+(.*)$/i', $_SERVER['REDIRECT_HTTP_AUTHORIZATION'], $matches)) {
  347. list($name, $password) = explode(':', base64_decode($matches[1]), 2);
  348. $_SERVER['PHP_AUTH_USER'] = strip_tags($name);
  349. $_SERVER['PHP_AUTH_PW'] = strip_tags($password);
  350. }
  351. self::initPaths();
  352. register_shutdown_function(array('OC_Log', 'onShutdown'));
  353. set_error_handler(array('OC_Log', 'onError'));
  354. set_exception_handler(array('OC_Log', 'onException'));
  355. // set debug mode if an xdebug session is active
  356. if (!defined('DEBUG') || !DEBUG) {
  357. if (isset($_COOKIE['XDEBUG_SESSION'])) {
  358. define('DEBUG', true);
  359. }
  360. }
  361. // register the stream wrappers
  362. require_once 'streamwrappers.php';
  363. stream_wrapper_register("fakedir", "OC_FakeDirStream");
  364. stream_wrapper_register('static', 'OC_StaticStreamWrapper');
  365. stream_wrapper_register('close', 'OC_CloseStreamWrapper');
  366. self::checkInstalled();
  367. self::checkSSL();
  368. self::initSession();
  369. self::initTemplateEngine();
  370. self::checkUpgrade();
  371. $errors = OC_Util::checkServer();
  372. if (count($errors) > 0) {
  373. OC_Template::printGuestPage('', 'error', array('errors' => $errors));
  374. exit;
  375. }
  376. // User and Groups
  377. if (!OC_Config::getValue("installed", false)) {
  378. $_SESSION['user_id'] = '';
  379. }
  380. OC_User::useBackend(new OC_User_Database());
  381. OC_Group::useBackend(new OC_Group_Database());
  382. if (isset($_SERVER['PHP_AUTH_USER']) && isset($_SESSION['user_id']) && $_SERVER['PHP_AUTH_USER'] != $_SESSION['user_id']) {
  383. OC_User::logout();
  384. }
  385. // Load Apps
  386. // This includes plugins for users and filesystems as well
  387. global $RUNTIME_NOAPPS;
  388. global $RUNTIME_APPTYPES;
  389. if (!$RUNTIME_NOAPPS) {
  390. if ($RUNTIME_APPTYPES) {
  391. OC_App::loadApps($RUNTIME_APPTYPES);
  392. } else {
  393. OC_App::loadApps();
  394. }
  395. }
  396. //setup extra user backends
  397. OC_User::setupBackends();
  398. self::registerCacheHooks();
  399. self::registerFilesystemHooks();
  400. self::registerShareHooks();
  401. //make sure temporary files are cleaned up
  402. register_shutdown_function(array('OC_Helper', 'cleanTmp'));
  403. //parse the given parameters
  404. self::$REQUESTEDAPP = (isset($_GET['app']) && trim($_GET['app']) != '' && !is_null($_GET['app']) ? str_replace(array('\0', '/', '\\', '..'), '', strip_tags($_GET['app'])) : OC_Config::getValue('defaultapp', 'files'));
  405. if (substr_count(self::$REQUESTEDAPP, '?') != 0) {
  406. $app = substr(self::$REQUESTEDAPP, 0, strpos(self::$REQUESTEDAPP, '?'));
  407. $param = substr($_GET['app'], strpos($_GET['app'], '?') + 1);
  408. parse_str($param, $get);
  409. $_GET = array_merge($_GET, $get);
  410. self::$REQUESTEDAPP = $app;
  411. $_GET['app'] = $app;
  412. }
  413. self::$REQUESTEDFILE = (isset($_GET['getfile']) ? $_GET['getfile'] : null);
  414. if (substr_count(self::$REQUESTEDFILE, '?') != 0) {
  415. $file = substr(self::$REQUESTEDFILE, 0, strpos(self::$REQUESTEDFILE, '?'));
  416. $param = substr(self::$REQUESTEDFILE, strpos(self::$REQUESTEDFILE, '?') + 1);
  417. parse_str($param, $get);
  418. $_GET = array_merge($_GET, $get);
  419. self::$REQUESTEDFILE = $file;
  420. $_GET['getfile'] = $file;
  421. }
  422. if (!is_null(self::$REQUESTEDFILE)) {
  423. $subdir = OC_App::getAppPath(OC::$REQUESTEDAPP) . '/' . self::$REQUESTEDFILE;
  424. $parent = OC_App::getAppPath(OC::$REQUESTEDAPP);
  425. if (!OC_Helper::issubdirectory($subdir, $parent)) {
  426. self::$REQUESTEDFILE = null;
  427. header('HTTP/1.0 404 Not Found');
  428. exit;
  429. }
  430. }
  431. // write error into log if locale can't be set
  432. if (OC_Util::issetlocaleworking() == false) {
  433. OC_Log::write('core', 'setting locate to en_US.UTF-8 failed. Support is probably not installed on your system', OC_Log::ERROR);
  434. }
  435. }
  436. /**
  437. * register hooks for the cache
  438. */
  439. public static function registerCacheHooks()
  440. {
  441. // register cache cleanup jobs
  442. OC_BackgroundJob_RegularTask::register('OC_Cache_FileGlobal', 'gc');
  443. OC_Hook::connect('OC_User', 'post_login', 'OC_Cache_File', 'loginListener');
  444. }
  445. /**
  446. * register hooks for the filesystem
  447. */
  448. public static function registerFilesystemHooks()
  449. {
  450. // Check for blacklisted files
  451. OC_Hook::connect('OC_Filesystem', 'write', 'OC_Filesystem', 'isBlacklisted');
  452. OC_Hook::connect('OC_Filesystem', 'rename', 'OC_Filesystem', 'isBlacklisted');
  453. }
  454. /**
  455. * register hooks for sharing
  456. */
  457. public static function registerShareHooks()
  458. {
  459. OC_Hook::connect('OC_User', 'post_deleteUser', 'OCP\Share', 'post_deleteUser');
  460. OC_Hook::connect('OC_User', 'post_addToGroup', 'OCP\Share', 'post_addToGroup');
  461. OC_Hook::connect('OC_User', 'post_removeFromGroup', 'OCP\Share', 'post_removeFromGroup');
  462. OC_Hook::connect('OC_User', 'post_deleteGroup', 'OCP\Share', 'post_deleteGroup');
  463. }
  464. /**
  465. * @brief Handle the request
  466. */
  467. public static function handleRequest()
  468. {
  469. if (!OC_Config::getValue('installed', false)) {
  470. require_once 'core/setup.php';
  471. exit();
  472. }
  473. // Handle redirect URL for logged in users
  474. if (isset($_REQUEST['redirect_url']) && OC_User::isLoggedIn()) {
  475. $location = OC_Helper::makeURLAbsolute(urldecode($_REQUEST['redirect_url']));
  476. header('Location: ' . $location);
  477. return;
  478. }
  479. // Handle WebDAV
  480. if ($_SERVER['REQUEST_METHOD'] == 'PROPFIND') {
  481. header('location: ' . OC_Helper::linkToRemote('webdav'));
  482. return;
  483. }
  484. try {
  485. OC::getRouter()->match(OC_Request::getPathInfo());
  486. return;
  487. } catch (Symfony\Component\Routing\Exception\ResourceNotFoundException $e) {
  488. //header('HTTP/1.0 404 Not Found');
  489. } catch (Symfony\Component\Routing\Exception\MethodNotAllowedException $e) {
  490. OC_Response::setStatus(405);
  491. return;
  492. }
  493. $app = OC::$REQUESTEDAPP;
  494. $file = OC::$REQUESTEDFILE;
  495. $param = array('app' => $app, 'file' => $file);
  496. // Handle app css files
  497. if (substr($file, -3) == 'css') {
  498. self::loadCSSFile($param);
  499. return;
  500. }
  501. // Someone is logged in :
  502. if (OC_User::isLoggedIn()) {
  503. OC_App::loadApps();
  504. OC_User::setupBackends();
  505. if (isset($_GET["logout"]) and ($_GET["logout"])) {
  506. OC_Preferences::deleteKey(OC_User::getUser(), 'login_token', $_COOKIE['oc_token']);
  507. OC_User::logout();
  508. header("Location: " . OC::$WEBROOT . '/');
  509. } else {
  510. if (is_null($file)) {
  511. $param['file'] = 'index.php';
  512. }
  513. $file_ext = substr($param['file'], -3);
  514. if ($file_ext != 'php'
  515. || !self::loadAppScriptFile($param)
  516. ) {
  517. header('HTTP/1.0 404 Not Found');
  518. }
  519. }
  520. return;
  521. }
  522. // Not handled and not logged in
  523. self::handleLogin();
  524. }
  525. public static function loadAppScriptFile($param)
  526. {
  527. OC_App::loadApps();
  528. $app = $param['app'];
  529. $file = $param['file'];
  530. $app_path = OC_App::getAppPath($app);
  531. $file = $app_path . '/' . $file;
  532. unset($app, $app_path);
  533. if (file_exists($file)) {
  534. require_once $file;
  535. return true;
  536. }
  537. return false;
  538. }
  539. public static function loadCSSFile($param)
  540. {
  541. $app = $param['app'];
  542. $file = $param['file'];
  543. $app_path = OC_App::getAppPath($app);
  544. if (file_exists($app_path . '/' . $file)) {
  545. $app_web_path = OC_App::getAppWebPath($app);
  546. $filepath = $app_web_path . '/' . $file;
  547. $minimizer = new OC_Minimizer_CSS();
  548. $info = array($app_path, $app_web_path, $file);
  549. $minimizer->output(array($info), $filepath);
  550. }
  551. }
  552. protected static function handleLogin()
  553. {
  554. OC_App::loadApps(array('prelogin'));
  555. $error = array();
  556. // remember was checked after last login
  557. if (OC::tryRememberLogin()) {
  558. $error[] = 'invalidcookie';
  559. // Someone wants to log in :
  560. } elseif (OC::tryFormLogin()) {
  561. $error[] = 'invalidpassword';
  562. // The user is already authenticated using Apaches AuthType Basic... very usable in combination with LDAP
  563. } elseif (OC::tryBasicAuthLogin()) {
  564. $error[] = 'invalidpassword';
  565. }
  566. OC_Util::displayLoginPage(array_unique($error));
  567. }
  568. protected static function cleanupLoginTokens($user)
  569. {
  570. $cutoff = time() - OC_Config::getValue('remember_login_cookie_lifetime', 60 * 60 * 24 * 15);
  571. $tokens = OC_Preferences::getKeys($user, 'login_token');
  572. foreach ($tokens as $token) {
  573. $time = OC_Preferences::getValue($user, 'login_token', $token);
  574. if ($time < $cutoff) {
  575. OC_Preferences::deleteKey($user, 'login_token', $token);
  576. }
  577. }
  578. }
  579. protected static function tryRememberLogin()
  580. {
  581. if (!isset($_COOKIE["oc_remember_login"])
  582. || !isset($_COOKIE["oc_token"])
  583. || !isset($_COOKIE["oc_username"])
  584. || !$_COOKIE["oc_remember_login"]
  585. ) {
  586. return false;
  587. }
  588. OC_App::loadApps(array('authentication'));
  589. if (defined("DEBUG") && DEBUG) {
  590. OC_Log::write('core', 'Trying to login from cookie', OC_Log::DEBUG);
  591. }
  592. // confirm credentials in cookie
  593. if (isset($_COOKIE['oc_token']) && OC_User::userExists($_COOKIE['oc_username'])) {
  594. // delete outdated cookies
  595. self::cleanupLoginTokens($_COOKIE['oc_username']);
  596. // get stored tokens
  597. $tokens = OC_Preferences::getKeys($_COOKIE['oc_username'], 'login_token');
  598. // test cookies token against stored tokens
  599. if (in_array($_COOKIE['oc_token'], $tokens, true)) {
  600. // replace successfully used token with a new one
  601. OC_Preferences::deleteKey($_COOKIE['oc_username'], 'login_token', $_COOKIE['oc_token']);
  602. $token = OC_Util::generate_random_bytes(32);
  603. OC_Preferences::setValue($_COOKIE['oc_username'], 'login_token', $token, time());
  604. OC_User::setMagicInCookie($_COOKIE['oc_username'], $token);
  605. // login
  606. OC_User::setUserId($_COOKIE['oc_username']);
  607. OC_Util::redirectToDefaultPage();
  608. // doesn't return
  609. }
  610. // if you reach this point you have changed your password
  611. // or you are an attacker
  612. // we can not delete tokens here because users may reach
  613. // this point multiple times after a password change
  614. OC_Log::write('core', 'Authentication cookie rejected for user ' . $_COOKIE['oc_username'], OC_Log::WARN);
  615. }
  616. OC_User::unsetMagicInCookie();
  617. return true;
  618. }
  619. protected static function tryFormLogin()
  620. {
  621. if (!isset($_POST["user"]) || !isset($_POST['password'])) {
  622. return false;
  623. }
  624. OC_App::loadApps();
  625. //setup extra user backends
  626. OC_User::setupBackends();
  627. if (OC_User::login($_POST["user"], $_POST["password"])) {
  628. // setting up the time zone
  629. if (isset($_POST['timezone-offset'])) {
  630. $_SESSION['timezone'] = $_POST['timezone-offset'];
  631. }
  632. self::cleanupLoginTokens($_POST['user']);
  633. if (!empty($_POST["remember_login"])) {
  634. if (defined("DEBUG") && DEBUG) {
  635. OC_Log::write('core', 'Setting remember login to cookie', OC_Log::DEBUG);
  636. }
  637. $token = OC_Util::generate_random_bytes(32);
  638. OC_Preferences::setValue($_POST['user'], 'login_token', $token, time());
  639. OC_User::setMagicInCookie($_POST["user"], $token);
  640. } else {
  641. OC_User::unsetMagicInCookie();
  642. }
  643. OC_Util::redirectToDefaultPage();
  644. exit();
  645. }
  646. return true;
  647. }
  648. protected static function tryBasicAuthLogin()
  649. {
  650. if (!isset($_SERVER["PHP_AUTH_USER"])
  651. || !isset($_SERVER["PHP_AUTH_PW"])
  652. ) {
  653. return false;
  654. }
  655. OC_App::loadApps(array('authentication'));
  656. if (OC_User::login($_SERVER["PHP_AUTH_USER"], $_SERVER["PHP_AUTH_PW"])) {
  657. //OC_Log::write('core',"Logged in with HTTP Authentication", OC_Log::DEBUG);
  658. OC_User::unsetMagicInCookie();
  659. $_REQUEST['redirect_url'] = (isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '');
  660. OC_Util::redirectToDefaultPage();
  661. }
  662. return true;
  663. }
  664. }
  665. // define runtime variables - unless this already has been done
  666. if (!isset($RUNTIME_NOAPPS)) {
  667. $RUNTIME_NOAPPS = false;
  668. }
  669. if (!function_exists('get_temp_dir')) {
  670. function get_temp_dir()
  671. {
  672. if ($temp = ini_get('upload_tmp_dir')) return $temp;
  673. if ($temp = getenv('TMP')) return $temp;
  674. if ($temp = getenv('TEMP')) return $temp;
  675. if ($temp = getenv('TMPDIR')) return $temp;
  676. $temp = tempnam(__FILE__, '');
  677. if (file_exists($temp)) {
  678. unlink($temp);
  679. return dirname($temp);
  680. }
  681. if ($temp = sys_get_temp_dir()) return $temp;
  682. return null;
  683. }
  684. }
  685. OC::init();