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.

328 lines
9.9 KiB

2 years ago
2 months ago
2 years ago
2 years ago
1 year ago
6 months ago
2 years ago
  1. <?php
  2. // 应用公共文件
  3. use think\facade\Db;
  4. function get_data_dir($os = 'Linux'){
  5. if($os == 'en'){
  6. return app()->getRootPath().'data/en/';
  7. }elseif($os == 'Windows'){
  8. return app()->getRootPath().'data/win/';
  9. }else{
  10. return app()->getRootPath().'data/';
  11. }
  12. }
  13. function authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) {
  14. $ckey_length = 4;
  15. $key = md5($key);
  16. $keya = md5(substr($key, 0, 16));
  17. $keyb = md5(substr($key, 16, 16));
  18. $keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : '';
  19. $cryptkey = $keya.md5($keya.$keyc);
  20. $key_length = strlen($cryptkey);
  21. $string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string;
  22. $string_length = strlen($string);
  23. $result = '';
  24. $box = range(0, 255);
  25. $rndkey = array();
  26. for($i = 0; $i <= 255; $i++) {
  27. $rndkey[$i] = ord($cryptkey[$i % $key_length]);
  28. }
  29. for($j = $i = 0; $i < 256; $i++) {
  30. $j = ($j + $box[$i] + $rndkey[$i]) % 256;
  31. $tmp = $box[$i];
  32. $box[$i] = $box[$j];
  33. $box[$j] = $tmp;
  34. }
  35. for($a = $j = $i = 0; $i < $string_length; $i++) {
  36. $a = ($a + 1) % 256;
  37. $j = ($j + $box[$a]) % 256;
  38. $tmp = $box[$a];
  39. $box[$a] = $box[$j];
  40. $box[$j] = $tmp;
  41. $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
  42. }
  43. if($operation == 'DECODE') {
  44. if(((int)substr($result, 0, 10) == 0 || (int)substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16)) {
  45. return substr($result, 26);
  46. } else {
  47. return '';
  48. }
  49. } else {
  50. return $keyc.str_replace('=', '', base64_encode($result));
  51. }
  52. }
  53. function random($length, $numeric = 0) {
  54. $seed = base_convert(md5(microtime().$_SERVER['DOCUMENT_ROOT']), 16, $numeric ? 10 : 35);
  55. $seed = $numeric ? (str_replace('0', '', $seed).'012340567890') : ($seed.'zZ'.strtoupper($seed));
  56. $hash = '';
  57. $max = strlen($seed) - 1;
  58. for($i = 0; $i < $length; $i++) {
  59. $hash .= $seed[mt_rand(0, $max)];
  60. }
  61. return $hash;
  62. }
  63. function get_curl($url, $post=0, $referer=0, $cookie=0, $header=0, $ua=0, $nobody=0, $addheader=0)
  64. {
  65. $ch = curl_init();
  66. curl_setopt($ch, CURLOPT_URL, $url);
  67. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
  68. curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
  69. $httpheader[] = "Accept: */*";
  70. $httpheader[] = "Accept-Encoding: gzip,deflate,sdch";
  71. $httpheader[] = "Accept-Language: zh-CN,zh;q=0.8";
  72. $httpheader[] = "Connection: close";
  73. if($addheader){
  74. $httpheader = array_merge($httpheader, $addheader);
  75. }
  76. curl_setopt($ch, CURLOPT_HTTPHEADER, $httpheader);
  77. if ($post) {
  78. curl_setopt($ch, CURLOPT_POST, 1);
  79. curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
  80. }
  81. if ($header) {
  82. curl_setopt($ch, CURLOPT_HEADER, true);
  83. }
  84. if ($cookie) {
  85. curl_setopt($ch, CURLOPT_COOKIE, $cookie);
  86. }
  87. if($referer){
  88. curl_setopt($ch, CURLOPT_REFERER, $referer);
  89. }
  90. if ($ua) {
  91. curl_setopt($ch, CURLOPT_USERAGENT, $ua);
  92. }
  93. else {
  94. curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36");
  95. }
  96. if ($nobody) {
  97. curl_setopt($ch, CURLOPT_NOBODY, 1);
  98. }
  99. curl_setopt($ch, CURLOPT_ENCODING, "gzip");
  100. curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  101. $ret = curl_exec($ch);
  102. curl_close($ch);
  103. return $ret;
  104. }
  105. function jsonp_decode($jsonp, $assoc = false)
  106. {
  107. $jsonp = trim($jsonp);
  108. if(isset($jsonp[0]) && $jsonp[0] !== '[' && $jsonp[0] !== '{') {
  109. $begin = strpos($jsonp, '(');
  110. if(false !== $begin)
  111. {
  112. $end = strrpos($jsonp, ')');
  113. if(false !== $end)
  114. {
  115. $jsonp = substr($jsonp, $begin + 1, $end - $begin - 1);
  116. }
  117. }
  118. }
  119. return json_decode($jsonp, $assoc);
  120. }
  121. function config_get($key, $default = null)
  122. {
  123. $value = config('sys.'.$key);
  124. return $value!==null ? $value : $default;
  125. }
  126. function config_set($key, $value)
  127. {
  128. $res = Db::name('config')->replace()->insert(['key'=>$key, 'value'=>$value]);
  129. return $res!==false;
  130. }
  131. function real_ip($type=0){
  132. $ip = $_SERVER['REMOTE_ADDR'];
  133. if($type<=0 && isset($_SERVER['HTTP_X_FORWARDED_FOR']) && preg_match_all('#\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}#s', $_SERVER['HTTP_X_FORWARDED_FOR'], $matches)) {
  134. foreach ($matches[0] AS $xip) {
  135. if (filter_var($xip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
  136. $ip = $xip;
  137. break;
  138. }
  139. }
  140. } elseif ($type<=0 && isset($_SERVER['HTTP_CLIENT_IP']) && filter_var($_SERVER['HTTP_CLIENT_IP'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
  141. $ip = $_SERVER['HTTP_CLIENT_IP'];
  142. } elseif ($type<=1 && isset($_SERVER['HTTP_CF_CONNECTING_IP']) && filter_var($_SERVER['HTTP_CF_CONNECTING_IP'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
  143. $ip = $_SERVER['HTTP_CF_CONNECTING_IP'];
  144. } elseif ($type<=1 && isset($_SERVER['HTTP_X_REAL_IP']) && filter_var($_SERVER['HTTP_X_REAL_IP'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
  145. $ip = $_SERVER['HTTP_X_REAL_IP'];
  146. }
  147. return $ip;
  148. }
  149. function getSubstr($str, $leftStr, $rightStr)
  150. {
  151. $left = strpos($str, $leftStr);
  152. $start = $left+strlen($leftStr);
  153. $right = strpos($str, $rightStr, $start);
  154. if($left < 0) return '';
  155. if($right>0){
  156. return substr($str, $start, $right-$start);
  157. }else{
  158. return substr($str, $start);
  159. }
  160. }
  161. function checkRefererHost(){
  162. if(!request()->header('referer'))return false;
  163. $url_arr = parse_url(request()->header('referer'));
  164. $http_host = request()->header('host');
  165. if(strpos($http_host,':'))$http_host = substr($http_host, 0, strpos($http_host, ':'));
  166. return $url_arr['host'] === $http_host;
  167. }
  168. function checkIfActive($string) {
  169. $array=explode(',',$string);
  170. $action = request()->action();
  171. if (in_array($action,$array)){
  172. return 'active';
  173. }else
  174. return null;
  175. }
  176. function checkDomain($domain){
  177. if(empty($domain) || !preg_match('/^[-$a-z0-9_*.]{2,512}$/i', $domain) || (stripos($domain, '.') === false) || substr($domain, -1) == '.' || substr($domain, 0 ,1) == '.' || substr($domain, 0 ,1) == '*' && substr($domain, 1 ,1) != '.' || substr_count($domain, '*')>1 || strpos($domain, '*')>0 || strlen($domain)<4) return false;
  178. return true;
  179. }
  180. function errorlog($msg){
  181. $handle = fopen(app()->getRootPath()."record.txt", 'a');
  182. fwrite($handle, date('Y-m-d H:i:s')."\t".$msg."\r\n");
  183. fclose($handle);
  184. }
  185. function licenseEncrypt($data, $key){
  186. $iv = substr($key, 0, 16);
  187. return openssl_encrypt($data, 'AES-256-CBC', $key, 0, $iv);
  188. }
  189. function licenseDecrypt($data, $key){
  190. $iv = substr($key, 0, 16);
  191. return openssl_decrypt($data, 'AES-256-CBC', $key, 0, $iv);
  192. }
  193. function generateKeyPairs(){
  194. $pkey_dir = app()->getRootPath().'data/config/';
  195. $public_key_path = $pkey_dir.'public_key.pem';
  196. $private_key_path = $pkey_dir.'private_key.pem';
  197. if(file_exists($public_key_path) && file_exists($private_key_path)){
  198. return [file_get_contents($public_key_path), file_get_contents($private_key_path)];
  199. }
  200. $pkey_config = ['private_key_bits'=>4096];
  201. $pkey_res = openssl_pkey_new($pkey_config);
  202. $private_key = '';
  203. openssl_pkey_export($pkey_res, $private_key, null, $pkey_config);
  204. $pkey_details = openssl_pkey_get_details($pkey_res);
  205. if(!$pkey_details) return false;
  206. $public_key = $pkey_details['key'];
  207. file_put_contents($public_key_path, $public_key);
  208. file_put_contents($private_key_path, $private_key);
  209. return [$public_key, $private_key];
  210. }
  211. function pemToBase64($pem){
  212. $lines = explode("\n", $pem);
  213. $encoded = '';
  214. foreach ($lines as $line) {
  215. if (trim($line) != '' && strpos($line, '-----BEGIN') === false && strpos($line, '-----END') === false) {
  216. $encoded .= trim($line);
  217. }
  218. }
  219. return $encoded;
  220. }
  221. function makeSelfSignSSL(string $commonName, array $domainList, $validity = 3650){
  222. // 加载 CA 证书和私钥
  223. $dir = app()->getBasePath().'script/';
  224. $caCert = file_get_contents($dir.'ca.crt');
  225. $caPrivateKey = file_get_contents($dir.'ca.key');
  226. $opensslConfigFile = sys_get_temp_dir().'/openssl'.time().mt_rand(1000, 9999).'.cnf';
  227. $opensslConfigContent = <<<EOF
  228. [req]
  229. req_extensions = extension_section
  230. x509_extensions = extension_section
  231. distinguished_name = dn
  232. [dn]
  233. [extension_section]
  234. basicConstraints = CA:FALSE
  235. keyUsage = nonRepudiation, digitalSignature, keyEncipherment
  236. subjectAltName = @alt_names
  237. [alt_names]
  238. EOF;
  239. $ip_index = 1;
  240. $dns_index = 1;
  241. foreach ($domainList as $value) {
  242. if(empty($value)) continue;
  243. if(filter_var($value, FILTER_VALIDATE_IP)){
  244. $opensslConfigContent .= sprintf("\nIP.%d = %s", $ip_index, $value);
  245. $ip_index++;
  246. }else{
  247. $opensslConfigContent .= sprintf("\nDNS.%d = %s", $dns_index, $value);
  248. $dns_index++;
  249. }
  250. }
  251. if(!file_put_contents($opensslConfigFile, $opensslConfigContent)) return false;
  252. // 生成域名证书的私钥和 CSR
  253. $domainPrivateKey = openssl_pkey_new([
  254. 'private_key_bits' => 2048,
  255. 'private_key_type' => OPENSSL_KEYTYPE_RSA,
  256. ]);
  257. if(!$domainPrivateKey) return false;
  258. $csrConfig = ['digest_alg' => 'sha256', 'config' => $opensslConfigFile];
  259. $domainCsr = openssl_csr_new([
  260. 'commonName' => $commonName
  261. ], $domainPrivateKey, $csrConfig);
  262. if(!$domainCsr) return false;
  263. // 生成域名证书
  264. $domainCertificate = openssl_csr_sign($domainCsr, $caCert, $caPrivateKey, $validity, $csrConfig);
  265. if(!$domainCertificate) return false;
  266. // 导出域名证书
  267. openssl_x509_export($domainCertificate, $certificate);
  268. openssl_pkey_export($domainPrivateKey, $privateKey);
  269. $certificate .= $caCert;
  270. unlink($opensslConfigFile);
  271. return ['cert' => $certificate, 'key' => $privateKey];
  272. }
  273. function deleteDir($dir){
  274. $rd = opendir($dir);
  275. if (!$rd) {
  276. return false;
  277. }
  278. while (($file = readdir($rd)) !== false) {
  279. if ($file == '.' || $file == '..') {
  280. continue;
  281. }
  282. $file = $dir . '/' . $file;
  283. if (is_dir($file)) {
  284. deleteDir($file);
  285. }
  286. else {
  287. unlink($file);
  288. }
  289. }
  290. closedir($rd);
  291. rmdir($dir);
  292. return true;
  293. }