You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

util.php 24KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798
  1. <?php
  2. /**
  3. * Class for utility functions
  4. *
  5. */
  6. class OC_Util {
  7. public static $scripts=array();
  8. public static $styles=array();
  9. public static $headers=array();
  10. private static $rootMounted=false;
  11. private static $fsSetup=false;
  12. public static $core_styles=array();
  13. public static $core_scripts=array();
  14. // Can be set up
  15. public static function setupFS( $user = '' ) {// configure the initial filesystem based on the configuration
  16. if(self::$fsSetup) {//setting up the filesystem twice can only lead to trouble
  17. return false;
  18. }
  19. // If we are not forced to load a specific user we load the one that is logged in
  20. if( $user == "" && OC_User::isLoggedIn()) {
  21. $user = OC_User::getUser();
  22. }
  23. // load all filesystem apps before, so no setup-hook gets lost
  24. if(!isset($RUNTIME_NOAPPS) || !$RUNTIME_NOAPPS) {
  25. OC_App::loadApps(array('filesystem'));
  26. }
  27. // the filesystem will finish when $user is not empty,
  28. // mark fs setup here to avoid doing the setup from loading
  29. // OC_Filesystem
  30. if ($user != '') {
  31. self::$fsSetup=true;
  32. }
  33. $CONFIG_DATADIRECTORY = OC_Config::getValue( "datadirectory", OC::$SERVERROOT."/data" );
  34. //first set up the local "root" storage
  35. if(!self::$rootMounted) {
  36. \OC\Files\Filesystem::mount('\OC\Files\Storage\Local', array('datadir'=>$CONFIG_DATADIRECTORY), '/');
  37. self::$rootMounted=true;
  38. }
  39. if( $user != "" ) { //if we aren't logged in, there is no use to set up the filesystem
  40. $user_dir = '/'.$user.'/files';
  41. $user_root = OC_User::getHome($user);
  42. $userdirectory = $user_root . '/files';
  43. if( !is_dir( $userdirectory )) {
  44. mkdir( $userdirectory, 0755, true );
  45. }
  46. //jail the user into his "home" directory
  47. \OC\Files\Filesystem::init($user, $user_dir);
  48. $quotaProxy=new OC_FileProxy_Quota();
  49. $fileOperationProxy = new OC_FileProxy_FileOperations();
  50. OC_FileProxy::register($quotaProxy);
  51. OC_FileProxy::register($fileOperationProxy);
  52. OC_Hook::emit('OC_Filesystem', 'setup', array('user' => $user, 'user_dir' => $user_dir));
  53. }
  54. return true;
  55. }
  56. public static function tearDownFS() {
  57. \OC\Files\Filesystem::tearDown();
  58. self::$fsSetup=false;
  59. }
  60. /**
  61. * get the current installed version of ownCloud
  62. * @return array
  63. */
  64. public static function getVersion() {
  65. // hint: We only can count up. Reset minor/patchlevel when
  66. // updating major/minor version number.
  67. return array(5, 80, 02);
  68. }
  69. /**
  70. * get the current installed version string of ownCloud
  71. * @return string
  72. */
  73. public static function getVersionString() {
  74. return '6.0 pre alpha';
  75. }
  76. /**
  77. * get the current installed edition of ownCloud. There is the community
  78. * edition that just returns an empty string and the enterprise edition
  79. * that returns "Enterprise".
  80. * @return string
  81. */
  82. public static function getEditionString() {
  83. return '';
  84. }
  85. /**
  86. * add a javascript file
  87. *
  88. * @param appid $application
  89. * @param filename $file
  90. */
  91. public static function addScript( $application, $file = null ) {
  92. if( is_null( $file )) {
  93. $file = $application;
  94. $application = "";
  95. }
  96. if( !empty( $application )) {
  97. self::$scripts[] = "$application/js/$file";
  98. }else{
  99. self::$scripts[] = "js/$file";
  100. }
  101. }
  102. /**
  103. * add a css file
  104. *
  105. * @param appid $application
  106. * @param filename $file
  107. */
  108. public static function addStyle( $application, $file = null ) {
  109. if( is_null( $file )) {
  110. $file = $application;
  111. $application = "";
  112. }
  113. if( !empty( $application )) {
  114. self::$styles[] = "$application/css/$file";
  115. }else{
  116. self::$styles[] = "css/$file";
  117. }
  118. }
  119. /**
  120. * @brief Add a custom element to the header
  121. * @param string tag tag name of the element
  122. * @param array $attributes array of attributes for the element
  123. * @param string $text the text content for the element
  124. */
  125. public static function addHeader( $tag, $attributes, $text='') {
  126. self::$headers[] = array('tag'=>$tag, 'attributes'=>$attributes, 'text'=>$text);
  127. }
  128. /**
  129. * formats a timestamp in the "right" way
  130. *
  131. * @param int timestamp $timestamp
  132. * @param bool dateOnly option to omit time from the result
  133. */
  134. public static function formatDate( $timestamp, $dateOnly=false) {
  135. if(isset($_SESSION['timezone'])) {//adjust to clients timezone if we know it
  136. $systemTimeZone = intval(date('O'));
  137. $systemTimeZone=(round($systemTimeZone/100, 0)*60)+($systemTimeZone%100);
  138. $clientTimeZone=$_SESSION['timezone']*60;
  139. $offset=$clientTimeZone-$systemTimeZone;
  140. $timestamp=$timestamp+$offset*60;
  141. }
  142. $l=OC_L10N::get('lib');
  143. return $l->l($dateOnly ? 'date' : 'datetime', $timestamp);
  144. }
  145. /**
  146. * check if the current server configuration is suitable for ownCloud
  147. * @return array arrays with error messages and hints
  148. */
  149. public static function checkServer() {
  150. $errors=array();
  151. $web_server_restart= false;
  152. //check for database drivers
  153. if(!(is_callable('sqlite_open') or class_exists('SQLite3'))
  154. and !is_callable('mysql_connect')
  155. and !is_callable('pg_connect')) {
  156. $errors[]=array('error'=>'No database drivers (sqlite, mysql, or postgresql) installed.',
  157. 'hint'=>'');//TODO: sane hint
  158. $web_server_restart= true;
  159. }
  160. //common hint for all file permissons error messages
  161. $permissionsHint='Permissions can usually be fixed by giving the webserver write access'
  162. .' to the ownCloud directory';
  163. // Check if config folder is writable.
  164. if(!is_writable(OC::$SERVERROOT."/config/") or !is_readable(OC::$SERVERROOT."/config/")) {
  165. $errors[]=array('error'=>"Can't write into config directory 'config'",
  166. 'hint'=>'You can usually fix this by giving the webserver user write access'
  167. .' to the config directory in owncloud');
  168. }
  169. // Check if there is a writable install folder.
  170. if(OC_Config::getValue('appstoreenabled', true)) {
  171. if( OC_App::getInstallPath() === null
  172. || !is_writable(OC_App::getInstallPath())
  173. || !is_readable(OC_App::getInstallPath()) ) {
  174. $errors[]=array('error'=>"Can't write into apps directory",
  175. 'hint'=>'You can usually fix this by giving the webserver user write access'
  176. .' to the apps directory in owncloud or disabling the appstore in the config file.');
  177. }
  178. }
  179. $CONFIG_DATADIRECTORY = OC_Config::getValue( "datadirectory", OC::$SERVERROOT."/data" );
  180. // Create root dir.
  181. if(!is_dir($CONFIG_DATADIRECTORY)) {
  182. $success=@mkdir($CONFIG_DATADIRECTORY);
  183. if ($success) {
  184. $errors = array_merge($errors, self::checkDataDirectoryPermissions($CONFIG_DATADIRECTORY));
  185. } else {
  186. $errors[]=array('error'=>"Can't create data directory (".$CONFIG_DATADIRECTORY.")",
  187. 'hint'=>"You can usually fix this by giving the webserver write access to the ownCloud directory '"
  188. .OC::$SERVERROOT."' (in a terminal, use the command "
  189. ."'chown -R www-data:www-data /path/to/your/owncloud/install/data' ");
  190. }
  191. } else if(!is_writable($CONFIG_DATADIRECTORY) or !is_readable($CONFIG_DATADIRECTORY)) {
  192. $errors[]=array('error'=>'Data directory ('.$CONFIG_DATADIRECTORY.') not writable by ownCloud',
  193. 'hint'=>$permissionsHint);
  194. } else {
  195. $errors = array_merge($errors, self::checkDataDirectoryPermissions($CONFIG_DATADIRECTORY));
  196. }
  197. // check if all required php modules are present
  198. if(!class_exists('ZipArchive')) {
  199. $errors[]=array('error'=>'PHP module zip not installed.',
  200. 'hint'=>'Please ask your server administrator to install the module.');
  201. $web_server_restart= false;
  202. }
  203. if(!class_exists('DOMDocument')) {
  204. $errors[] = array('error' => 'PHP module dom not installed.',
  205. 'hint' => 'Please ask your server administrator to install the module.');
  206. $web_server_restart = false;
  207. }
  208. if(!function_exists('xml_parser_create')) {
  209. $errors[] = array('error' => 'PHP module libxml not installed.',
  210. 'hint' => 'Please ask your server administrator to install the module.');
  211. $web_server_restart = false;
  212. }
  213. if(!function_exists('mb_detect_encoding')) {
  214. $errors[]=array('error'=>'PHP module mb multibyte not installed.',
  215. 'hint'=>'Please ask your server administrator to install the module.');
  216. $web_server_restart= false;
  217. }
  218. if(!function_exists('ctype_digit')) {
  219. $errors[]=array('error'=>'PHP module ctype is not installed.',
  220. 'hint'=>'Please ask your server administrator to install the module.');
  221. $web_server_restart= false;
  222. }
  223. if(!function_exists('json_encode')) {
  224. $errors[]=array('error'=>'PHP module JSON is not installed.',
  225. 'hint'=>'Please ask your server administrator to install the module.');
  226. $web_server_restart= false;
  227. }
  228. if(!function_exists('imagepng')) {
  229. $errors[]=array('error'=>'PHP module GD is not installed.',
  230. 'hint'=>'Please ask your server administrator to install the module.');
  231. $web_server_restart= false;
  232. }
  233. if(!function_exists('gzencode')) {
  234. $errors[]=array('error'=>'PHP module zlib is not installed.',
  235. 'hint'=>'Please ask your server administrator to install the module.');
  236. $web_server_restart= false;
  237. }
  238. if(!function_exists('iconv')) {
  239. $errors[]=array('error'=>'PHP module iconv is not installed.',
  240. 'hint'=>'Please ask your server administrator to install the module.');
  241. $web_server_restart= false;
  242. }
  243. if(!function_exists('simplexml_load_string')) {
  244. $errors[]=array('error'=>'PHP module SimpleXML is not installed.',
  245. 'hint'=>'Please ask your server administrator to install the module.');
  246. $web_server_restart= false;
  247. }
  248. if(floatval(phpversion())<5.3) {
  249. $errors[]=array('error'=>'PHP 5.3 is required.',
  250. 'hint'=>'Please ask your server administrator to update PHP to version 5.3 or higher.'
  251. .' PHP 5.2 is no longer supported by ownCloud and the PHP community.');
  252. $web_server_restart= false;
  253. }
  254. if(!defined('PDO::ATTR_DRIVER_NAME')) {
  255. $errors[]=array('error'=>'PHP PDO module is not installed.',
  256. 'hint'=>'Please ask your server administrator to install the module.');
  257. $web_server_restart= false;
  258. }
  259. if (((strtolower(@ini_get('safe_mode')) == 'on')
  260. || (strtolower(@ini_get('safe_mode')) == 'yes')
  261. || (strtolower(@ini_get('safe_mode')) == 'true')
  262. || (ini_get("safe_mode") == 1 ))) {
  263. $errors[]=array('error'=>'PHP Safe Mode is enabled. ownCloud requires that it is disabled to work properly.',
  264. 'hint'=>'PHP Safe Mode is a deprecated and mostly useless setting that should be disabled. Please ask your server administrator to disable it in php.ini or in your webserver config.');
  265. $web_server_restart= false;
  266. }
  267. if($web_server_restart) {
  268. $errors[]=array('error'=>'PHP modules have been installed, but they are still listed as missing?',
  269. 'hint'=>'Please ask your server administrator to restart the web server.');
  270. }
  271. return $errors;
  272. }
  273. /**
  274. * Check for correct file permissions of data directory
  275. * @return array arrays with error messages and hints
  276. */
  277. public static function checkDataDirectoryPermissions($dataDirectory) {
  278. $errors = array();
  279. if (stristr(PHP_OS, 'WIN')) {
  280. //TODO: permissions checks for windows hosts
  281. } else {
  282. $permissionsModHint = 'Please change the permissions to 0770 so that the directory'
  283. .' cannot be listed by other users.';
  284. $prems = substr(decoct(@fileperms($dataDirectory)), -3);
  285. if (substr($prems, -1) != '0') {
  286. OC_Helper::chmodr($dataDirectory, 0770);
  287. clearstatcache();
  288. $prems = substr(decoct(@fileperms($dataDirectory)), -3);
  289. if (substr($prems, 2, 1) != '0') {
  290. $errors[] = array('error' => 'Data directory ('.$dataDirectory.') is readable for other users',
  291. 'hint' => $permissionsModHint);
  292. }
  293. }
  294. }
  295. return $errors;
  296. }
  297. public static function displayLoginPage($errors = array()) {
  298. $parameters = array();
  299. foreach( $errors as $key => $value ) {
  300. $parameters[$value] = true;
  301. }
  302. if (!empty($_POST['user'])) {
  303. $parameters["username"] = $_POST['user'];
  304. $parameters['user_autofocus'] = false;
  305. } else {
  306. $parameters["username"] = '';
  307. $parameters['user_autofocus'] = true;
  308. }
  309. if (isset($_REQUEST['redirect_url'])) {
  310. $redirect_url = $_REQUEST['redirect_url'];
  311. $parameters['redirect_url'] = urlencode($redirect_url);
  312. }
  313. $parameters['alt_login'] = OC_App::getAlternativeLogIns();
  314. OC_Template::printGuestPage("", "login", $parameters);
  315. }
  316. /**
  317. * Check if the app is enabled, redirects to home if not
  318. */
  319. public static function checkAppEnabled($app) {
  320. if( !OC_App::isEnabled($app)) {
  321. header( 'Location: '.OC_Helper::linkToAbsolute( '', 'index.php' ));
  322. exit();
  323. }
  324. }
  325. /**
  326. * Check if the user is logged in, redirects to home if not. With
  327. * redirect URL parameter to the request URI.
  328. */
  329. public static function checkLoggedIn() {
  330. // Check if we are a user
  331. if( !OC_User::isLoggedIn()) {
  332. header( 'Location: '.OC_Helper::linkToAbsolute( '', 'index.php',
  333. array('redirect_url' => OC_Request::requestUri())));
  334. exit();
  335. }
  336. }
  337. /**
  338. * Check if the user is a admin, redirects to home if not
  339. */
  340. public static function checkAdminUser() {
  341. if( !OC_User::isAdminUser(OC_User::getUser())) {
  342. header( 'Location: '.OC_Helper::linkToAbsolute( '', 'index.php' ));
  343. exit();
  344. }
  345. }
  346. /**
  347. * Check if the user is a subadmin, redirects to home if not
  348. * @return array $groups where the current user is subadmin
  349. */
  350. public static function checkSubAdminUser() {
  351. if(!OC_SubAdmin::isSubAdmin(OC_User::getUser())) {
  352. header( 'Location: '.OC_Helper::linkToAbsolute( '', 'index.php' ));
  353. exit();
  354. }
  355. return true;
  356. }
  357. /**
  358. * Redirect to the user default page
  359. */
  360. public static function redirectToDefaultPage() {
  361. if(isset($_REQUEST['redirect_url'])) {
  362. $location = OC_Helper::makeURLAbsolute(urldecode($_REQUEST['redirect_url']));
  363. }
  364. else if (isset(OC::$REQUESTEDAPP) && !empty(OC::$REQUESTEDAPP)) {
  365. $location = OC_Helper::linkToAbsolute( OC::$REQUESTEDAPP, 'index.php' );
  366. }
  367. else {
  368. $defaultpage = OC_Appconfig::getValue('core', 'defaultpage');
  369. if ($defaultpage) {
  370. $location = OC_Helper::makeURLAbsolute(OC::$WEBROOT.'/'.$defaultpage);
  371. }
  372. else {
  373. $location = OC_Helper::linkToAbsolute( 'files', 'index.php' );
  374. }
  375. }
  376. OC_Log::write('core', 'redirectToDefaultPage: '.$location, OC_Log::DEBUG);
  377. header( 'Location: '.$location );
  378. exit();
  379. }
  380. /**
  381. * get an id unique for this instance
  382. * @return string
  383. */
  384. public static function getInstanceId() {
  385. $id = OC_Config::getValue('instanceid', null);
  386. if(is_null($id)) {
  387. // We need to guarantee at least one letter in instanceid so it can be used as the session_name
  388. $id = 'oc' . OC_Util::generate_random_bytes(10);
  389. OC_Config::setValue('instanceid', $id);
  390. }
  391. return $id;
  392. }
  393. /**
  394. * @brief Static lifespan (in seconds) when a request token expires.
  395. * @see OC_Util::callRegister()
  396. * @see OC_Util::isCallRegistered()
  397. * @description
  398. * Also required for the client side to compute the piont in time when to
  399. * request a fresh token. The client will do so when nearly 97% of the
  400. * timespan coded here has expired.
  401. */
  402. public static $callLifespan = 3600; // 3600 secs = 1 hour
  403. /**
  404. * @brief Register an get/post call. Important to prevent CSRF attacks.
  405. * @todo Write howto: CSRF protection guide
  406. * @return $token Generated token.
  407. * @description
  408. * Creates a 'request token' (random) and stores it inside the session.
  409. * Ever subsequent (ajax) request must use such a valid token to succeed,
  410. * otherwise the request will be denied as a protection against CSRF.
  411. * The tokens expire after a fixed lifespan.
  412. * @see OC_Util::$callLifespan
  413. * @see OC_Util::isCallRegistered()
  414. */
  415. public static function callRegister() {
  416. // Check if a token exists
  417. if(!isset($_SESSION['requesttoken'])) {
  418. // No valid token found, generate a new one.
  419. $requestToken = self::generate_random_bytes(20);
  420. $_SESSION['requesttoken']=$requestToken;
  421. } else {
  422. // Valid token already exists, send it
  423. $requestToken = $_SESSION['requesttoken'];
  424. }
  425. return($requestToken);
  426. }
  427. /**
  428. * @brief Check an ajax get/post call if the request token is valid.
  429. * @return boolean False if request token is not set or is invalid.
  430. * @see OC_Util::$callLifespan
  431. * @see OC_Util::callRegister()
  432. */
  433. public static function isCallRegistered() {
  434. if(!isset($_SESSION['requesttoken'])) {
  435. return false;
  436. }
  437. if(isset($_GET['requesttoken'])) {
  438. $token=$_GET['requesttoken'];
  439. } elseif(isset($_POST['requesttoken'])) {
  440. $token=$_POST['requesttoken'];
  441. } elseif(isset($_SERVER['HTTP_REQUESTTOKEN'])) {
  442. $token=$_SERVER['HTTP_REQUESTTOKEN'];
  443. } else {
  444. //no token found.
  445. return false;
  446. }
  447. // Check if the token is valid
  448. if($token !== $_SESSION['requesttoken']) {
  449. // Not valid
  450. return false;
  451. } else {
  452. // Valid token
  453. return true;
  454. }
  455. }
  456. /**
  457. * @brief Check an ajax get/post call if the request token is valid. exit if not.
  458. * Todo: Write howto
  459. */
  460. public static function callCheck() {
  461. if(!OC_Util::isCallRegistered()) {
  462. exit;
  463. }
  464. }
  465. /**
  466. * @brief Public function to sanitize HTML
  467. *
  468. * This function is used to sanitize HTML and should be applied on any
  469. * string or array of strings before displaying it on a web page.
  470. *
  471. * @param string or array of strings
  472. * @return array with sanitized strings or a single sanitized string, depends on the input parameter.
  473. */
  474. public static function sanitizeHTML( &$value ) {
  475. if (is_array($value)) {
  476. array_walk_recursive($value, 'OC_Util::sanitizeHTML');
  477. } else {
  478. $value = htmlentities((string)$value, ENT_QUOTES, 'UTF-8'); //Specify encoding for PHP<5.4
  479. }
  480. return $value;
  481. }
  482. /**
  483. * Check if the htaccess file is working by creating a test file in the data directory and trying to access via http
  484. */
  485. public static function ishtaccessworking() {
  486. // testdata
  487. $filename='/htaccesstest.txt';
  488. $testcontent='testcontent';
  489. // creating a test file
  490. $testfile = OC_Config::getValue( "datadirectory", OC::$SERVERROOT."/data" ).'/'.$filename;
  491. if(file_exists($testfile)) {// already running this test, possible recursive call
  492. return false;
  493. }
  494. $fp = @fopen($testfile, 'w');
  495. @fwrite($fp, $testcontent);
  496. @fclose($fp);
  497. // accessing the file via http
  498. $url = OC_Helper::makeURLAbsolute(OC::$WEBROOT.'/data'.$filename);
  499. $fp = @fopen($url, 'r');
  500. $content=@fread($fp, 2048);
  501. @fclose($fp);
  502. // cleanup
  503. @unlink($testfile);
  504. // does it work ?
  505. if($content==$testcontent) {
  506. return(false);
  507. }else{
  508. return(true);
  509. }
  510. }
  511. /**
  512. * we test if webDAV is working properly
  513. *
  514. * The basic assumption is that if the server returns 401/Not Authenticated for an unauthenticated PROPFIND
  515. * the web server it self is setup properly.
  516. *
  517. * Why not an authenticated PROFIND and other verbs?
  518. * - We don't have the password available
  519. * - We have no idea about other auth methods implemented (e.g. OAuth with Bearer header)
  520. *
  521. */
  522. public static function isWebDAVWorking() {
  523. if (!function_exists('curl_init')) {
  524. return true;
  525. }
  526. $settings = array(
  527. 'baseUri' => OC_Helper::linkToRemote('webdav'),
  528. );
  529. // save the old timeout so that we can restore it later
  530. $old_timeout=ini_get("default_socket_timeout");
  531. // use a 5 sec timeout for the check. Should be enough for local requests.
  532. ini_set("default_socket_timeout", 5);
  533. $client = new \Sabre_DAV_Client($settings);
  534. // for this self test we don't care if the ssl certificate is self signed and the peer cannot be verified.
  535. $client->setVerifyPeer(false);
  536. $return = true;
  537. try {
  538. // test PROPFIND
  539. $client->propfind('', array('{DAV:}resourcetype'));
  540. } catch(\Sabre_DAV_Exception_NotAuthenticated $e) {
  541. $return = true;
  542. } catch(\Exception $e) {
  543. OC_Log::write('core', 'isWebDAVWorking: NO - Reason: '.$e->getMessage(). ' ('.get_class($e).')', OC_Log::WARN);
  544. $return = false;
  545. }
  546. // restore the original timeout
  547. ini_set("default_socket_timeout", $old_timeout);
  548. return $return;
  549. }
  550. /**
  551. * Check if the setlocal call doesn't work. This can happen if the right
  552. * local packages are not available on the server.
  553. */
  554. public static function issetlocaleworking() {
  555. // setlocale test is pointless on Windows
  556. if (OC_Util::runningOnWindows() ) {
  557. return true;
  558. }
  559. $result = setlocale(LC_ALL, 'en_US.UTF-8', 'en_US.UTF8');
  560. if($result == false) {
  561. return false;
  562. }
  563. return true;
  564. }
  565. /**
  566. * Check if the PHP module fileinfo is loaded.
  567. * @return bool
  568. */
  569. public static function fileInfoLoaded() {
  570. return function_exists('finfo_open');
  571. }
  572. /**
  573. * Check if the ownCloud server can connect to the internet
  574. */
  575. public static function isinternetconnectionworking() {
  576. // in case there is no internet connection on purpose there is no need to display a warning
  577. if (!\OC_Config::getValue("has_internet_connection", true)) {
  578. return true;
  579. }
  580. // try to connect to owncloud.org to see if http connections to the internet are possible.
  581. $connected = @fsockopen("www.owncloud.org", 80);
  582. if ($connected) {
  583. fclose($connected);
  584. return true;
  585. }else{
  586. // second try in case one server is down
  587. $connected = @fsockopen("apps.owncloud.com", 80);
  588. if ($connected) {
  589. fclose($connected);
  590. return true;
  591. }else{
  592. return false;
  593. }
  594. }
  595. }
  596. /**
  597. * clear all levels of output buffering
  598. */
  599. public static function obEnd(){
  600. while (ob_get_level()) {
  601. ob_end_clean();
  602. }
  603. }
  604. /**
  605. * @brief Generates a cryptographical secure pseudorandom string
  606. * @param Int with the length of the random string
  607. * @return String
  608. * Please also update secureRNG_available if you change something here
  609. */
  610. public static function generate_random_bytes($length = 30) {
  611. // Try to use openssl_random_pseudo_bytes
  612. if(function_exists('openssl_random_pseudo_bytes')) {
  613. $pseudo_byte = bin2hex(openssl_random_pseudo_bytes($length, $strong));
  614. if($strong == true) {
  615. return substr($pseudo_byte, 0, $length); // Truncate it to match the length
  616. }
  617. }
  618. // Try to use /dev/urandom
  619. $fp = @file_get_contents('/dev/urandom', false, null, 0, $length);
  620. if ($fp !== false) {
  621. $string = substr(bin2hex($fp), 0, $length);
  622. return $string;
  623. }
  624. // Fallback to mt_rand()
  625. $characters = '0123456789';
  626. $characters .= 'abcdefghijklmnopqrstuvwxyz';
  627. $charactersLength = strlen($characters)-1;
  628. $pseudo_byte = "";
  629. // Select some random characters
  630. for ($i = 0; $i < $length; $i++) {
  631. $pseudo_byte .= $characters[mt_rand(0, $charactersLength)];
  632. }
  633. return $pseudo_byte;
  634. }
  635. /**
  636. * @brief Checks if a secure random number generator is available
  637. * @return bool
  638. */
  639. public static function secureRNG_available() {
  640. // Check openssl_random_pseudo_bytes
  641. if(function_exists('openssl_random_pseudo_bytes')) {
  642. openssl_random_pseudo_bytes(1, $strong);
  643. if($strong == true) {
  644. return true;
  645. }
  646. }
  647. // Check /dev/urandom
  648. $fp = @file_get_contents('/dev/urandom', false, null, 0, 1);
  649. if ($fp !== false) {
  650. return true;
  651. }
  652. return false;
  653. }
  654. /**
  655. * @Brief Get file content via curl.
  656. * @param string $url Url to get content
  657. * @return string of the response or false on error
  658. * This function get the content of a page via curl, if curl is enabled.
  659. * If not, file_get_element is used.
  660. */
  661. public static function getUrlContent($url){
  662. if (function_exists('curl_init')) {
  663. $curl = curl_init();
  664. curl_setopt($curl, CURLOPT_HEADER, 0);
  665. curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
  666. curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 10);
  667. curl_setopt($curl, CURLOPT_URL, $url);
  668. curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
  669. curl_setopt($curl, CURLOPT_MAXREDIRS, 10);
  670. curl_setopt($curl, CURLOPT_USERAGENT, "ownCloud Server Crawler");
  671. if(OC_Config::getValue('proxy', '')<>'') {
  672. curl_setopt($curl, CURLOPT_PROXY, OC_Config::getValue('proxy'));
  673. }
  674. if(OC_Config::getValue('proxyuserpwd', '')<>'') {
  675. curl_setopt($curl, CURLOPT_PROXYUSERPWD, OC_Config::getValue('proxyuserpwd'));
  676. }
  677. $data = curl_exec($curl);
  678. curl_close($curl);
  679. } else {
  680. $contextArray = null;
  681. if(OC_Config::getValue('proxy', '')<>'') {
  682. $contextArray = array(
  683. 'http' => array(
  684. 'timeout' => 10,
  685. 'proxy' => OC_Config::getValue('proxy')
  686. )
  687. );
  688. } else {
  689. $contextArray = array(
  690. 'http' => array(
  691. 'timeout' => 10
  692. )
  693. );
  694. }
  695. $ctx = stream_context_create(
  696. $contextArray
  697. );
  698. $data=@file_get_contents($url, 0, $ctx);
  699. }
  700. return $data;
  701. }
  702. /**
  703. * @return bool - well are we running on windows or not
  704. */
  705. public static function runningOnWindows() {
  706. return (substr(PHP_OS, 0, 3) === "WIN");
  707. }
  708. }