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.

322 lines
9.8 KiB

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