PageRenderTime 26ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/utils.php

https://github.com/andreassolberg/DiscoJuice
PHP | 343 lines | 197 code | 55 blank | 91 comment | 39 complexity | 54feb1d52d318d38f3c03078e1fd9e02 MD5 | raw file
  1. <?php
  2. class Utils {
  3. public static function getSubID($hostname = null) {
  4. if(php_sapi_name() == 'cli' || empty($_SERVER['REMOTE_ADDR'])) {
  5. return '_CLI';
  6. }
  7. if ($hostname === null) {
  8. $hostname = $_SERVER['HTTP_HOST'];
  9. }
  10. $subhost = null;
  11. $mainhost = GlobalConfig::hostname();
  12. if (preg_match('/^([a-zA-Z0-9]+).' . $mainhost . '$/', $hostname, $matches)) {
  13. $subhost = $matches[1];
  14. } else {
  15. return false;
  16. }
  17. self::validateID($subhost);
  18. return $subhost;
  19. }
  20. public static function getHost() {
  21. return $_SERVER['HTTP_HOST'];
  22. }
  23. public static function route($method = false, $match, $parameters, $object = null) {
  24. if (empty($_SERVER['PATH_INFO']) || strlen($_SERVER['PATH_INFO']) < 2) return false;
  25. $inputraw = file_get_contents("php://input");
  26. if ($inputraw) {
  27. $object = json_decode($inputraw, true);
  28. }
  29. $path = $_SERVER['PATH_INFO'];
  30. $realmethod = strtolower($_SERVER['REQUEST_METHOD']);
  31. if ($method !== false) {
  32. if (strtolower($method) !== $realmethod) return false;
  33. }
  34. if (!preg_match('|^' . $match . '|', $path, &$parameters)) return false;
  35. return true;
  36. }
  37. public static function genID() {
  38. // http://www.php.net/manual/en/function.uniqid.php#94959
  39. return sprintf( '%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
  40. // 32 bits for "time_low"
  41. mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ),
  42. // 16 bits for "time_mid"
  43. mt_rand( 0, 0xffff ),
  44. // 16 bits for "time_hi_and_version",
  45. // four most significant bits holds version number 4
  46. mt_rand( 0, 0x0fff ) | 0x4000,
  47. // 16 bits, 8 bits for "clk_seq_hi_res",
  48. // 8 bits for "clk_seq_low",
  49. // two most significant bits holds zero and one for variant DCE1.1
  50. mt_rand( 0, 0x3fff ) | 0x8000,
  51. // 48 bits for "node"
  52. mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff )
  53. );
  54. }
  55. public static function validateGroupID($id) {
  56. if (preg_match('/^([a-zA-Z0-9\-]+)$/', $id, $matches)) {
  57. return true;
  58. }
  59. throw new Exception('Invalid characters in provided identifier');
  60. }
  61. public static function validateID($id) {
  62. if (preg_match('/^([a-zA-Z0-9\-]+)$/', $id, $matches)) {
  63. return true;
  64. }
  65. throw new Exception('Invalid characters in provided app ID');
  66. }
  67. public static function human_filesize($bytes, $decimals = 2) {
  68. $sz = 'BKMGTP';
  69. $factor = floor((strlen($bytes) - 1) / 3);
  70. return sprintf("%.{$decimals}f", $bytes / pow(1024, $factor)) . @$sz[$factor];
  71. }
  72. /*
  73. * TODO: Moved to Utils from Config, Start using it.
  74. */
  75. public static function generateCleanUsername($userid) {
  76. $username = preg_replace('/[^a-zA-Z0-9]+/', '_', $userid);
  77. return $username;
  78. }
  79. /**
  80. *
  81. * TODO: Moved to Utils. From Config. STart using it.
  82. *
  83. * Generate random password.
  84. * Borrowed from here: http://www.codemiles.com/php-tutorials/generate-password-using-php-t3120.html
  85. * @var integer
  86. */
  87. public static function generateRandpassword($size=12, $power=7) {
  88. $vowels = 'aeuy';
  89. $randconstant = 'bdghjmnpqrstvz';
  90. if ($power & 1) {
  91. $randconstant .= 'BDGHJLMNPQRSTVWXZ';
  92. }
  93. if ($power & 2) {
  94. $vowels .= "AEUY";
  95. }
  96. if ($power & 4) {
  97. $randconstant .= '23456789';
  98. }
  99. if ($power & 8) {
  100. $randconstant .= '@#$%';
  101. }
  102. $Randpassword = '';
  103. $alt = time() % 2;
  104. for ($i = 0; $i < $size; $i++) {
  105. if ($alt == 1) {
  106. $Randpassword .= $randconstant[(rand() % strlen($randconstant))];
  107. $alt = 0;
  108. } else {
  109. $Randpassword .= $vowels[(rand() % strlen($vowels))];
  110. $alt = 1;
  111. }
  112. }
  113. return $Randpassword;
  114. }
  115. // TODO: Moved from Config. Start using it...
  116. public static function getPath($path) {
  117. $base = dirname(dirname(__FILE__));
  118. return $base . '/' . $path;
  119. }
  120. /* This function redirects the user to the specified address.
  121. * An optional set of query parameters can be appended by passing
  122. * them in an array.
  123. *
  124. * This function will use the HTTP 303 See Other redirect if the
  125. * current request is a POST request and the HTTP version is HTTP/1.1.
  126. * Otherwise a HTTP 302 Found redirect will be used.
  127. *
  128. * The fuction will also generate a simple web page with a clickable
  129. * link to the target page.
  130. *
  131. * Parameters:
  132. * $url URL we should redirect to. This URL may include
  133. * query parameters. If this URL is a relative URL
  134. * (starting with '/'), then it will be turned into an
  135. * absolute URL by prefixing it with the absolute URL
  136. * to the root of the website.
  137. * $parameters Array with extra query string parameters which should
  138. * be appended to the URL. The name of the parameter is
  139. * the array index. The value of the parameter is the
  140. * value stored in the index. Both the name and the value
  141. * will be urlencoded. If the value is NULL, then the
  142. * parameter will be encoded as just the name, without a
  143. * value.
  144. *
  145. * Returns:
  146. * This function never returns.
  147. */
  148. public static function redirect($url, $parameters = array()) {
  149. assert(is_string($url));
  150. assert(strlen($url) > 0);
  151. assert(is_array($parameters));
  152. /* Check for relative URL. */
  153. if(substr($url, 0, 1) === '/') {
  154. /* Prefix the URL with the url to the root of the
  155. * website.
  156. */
  157. $url = self::selfURLhost() . $url;
  158. }
  159. /* Verify that the URL is to a http or https site. */
  160. if (!preg_match('@^https?://@i', $url)) {
  161. throw new SimpleSAML_Error_Exception('Redirect to invalid URL: ' . $url);
  162. }
  163. /* Determine which prefix we should put before the first
  164. * parameter.
  165. */
  166. if(strpos($url, '?') === FALSE) {
  167. $paramPrefix = '?';
  168. } else {
  169. $paramPrefix = '&';
  170. }
  171. /* Iterate over the parameters and append them to the query
  172. * string.
  173. */
  174. foreach($parameters as $name => $value) {
  175. /* Encode the parameter. */
  176. if($value === NULL) {
  177. $param = urlencode($name);
  178. } elseif (is_array($value)) {
  179. $param = "";
  180. foreach ($value as $val) {
  181. $param .= urlencode($name) . "[]=" . urlencode($val) . '&';
  182. }
  183. } else {
  184. $param = urlencode($name) . '=' .
  185. urlencode($value);
  186. }
  187. /* Append the parameter to the query string. */
  188. $url .= $paramPrefix . $param;
  189. /* Every following parameter is guaranteed to follow
  190. * another parameter. Therefore we use the '&' prefix.
  191. */
  192. $paramPrefix = '&';
  193. }
  194. /* Set the HTTP result code. This is either 303 See Other or
  195. * 302 Found. HTTP 303 See Other is sent if the HTTP version
  196. * is HTTP/1.1 and the request type was a POST request.
  197. */
  198. if($_SERVER['SERVER_PROTOCOL'] === 'HTTP/1.1' &&
  199. $_SERVER['REQUEST_METHOD'] === 'POST') {
  200. $code = 303;
  201. } else {
  202. $code = 302;
  203. }
  204. if (strlen($url) > 2048) {
  205. SimpleSAML_Logger::warning('Redirecting to URL longer than 2048 bytes.');
  206. }
  207. /* Set the location header. */
  208. header('Location: ' . $url, TRUE, $code);
  209. /* Disable caching of this response. */
  210. header('Pragma: no-cache');
  211. header('Cache-Control: no-cache, must-revalidate');
  212. /* Show a minimal web page with a clickable link to the URL. */
  213. echo '<?xml version="1.0" encoding="UTF-8"?>' . "\n";
  214. echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"' .
  215. ' "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">' . "\n";
  216. echo '<html xmlns="http://www.w3.org/1999/xhtml">';
  217. echo '<head>
  218. <meta http-equiv="content-type" content="text/html; charset=utf-8">
  219. <title>Redirect</title>
  220. </head>';
  221. echo '<body>';
  222. echo '<h1>Redirect</h1>';
  223. echo '<p>';
  224. echo 'You were redirected to: ';
  225. echo '<a id="redirlink" href="' . htmlspecialchars($url) . '">' . htmlspecialchars($url) . '</a>';
  226. echo '<script type="text/javascript">document.getElementById("redirlink").focus();</script>';
  227. echo '</p>';
  228. echo '</body>';
  229. echo '</html>';
  230. error_log("Redirecting user to : " . $url);
  231. /* End script execution. */
  232. exit;
  233. }
  234. public static function crypt_apr1_md5($plainpasswd) {
  235. $salt = substr(str_shuffle("abcdefghijklmnopqrstuvwxyz0123456789"), 0, 8);
  236. $len = strlen($plainpasswd);
  237. $text = $plainpasswd.'$apr1$'.$salt;
  238. $bin = pack("H32", md5($plainpasswd.$salt.$plainpasswd));
  239. for($i = $len; $i > 0; $i -= 16) { $text .= substr($bin, 0, min(16, $i)); }
  240. for($i = $len; $i > 0; $i >>= 1) { $text .= ($i & 1) ? chr(0) : $plainpasswd{0}; }
  241. $bin = pack("H32", md5($text));
  242. for($i = 0; $i < 1000; $i++) {
  243. $new = ($i & 1) ? $plainpasswd : $bin;
  244. if ($i % 3) $new .= $salt;
  245. if ($i % 7) $new .= $plainpasswd;
  246. $new .= ($i & 1) ? $bin : $plainpasswd;
  247. $bin = pack("H32", md5($new));
  248. }
  249. for ($i = 0; $i < 5; $i++) {
  250. $k = $i + 6;
  251. $j = $i + 12;
  252. if ($j == 16) $j = 5;
  253. $tmp = $bin[$i].$bin[$k].$bin[$j].$tmp;
  254. }
  255. $tmp = chr(0).chr(0).$bin[11].$tmp;
  256. $tmp = strtr(strrev(substr(base64_encode($tmp), 2)),
  257. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",
  258. "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz");
  259. return "$"."apr1"."$".$salt."$".$tmp;
  260. }
  261. /**
  262. * Command line log function
  263. * @param string $header A colored header to show first
  264. * @param string $str The rest of the string
  265. * @return string The encoded for terminal / CLI string
  266. */
  267. public static function cliLog($header, $str) {
  268. $tag = "\033[0;35m" . sprintf("%18s ", $header) . "\033[0m";
  269. echo($tag . $str . "\n");
  270. }
  271. /**
  272. * Encode username and password for use in .htpassword file.
  273. * The latest version is prepared to be supported with the HTTP Digest
  274. * Authentication method.
  275. * @param string $u Username
  276. * @param string $p Password
  277. * @return string Encoded string, representing one line in the .htpasswd file.
  278. */
  279. public static function encodeUserPass($u, $p) {
  280. $hash = base64_encode(sha1($p, true));
  281. // return crypt(crypt($p, base64_encode($p)));
  282. // return crypt($p,rand(10000, 99999));
  283. $realm = 'UWAP';
  284. return $realm . ':' . md5($u . ':' . $realm . ':' .$p);
  285. // return Utils::crypt_apr1_md5($p);
  286. // return '{SHA}'.$hash;
  287. }
  288. }