├── .github
└── workflows
│ └── integrate.yml
├── CREDITS
├── EXPERIMENTAL
├── README.md
├── aes_algo_handler.c
├── aes_algo_lib.c
├── base64_algo_handler.c
├── beast.c
├── beast_log.c
├── beast_log.h
├── beast_mm.c
├── beast_mm.h
├── beast_module.h
├── cache.c
├── cache.h
├── config.m4
├── config.w32
├── des_algo_handler.c
├── des_algo_lib.c
├── file_handler.h
├── file_handler_switch.c
├── global_algo_modules.c
├── header.c
├── images
├── beast1.png
├── beast2.png
└── pay.jpg
├── networkcards.c
├── php_beast.h
├── pipe_file_handler.c
├── shm.c
├── shm.h
├── spinlock.c
├── spinlock.h
├── tests
├── 001.phpt
└── encrypt.php
├── tmpfile_file_handler.c
└── tools
├── configure.ini
├── encode_file.php
└── encode_files.php
/.github/workflows/integrate.yml:
--------------------------------------------------------------------------------
1 | name: integrate
2 | on:
3 | push:
4 | branches: [ master ]
5 | pull_request:
6 | branches: [ master ]
7 |
8 | jobs:
9 | matrix:
10 | name: "PHP"
11 | runs-on: ${{ matrix.OS }}
12 | strategy:
13 | matrix:
14 | PHP: ["7.0", "7.1", "7.2", "7.3"]
15 | OS: ["ubuntu-latest"]
16 | include:
17 | - PHP: "7.4"
18 | OS: "ubuntu-latest"
19 | ZTS: true
20 | env:
21 | GITHUB: "yes"
22 | enable_debug: "yes"
23 | enable_session: "yes"
24 | TEST_PHP_ARGS : "--show-diff"
25 | REPORT_EXIT_STATUS: "yes"
26 | NO_INTERACTION: "yes"
27 | steps:
28 | - name: Checkout
29 | uses: actions/checkout@v2
30 | with:
31 | submodules: true
32 | - name: Setup
33 | uses: shivammathur/setup-php@v2
34 | with:
35 | php-version: ${{ matrix.PHP }}
36 | - name: Install
37 | run: |
38 | sudo apt-get install -y re2c
39 | - name: Prepare
40 | run: |
41 | phpize
42 | - name: Build
43 | run: |
44 | ./configure
45 | - name: Make
46 | run: |
47 | make
48 | - name: Test
49 | run: |
50 | make test
--------------------------------------------------------------------------------
/CREDITS:
--------------------------------------------------------------------------------
1 | beast
--------------------------------------------------------------------------------
/EXPERIMENTAL:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liexusong/php-beast/4549b2a642a9b04408b4bfbb3af64131c7f1f2dd/EXPERIMENTAL
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | ____ __ ______ ____ _________ ___________
3 | / __ \/ / / / __ \ / __ )/ ____/ | / ___/_ __/
4 | / /_/ / /_/ / /_/ / / __ / __/ / /| | \__ \ / /
5 | / ____/ __ / ____/ / /_/ / /___/ ___ |___/ // /
6 | /_/ /_/ /_/_/ /_____/_____/_/ |_/____//_/
7 |
8 | 贡献者名字:
9 | @imaben (windows版本提供者) https://github.com/imaben
10 | @pinguo-niulingyun (PHP7版本提供者) https://github.com/pinguo-niulingyun
11 |
12 | QQ交流群:239243332
13 |
14 |
15 | Windows DLL:下载地址
16 |
17 | php-beast可以自定义加密模块,加密模块编写教程: 点击
18 |
19 | 编译安装如下:
20 |
21 | $ wget https://github.com/liexusong/php-beast/archive/master.zip
22 | $ unzip master.zip
23 | $ cd php-beast-master
24 | $ phpize
25 | $ ./configure
26 | $ sudo make && make install
27 |
28 | 编译好之后修改php.ini配置文件, 加入配置项: extension=beast.so, 重启php-fpm
29 |
30 |
31 | 温馨提示: 可以设置较大的缓存提高效率
32 |
33 | 使用php-beast的性能:
34 | 
35 |
36 | 不使用php-beast的性能:
37 | 
38 |
39 | 配置项:
40 |
41 | beast.cache_size = size
42 | beast.log_file = "path_to_log"
43 | beast.log_user = "user"
44 | beast.log_level = "debug"
45 | beast.enable = On
46 |
47 |
48 | beast.log_level支持参数:
49 |
50 | 1. DEBUG
51 | 2. NOTICE
52 | 3. ERROR
53 |
54 |
55 | 支持的模块有:
56 |
57 | 1. AES
58 | 2. DES
59 | 3. Base64
60 |
61 |
62 | 通过测试环境:
63 |
64 | Nginx + Fastcgi + (PHP-5.2.x ~ PHP-7.1.x)
65 |
66 |
67 | ------------------------------
68 |
69 | ## 怎么加密项目
70 | **加密方案1**
71 |
72 | 安装完 `php-beast` 后可以使用 `tools` 目录下的 `encode_files.php` 来加密你的项目。使用 `encode_files.php` 之前先修改 `tools` 目录下的 `configure.ini` 文件,如下:
73 | ```ini
74 | ; source path
75 | src_path = ""
76 |
77 | ; destination path
78 | dst_path = ""
79 |
80 | ; expire time
81 | expire = ""
82 |
83 | ; encrypt type (selection: DES, AES, BASE64)
84 | encrypt_type = "DES"
85 | ```
86 | `src_path` 是要加密项目的路径,`dst_path` 是保存加密后项目的路径,`expire` 是设置项目可使用的时间 (`expire` 的格式是:`YYYY-mm-dd HH:ii:ss`)。`encrypt_type`是加密的方式,选择项有:DES、AES、BASE64。
87 | 修改完 `configure.ini` 文件后就可以使用命令 `php encode_files.php` 开始加密项目。
88 |
89 | **加密方案2**
90 |
91 | 使用`beast_encode_file()`函数加密文件,函数原型如下:
92 | `beast_encode_file(string $input_file, string $output_file, int expire_timestamp, int encrypt_type)`。
93 |
94 | 1. $input_file: 要加密的文件
95 | 2. $output_file: 输出的加密文件路径
96 | 3. $expire_timestamp: 文件过期时间戳
97 | 4. $encrypt_type: 加密使用的算法(支持:BEAST_ENCRYPT_TYPE_DES、BEAST_ENCRYPT_TYPE_AES)
98 |
99 |
100 | ------------------------------
101 |
102 | ## 制定自己的php-beast
103 |
104 | `php-beast` 有多个地方可以定制的,以下一一列出:
105 |
106 | *1.* 使用 `header.c` 文件可以修改 `php-beast` 加密后的文件头结构,这样网上的解密软件就不能认识我们的加密文件,就不能进行解密,增加加密的安全性。
107 |
108 | *2.* `php-beast` 提供只能在指定的机器上运行的功能。要使用此功能可以在 `networkcards.c` 文件添加能够运行机器的网卡号,例如:
109 | ```c
110 | char *allow_networkcards[] = {
111 | "fa:16:3e:08:88:01",
112 | NULL,
113 | };
114 | ```
115 | 这样设置之后,`php-beast` 扩展就只能在 `fa:16:3e:08:88:01` 这台机器上运行。另外要注意的是,由于有些机器网卡名可能不一样,所以如果你的网卡名不是 `eth0` 的话,可以在 `php.ini` 中添加配置项: `beast.networkcard = "xxx"` 其中 `xxx` 就是你的网卡名,也可以配置多张网卡,如:`beast.networkcard = "eth0,eth1,eth2"`。
116 |
117 | *3.* 使用 `php-beast` 时最好不要使用默认的加密key,因为扩展是开源的,如果使用默认加密key的话,很容易被人发现。所以最好编译的时候修改加密的key,`aes模块` 可以在 `aes_algo_handler.c` 文件修改,而 `des模块` 可以在 `des_algo_handler.c` 文件修改。
118 |
119 | ------------------------------
120 |
121 | ## 开启debug模式
122 | 可以在configure时加上 `--enable-beast-debug` 选项来开启debug模式。开启debug模式后需要在php.ini配置文件中加入配置项:`beast.debug_path` 和 `beast.debug_mode`。`beast.debug_mode` 用于指定是否使用debug模式,而 `beast.debug_path` 用于输出解密后的php脚本源码。这样就可以在 `beast.debug_path` 目录中看到php-beast解密后的源代码,可以方便知道扩展解密是否正确。
123 |
124 | ## 开启禁止执行未加密的脚本
125 | 可以在configure时加上 `--enable-execute-normal-script=off` 选项来禁止执行未加密的PHP脚本。
126 |
127 | ------------------------------
128 |
129 | ## 函数列表
130 | *1.* beast_encode_file(): 用于加密一个文件
131 |
132 | *2.* beast_avail_cache(): 获取可以缓存大小
133 |
134 | *3.* beast_support_filesize(): 获取beast支持的最大可加密文件大小
135 |
136 | *4.* beast_file_expire(): 获取一个文件的过期时间
137 |
138 | *5.* beast_clean_cache(): 清空beast的所有缓存(如果有文件更新, 可以使用此函数清空缓存)
139 |
140 | ------------------------------
141 |
142 | ## 常见问题
143 |
144 | *1.* linux:如果出现502错误,一般是由于GCC版本太低导致,请先升级GCC再安装本模块。
145 |
146 | *2.* Windows:IIS环境下FastCGI进程异常退出:尝试将IIS的运行用户从ApplicationPoolIdentity改为LocalSystem
147 |
148 | ------------------------------
149 |
150 | ### 我们的公众号
151 |
152 | 
153 |
154 | ------------------------------
155 |
--------------------------------------------------------------------------------
/aes_algo_handler.c:
--------------------------------------------------------------------------------
1 | /**
2 | * AES encrypt algorithms handler module for Beast
3 | * @author: liexusong
4 | */
5 |
6 | #include
7 | #include
8 | #include "beast_log.h"
9 | #include "beast_module.h"
10 | #include "aes_algo_lib.c"
11 |
12 | static uint8_t key[] = {
13 | 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
14 | 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c,
15 | };
16 |
17 | int aes_encrypt_handler(char *inbuf, int len,
18 | char **outbuf, int *outlen)
19 | {
20 | int blocks, i;
21 | char *out;
22 | char in[16];
23 |
24 | blocks = len / 16;
25 | if (len % 16) { /* not enough one block (16 bytes) */
26 | blocks += 1;
27 | }
28 |
29 | out = malloc(blocks * 16);
30 | if (!out) {
31 | beast_write_log(beast_log_error,
32 | "Out of memory when allocate `%d' size by encrypt(AES)", blocks*16);
33 | return -1;
34 | }
35 |
36 | for (i = 0; i < blocks; i++) {
37 | int size;
38 |
39 | memset(in, 0, 16);
40 |
41 | if (i == blocks - 1 && (len % 16)) { /* the last block */
42 | size = len % 16;
43 | } else {
44 | size = 16;
45 | }
46 |
47 | memcpy(in, inbuf + i * 16, size);
48 |
49 | AES128_ECB_encrypt(in, key, out + i * 16);
50 | }
51 |
52 | *outbuf = out;
53 | *outlen = blocks * 16;
54 |
55 | return 0;
56 | }
57 |
58 |
59 | int aes_decrypt_handler(char *inbuf, int len,
60 | char **outbuf, int *outlen)
61 | {
62 | int blocks, i;
63 | char *out;
64 |
65 | if (len % 16) {
66 | return -1;
67 | }
68 |
69 | blocks = len / 16;
70 |
71 | out = malloc(blocks * 16);
72 | if (!out) {
73 | beast_write_log(beast_log_error,
74 | "Out of memory when allocate `%d' size by decrypt(AES)", blocks*16);
75 | return -1;
76 | }
77 |
78 | for (i = 0; i < blocks; i++) {
79 | AES128_ECB_decrypt(inbuf + i * 16, key, out + i * 16);
80 | }
81 |
82 | *outbuf = out;
83 | *outlen = blocks * 16;
84 |
85 | return 0;
86 | }
87 |
88 |
89 | void aes_free_handler(void *ptr)
90 | {
91 | if (ptr) {
92 | free(ptr);
93 | }
94 | }
95 |
96 | struct beast_ops aes_handler_ops = {
97 | "aes-algo",
98 | aes_encrypt_handler,
99 | aes_decrypt_handler,
100 | aes_free_handler,
101 | NULL
102 | };
103 |
--------------------------------------------------------------------------------
/aes_algo_lib.c:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | This is an implementation of the AES128 algorithm, specifically ECB and CBC mode.
4 |
5 | The implementation is verified against the test vectors in:
6 | National Institute of Standards and Technology Special Publication 800-38A 2001 ED
7 |
8 | ECB-AES128
9 | ----------
10 |
11 | plain-text:
12 | 6bc1bee22e409f96e93d7e117393172a
13 | ae2d8a571e03ac9c9eb76fac45af8e51
14 | 30c81c46a35ce411e5fbc1191a0a52ef
15 | f69f2445df4f9b17ad2b417be66c3710
16 |
17 | key:
18 | 2b7e151628aed2a6abf7158809cf4f3c
19 |
20 | resulting cipher
21 | 3ad77bb40d7a3660a89ecaf32466ef97
22 | f5d3d58503b9699de785895a96fdbaaf
23 | 43b1cd7f598ece23881b00e3ed030688
24 | 7b0c785e27e8ad3f8223207104725dd4
25 |
26 |
27 | NOTE: String length must be evenly divisible by 16byte (str_len % 16 == 0)
28 | You should pad the end of the string with zeros if this is not the case.
29 |
30 | */
31 |
32 |
33 | /*****************************************************************************/
34 | /* Includes: */
35 | /*****************************************************************************/
36 | #include
37 | #include // CBC mode, for memset
38 |
39 | /*****************************************************************************/
40 | /* Defines: */
41 | /*****************************************************************************/
42 | // The number of columns comprising a state in AES. This is a constant in AES. Value=4
43 | #define Nb 4
44 | // The number of 32 bit words in a key.
45 | #define Nk 4
46 | // Key length in bytes [128 bit]
47 | #define KEYLEN 16
48 | // The number of rounds in AES Cipher.
49 | #define Nr 10
50 |
51 | // jcallan@github points out that declaring Multiply as a function
52 | // reduces code size considerably with the Keil ARM compiler.
53 | // See this link for more information: https://github.com/kokke/tiny-AES128-C/pull/3
54 | #ifndef MULTIPLY_AS_A_FUNCTION
55 | #define MULTIPLY_AS_A_FUNCTION 0
56 | #endif
57 |
58 |
59 | /*****************************************************************************/
60 | /* Private variables: */
61 | /*****************************************************************************/
62 | // state - array holding the intermediate results during decryption.
63 | typedef uint8_t state_t[4][4];
64 | static state_t* state;
65 |
66 | // The array that stores the round keys.
67 | static uint8_t RoundKey[176];
68 |
69 | // The Key input to the AES Program
70 | static const uint8_t* Key;
71 |
72 | // The lookup-tables are marked const so they can be placed in read-only storage instead of RAM
73 | // The numbers below can be computed dynamically trading ROM for RAM -
74 | // This can be useful in (embedded) bootloader applications, where ROM is often limited.
75 | static const uint8_t sbox[256] = {
76 | //0 1 2 3 4 5 6 7 8 9 A B C D E F
77 | 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
78 | 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
79 | 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
80 | 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
81 | 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
82 | 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
83 | 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
84 | 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
85 | 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
86 | 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
87 | 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
88 | 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
89 | 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
90 | 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
91 | 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
92 | 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 };
93 |
94 | static const uint8_t rsbox[256] =
95 | { 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
96 | 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
97 | 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
98 | 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
99 | 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
100 | 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
101 | 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
102 | 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
103 | 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
104 | 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
105 | 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
106 | 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
107 | 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
108 | 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
109 | 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
110 | 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d };
111 |
112 |
113 | // The round constant word array, Rcon[i], contains the values given by
114 | // x to th e power (i-1) being powers of x (x is denoted as {02}) in the field GF(2^8)
115 | // Note that i starts at 1, not 0).
116 | static const uint8_t Rcon[255] = {
117 | 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a,
118 | 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39,
119 | 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a,
120 | 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8,
121 | 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef,
122 | 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc,
123 | 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b,
124 | 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3,
125 | 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94,
126 | 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20,
127 | 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35,
128 | 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f,
129 | 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04,
130 | 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63,
131 | 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd,
132 | 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb };
133 |
134 |
135 | /*****************************************************************************/
136 | /* Private functions: */
137 | /*****************************************************************************/
138 | static uint8_t getSBoxValue(uint8_t num)
139 | {
140 | return sbox[num];
141 | }
142 |
143 | static uint8_t getSBoxInvert(uint8_t num)
144 | {
145 | return rsbox[num];
146 | }
147 |
148 | // This function produces Nb(Nr+1) round keys. The round keys are used in each round to decrypt the states.
149 | static void KeyExpansion(void)
150 | {
151 | uint32_t i, j, k;
152 | uint8_t tempa[4]; // Used for the column/row operations
153 |
154 | // The first round key is the key itself.
155 | for(i = 0; i < Nk; ++i)
156 | {
157 | RoundKey[(i * 4) + 0] = Key[(i * 4) + 0];
158 | RoundKey[(i * 4) + 1] = Key[(i * 4) + 1];
159 | RoundKey[(i * 4) + 2] = Key[(i * 4) + 2];
160 | RoundKey[(i * 4) + 3] = Key[(i * 4) + 3];
161 | }
162 |
163 | // All other round keys are found from the previous round keys.
164 | for(; (i < (Nb * (Nr + 1))); ++i)
165 | {
166 | for(j = 0; j < 4; ++j)
167 | {
168 | tempa[j]=RoundKey[(i-1) * 4 + j];
169 | }
170 | if (i % Nk == 0)
171 | {
172 | // This function rotates the 4 bytes in a word to the left once.
173 | // [a0,a1,a2,a3] becomes [a1,a2,a3,a0]
174 |
175 | // Function RotWord()
176 | {
177 | k = tempa[0];
178 | tempa[0] = tempa[1];
179 | tempa[1] = tempa[2];
180 | tempa[2] = tempa[3];
181 | tempa[3] = k;
182 | }
183 |
184 | // SubWord() is a function that takes a four-byte input word and
185 | // applies the S-box to each of the four bytes to produce an output word.
186 |
187 | // Function Subword()
188 | {
189 | tempa[0] = getSBoxValue(tempa[0]);
190 | tempa[1] = getSBoxValue(tempa[1]);
191 | tempa[2] = getSBoxValue(tempa[2]);
192 | tempa[3] = getSBoxValue(tempa[3]);
193 | }
194 |
195 | tempa[0] = tempa[0] ^ Rcon[i/Nk];
196 | }
197 | else if (Nk > 6 && i % Nk == 4)
198 | {
199 | // Function Subword()
200 | {
201 | tempa[0] = getSBoxValue(tempa[0]);
202 | tempa[1] = getSBoxValue(tempa[1]);
203 | tempa[2] = getSBoxValue(tempa[2]);
204 | tempa[3] = getSBoxValue(tempa[3]);
205 | }
206 | }
207 | RoundKey[i * 4 + 0] = RoundKey[(i - Nk) * 4 + 0] ^ tempa[0];
208 | RoundKey[i * 4 + 1] = RoundKey[(i - Nk) * 4 + 1] ^ tempa[1];
209 | RoundKey[i * 4 + 2] = RoundKey[(i - Nk) * 4 + 2] ^ tempa[2];
210 | RoundKey[i * 4 + 3] = RoundKey[(i - Nk) * 4 + 3] ^ tempa[3];
211 | }
212 | }
213 |
214 | // This function adds the round key to state.
215 | // The round key is added to the state by an XOR function.
216 | static void AddRoundKey(uint8_t round)
217 | {
218 | uint8_t i,j;
219 | for(i=0;i<4;++i)
220 | {
221 | for(j = 0; j < 4; ++j)
222 | {
223 | (*state)[i][j] ^= RoundKey[round * Nb * 4 + i * Nb + j];
224 | }
225 | }
226 | }
227 |
228 | // The SubBytes Function Substitutes the values in the
229 | // state matrix with values in an S-box.
230 | static void SubBytes(void)
231 | {
232 | uint8_t i, j;
233 | for(i = 0; i < 4; ++i)
234 | {
235 | for(j = 0; j < 4; ++j)
236 | {
237 | (*state)[j][i] = getSBoxValue((*state)[j][i]);
238 | }
239 | }
240 | }
241 |
242 | // The ShiftRows() function shifts the rows in the state to the left.
243 | // Each row is shifted with different offset.
244 | // Offset = Row number. So the first row is not shifted.
245 | static void ShiftRows(void)
246 | {
247 | uint8_t temp;
248 |
249 | // Rotate first row 1 columns to left
250 | temp = (*state)[0][1];
251 | (*state)[0][1] = (*state)[1][1];
252 | (*state)[1][1] = (*state)[2][1];
253 | (*state)[2][1] = (*state)[3][1];
254 | (*state)[3][1] = temp;
255 |
256 | // Rotate second row 2 columns to left
257 | temp = (*state)[0][2];
258 | (*state)[0][2] = (*state)[2][2];
259 | (*state)[2][2] = temp;
260 |
261 | temp = (*state)[1][2];
262 | (*state)[1][2] = (*state)[3][2];
263 | (*state)[3][2] = temp;
264 |
265 | // Rotate third row 3 columns to left
266 | temp = (*state)[0][3];
267 | (*state)[0][3] = (*state)[3][3];
268 | (*state)[3][3] = (*state)[2][3];
269 | (*state)[2][3] = (*state)[1][3];
270 | (*state)[1][3] = temp;
271 | }
272 |
273 | static uint8_t xtime(uint8_t x)
274 | {
275 | return ((x<<1) ^ (((x>>7) & 1) * 0x1b));
276 | }
277 |
278 | // MixColumns function mixes the columns of the state matrix
279 | static void MixColumns(void)
280 | {
281 | uint8_t i;
282 | uint8_t Tmp,Tm,t;
283 | for(i = 0; i < 4; ++i)
284 | {
285 | t = (*state)[i][0];
286 | Tmp = (*state)[i][0] ^ (*state)[i][1] ^ (*state)[i][2] ^ (*state)[i][3] ;
287 | Tm = (*state)[i][0] ^ (*state)[i][1] ; Tm = xtime(Tm); (*state)[i][0] ^= Tm ^ Tmp ;
288 | Tm = (*state)[i][1] ^ (*state)[i][2] ; Tm = xtime(Tm); (*state)[i][1] ^= Tm ^ Tmp ;
289 | Tm = (*state)[i][2] ^ (*state)[i][3] ; Tm = xtime(Tm); (*state)[i][2] ^= Tm ^ Tmp ;
290 | Tm = (*state)[i][3] ^ t ; Tm = xtime(Tm); (*state)[i][3] ^= Tm ^ Tmp ;
291 | }
292 | }
293 |
294 | // Multiply is used to multiply numbers in the field GF(2^8)
295 | #if MULTIPLY_AS_A_FUNCTION
296 | static uint8_t Multiply(uint8_t x, uint8_t y)
297 | {
298 | return (((y & 1) * x) ^
299 | ((y>>1 & 1) * xtime(x)) ^
300 | ((y>>2 & 1) * xtime(xtime(x))) ^
301 | ((y>>3 & 1) * xtime(xtime(xtime(x)))) ^
302 | ((y>>4 & 1) * xtime(xtime(xtime(xtime(x))))));
303 | }
304 | #else
305 | #define Multiply(x, y) \
306 | ( ((y & 1) * x) ^ \
307 | ((y>>1 & 1) * xtime(x)) ^ \
308 | ((y>>2 & 1) * xtime(xtime(x))) ^ \
309 | ((y>>3 & 1) * xtime(xtime(xtime(x)))) ^ \
310 | ((y>>4 & 1) * xtime(xtime(xtime(xtime(x)))))) \
311 |
312 | #endif
313 |
314 | // MixColumns function mixes the columns of the state matrix.
315 | // The method used to multiply may be difficult to understand for the inexperienced.
316 | // Please use the references to gain more information.
317 | static void InvMixColumns(void)
318 | {
319 | int i;
320 | uint8_t a,b,c,d;
321 | for(i=0;i<4;++i)
322 | {
323 | a = (*state)[i][0];
324 | b = (*state)[i][1];
325 | c = (*state)[i][2];
326 | d = (*state)[i][3];
327 |
328 | (*state)[i][0] = Multiply(a, 0x0e) ^ Multiply(b, 0x0b) ^ Multiply(c, 0x0d) ^ Multiply(d, 0x09);
329 | (*state)[i][1] = Multiply(a, 0x09) ^ Multiply(b, 0x0e) ^ Multiply(c, 0x0b) ^ Multiply(d, 0x0d);
330 | (*state)[i][2] = Multiply(a, 0x0d) ^ Multiply(b, 0x09) ^ Multiply(c, 0x0e) ^ Multiply(d, 0x0b);
331 | (*state)[i][3] = Multiply(a, 0x0b) ^ Multiply(b, 0x0d) ^ Multiply(c, 0x09) ^ Multiply(d, 0x0e);
332 | }
333 | }
334 |
335 |
336 | // The SubBytes Function Substitutes the values in the
337 | // state matrix with values in an S-box.
338 | static void InvSubBytes(void)
339 | {
340 | uint8_t i,j;
341 | for(i=0;i<4;++i)
342 | {
343 | for(j=0;j<4;++j)
344 | {
345 | (*state)[j][i] = getSBoxInvert((*state)[j][i]);
346 | }
347 | }
348 | }
349 |
350 | static void InvShiftRows(void)
351 | {
352 | uint8_t temp;
353 |
354 | // Rotate first row 1 columns to right
355 | temp=(*state)[3][1];
356 | (*state)[3][1]=(*state)[2][1];
357 | (*state)[2][1]=(*state)[1][1];
358 | (*state)[1][1]=(*state)[0][1];
359 | (*state)[0][1]=temp;
360 |
361 | // Rotate second row 2 columns to right
362 | temp=(*state)[0][2];
363 | (*state)[0][2]=(*state)[2][2];
364 | (*state)[2][2]=temp;
365 |
366 | temp=(*state)[1][2];
367 | (*state)[1][2]=(*state)[3][2];
368 | (*state)[3][2]=temp;
369 |
370 | // Rotate third row 3 columns to right
371 | temp=(*state)[0][3];
372 | (*state)[0][3]=(*state)[1][3];
373 | (*state)[1][3]=(*state)[2][3];
374 | (*state)[2][3]=(*state)[3][3];
375 | (*state)[3][3]=temp;
376 | }
377 |
378 |
379 | // Cipher is the main function that encrypts the PlainText.
380 | static void Cipher(void)
381 | {
382 | uint8_t round = 0;
383 |
384 | // Add the First round key to the state before starting the rounds.
385 | AddRoundKey(0);
386 |
387 | // There will be Nr rounds.
388 | // The first Nr-1 rounds are identical.
389 | // These Nr-1 rounds are executed in the loop below.
390 | for(round = 1; round < Nr; ++round)
391 | {
392 | SubBytes();
393 | ShiftRows();
394 | MixColumns();
395 | AddRoundKey(round);
396 | }
397 |
398 | // The last round is given below.
399 | // The MixColumns function is not here in the last round.
400 | SubBytes();
401 | ShiftRows();
402 | AddRoundKey(Nr);
403 | }
404 |
405 | static void InvCipher(void)
406 | {
407 | uint8_t round=0;
408 |
409 | // Add the First round key to the state before starting the rounds.
410 | AddRoundKey(Nr);
411 |
412 | // There will be Nr rounds.
413 | // The first Nr-1 rounds are identical.
414 | // These Nr-1 rounds are executed in the loop below.
415 | for(round=Nr-1;round>0;round--)
416 | {
417 | InvShiftRows();
418 | InvSubBytes();
419 | AddRoundKey(round);
420 | InvMixColumns();
421 | }
422 |
423 | // The last round is given below.
424 | // The MixColumns function is not here in the last round.
425 | InvShiftRows();
426 | InvSubBytes();
427 | AddRoundKey(0);
428 | }
429 |
430 | static void BlockCopy(uint8_t* output, uint8_t* input)
431 | {
432 | uint8_t i;
433 | for (i=0;i
7 | #include
8 | #include "beast_log.h"
9 | #include "beast_module.h"
10 |
11 | static const char base64_table[] =
12 | { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
13 | 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
14 | 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
15 | 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
16 | '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/', '\0'
17 | };
18 |
19 | static const char base64_pad = '=';
20 |
21 | static const short base64_reverse_table[256] = {
22 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
23 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
24 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
25 | 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
26 | -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
27 | 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
28 | -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
29 | 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,
30 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
31 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
32 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
33 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
34 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
35 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
36 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
37 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
38 | };
39 |
40 | char *base64_encode(char *str, int length, int *ret_length)
41 | {
42 | char *current = str;
43 | char *p;
44 | char *result;
45 | int alen;
46 |
47 | if ((length + 2) < 0
48 | || ((length + 2) / 3) >= (1 << (sizeof(int) * 8 - 2)))
49 | {
50 | if (ret_length != NULL) {
51 | *ret_length = 0;
52 | }
53 | return NULL;
54 | }
55 |
56 | alen = ((length + 2) / 3) * 4 + 1;
57 |
58 | result = malloc(alen);
59 | if (!result) {
60 | beast_write_log(beast_log_error,
61 | "Out of memory when allocate `%d' size by encrypt(BASE64)", alen);
62 | return NULL;
63 | }
64 |
65 | p = result;
66 |
67 | while (length > 2) { /* keep going until we have less than 24 bits */
68 | *p++ = base64_table[current[0] >> 2];
69 | *p++ = base64_table[((current[0] & 0x03) << 4) + (current[1] >> 4)];
70 | *p++ = base64_table[((current[1] & 0x0f) << 2) + (current[2] >> 6)];
71 | *p++ = base64_table[current[2] & 0x3f];
72 |
73 | current += 3;
74 | length -= 3; /* we just handle 3 octets of data */
75 | }
76 |
77 | /* now deal with the tail end of things */
78 | if (length != 0) {
79 | *p++ = base64_table[current[0] >> 2];
80 | if (length > 1) {
81 | *p++ = base64_table[((current[0] & 0x03) << 4) + (current[1] >> 4)];
82 | *p++ = base64_table[(current[1] & 0x0f) << 2];
83 | *p++ = base64_pad;
84 | } else {
85 | *p++ = base64_table[(current[0] & 0x03) << 4];
86 | *p++ = base64_pad;
87 | *p++ = base64_pad;
88 | }
89 | }
90 |
91 | if (ret_length != NULL) {
92 | *ret_length = (int)(p - result);
93 | }
94 |
95 | *p = '\0';
96 |
97 | return result;
98 | }
99 |
100 |
101 | char *base64_decode(char *str, int length, int *ret_length)
102 | {
103 | char *current = str;
104 | int ch, i = 0, j = 0, k;
105 | char *result;
106 |
107 | result = malloc(length + 1);
108 | if (result == NULL) {
109 | beast_write_log(beast_log_error,
110 | "Out of memory when allocate `%d' size by decrypt(BASE64)", length+1);
111 | return NULL;
112 | }
113 |
114 | /* run through the whole string, converting as we go */
115 | while ((ch = *current++) != '\0' && length-- > 0) {
116 | if (ch == base64_pad) break;
117 |
118 | ch = base64_reverse_table[ch];
119 | if (ch < 0) continue;
120 |
121 | switch(i % 4) {
122 | case 0:
123 | result[j] = ch << 2;
124 | break;
125 | case 1:
126 | result[j++] |= ch >> 4;
127 | result[j] = (ch & 0x0f) << 4;
128 | break;
129 | case 2:
130 | result[j++] |= ch >>2;
131 | result[j] = (ch & 0x03) << 6;
132 | break;
133 | case 3:
134 | result[j++] |= ch;
135 | break;
136 | }
137 | i++;
138 | }
139 |
140 | k = j;
141 | /* mop things up if we ended on a boundary */
142 | if (ch == base64_pad) {
143 | switch(i % 4) {
144 | case 1:
145 | free(result);
146 | return NULL;
147 | case 2:
148 | k++;
149 | case 3:
150 | result[k++] = 0;
151 | }
152 | }
153 |
154 | if(ret_length) {
155 | *ret_length = j;
156 | }
157 |
158 | result[j] = '\0';
159 |
160 | return result;
161 | }
162 |
163 |
164 | int base64_encrypt_handler(char *inbuf, int len,
165 | char **outbuf, int *outlen)
166 | {
167 | char *result;
168 | int reslen;
169 |
170 | result = base64_encode(inbuf, len, &reslen);
171 | if (!result) {
172 | return -1;
173 | }
174 |
175 | *outbuf = result;
176 | *outlen = reslen;
177 |
178 | return 0;
179 | }
180 |
181 |
182 | int base64_decrypt_handler(char *inbuf, int len,
183 | char **outbuf, int *outlen)
184 | {
185 | char *result;
186 | int reslen;
187 |
188 | result = base64_decode(inbuf, len, &reslen);
189 | if (!result) {
190 | return -1;
191 | }
192 |
193 | *outbuf = result;
194 | *outlen = reslen;
195 |
196 | return 0;
197 | }
198 |
199 |
200 | void base64_free_handler(void *ptr)
201 | {
202 | if (ptr) {
203 | free(ptr);
204 | }
205 | }
206 |
207 |
208 | struct beast_ops base64_handler_ops = {
209 | "base64-algo",
210 | base64_encrypt_handler,
211 | base64_decrypt_handler,
212 | base64_free_handler,
213 | NULL
214 | };
215 |
--------------------------------------------------------------------------------
/beast.c:
--------------------------------------------------------------------------------
1 | /*
2 | +----------------------------------------------------------------------+
3 | | PHP Version 5 |
4 | +----------------------------------------------------------------------+
5 | | Copyright (c) 1997-2007 The PHP Group |
6 | +----------------------------------------------------------------------+
7 | | This source file is subject to version 3.01 of the PHP license, |
8 | | that is bundled with this package in the file LICENSE, and is |
9 | | available through the world-wide-web at the following url: |
10 | | http://www.php.net/license/3_01.txt |
11 | | If you did not receive a copy of the PHP license and are unable to |
12 | | obtain it through the world-wide-web, please send a note to |
13 | | license@php.net so we can mail you a copy immediately. |
14 | +----------------------------------------------------------------------+
15 | | Author: Liexusong |
16 | | maben |
17 | +----------------------------------------------------------------------+
18 | */
19 |
20 | /* $Id: header,v 1.16.2.1.2.1 2007/01/01 19:32:09 iliaa Exp $ */
21 |
22 | #ifdef HAVE_CONFIG_H
23 | #include "config.h"
24 | #endif
25 |
26 | #include
27 | #include
28 | #include
29 | #include
30 | #include
31 |
32 | typedef struct yy_buffer_state *YY_BUFFER_STATE;
33 |
34 | #include "zend.h"
35 | #include "zend_operators.h"
36 | #include "zend_globals.h"
37 | #include "zend_highlight.h"
38 | #include "zend_language_scanner.h"
39 |
40 | #include "zend_API.h"
41 | #include "zend_compile.h"
42 |
43 | #include "php.h"
44 | #include "php_main.h"
45 | #include "php_globals.h"
46 | #include "php_ini.h"
47 | #include "main/SAPI.h"
48 | #include "ext/standard/info.h"
49 | #include "ext/date/php_date.h"
50 | #include "php_streams.h"
51 | #include "php_beast.h"
52 | #include "beast_mm.h"
53 | #include "cache.h"
54 | #include "beast_log.h"
55 | #include "beast_module.h"
56 | #include "file_handler.h"
57 |
58 | #ifdef PHP_WIN32
59 | #include
60 | #include
61 | #pragma comment(lib, PHP_LIB)
62 | #pragma comment(lib, "Iphlpapi.lib")
63 | #else
64 | #include
65 | #include
66 | #include
67 | #endif
68 |
69 | #if ZEND_MODULE_API_NO >= 20151012
70 | # define BEAST_RETURN_STRING(str, dup) RETURN_STRING(str)
71 | #else
72 | # define BEAST_RETURN_STRING(str, dup) RETURN_STRING(str, dup)
73 | #endif
74 |
75 | #define BEAST_VERSION "2.7"
76 | #define DEFAULT_CACHE_SIZE 10485760 /* 10MB */
77 | #define HEADER_MAX_SIZE 256
78 | #define INT_SIZE (sizeof(int))
79 |
80 | extern struct beast_ops *ops_handler_list[];
81 |
82 | /*
83 | * Global vaiables for extension
84 | */
85 | char *beast_log_file = NULL;
86 | char *beast_log_user = NULL;
87 | int log_level = beast_log_notice;
88 | int beast_ncpu = 1;
89 | int beast_is_root = 0;
90 | int beast_pid = -1;
91 |
92 | /* True global resources - no need for thread safety here */
93 | static zend_op_array* (*old_compile_file)(zend_file_handle*, int TSRMLS_DC);
94 |
95 | static int le_beast;
96 | static int max_cache_size = DEFAULT_CACHE_SIZE;
97 | static int beast_enable = 1;
98 | static int beast_max_filesize = 0;
99 | static char *local_networkcard = NULL;
100 | static int beast_now_time = 0;
101 | static int log_normal_file = 0;
102 | static char *beast_debug_path = NULL;
103 | static int beast_debug_mode = 0;
104 |
105 | /* {{{ beast_functions[]
106 | *
107 | * Every user visible function must have an entry in beast_functions[].
108 | */
109 | zend_function_entry beast_functions[] = {
110 | PHP_FE(beast_encode_file, NULL)
111 | PHP_FE(beast_avail_cache, NULL)
112 | PHP_FE(beast_support_filesize, NULL)
113 | PHP_FE(beast_file_expire, NULL)
114 | PHP_FE(beast_clean_cache, NULL)
115 | {NULL, NULL, NULL} /* Must be the last line in beast_functions[] */
116 | };
117 | /* }}} */
118 |
119 | /* {{{ beast_module_entry
120 | */
121 | zend_module_entry beast_module_entry = {
122 | #if ZEND_MODULE_API_NO >= 20010901
123 | STANDARD_MODULE_HEADER,
124 | #endif
125 | "beast",
126 | beast_functions,
127 | PHP_MINIT(beast),
128 | PHP_MSHUTDOWN(beast),
129 | PHP_RINIT(beast),
130 | PHP_RSHUTDOWN(beast),
131 | PHP_MINFO(beast),
132 | #if ZEND_MODULE_API_NO >= 20010901
133 | BEAST_VERSION, /* Replace with version number for your extension */
134 | #endif
135 | STANDARD_MODULE_PROPERTIES
136 | };
137 | /* }}} */
138 |
139 | #ifdef COMPILE_DL_BEAST
140 | ZEND_GET_MODULE(beast)
141 | #endif
142 |
143 | extern struct file_handler tmpfile_handler;
144 | extern struct file_handler pipe_handler;
145 |
146 | static struct file_handler *default_file_handler = NULL;
147 | static struct file_handler *file_handlers[] = {
148 | &tmpfile_handler,
149 | #ifndef PHP_WIN32
150 | &pipe_handler,
151 | #endif
152 | NULL
153 | };
154 |
155 | extern char encrypt_file_header_sign[];
156 | extern int encrypt_file_header_length;
157 | extern char *file_handler_switch;
158 |
159 | #define swab32(x) \
160 | ((x & 0x000000FF) << 24 | (x & 0x0000FF00) << 8 | \
161 | (x & 0x00FF0000) >> 8 | (x & 0xFF000000) >> 24)
162 |
163 |
164 | #define little_endian() (!big_endian())
165 |
166 | static int big_endian()
167 | {
168 | unsigned short num = 0x1122;
169 |
170 | if(*((unsigned char *)&num) == 0x11) {
171 | return 1;
172 | }
173 |
174 | return 0;
175 | }
176 |
177 |
178 | int filter_code_comments(char *filename, zval *retval TSRMLS_DC)
179 | {
180 | zend_lex_state original_lex_state;
181 | zend_file_handle file_handle = {0};
182 |
183 | #if PHP_API_VERSION > 20090626
184 |
185 | php_output_start_default(TSRMLS_C);
186 |
187 | file_handle.type = ZEND_HANDLE_FILENAME;
188 | file_handle.filename = filename;
189 | file_handle.free_filename = 0;
190 | file_handle.opened_path = NULL;
191 |
192 | zend_save_lexical_state(&original_lex_state TSRMLS_CC);
193 | if (open_file_for_scanning(&file_handle TSRMLS_CC) == FAILURE) {
194 | zend_restore_lexical_state(&original_lex_state TSRMLS_CC);
195 | php_output_end(TSRMLS_C);
196 | return -1;
197 | }
198 |
199 | zend_strip(TSRMLS_C);
200 |
201 | zend_destroy_file_handle(&file_handle TSRMLS_CC);
202 | zend_restore_lexical_state(&original_lex_state TSRMLS_CC);
203 |
204 | php_output_get_contents(retval TSRMLS_CC);
205 | php_output_discard(TSRMLS_C);
206 |
207 | #else
208 |
209 | file_handle.type = ZEND_HANDLE_FILENAME;
210 | file_handle.filename = filename;
211 | file_handle.free_filename = 0;
212 | file_handle.opened_path = NULL;
213 |
214 | zend_save_lexical_state(&original_lex_state TSRMLS_CC);
215 | if (open_file_for_scanning(&file_handle TSRMLS_CC) == FAILURE) {
216 | zend_restore_lexical_state(&original_lex_state TSRMLS_CC);
217 | return -1;
218 | }
219 |
220 | php_start_ob_buffer(NULL, 0, 1 TSRMLS_CC);
221 |
222 | zend_strip(TSRMLS_C);
223 |
224 | zend_destroy_file_handle(&file_handle TSRMLS_CC);
225 | zend_restore_lexical_state(&original_lex_state TSRMLS_CC);
226 |
227 | php_ob_get_buffer(retval TSRMLS_CC);
228 | php_end_ob_buffer(0, 0 TSRMLS_CC);
229 |
230 | #endif
231 |
232 | return 0;
233 | }
234 |
235 |
236 | struct beast_ops *beast_get_encrypt_algo(int type)
237 | {
238 | int index = type - 1;
239 |
240 | if (index < 0 || index >= BEAST_ENCRYPT_TYPE_ERROR) {
241 | return ops_handler_list[0];
242 | }
243 |
244 | return ops_handler_list[index];
245 | }
246 |
247 |
248 | /*****************************************************************************
249 | * *
250 | * Encrypt a plain text file and output a cipher file *
251 | * *
252 | *****************************************************************************/
253 |
254 | int encrypt_file(const char *inputfile,
255 | const char *outputfile, int expire,
256 | int encrypt_type TSRMLS_DC)
257 | {
258 | php_stream *output_stream = NULL;
259 | zval codes;
260 | int need_free_code = 0;
261 | char *inbuf, *outbuf;
262 | int inlen, outlen, dumplen, expireval, dumptype;
263 | struct beast_ops *encrypt_ops = beast_get_encrypt_algo(encrypt_type);
264 |
265 | /* Get php codes from script file */
266 | if (filter_code_comments((char *)inputfile, &codes TSRMLS_CC) == -1) {
267 | php_error_docref(NULL TSRMLS_CC, E_ERROR,
268 | "Unable get codes from php file `%s'", inputfile);
269 | return -1;
270 | }
271 |
272 | need_free_code = 1;
273 |
274 | #if ZEND_MODULE_API_NO >= 20151012
275 | inlen = Z_STRLEN(codes);
276 | inbuf = Z_STRVAL(codes);
277 | #else
278 | inlen = codes.value.str.len;
279 | inbuf = codes.value.str.val;
280 | #endif
281 |
282 | /* PHP file size can not large than beast_max_filesize */
283 | if (beast_max_filesize > 0 && inlen > beast_max_filesize) {
284 | return -1;
285 | }
286 |
287 | /* Open output file */
288 | #if ZEND_MODULE_API_NO >= 20151012
289 | output_stream = php_stream_open_wrapper((char *)outputfile, "w+",
290 | IGNORE_URL_WIN|REPORT_ERRORS, NULL);
291 | #else
292 | output_stream = php_stream_open_wrapper((char *)outputfile, "w+",
293 | ENFORCE_SAFE_MODE|REPORT_ERRORS, NULL);
294 | #endif
295 |
296 | if (!output_stream) {
297 | php_error_docref(NULL TSRMLS_CC, E_ERROR,
298 | "Unable to open file `%s'", outputfile);
299 | goto failed;
300 | }
301 |
302 | /* if computer is little endian, change file size to big endian */
303 | if (little_endian()) {
304 | dumplen = swab32(inlen);
305 | expireval = swab32(expire);
306 | dumptype = swab32(encrypt_type);
307 |
308 | } else {
309 | dumplen = inlen;
310 | expireval = expire;
311 | dumptype = encrypt_type;
312 | }
313 |
314 | php_stream_write(output_stream,
315 | encrypt_file_header_sign, encrypt_file_header_length);
316 | php_stream_write(output_stream, (const char *)&dumplen, INT_SIZE);
317 | php_stream_write(output_stream, (const char *)&expireval, INT_SIZE);
318 | php_stream_write(output_stream, (const char *)&dumptype, INT_SIZE);
319 |
320 | if (encrypt_ops->encrypt(inbuf, inlen, &outbuf, &outlen) == -1) {
321 | php_error_docref(NULL TSRMLS_CC, E_ERROR,
322 | "Unable to encrypt file `%s'", outputfile);
323 | goto failed;
324 | }
325 |
326 | php_stream_write(output_stream, outbuf, outlen);
327 | php_stream_close(output_stream);
328 | zval_dtor(&codes);
329 |
330 | if (encrypt_ops->free) {
331 | encrypt_ops->free(outbuf);
332 | }
333 |
334 | return 0;
335 |
336 | failed:
337 | if (output_stream)
338 | php_stream_close(output_stream);
339 | if (need_free_code)
340 | zval_dtor(&codes);
341 | return -1;
342 | }
343 |
344 |
345 | /*****************************************************************************
346 | * *
347 | * Decrypt a cipher text file and output plain buffer *
348 | * *
349 | *****************************************************************************/
350 |
351 | int decrypt_file(const char *filename, int stream,
352 | char **retbuf, int *retlen, int *free_buffer,
353 | struct beast_ops **ret_encrypt TSRMLS_DC)
354 | {
355 | struct stat stat_ssb;
356 | cache_key_t findkey;
357 | cache_item_t *cache;
358 | int reallen, bodylen, expire;
359 | char header[HEADER_MAX_SIZE];
360 | int headerlen;
361 | char *buffer = NULL, *decbuf;
362 | int declen;
363 | int entype;
364 | struct beast_ops *encrypt_ops;
365 | int retval = -1;
366 | int n = 0;
367 | int filesize = 0;
368 |
369 | #ifdef PHP_WIN32
370 | ULARGE_INTEGER ull;
371 | BY_HANDLE_FILE_INFORMATION fileinfo;
372 | HANDLE hFile = (HANDLE)_get_osfhandle(stream);
373 | if (!GetFileInformationByHandle(hFile, &fileinfo)) {
374 | beast_write_log(beast_log_error,
375 | "Failed to get file information from file `%s'", filename);
376 | retval = -1;
377 | goto failed;
378 | }
379 | findkey.device = fileinfo.dwVolumeSerialNumber;
380 | findkey.inode = fileinfo.nFileIndexHigh * (MAXDWORD + 1) + fileinfo.nFileIndexLow;
381 |
382 |
383 | ull.LowPart = fileinfo.ftLastWriteTime.dwLowDateTime;
384 | ull.HighPart = fileinfo.ftLastWriteTime.dwHighDateTime;
385 |
386 | findkey.mtime = ull.QuadPart / 10000000ULL - 11644473600ULL;
387 | filesize = fileinfo.nFileSizeHigh * (MAXDWORD + 1) + fileinfo.nFileSizeLow;
388 |
389 | #else
390 | if (fstat(stream, &stat_ssb) == -1) {
391 | beast_write_log(beast_log_error,
392 | "Failed to readed state buffer from file `%s'", filename);
393 | retval = -1;
394 | goto failed;
395 | }
396 | findkey.device = stat_ssb.st_dev;
397 | findkey.inode = stat_ssb.st_ino;
398 | findkey.mtime = stat_ssb.st_mtime;
399 | filesize = stat_ssb.st_size;
400 | #endif
401 |
402 | /**
403 | * 1) 1 int is dump length,
404 | * 2) 1 int is expire time.
405 | * 3) 1 int is encrypt type.
406 | */
407 | headerlen = encrypt_file_header_length + INT_SIZE * 3;
408 |
409 | if (filesize < headerlen) { /* This file is not a encrypt file */
410 | retval = -1;
411 | goto failed;
412 | }
413 |
414 | cache = beast_cache_find(&findkey);
415 |
416 | if (cache != NULL) { /* Found cache */
417 | *retbuf = beast_cache_data(cache);
418 | *retlen = beast_cache_size(cache);
419 | return 0;
420 | }
421 |
422 | *free_buffer = 0; /* Set free buffer flag to false */
423 |
424 | /* Not found cache and decrypt file */
425 |
426 | if ((n = read(stream, header, headerlen)) != headerlen) {
427 | beast_write_log(beast_log_error,
428 | "Failed to readed header from file `%s', headerlen:%d, readlen:%d",
429 | filename, headerlen, n);
430 | retval = -1;
431 | goto failed;
432 | }
433 |
434 | /* Not a encrypted file */
435 | if (memcmp(header,
436 | encrypt_file_header_sign,
437 | encrypt_file_header_length))
438 | {
439 | if (log_normal_file) {
440 | beast_write_log(beast_log_error,
441 | "File `%s' isn't a encrypted file", filename);
442 | }
443 |
444 | retval = -1;
445 | goto failed;
446 | }
447 |
448 | /* Real php script file's size */
449 | reallen = *((int *)&header[encrypt_file_header_length]);
450 | expire = *((int *)&header[encrypt_file_header_length + INT_SIZE]);
451 | entype = *((int *)&header[encrypt_file_header_length + 2 * INT_SIZE]);
452 |
453 | if (little_endian()) {
454 | reallen = swab32(reallen);
455 | expire = swab32(expire);
456 | entype = swab32(entype);
457 | }
458 |
459 | /* Check file size is vaild */
460 | if (beast_max_filesize > 0 && reallen > beast_max_filesize) {
461 | beast_write_log(beast_log_error,
462 | "File size `%d' out of max size `%d'",
463 | reallen, beast_max_filesize);
464 | retval = -1;
465 | goto failed;
466 | }
467 |
468 | /* Check file is not expired */
469 | if (expire > 0 && expire < beast_now_time) {
470 | beast_write_log(beast_log_error, "File `%s' was expired", filename);
471 | retval = -2;
472 | goto failed;
473 | }
474 |
475 | *ret_encrypt = encrypt_ops = beast_get_encrypt_algo(entype);
476 |
477 | /**
478 | * How many bytes would be read from encrypt file,
479 | * subtract encrypt file's header size,
480 | * because we had read the header yet.
481 | */
482 |
483 | bodylen = filesize - headerlen;
484 |
485 | /* 1) Alloc memory for decrypt file */
486 | if (!(buffer = malloc(bodylen))) {
487 | beast_write_log(beast_log_error,
488 | "Failed to alloc memory to file `%s' size `%d'",
489 | filename, bodylen);
490 | retval = -1;
491 | goto failed;
492 | }
493 |
494 | /* 2) Read file stream */
495 | if (read(stream, buffer, bodylen) != bodylen) {
496 | beast_write_log(beast_log_error,
497 | "Failed to readed stream from file `%s'", filename);
498 | retval = -1;
499 | goto failed;
500 | }
501 |
502 | /* 3) Decrypt file stream */
503 | if (encrypt_ops->decrypt(buffer, bodylen, &decbuf, &declen) == -1) {
504 | beast_write_log(beast_log_error,
505 | "Failed to decrypted file `%s', using `%s' handler",
506 | filename, encrypt_ops->name);
507 | retval = -1;
508 | goto failed;
509 | }
510 |
511 | free(buffer); /* Buffer don't need right now and free it */
512 |
513 | findkey.fsize = reallen; /* How many size would we alloc from cache */
514 |
515 | /* Try to add decrypt result to cache */
516 | if ((cache = beast_cache_create(&findkey))) {
517 |
518 | memcpy(beast_cache_data(cache), decbuf, reallen);
519 |
520 | cache = beast_cache_push(cache); /* Push cache into hash table */
521 |
522 | *retbuf = beast_cache_data(cache);
523 | *retlen = beast_cache_size(cache);
524 |
525 | if (encrypt_ops->free) {
526 | encrypt_ops->free(decbuf);
527 | }
528 |
529 | } else { /* Return raw buffer and we need free after PHP finished */
530 |
531 | *retbuf = decbuf;
532 | *retlen = reallen;
533 |
534 | *free_buffer = 1;
535 | }
536 |
537 | return 0;
538 |
539 | failed:
540 | if (buffer) {
541 | free(buffer);
542 | }
543 |
544 | return retval;
545 | }
546 |
547 |
548 | int beast_super_mkdir(char *path)
549 | {
550 | char *head, *last;
551 | char temp[1024];
552 |
553 | for (head = last = path; *last; last++) {
554 |
555 | if (*last == '/') {
556 |
557 | if (last > head) {
558 |
559 | memset(temp, 0, 1024);
560 | memcpy(temp, path, last - path);
561 |
562 | if (access(temp, F_OK) == -1) {
563 | if (mkdir(temp, 0777) != 0) {
564 | beast_write_log(beast_log_error,
565 | "Failed to make new directory `%s'",
566 | temp);
567 | return -1;
568 | }
569 | }
570 | }
571 |
572 | head = last + 1;
573 | }
574 | }
575 |
576 | return 0;
577 | }
578 |
579 |
580 | /*
581 | * CGI compile file
582 | */
583 | zend_op_array *
584 | cgi_compile_file(zend_file_handle *h, int type TSRMLS_DC)
585 | {
586 | #if ZEND_MODULE_API_NO >= 20151012
587 | zend_string *opened_path;
588 | #else
589 | char *opened_path;
590 | #endif
591 | char *buf;
592 | int fd;
593 | FILE *fp = NULL;
594 | int size, free_buffer = 0;
595 | int retval;
596 | struct beast_ops *ops = NULL;
597 | int destroy_file_handler = 0;
598 |
599 | #if 0
600 | fp = zend_fopen(h->filename, &opened_path TSRMLS_CC);
601 | #else
602 | fp = fopen(h->filename, "rb");
603 | #endif
604 | if (fp != NULL) {
605 | fd = fileno(fp);
606 | } else {
607 | goto final;
608 | }
609 |
610 | retval = decrypt_file(h->filename, fd, &buf, &size,
611 | &free_buffer, &ops TSRMLS_CC);
612 | if (retval == -2) {
613 | php_error_docref(NULL TSRMLS_CC, E_ERROR,
614 | "This program was expired, please contact administrator");
615 | return NULL;
616 | }
617 |
618 | if (retval == -1) {
619 | #if BEAST_EXECUTE_NORMAL_SCRIPT
620 | goto final;
621 | #else
622 | php_error_docref(NULL TSRMLS_CC, E_ERROR,
623 | "Not allow execute normal PHP script");
624 | return NULL;
625 | #endif
626 | }
627 |
628 | #if BEAST_DEBUG_MODE
629 |
630 | if (beast_debug_mode && beast_debug_path) {
631 |
632 | if (access(beast_debug_path, F_OK) == 0) {
633 |
634 | char realpath[1024];
635 |
636 | sprintf(realpath, "%s/%s", beast_debug_path, h->filename);
637 |
638 | if (beast_super_mkdir(realpath) == 0) {
639 |
640 | FILE *debug_fp = fopen(realpath, "w+");
641 |
642 | if (debug_fp) {
643 | fwrite(buf, size, 1, debug_fp);
644 | fclose(debug_fp);
645 | }
646 | }
647 | }
648 | }
649 |
650 | #endif
651 |
652 | if (default_file_handler->open(default_file_handler) == -1 ||
653 | default_file_handler->write(default_file_handler, buf, size) == -1 ||
654 | default_file_handler->rewind(default_file_handler) == -1)
655 | {
656 | destroy_file_handler = 1;
657 | goto final;
658 | }
659 |
660 | if (h->type == ZEND_HANDLE_FP) fclose(h->handle.fp);
661 | #ifdef ZEND_HANDLE_FD
662 | if (h->type == ZEND_HANDLE_FD) close(h->handle.fd);
663 | #endif
664 | /*
665 | * Get file handler and free context
666 | */
667 | switch (default_file_handler->type) {
668 | case BEAST_FILE_HANDLER_FP:
669 | h->type = ZEND_HANDLE_FP;
670 | h->handle.fp = default_file_handler->get_fp(default_file_handler);
671 | break;
672 | #ifdef ZEND_HANDLE_FD
673 | case BEAST_FILE_HANDLER_FD:
674 | h->type = ZEND_HANDLE_FD;
675 | h->handle.fd = default_file_handler->get_fd(default_file_handler);
676 | break;
677 | #endif
678 | }
679 |
680 | final:
681 | if (free_buffer && ops) {
682 | if (ops->free) {
683 | ops->free(buf);
684 | }
685 | }
686 |
687 | if (fp) fclose(fp);
688 |
689 | if (destroy_file_handler) {
690 | default_file_handler->destroy(default_file_handler);
691 | }
692 |
693 | return old_compile_file(h, type TSRMLS_CC);
694 | }
695 |
696 |
697 | /* Configure entries */
698 |
699 | void beast_atoi(const char *str, int *ret, int *len)
700 | {
701 | const char *ptr = str;
702 | char ch;
703 | int absolute = 1;
704 | int rlen, result;
705 |
706 | ch = *ptr;
707 |
708 | if (ch == '-') {
709 | absolute = -1;
710 | ++ptr;
711 | } else if (ch == '+') {
712 | absolute = 1;
713 | ++ptr;
714 | }
715 |
716 | for (rlen = 0, result = 0; *ptr != '\0'; ptr++) {
717 | ch = *ptr;
718 |
719 | if (ch >= '0' && ch <= '9') {
720 | result = result * 10 + (ch - '0');
721 | rlen++;
722 | } else {
723 | break;
724 | }
725 | }
726 |
727 | if (ret) *ret = absolute * result;
728 | if (len) *len = rlen;
729 | }
730 |
731 | ZEND_INI_MH(php_beast_cache_size)
732 | {
733 | #if ZEND_MODULE_API_NO >= 20151012
734 |
735 | char *value = ZSTR_VAL(new_value);
736 | int length = ZSTR_LEN(new_value);
737 | int retlen;
738 |
739 | if (length == 0) {
740 | return FAILURE;
741 | }
742 |
743 | beast_atoi(value, &max_cache_size, &retlen);
744 |
745 | if (retlen > 0 && retlen < length) {
746 | switch (value[retlen]) {
747 | case 'k':
748 | case 'K':
749 | max_cache_size *= 1024;
750 | break;
751 | case 'm':
752 | case 'M':
753 | max_cache_size *= 1024 * 1024;
754 | break;
755 | case 'g':
756 | case 'G':
757 | max_cache_size *= 1024 * 1024 * 1024;
758 | break;
759 | default:
760 | return FAILURE;
761 | }
762 |
763 | } else if (retlen == 0) {
764 | return FAILURE;
765 | }
766 |
767 | return SUCCESS;
768 |
769 | #else
770 |
771 | int len;
772 |
773 | if (new_value_length == 0) {
774 | return FAILURE;
775 | }
776 |
777 | beast_atoi(new_value, &max_cache_size, &len);
778 |
779 | if (len > 0 && len < new_value_length) {
780 | switch (new_value[len]) {
781 | case 'k':
782 | case 'K':
783 | max_cache_size *= 1024;
784 | break;
785 | case 'm':
786 | case 'M':
787 | max_cache_size *= 1024 * 1024;
788 | break;
789 | case 'g':
790 | case 'G':
791 | max_cache_size *= 1024 * 1024 * 1024;
792 | break;
793 | default:
794 | return FAILURE;
795 | }
796 |
797 | } else if (len == 0) {
798 | return FAILURE;
799 | }
800 |
801 | return SUCCESS;
802 |
803 | #endif
804 | }
805 |
806 | ZEND_INI_MH(php_beast_log_file)
807 | {
808 | #if ZEND_MODULE_API_NO >= 20151012
809 |
810 | if (ZSTR_LEN(new_value) == 0) {
811 | return SUCCESS;
812 | }
813 |
814 | beast_log_file = estrdup(ZSTR_VAL(new_value));
815 | if (beast_log_file == NULL) {
816 | return FAILURE;
817 | }
818 |
819 | return SUCCESS;
820 |
821 | #else
822 |
823 | if (new_value_length == 0) {
824 | return SUCCESS;
825 | }
826 |
827 | beast_log_file = strdup(new_value);
828 | if (beast_log_file == NULL) {
829 | return FAILURE;
830 | }
831 |
832 | return SUCCESS;
833 |
834 | #endif
835 | }
836 |
837 |
838 | ZEND_INI_MH(php_beast_log_user)
839 | {
840 | #if ZEND_MODULE_API_NO >= 20151012
841 |
842 | if (ZSTR_LEN(new_value) == 0) {
843 | return SUCCESS;
844 | }
845 |
846 | beast_log_user = estrdup(ZSTR_VAL(new_value));
847 | if (beast_log_user == NULL) {
848 | return FAILURE;
849 | }
850 |
851 | return SUCCESS;
852 |
853 | #else
854 |
855 | if (new_value_length == 0) {
856 | return SUCCESS;
857 | }
858 |
859 | beast_log_user = strdup(new_value);
860 | if (beast_log_user == NULL) {
861 | return FAILURE;
862 | }
863 |
864 | return SUCCESS;
865 |
866 | #endif
867 | }
868 |
869 | ZEND_INI_MH(php_beast_log_level)
870 | {
871 | char *level = NULL;
872 | #if ZEND_MODULE_API_NO >= 20151012
873 |
874 | if (ZSTR_LEN(new_value) == 0) {
875 | return SUCCESS;
876 | }
877 |
878 | level = ZSTR_VAL(new_value);
879 |
880 | #else
881 |
882 | if (new_value_length == 0) {
883 | return SUCCESS;
884 | }
885 |
886 | level = new_value;
887 |
888 | #endif
889 | if (level == NULL) {
890 | return FAILURE;
891 | }
892 |
893 | if (strcasecmp(level, "debug") == 0) {
894 | log_level = beast_log_debug;
895 | } else if (strcasecmp(level, "notice") == 0) {
896 | log_level = beast_log_notice;
897 | } else if (strcasecmp(level, "error") == 0) {
898 | log_level = beast_log_error;
899 | } else {
900 | return FAILURE;
901 | }
902 |
903 | return SUCCESS;
904 | }
905 |
906 |
907 | ZEND_INI_MH(php_beast_enable)
908 | {
909 | #if ZEND_MODULE_API_NO >= 20151012
910 |
911 | if (ZSTR_LEN(new_value) == 0) {
912 | return FAILURE;
913 | }
914 |
915 | if (!strcasecmp(ZSTR_VAL(new_value), "on")
916 | || !strcmp(ZSTR_VAL(new_value), "1"))
917 | {
918 | beast_enable = 1;
919 | } else {
920 | beast_enable = 0;
921 | }
922 |
923 | return SUCCESS;
924 |
925 | #else
926 |
927 | if (new_value_length == 0) {
928 | return FAILURE;
929 | }
930 |
931 | if (!strcasecmp(new_value, "on")
932 | || !strcmp(new_value, "1"))
933 | {
934 | beast_enable = 1;
935 | } else {
936 | beast_enable = 0;
937 | }
938 |
939 | return SUCCESS;
940 | #endif
941 | }
942 |
943 |
944 | ZEND_INI_MH(php_beast_set_networkcard)
945 | {
946 | #if ZEND_MODULE_API_NO >= 20151012
947 |
948 | if (ZSTR_LEN(new_value) == 0) {
949 | return FAILURE;
950 | }
951 |
952 | local_networkcard = estrdup(ZSTR_VAL(new_value));
953 | if (local_networkcard == NULL) {
954 | return FAILURE;
955 | }
956 |
957 | return SUCCESS;
958 |
959 | #else
960 |
961 | if (new_value_length == 0) {
962 | return FAILURE;
963 | }
964 |
965 | local_networkcard = strdup(new_value);
966 | if (local_networkcard == NULL) {
967 | return FAILURE;
968 | }
969 |
970 | return SUCCESS;
971 |
972 | #endif
973 | }
974 |
975 |
976 | ZEND_INI_MH(php_beast_set_log_normal_file)
977 | {
978 | #if ZEND_MODULE_API_NO >= 20151012
979 |
980 | if (ZSTR_LEN(new_value) == 0) {
981 | return FAILURE;
982 | }
983 |
984 | if (!strcasecmp(ZSTR_VAL(new_value), "on")
985 | || !strcmp(ZSTR_VAL(new_value), "1"))
986 | {
987 | log_normal_file = 1;
988 | } else {
989 | log_normal_file = 0;
990 | }
991 |
992 | return SUCCESS;
993 |
994 | #else
995 |
996 | if (new_value_length == 0) {
997 | return FAILURE;
998 | }
999 |
1000 | if (!strcasecmp(new_value, "on")
1001 | || !strcmp(new_value, "1"))
1002 | {
1003 | log_normal_file = 1;
1004 | } else {
1005 | log_normal_file = 0;
1006 | }
1007 |
1008 | return SUCCESS;
1009 |
1010 | #endif
1011 | }
1012 |
1013 |
1014 | ZEND_INI_MH(php_beast_debug_path)
1015 | {
1016 | #if ZEND_MODULE_API_NO >= 20151012
1017 |
1018 | if (ZSTR_LEN(new_value) == 0) {
1019 | return SUCCESS;
1020 | }
1021 |
1022 | beast_debug_path = estrdup(ZSTR_VAL(new_value));
1023 | if (beast_debug_path == NULL) {
1024 | return FAILURE;
1025 | }
1026 |
1027 | return SUCCESS;
1028 |
1029 | #else
1030 |
1031 | if (new_value_length == 0) {
1032 | return SUCCESS;
1033 | }
1034 |
1035 | beast_debug_path = strdup(new_value);
1036 | if (beast_debug_path == NULL) {
1037 | return FAILURE;
1038 | }
1039 |
1040 | return SUCCESS;
1041 |
1042 | #endif
1043 | }
1044 |
1045 |
1046 | ZEND_INI_MH(php_beast_debug_mode)
1047 | {
1048 | #if ZEND_MODULE_API_NO >= 20151012
1049 |
1050 | if (ZSTR_LEN(new_value) == 0) {
1051 | return FAILURE;
1052 | }
1053 |
1054 | if (!strcasecmp(ZSTR_VAL(new_value), "on")
1055 | || !strcmp(ZSTR_VAL(new_value), "1"))
1056 | {
1057 | beast_debug_mode = 1;
1058 | } else {
1059 | beast_debug_mode = 0;
1060 | }
1061 |
1062 | return SUCCESS;
1063 |
1064 | #else
1065 |
1066 | if (new_value_length == 0) {
1067 | return FAILURE;
1068 | }
1069 |
1070 | if (!strcasecmp(new_value, "on")
1071 | || !strcmp(new_value, "1"))
1072 | {
1073 | beast_debug_mode = 1;
1074 | } else {
1075 | beast_debug_mode = 0;
1076 | }
1077 |
1078 | return SUCCESS;
1079 |
1080 | #endif
1081 | }
1082 |
1083 |
1084 | PHP_INI_BEGIN()
1085 | PHP_INI_ENTRY("beast.cache_size", "10485760", PHP_INI_ALL,
1086 | php_beast_cache_size)
1087 | PHP_INI_ENTRY("beast.log_file", "./php-beast.log", PHP_INI_ALL,
1088 | php_beast_log_file)
1089 | PHP_INI_ENTRY("beast.log_user", "root", PHP_INI_ALL,
1090 | php_beast_log_user)
1091 | PHP_INI_ENTRY("beast.log_level", "notice", PHP_INI_ALL,
1092 | php_beast_log_level)
1093 | PHP_INI_ENTRY("beast.enable", "1", PHP_INI_ALL,
1094 | php_beast_enable)
1095 | PHP_INI_ENTRY("beast.networkcard", "eth0", PHP_INI_ALL,
1096 | php_beast_set_networkcard)
1097 | PHP_INI_ENTRY("beast.log_normal_file", "0", PHP_INI_ALL,
1098 | php_beast_set_log_normal_file)
1099 | #if BEAST_DEBUG_MODE
1100 | PHP_INI_ENTRY("beast.debug_path", "/tmp", PHP_INI_ALL,
1101 | php_beast_debug_path)
1102 | PHP_INI_ENTRY("beast.debug_mode", "0", PHP_INI_ALL,
1103 | php_beast_debug_mode)
1104 | #endif
1105 | PHP_INI_END()
1106 |
1107 | /* }}} */
1108 |
1109 |
1110 | void segmentfault_deadlock_fix(int sig)
1111 | {
1112 | #ifdef PHP_WIN32 // windows not support backtrace
1113 | beast_write_log(beast_log_error, "Segmentation fault and fix deadlock");
1114 | #else
1115 | void *array[10] = {0};
1116 | size_t size;
1117 | char **info = NULL;
1118 | int i;
1119 |
1120 | size = backtrace(array, 10);
1121 | info = backtrace_symbols(array, (int)size);
1122 |
1123 | beast_write_log(beast_log_error, "Segmentation fault and fix deadlock");
1124 |
1125 | if (info) {
1126 | for (i = 0; i < size; i++) {
1127 | beast_write_log(beast_log_error, info[i]);
1128 | }
1129 | free(info);
1130 | }
1131 | #endif
1132 | beast_mm_unlock(); /* Maybe lock mm so free here */
1133 | beast_cache_unlock(); /* Maybe lock cache so free here */
1134 |
1135 | exit(sig);
1136 | }
1137 |
1138 |
1139 | static char *get_mac_address(char *networkcard)
1140 | {
1141 | #ifdef PHP_WIN32
1142 |
1143 | // For windows
1144 | ULONG size = sizeof(IP_ADAPTER_INFO);
1145 | int ret, i;
1146 | char *address = NULL;
1147 | char buf[128] = { 0 }, *pos;
1148 |
1149 | PIP_ADAPTER_INFO pCurrentAdapter = NULL;
1150 | PIP_ADAPTER_INFO pIpAdapterInfo = (PIP_ADAPTER_INFO)malloc(sizeof(*pIpAdapterInfo));
1151 | if (!pIpAdapterInfo) {
1152 | beast_write_log(beast_log_error, "Failed to allocate memory for IP_ADAPTER_INFO");
1153 | return NULL;
1154 | }
1155 |
1156 | ret = GetAdaptersInfo(pIpAdapterInfo, &size);
1157 | if (ERROR_BUFFER_OVERFLOW == ret) {
1158 | // see ERROR_BUFFER_OVERFLOW https://msdn.microsoft.com/en-us/library/aa365917(VS.85).aspx
1159 | free(pIpAdapterInfo);
1160 | pIpAdapterInfo = (PIP_ADAPTER_INFO)malloc(size);
1161 |
1162 | ret = GetAdaptersInfo(pIpAdapterInfo, &size);
1163 | }
1164 |
1165 | if (ERROR_SUCCESS != ret) {
1166 | beast_write_log(beast_log_error, "Failed to get network adapter information");
1167 | free(pIpAdapterInfo);
1168 | return NULL;
1169 | }
1170 |
1171 | pCurrentAdapter = pIpAdapterInfo;
1172 | do {
1173 | if (strcmp(pCurrentAdapter->AdapterName, networkcard) == 0) {
1174 | for (i = 0, pos = buf; i < pCurrentAdapter->AddressLength; i++, pos += 3) {
1175 | sprintf(pos, "%.2X-", (int)pCurrentAdapter->Address[i]);
1176 | }
1177 | *(--pos) = '\0'; // remove last -
1178 | address = strdup(buf);
1179 | break;
1180 | }
1181 | pCurrentAdapter = pCurrentAdapter->Next;
1182 | } while (pCurrentAdapter);
1183 |
1184 | free(pIpAdapterInfo);
1185 | return address;
1186 |
1187 | #else
1188 |
1189 | // For linux / unix
1190 | char netfile[128] = { 0 }, cmd[128] = { 0 }, buf[128] = { 0 };
1191 | FILE *fp;
1192 | char *retbuf, *curr, *last;
1193 |
1194 | snprintf(netfile, 128, "/sys/class/net/%s/address", networkcard);
1195 |
1196 | if (access((const char *)netfile, R_OK) != 0) { /* File not exists */
1197 | snprintf(cmd, 128, "ifconfig %s|awk '/ether/ {print $2}'", networkcard);
1198 | } else {
1199 | snprintf(cmd, 128, "cat %s", netfile);
1200 | }
1201 |
1202 | fp = popen(cmd, "r");
1203 | if (!fp) {
1204 | return NULL;
1205 | }
1206 |
1207 | retbuf = fgets(buf, 128, fp);
1208 |
1209 | for (curr = buf, last = NULL; *curr; curr++) {
1210 | if (*curr != '\n') {
1211 | last = curr;
1212 | }
1213 | }
1214 |
1215 | if (!last) {
1216 | return NULL;
1217 | }
1218 |
1219 | for (last += 1; *last; last++) {
1220 | *last = '\0';
1221 | }
1222 |
1223 | pclose(fp);
1224 |
1225 | return strdup(buf);
1226 |
1227 | #endif
1228 | }
1229 |
1230 | static int validate_networkcard()
1231 | {
1232 | extern char *allow_networkcards[];
1233 | char **ptr;
1234 | char *networkcard_start, *networkcard_end;
1235 | int endof_networkcard = 0;
1236 | int active = 0;
1237 | char *address;
1238 |
1239 | for (ptr = allow_networkcards; *ptr; ptr++, active++);
1240 |
1241 | if (!active) {
1242 | return 0;
1243 | }
1244 |
1245 | networkcard_start = networkcard_end = local_networkcard;
1246 |
1247 | while (1) {
1248 | while (*networkcard_end && *networkcard_end != ',') {
1249 | networkcard_end++;
1250 | }
1251 |
1252 | if (networkcard_start == networkcard_end) { /* empty string */
1253 | break;
1254 | }
1255 |
1256 | if (*networkcard_end == ',') {
1257 | *networkcard_end = '\0';
1258 | }
1259 | else {
1260 | endof_networkcard = 1;
1261 | }
1262 |
1263 | address = get_mac_address(networkcard_start);
1264 | if (address) {
1265 | for (ptr = allow_networkcards; *ptr; ptr++) {
1266 | if (!strcasecmp(address, *ptr)) {
1267 | free(address); /* release buffer */
1268 | return 0;
1269 | }
1270 | }
1271 | free(address);
1272 | }
1273 |
1274 | if (endof_networkcard) {
1275 | break;
1276 | }
1277 |
1278 | networkcard_start = networkcard_end + 1;
1279 | }
1280 |
1281 | return -1;
1282 | }
1283 |
1284 | /* {{{ PHP_MINIT_FUNCTION
1285 | */
1286 | PHP_MINIT_FUNCTION(beast)
1287 | {
1288 | int i;
1289 | #ifdef PHP_WIN32
1290 | SYSTEM_INFO info;
1291 | #endif
1292 |
1293 | /* If you have INI entries, uncomment these lines */
1294 | REGISTER_INI_ENTRIES();
1295 |
1296 | if (!beast_enable) {
1297 | return SUCCESS;
1298 | }
1299 |
1300 | if (validate_networkcard() == -1) {
1301 | php_error_docref(NULL TSRMLS_CC, E_ERROR,
1302 | "Not allow run at this computer");
1303 | return FAILURE;
1304 | }
1305 |
1306 | if ((encrypt_file_header_length + INT_SIZE * 2) > HEADER_MAX_SIZE) {
1307 | php_error_docref(NULL TSRMLS_CC, E_ERROR,
1308 | "Header size overflow max size `%d'", HEADER_MAX_SIZE);
1309 | return FAILURE;
1310 | }
1311 |
1312 | /* Check module support the max file size */
1313 | for (i = 0; ; i++) {
1314 | default_file_handler = file_handlers[i];
1315 | if (!default_file_handler ||
1316 | !strcasecmp(file_handler_switch, default_file_handler->name))
1317 | {
1318 | break;
1319 | }
1320 | }
1321 |
1322 | if (!default_file_handler) {
1323 | return FAILURE;
1324 | }
1325 |
1326 | beast_max_filesize = default_file_handler->check();
1327 | if (beast_max_filesize == -1) {
1328 | return FAILURE;
1329 | }
1330 |
1331 | if (beast_cache_init(max_cache_size) == -1) {
1332 | php_error_docref(NULL TSRMLS_CC,
1333 | E_ERROR, "Unable initialize cache for beast");
1334 | return FAILURE;
1335 | }
1336 |
1337 | if (beast_log_init(beast_log_file, log_level) == -1) {
1338 | php_error_docref(NULL TSRMLS_CC,
1339 | E_ERROR, "Unable open log file for beast");
1340 | return FAILURE;
1341 | }
1342 |
1343 | #ifndef PHP_WIN32
1344 | if (getuid() == 0 && beast_log_user) { /* Change log file owner user */
1345 | struct passwd *pwd;
1346 |
1347 | pwd = getpwnam((const char *)beast_log_user);
1348 | if (!pwd) {
1349 | php_error_docref(NULL TSRMLS_CC,
1350 | E_ERROR, "Unable get user passwd information");
1351 | return FAILURE;
1352 | }
1353 |
1354 | if (beast_log_chown(pwd->pw_uid, pwd->pw_gid) != 0) {
1355 | php_error_docref(NULL TSRMLS_CC,
1356 | E_ERROR, "Unable change log file owner");
1357 | return FAILURE;
1358 | }
1359 | }
1360 | #endif
1361 |
1362 | old_compile_file = zend_compile_file;
1363 | zend_compile_file = cgi_compile_file;
1364 |
1365 | #ifdef PHP_WIN32
1366 | GetSystemInfo(&info);
1367 | beast_ncpu = info.dwNumberOfProcessors;
1368 | #else
1369 | beast_ncpu = sysconf(_SC_NPROCESSORS_ONLN); /* Get CPU nums */
1370 | #endif
1371 | if (beast_ncpu <= 0) {
1372 | beast_ncpu = 1;
1373 | }
1374 |
1375 | signal(SIGSEGV, segmentfault_deadlock_fix);
1376 |
1377 | REGISTER_LONG_CONSTANT("BEAST_ENCRYPT_TYPE_DES",
1378 | BEAST_ENCRYPT_TYPE_DES, CONST_CS|CONST_PERSISTENT);
1379 | REGISTER_LONG_CONSTANT("BEAST_ENCRYPT_TYPE_AES",
1380 | BEAST_ENCRYPT_TYPE_AES, CONST_CS|CONST_PERSISTENT);
1381 | REGISTER_LONG_CONSTANT("BEAST_ENCRYPT_TYPE_BASE64",
1382 | BEAST_ENCRYPT_TYPE_BASE64, CONST_CS|CONST_PERSISTENT);
1383 |
1384 | beast_write_log(beast_log_debug, "Beast module was initialized");
1385 |
1386 | return SUCCESS;
1387 | }
1388 | /* }}} */
1389 |
1390 | /* {{{ PHP_MSHUTDOWN_FUNCTION
1391 | */
1392 | PHP_MSHUTDOWN_FUNCTION(beast)
1393 | {
1394 | /* uncomment this line if you have INI entries */
1395 | UNREGISTER_INI_ENTRIES();
1396 |
1397 | if (!beast_enable) {
1398 | return SUCCESS;
1399 | }
1400 |
1401 | beast_cache_destroy();
1402 | beast_log_destroy();
1403 |
1404 | zend_compile_file = old_compile_file;
1405 |
1406 | return SUCCESS;
1407 | }
1408 | /* }}} */
1409 |
1410 | /* {{{ PHP_RINIT_FUNCTION
1411 | */
1412 | PHP_RINIT_FUNCTION(beast)
1413 | {
1414 | if (beast_pid == -1) {
1415 | beast_pid = getpid();
1416 | }
1417 |
1418 | beast_now_time = time(NULL); /* Update now time */
1419 |
1420 | return SUCCESS;
1421 | }
1422 | /* }}} */
1423 |
1424 | /* {{{ PHP_RSHUTDOWN_FUNCTION
1425 | */
1426 | PHP_RSHUTDOWN_FUNCTION(beast)
1427 | {
1428 | return SUCCESS;
1429 | }
1430 | /* }}} */
1431 |
1432 | /* {{{ PHP_MINFO_FUNCTION
1433 | */
1434 | PHP_MINFO_FUNCTION(beast)
1435 | {
1436 | php_info_print_table_start();
1437 | php_info_print_table_header(2,
1438 | "beast V" BEAST_VERSION " support", "enabled");
1439 | php_info_print_table_end();
1440 |
1441 | DISPLAY_INI_ENTRIES();
1442 | }
1443 | /* }}} */
1444 |
1445 |
1446 | PHP_FUNCTION(beast_file_expire)
1447 | {
1448 | char *file;
1449 | int file_len;
1450 | char header[HEADER_MAX_SIZE] = {0};
1451 | int header_len;
1452 | signed long expire = 0;
1453 | int fd = -1;
1454 | char *string;
1455 | char *format = "Y-m-d H:i:s";
1456 |
1457 | #if ZEND_MODULE_API_NO >= 20151012
1458 |
1459 | zend_string *input_file;
1460 |
1461 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "S",
1462 | &input_file TSRMLS_CC) == FAILURE)
1463 | {
1464 | RETURN_FALSE;
1465 | }
1466 |
1467 | file = ZSTR_VAL(input_file);
1468 | file_len = ZSTR_LEN(input_file);
1469 |
1470 | #else
1471 |
1472 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s",
1473 | &file, &file_len TSRMLS_CC) == FAILURE)
1474 | {
1475 | RETURN_FALSE;
1476 | }
1477 |
1478 | #endif
1479 |
1480 | fd = open(file, O_RDONLY);
1481 | if (fd < 0) {
1482 | goto error;
1483 | }
1484 |
1485 | header_len = encrypt_file_header_length + INT_SIZE * 2;
1486 |
1487 | if (read(fd, header, header_len) != header_len
1488 | || memcmp(header, encrypt_file_header_sign, encrypt_file_header_length))
1489 | {
1490 | goto error;
1491 | }
1492 |
1493 | close(fd);
1494 |
1495 | expire = *((int *)&header[encrypt_file_header_length + INT_SIZE]);
1496 |
1497 | if (little_endian()) {
1498 | expire = swab32(expire);
1499 | }
1500 |
1501 | if (expire > 0) {
1502 | string = (char *)php_format_date(format, strlen(format), expire, 1 TSRMLS_CC);
1503 | BEAST_RETURN_STRING(string, 0);
1504 | } else {
1505 | BEAST_RETURN_STRING("+Infinity", 1);
1506 | }
1507 |
1508 | error:
1509 | if (fd >= 0) {
1510 | close(fd);
1511 | }
1512 |
1513 | RETURN_FALSE;
1514 | }
1515 |
1516 |
1517 | PHP_FUNCTION(beast_encode_file)
1518 | {
1519 | char *input, *output;
1520 | int input_len, output_len;
1521 | long expire = 0;
1522 | long encrypt_type = BEAST_ENCRYPT_TYPE_DES;
1523 | int ret;
1524 |
1525 | #if ZEND_MODULE_API_NO >= 20151012
1526 |
1527 | zend_string *in, *out;
1528 |
1529 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "SS|ll",
1530 | &in, &out, &expire, &encrypt_type) == FAILURE)
1531 | {
1532 | RETURN_FALSE;
1533 | }
1534 |
1535 | input = ZSTR_VAL(in);
1536 | output = ZSTR_VAL(out);
1537 | input_len = ZSTR_LEN(in);
1538 | output_len = ZSTR_LEN(out);
1539 |
1540 | #else
1541 |
1542 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|ll",
1543 | &input, &input_len, &output, &output_len,
1544 | &expire, &encrypt_type TSRMLS_CC) == FAILURE)
1545 | {
1546 | RETURN_FALSE;
1547 | }
1548 |
1549 | #endif
1550 |
1551 | if (encrypt_type <= 0
1552 | || encrypt_type >= BEAST_ENCRYPT_TYPE_ERROR)
1553 | {
1554 | RETURN_FALSE;
1555 | }
1556 |
1557 | ret = encrypt_file(input, output,
1558 | (int)expire, (int)encrypt_type TSRMLS_CC);
1559 | if (ret == -1) {
1560 | RETURN_FALSE;
1561 | }
1562 |
1563 | RETURN_TRUE;
1564 | }
1565 |
1566 |
1567 | PHP_FUNCTION(beast_avail_cache)
1568 | {
1569 | RETURN_LONG(beast_mm_availspace());
1570 | }
1571 |
1572 |
1573 | PHP_FUNCTION(beast_support_filesize)
1574 | {
1575 | RETURN_LONG(beast_max_filesize);
1576 | }
1577 |
1578 |
1579 | PHP_FUNCTION(beast_clean_cache)
1580 | {
1581 | beast_cache_flush();
1582 | }
1583 |
1584 | /*
1585 | * Local variables:
1586 | * tab-width: 4
1587 | * c-basic-offset: 4
1588 | * End:
1589 | * vim600: noet sw=4 ts=4 fdm=marker expandtab
1590 | * vim<600: noet sw=4 ts=4
1591 | */
1592 |
--------------------------------------------------------------------------------
/beast_log.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #ifdef PHP_WIN32
6 |
7 | #else
8 | #include
9 | #endif
10 | #include "main/php_reentrancy.h"
11 | #include "beast_log.h"
12 |
13 | static FILE *beast_log_fp = NULL;
14 | static int log_level = beast_log_notice;
15 |
16 | int beast_log_init(char *log_file, int level)
17 | {
18 | if (!log_file || strlen(log_file) == 0) {
19 | return 0;
20 | }
21 |
22 | beast_log_fp = fopen(log_file, "a+");
23 | if (!beast_log_fp)
24 | return -1;
25 | log_level = level;
26 | return 0;
27 | }
28 |
29 |
30 | int beast_log_chown(uid_t uid, gid_t gid)
31 | {
32 | #ifdef PHP_WIN32
33 | return 1;
34 | #else
35 | int fd;
36 |
37 | if (!beast_log_fp) {
38 | return 0;
39 | }
40 |
41 | fd = fileno(beast_log_fp);
42 |
43 | return fchown(fd, uid, gid);
44 | #endif
45 | }
46 |
47 |
48 | void beast_write_log(beast_log_level level, const char *fmt, ...)
49 | {
50 |
51 | struct tm local_tm, *result_tm;
52 | time_t the_time;
53 | char buf[64];
54 | char *headers[] = {"DEBUG", "NOTICE", "ERROR"};
55 | va_list ap;
56 |
57 | if (beast_log_fp == NULL ||
58 | level > beast_log_error ||
59 | level < log_level)
60 | {
61 | return;
62 | }
63 |
64 | va_start(ap, fmt);
65 |
66 | the_time = time(NULL);
67 | result_tm = php_localtime_r(&the_time, &local_tm);
68 | strftime(buf, 64, "%d %b %H:%M:%S", result_tm);
69 |
70 | fprintf(beast_log_fp, "[%s] %s: ", buf, headers[level]);
71 | vfprintf(beast_log_fp, fmt, ap);
72 | fprintf(beast_log_fp, "\n");
73 | fflush(beast_log_fp);
74 |
75 | va_end(ap);
76 |
77 | return;
78 | }
79 |
80 | void beast_log_destroy()
81 | {
82 | if (beast_log_fp) {
83 | fclose(beast_log_fp);
84 | beast_log_fp = NULL;
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/beast_log.h:
--------------------------------------------------------------------------------
1 | #ifndef BEAST_LOG_H
2 | #define BEAST_LOG_H
3 |
4 | #ifdef PHP_WIN32
5 | #include "win95nt.h"
6 | #else
7 | #include
8 | #endif
9 |
10 | typedef enum {
11 | beast_log_debug, /* 0 */
12 | beast_log_notice, /* 1 */
13 | beast_log_error /* 2 */
14 | } beast_log_level;
15 |
16 | int beast_log_init(char *log_file, int level);
17 | int beast_log_chown(uid_t uid, gid_t gid);
18 | void beast_write_log(beast_log_level level, const char *fmt, ...);
19 | void beast_log_destroy();
20 |
21 | #endif
22 |
--------------------------------------------------------------------------------
/beast_mm.c:
--------------------------------------------------------------------------------
1 | /*
2 | +----------------------------------------------------------------------+
3 | | PHP Version 5 |
4 | +----------------------------------------------------------------------+
5 | | Copyright (c) 1997-2007 The PHP Group |
6 | +----------------------------------------------------------------------+
7 | | This source file is subject to version 3.01 of the PHP license, |
8 | | that is bundled with this package in the file LICENSE, and is |
9 | | available through the world-wide-web at the following url: |
10 | | http://www.php.net/license/3_01.txt |
11 | | If you did not receive a copy of the PHP license and are unable to |
12 | | obtain it through the world-wide-web, please send a note to |
13 | | license@php.net so we can mail you a copy immediately. |
14 | +----------------------------------------------------------------------+
15 | | Author: Liexusong |
16 | +----------------------------------------------------------------------+
17 | */
18 |
19 | /*
20 | * The simple share memory manager algorithm
21 | */
22 |
23 | #include
24 | #include
25 | #include
26 | #include
27 | #include
28 | #ifdef PHP_WIN32
29 | #include
30 | #else
31 | #include
32 | #endif
33 |
34 | #include "spinlock.h"
35 | #include "beast_log.h"
36 | #include "shm.h"
37 |
38 | #define BEAST_SEGMENT_DEFAULT_SIZE (256 * 1024)
39 |
40 | #define BLOCKAT(addr, offset) ((beast_block_t *)((char *)(addr) + (offset)))
41 |
42 | #ifdef max
43 | #undef max
44 | #endif
45 | #define max(a, b) ((a) > (b) ? (a) : (b))
46 |
47 | typedef struct beast_header_s {
48 | int segsize; /* size of entire segment */
49 | int avail; /* bytes available memorys */
50 | } beast_header_t;
51 |
52 | typedef struct beast_block_s {
53 | int size; /* size of this block */
54 | int next; /* offset in segment of next free block */
55 | } beast_block_t;
56 |
57 | static int beast_mm_initialized = 0;
58 | static void *beast_mm_block = NULL;
59 | static int beast_mm_block_size = 0;
60 | static beast_atomic_t *mm_lock;
61 | extern int beast_pid;
62 |
63 | void beast_mm_lock()
64 | {
65 | beast_spinlock(mm_lock, beast_pid);
66 | }
67 |
68 | void beast_mm_unlock()
69 | {
70 | beast_spinunlock(mm_lock, beast_pid);
71 | }
72 |
73 | /*
74 | * memory align function
75 | * @param bits, align bits
76 | */
77 | static inline int beast_mm_alignmem(int bits)
78 | {
79 | typedef union {
80 | void* p;
81 | int i;
82 | long l;
83 | double d;
84 | void (*f)();
85 | } beast_word_t; /* may be 8 bits */
86 |
87 | return sizeof(beast_word_t) * (1 + ((bits - 1) / sizeof(beast_word_t)));
88 | }
89 |
90 | static int beast_mm_allocate(void *shmaddr, int size)
91 | {
92 | beast_header_t *header; /* header of shared memory segment */
93 | beast_block_t *prv; /* block prior to working block */
94 | beast_block_t *cur; /* working block in list */
95 | beast_block_t *prvbestfit; /* block before best fit */
96 | int realsize; /* actual size of block needed, including header */
97 | int minsize; /* for finding best fit */
98 | int offset;
99 |
100 | /* Realsize must be aligned to a word boundary on some architectures. */
101 | realsize = size + beast_mm_alignmem(sizeof(int));
102 | realsize = beast_mm_alignmem(max(realsize, sizeof(beast_block_t)));
103 |
104 | /*
105 | * First, insure that the segment contains at least realsize free bytes,
106 | * even if they are not contiguous.
107 | */
108 | header = (beast_header_t *)shmaddr;
109 | if (header->avail < realsize) {
110 | beast_write_log(beast_log_error,
111 | "Not enough memory for beast_mm_alloc()");
112 | return -1;
113 | }
114 |
115 | prvbestfit = 0; /* Best block prev's node */
116 | minsize = INT_MAX;
117 |
118 | prv = BLOCKAT(shmaddr, sizeof(beast_header_t)); /* Free list header */
119 |
120 | while (prv->next != 0) {
121 | cur = BLOCKAT(shmaddr, prv->next); /* Current active block */
122 | if (cur->size == realsize) {
123 | prvbestfit = prv;
124 | break;
125 | }
126 | else if (cur->size > (sizeof(beast_block_t) + realsize)
127 | && cur->size < minsize)
128 | {
129 | prvbestfit = prv;
130 | minsize = cur->size;
131 | }
132 | prv = cur;
133 | }
134 |
135 | if (prvbestfit == 0) { /* Not found best block */
136 | return -1;
137 | }
138 |
139 | prv = prvbestfit;
140 | cur = BLOCKAT(shmaddr, prv->next);
141 |
142 | /* update the block header */
143 | header->avail -= realsize;
144 |
145 | if (cur->size == realsize) {
146 | prv->next = cur->next;
147 |
148 | } else {
149 | beast_block_t *nxt; /* The new block (chopped part of cur) */
150 | int nxtoffset; /* Offset of the block currently after cur */
151 | int oldsize; /* Size of cur before split */
152 |
153 | /* bestfit is too big; split it into two smaller blocks */
154 | nxtoffset = cur->next;
155 | oldsize = cur->size;
156 | prv->next += realsize;
157 | cur->size = realsize;
158 | nxt = BLOCKAT(shmaddr, prv->next);
159 | nxt->next = nxtoffset;
160 | nxt->size = oldsize - realsize;
161 | }
162 |
163 | /* skip size field */
164 |
165 | offset = (char *)cur - (char *)shmaddr;
166 |
167 | return offset + beast_mm_alignmem(sizeof(int));
168 | }
169 |
170 | static int beast_mm_deallocate(void *shmaddr, int offset)
171 | {
172 | beast_header_t *header; /* Header of shared memory segment */
173 | beast_block_t *cur; /* The new block to insert */
174 | beast_block_t *prv; /* The block before cur */
175 | beast_block_t *nxt; /* The block after cur */
176 | int size; /* Size of deallocated block */
177 |
178 | offset -= beast_mm_alignmem(sizeof(int)); /* Really offset */
179 |
180 | /* Find position of new block in free list */
181 | prv = BLOCKAT(shmaddr, sizeof(beast_header_t));
182 |
183 | while (prv->next != 0 && prv->next < offset) {
184 | prv = BLOCKAT(shmaddr, prv->next);
185 | }
186 |
187 | /* Insert new block after prv */
188 | cur = BLOCKAT(shmaddr, offset);
189 | cur->next = prv->next;
190 | prv->next = offset;
191 |
192 | /* Update the block header */
193 | header = (beast_header_t *)shmaddr;
194 | header->avail += cur->size;
195 | size = cur->size;
196 |
197 | if (((char *)prv) + prv->size == (char *) cur) {
198 | /* cur and prv share an edge, combine them */
199 | prv->size += cur->size;
200 | prv->next = cur->next;
201 | cur = prv;
202 | }
203 |
204 | nxt = BLOCKAT(shmaddr, cur->next);
205 | if (((char *)cur) + cur->size == (char *) nxt) {
206 | /* cur and nxt shared an edge, combine them */
207 | cur->size += nxt->size;
208 | cur->next = nxt->next;
209 | }
210 |
211 | return size;
212 | }
213 |
214 | void beast_mm_reinit()
215 | {
216 | beast_header_t *header;
217 | beast_block_t *block;
218 |
219 | header = (beast_header_t *)beast_mm_block;
220 | header->segsize = beast_mm_block_size;
221 | header->avail = beast_mm_block_size
222 | - sizeof(beast_header_t)
223 | - sizeof(beast_block_t)
224 | - beast_mm_alignmem(sizeof(int));
225 |
226 | /* The free list head block node */
227 | block = BLOCKAT(beast_mm_block, sizeof(beast_header_t));
228 | block->size = 0;
229 | block->next = sizeof(beast_header_t) + sizeof(beast_block_t);
230 |
231 | /* The avail block */
232 | block = BLOCKAT(beast_mm_block, block->next);
233 | block->size = header->avail;
234 | block->next = 0;
235 | }
236 |
237 | /*
238 | * Init memory manager
239 | */
240 | int beast_mm_init(int block_size)
241 | {
242 | if (beast_mm_initialized) {
243 | return 0;
244 | }
245 |
246 | /* Init memory manager lock */
247 | mm_lock = (int *)beast_shm_alloc(sizeof(beast_atomic_t));
248 | if (!mm_lock) {
249 | beast_write_log(beast_log_error,
250 | "Unable alloc share memory for memory manager lock");
251 | return -1;
252 | }
253 |
254 | *mm_lock = 0;
255 |
256 | /* Init share memory for beast */
257 | if (block_size < BEAST_SEGMENT_DEFAULT_SIZE) {
258 | beast_mm_block_size = BEAST_SEGMENT_DEFAULT_SIZE;
259 | } else {
260 | beast_mm_block_size = block_size;
261 | }
262 |
263 | beast_mm_block = (void *)beast_shm_alloc(beast_mm_block_size);
264 | if (!beast_mm_block) {
265 | beast_write_log(beast_log_error,
266 | "Unable alloc share memory for beast");
267 | beast_shm_free((void *)mm_lock, sizeof(beast_atomic_t));
268 | return -1;
269 | }
270 |
271 | beast_mm_reinit();
272 |
273 | beast_mm_initialized = 1;
274 |
275 | return 0;
276 | }
277 |
278 | void *beast_mm_malloc(int size)
279 | {
280 | int offset;
281 | void *p = NULL;
282 |
283 | beast_mm_lock();
284 |
285 | offset = beast_mm_allocate(beast_mm_block, size);
286 | if (offset != -1) {
287 | p = (void *)(((char *)beast_mm_block) + offset);
288 | }
289 |
290 | beast_mm_unlock();
291 |
292 | return p;
293 | }
294 |
295 | void *beast_mm_calloc(int size)
296 | {
297 | int offset;
298 | void *p = NULL;
299 |
300 | beast_mm_lock();
301 |
302 | offset = beast_mm_allocate(beast_mm_block, size);
303 | if (offset != -1) {
304 | p = (void *)(((char *)beast_mm_block) + offset);
305 | }
306 |
307 | beast_mm_unlock();
308 |
309 | if (NULL != p) {
310 | memset(p, 0, size);
311 | }
312 |
313 | return p;
314 | }
315 |
316 | void beast_mm_free(void *p)
317 | {
318 | int offset;
319 |
320 | offset = (unsigned int)((char *)p - (char *)beast_mm_block);
321 | if (offset <= 0) {
322 | return;
323 | }
324 |
325 | beast_mm_lock();
326 | beast_mm_deallocate(beast_mm_block, offset);
327 | beast_mm_unlock();
328 | }
329 |
330 | void beast_mm_flush()
331 | {
332 | beast_mm_lock();
333 | beast_mm_reinit();
334 | beast_mm_unlock();
335 | }
336 |
337 | /*
338 | * Get the avail's memory space
339 | */
340 | int beast_mm_availspace()
341 | {
342 | int size;
343 | beast_header_t *header = (beast_header_t *)beast_mm_block;
344 |
345 | beast_mm_lock();
346 | size = header->avail;
347 | beast_mm_unlock();
348 |
349 | return size;
350 | }
351 |
352 | /*
353 | * Don't locked here, because the segsize not change forever
354 | */
355 | int beast_mm_realspace()
356 | {
357 | int size;
358 |
359 | beast_mm_lock();
360 | size = ((beast_header_t *)beast_mm_block)->segsize;
361 | beast_mm_unlock();
362 |
363 | return size;
364 | }
365 |
366 | /*
367 | * Destroy memory's manager
368 | */
369 | void beast_mm_destroy()
370 | {
371 | if (beast_mm_initialized) {
372 | beast_shm_free((void *)beast_mm_block, beast_mm_block_size);
373 | beast_shm_free((void *)mm_lock, sizeof(beast_atomic_t));
374 | beast_mm_initialized = 0;
375 | }
376 | }
377 |
--------------------------------------------------------------------------------
/beast_mm.h:
--------------------------------------------------------------------------------
1 | #ifndef __BEAST_MM_H
2 | #define __BEAST_MM_H
3 |
4 | int beast_mm_init(int block_size);
5 | void *beast_mm_malloc(int size);
6 | void *beast_mm_calloc(int size);
7 | void beast_mm_free(void *p);
8 | void beast_mm_flush();
9 | int beast_mm_availspace();
10 | int beast_mm_realspace();
11 | void beast_mm_destroy();
12 |
13 | void beast_mm_lock();
14 | void beast_mm_unlock();
15 |
16 | #endif
17 |
--------------------------------------------------------------------------------
/beast_module.h:
--------------------------------------------------------------------------------
1 | #ifndef __BEAST_MODULE_H
2 | #define __BEAST_MODULE_H
3 |
4 | typedef int beast_encrypt_op_t(char *inbuf, int inlen,
5 | char **outbuf, int *outlen);
6 | typedef int beast_decrypt_op_t(char *inbuf, int inlen,
7 | char **outbuf, int *outlen);
8 | typedef void beast_free_buf_t(void *buf);
9 |
10 | typedef enum {
11 | BEAST_ENCRYPT_TYPE_DES = 1,
12 | BEAST_ENCRYPT_TYPE_AES,
13 | BEAST_ENCRYPT_TYPE_BASE64,
14 | BEAST_ENCRYPT_TYPE_ERROR
15 | } beast_encrypt_type_t;
16 |
17 | struct beast_ops {
18 | char *name;
19 | beast_encrypt_op_t *encrypt;
20 | beast_decrypt_op_t *decrypt;
21 | beast_free_buf_t *free;
22 | struct beast_ops *next;
23 | };
24 |
25 | #endif
26 |
--------------------------------------------------------------------------------
/cache.c:
--------------------------------------------------------------------------------
1 | /*
2 | +----------------------------------------------------------------------+
3 | | PHP Version 5 |
4 | +----------------------------------------------------------------------+
5 | | Copyright (c) 1997-2007 The PHP Group |
6 | +----------------------------------------------------------------------+
7 | | This source file is subject to version 3.01 of the PHP license, |
8 | | that is bundled with this package in the file LICENSE, and is |
9 | | available through the world-wide-web at the following url: |
10 | | http://www.php.net/license/3_01.txt |
11 | | If you did not receive a copy of the PHP license and are unable to |
12 | | obtain it through the world-wide-web, please send a note to |
13 | | license@php.net so we can mail you a copy immediately. |
14 | +----------------------------------------------------------------------+
15 | | Author: Liexusong <280259971@qq.com> |
16 | +----------------------------------------------------------------------+
17 | */
18 |
19 | #include
20 | #include
21 | #ifndef PHP_WIN32
22 | #include
23 | #endif
24 |
25 | #include "beast_mm.h"
26 | #include "spinlock.h"
27 | #include "php.h"
28 | #include "cache.h"
29 | #include "beast_log.h"
30 | #include "shm.h"
31 |
32 | #define BUCKETS_DEFAULT_SIZE 8191
33 |
34 | static int beast_cache_initialization = 0;
35 | static cache_item_t **beast_cache_buckets = NULL;
36 | static beast_atomic_t *cache_lock;
37 | extern int beast_pid;
38 |
39 | void beast_cache_lock()
40 | {
41 | beast_spinlock(cache_lock, beast_pid);
42 | }
43 |
44 | void beast_cache_unlock()
45 | {
46 | beast_spinunlock(cache_lock, beast_pid);
47 | }
48 |
49 | static inline unsigned int
50 | beast_cache_hash(cache_key_t *key)
51 | {
52 | unsigned int retval;
53 |
54 | retval = (unsigned int)key->device * 3
55 | + (unsigned int)key->inode * 7;
56 |
57 | return retval;
58 | }
59 |
60 |
61 | int beast_cache_init(int size)
62 | {
63 | int index, bucket_size;
64 |
65 | if (beast_cache_initialization) {
66 | return 0;
67 | }
68 |
69 | if (beast_mm_init(size) == -1) {
70 | return -1;
71 | }
72 |
73 | /* init cache lock */
74 | cache_lock = (int *)beast_shm_alloc(sizeof(int));
75 | if (!cache_lock) {
76 | beast_write_log(beast_log_error,
77 | "Unable alloc share memory for cache lock");
78 | beast_mm_destroy();
79 | return -1;
80 | }
81 |
82 | *cache_lock = 0;
83 |
84 | /* init cache buckets's memory */
85 | bucket_size = sizeof(cache_item_t *) * BUCKETS_DEFAULT_SIZE;
86 |
87 | beast_cache_buckets = (cache_item_t **)beast_shm_alloc(bucket_size);
88 |
89 | if (!beast_cache_buckets) {
90 | beast_write_log(beast_log_error,
91 | "Unable alloc share memory for cache buckets");
92 | beast_shm_free((void *)cache_lock, sizeof(int));
93 | beast_mm_destroy();
94 | return -1;
95 | }
96 |
97 | for (index = 0; index < BUCKETS_DEFAULT_SIZE; index++) {
98 | beast_cache_buckets[index] = NULL;
99 | }
100 |
101 | beast_cache_initialization = 1;
102 |
103 | return 0;
104 | }
105 |
106 |
107 | cache_item_t *beast_cache_find(cache_key_t *key)
108 | {
109 | unsigned int hashval = beast_cache_hash(key);
110 | unsigned int index = hashval % BUCKETS_DEFAULT_SIZE;
111 | cache_item_t *item, *temp;
112 |
113 | beast_cache_lock();
114 |
115 | item = beast_cache_buckets[index];
116 | while (item) {
117 | if (item->key.device == key->device &&
118 | item->key.inode == key->inode)
119 | {
120 | break;
121 | }
122 | item = item->next;
123 | }
124 |
125 | if (item && item->key.mtime < key->mtime) /* cache exprie */
126 | {
127 | temp = beast_cache_buckets[index];
128 | if (temp == item) { /* the header node */
129 | beast_cache_buckets[index] = item->next;
130 | } else {
131 | while (temp->next != item) { /* find prev node */
132 | temp = temp->next;
133 | }
134 | temp->next = item->next;
135 | }
136 |
137 | beast_mm_free(item);
138 |
139 | item = NULL;
140 | }
141 |
142 | beast_cache_unlock();
143 |
144 | return item;
145 | }
146 |
147 |
148 | cache_item_t *beast_cache_create(cache_key_t *key)
149 | {
150 | cache_item_t *item;
151 | int msize, bsize;
152 |
153 | msize = sizeof(*item) + key->fsize;
154 | bsize = sizeof(cache_item_t *) * BUCKETS_DEFAULT_SIZE;
155 |
156 | if ((msize + bsize) > beast_mm_realspace()) {
157 | beast_write_log(beast_log_error,
158 | "Cache item size too big");
159 | return NULL;
160 | }
161 |
162 | item = beast_mm_malloc(msize);
163 |
164 | if (!item) {
165 | beast_write_log(beast_log_notice,
166 | "Not enough memory for alloc cache");
167 | return NULL;
168 | }
169 |
170 | item->key.device = key->device;
171 | item->key.inode = key->inode;
172 | item->key.fsize = key->fsize;
173 | item->key.mtime = key->mtime;
174 |
175 | item->next = NULL;
176 |
177 | return item;
178 | }
179 |
180 |
181 | /*
182 | * Push cache item into cache manager,
183 | * this function return a cache item,
184 | * may be return value not equals push item,
185 | * so we must use return value.
186 | */
187 | cache_item_t *beast_cache_push(cache_item_t *item)
188 | {
189 | unsigned int hashval = beast_cache_hash(&item->key);
190 | unsigned int index = hashval % BUCKETS_DEFAULT_SIZE;
191 |
192 | beast_cache_lock();
193 |
194 | item->next = beast_cache_buckets[index];
195 | beast_cache_buckets[index] = item;
196 |
197 | beast_cache_unlock();
198 |
199 | return item;
200 | }
201 |
202 |
203 | int beast_cache_destroy()
204 | {
205 | if (!beast_cache_initialization) {
206 | return 0;
207 | }
208 |
209 | beast_mm_destroy(); /* Destroy memory manager */
210 |
211 | /* Free cache buckets's mmap memory */
212 | beast_shm_free((void *)beast_cache_buckets,
213 | sizeof(cache_item_t *) * BUCKETS_DEFAULT_SIZE);
214 | beast_shm_free((void *)cache_lock, sizeof(int));
215 | beast_cache_initialization = 0;
216 |
217 | return 0;
218 | }
219 |
220 |
221 | void beast_cache_info(zval *retval)
222 | {
223 | char key[128];
224 | int i;
225 | cache_item_t *item;
226 |
227 | beast_cache_lock();
228 |
229 | for (i = 0; i < BUCKETS_DEFAULT_SIZE; i++) {
230 | item = beast_cache_buckets[i];
231 | while (item) {
232 | sprintf(key, "{device(%d)#inode(%d)}",
233 | item->key.device, item->key.inode);
234 | add_assoc_long(retval, key, item->key.fsize);
235 | item = item->next;
236 | }
237 | }
238 |
239 | beast_cache_unlock();
240 | }
241 |
242 | void beast_cache_flush()
243 | {
244 | int index;
245 |
246 | beast_cache_lock();
247 |
248 | /* Flush hash buckets */
249 | for (index = 0; index < BUCKETS_DEFAULT_SIZE; index++) {
250 | beast_cache_buckets[index] = NULL;
251 | }
252 |
253 | /* Flush share memory */
254 | beast_mm_flush();
255 |
256 | beast_cache_unlock();
257 | }
258 |
--------------------------------------------------------------------------------
/cache.h:
--------------------------------------------------------------------------------
1 | #ifndef __BEAST_CACHE_H
2 | #define __BEAST_CACHE_H
3 |
4 | typedef struct cache_key_s {
5 | int device;
6 | int inode;
7 | int mtime;
8 | int fsize;
9 | } cache_key_t;
10 |
11 |
12 | typedef struct cache_item_s {
13 | cache_key_t key;
14 | struct cache_item_s *next;
15 | char data[0];
16 | } cache_item_t;
17 |
18 |
19 | #define beast_cache_data(item) (item)->data
20 | #define beast_cache_size(item) (item)->key.fsize
21 |
22 | int beast_cache_init();
23 | cache_item_t *beast_cache_find(cache_key_t *key);
24 | cache_item_t *beast_cache_create(cache_key_t *key);
25 | cache_item_t *beast_cache_push(cache_item_t *item);
26 | int beast_cache_destroy();
27 | void beast_cache_flush();
28 |
29 | void beast_cache_lock();
30 | void beast_cache_unlock();
31 | void beast_cache_info(zval *);
32 |
33 | #endif
34 |
--------------------------------------------------------------------------------
/config.m4:
--------------------------------------------------------------------------------
1 | dnl $Id$
2 | dnl config.m4 for extension beast
3 |
4 | dnl Comments in this file start with the string 'dnl'.
5 | dnl Remove where necessary. This file will not work
6 | dnl without editing.
7 |
8 | dnl If your extension references something external, use with:
9 |
10 | dnl PHP_ARG_WITH(beast, for beast support,
11 | dnl Make sure that the comment is aligned:
12 | dnl [ --with-beast Include beast support])
13 |
14 | dnl Otherwise use enable:
15 |
16 | PHP_ARG_ENABLE(beast, whether to enable beast support,
17 | dnl Make sure that the comment is aligned:
18 | [ --enable-beast Enable beast support])
19 |
20 | PHP_ARG_ENABLE(beast-debug, whether to enable beast debug mode,
21 | dnl Make sure that the comment is aligned:
22 | [ --enable-beast-debug Enable beast debug mode], no, no)
23 |
24 | PHP_ARG_ENABLE(execute-normal-script, whether to enable execute normal PHP script mode,
25 | dnl Make sure that the comment is aligned:
26 | [ --enable-execute-normal-script Enable execute normal PHP script], yes, yes)
27 |
28 | if test "$PHP_BEAST" != "no"; then
29 | dnl Write more examples of tests here...
30 |
31 | if test "$PHP_BEAST_DEBUG" != "yes"; then
32 | AC_DEFINE(BEAST_DEBUG_MODE, 0, [ ])
33 | else
34 | AC_DEFINE(BEAST_DEBUG_MODE, 1, [ ])
35 | fi
36 |
37 | if test "$PHP_EXECUTE_NORMAL_SCRIPT" != "yes"; then
38 | AC_DEFINE(BEAST_EXECUTE_NORMAL_SCRIPT, 0, [ ])
39 | else
40 | AC_DEFINE(BEAST_EXECUTE_NORMAL_SCRIPT, 1, [ ])
41 | fi
42 |
43 | dnl # --with-beast -> check with-path
44 | dnl SEARCH_PATH="/usr/local /usr" # you might want to change this
45 | dnl SEARCH_FOR="/include/beast.h" # you most likely want to change this
46 | dnl if test -r $PHP_BEAST/$SEARCH_FOR; then # path given as parameter
47 | dnl BEAST_DIR=$PHP_BEAST
48 | dnl else # search default path list
49 | dnl AC_MSG_CHECKING([for beast files in default path])
50 | dnl for i in $SEARCH_PATH ; do
51 | dnl if test -r $i/$SEARCH_FOR; then
52 | dnl BEAST_DIR=$i
53 | dnl AC_MSG_RESULT(found in $i)
54 | dnl fi
55 | dnl done
56 | dnl fi
57 | dnl
58 | dnl if test -z "$BEAST_DIR"; then
59 | dnl AC_MSG_RESULT([not found])
60 | dnl AC_MSG_ERROR([Please reinstall the beast distribution])
61 | dnl fi
62 |
63 | dnl # --with-beast -> add include path
64 | dnl PHP_ADD_INCLUDE($BEAST_DIR/include)
65 |
66 | dnl # --with-beast -> check for lib and symbol presence
67 | dnl LIBNAME=beast # you may want to change this
68 | dnl LIBSYMBOL=beast # you most likely want to change this
69 |
70 | dnl PHP_CHECK_LIBRARY($LIBNAME,$LIBSYMBOL,
71 | dnl [
72 | dnl PHP_ADD_LIBRARY_WITH_PATH($LIBNAME, $BEAST_DIR/lib, BEAST_SHARED_LIBADD)
73 | dnl AC_DEFINE(HAVE_BEASTLIB,1,[ ])
74 | dnl ],[
75 | dnl AC_MSG_ERROR([wrong beast lib version or lib not found])
76 | dnl ],[
77 | dnl -L$BEAST_DIR/lib -lm -ldl
78 | dnl ])
79 | dnl
80 | dnl PHP_SUBST(BEAST_SHARED_LIBADD)
81 |
82 | PHP_NEW_EXTENSION(beast, beast.c aes_algo_handler.c des_algo_handler.c base64_algo_handler.c beast_mm.c spinlock.c cache.c beast_log.c global_algo_modules.c header.c networkcards.c tmpfile_file_handler.c pipe_file_handler.c file_handler_switch.c shm.c, $ext_shared)
83 | fi
84 |
--------------------------------------------------------------------------------
/config.w32:
--------------------------------------------------------------------------------
1 | // $Id$
2 | // vim:ft=javascript
3 |
4 | // If your extension references something external
5 | ARG_WITH("beast", "for beast support", "yes,shared");
6 |
7 |
8 | ARG_ENABLE("beast", "enable beast support", "yes,shared");
9 |
10 | ARG_ENABLE("beast-debug", "enable beast debug mode", "no");
11 |
12 | if (PHP_BEAST != "no") {
13 | if (PHP_BEAST_DEBUG != "no") {
14 | AC_DEFINE('BEAST_DEBUG_MODE', 1, 'Debug support in beast');
15 | }
16 |
17 | EXTENSION("beast", "beast.c aes_algo_handler.c des_algo_handler.c base64_algo_handler.c beast_mm.c spinlock.c cache.c beast_log.c global_algo_modules.c header.c networkcards.c tmpfile_file_handler.c file_handler_switch.c shm.c", true);
18 | }
19 |
20 |
--------------------------------------------------------------------------------
/des_algo_handler.c:
--------------------------------------------------------------------------------
1 | /**
2 | * DES encrypt algorithms handler module for Beast
3 | * @author: liexusong
4 | */
5 |
6 | #include
7 | #include
8 | #include "beast_log.h"
9 | #include "beast_module.h"
10 | #include "des_algo_lib.c"
11 |
12 |
13 | static char key[8] = {
14 | 0x01, 0x1f, 0x01, 0x1f,
15 | 0x01, 0x0e, 0x01, 0x0e,
16 | };
17 |
18 |
19 | int des_encrypt_handler(char *inbuf, int len,
20 | char **outbuf, int *outlen)
21 | {
22 | int blocks, i, fixcnt;
23 | char input[8], output[8];
24 | char *out;
25 | int retlen;
26 |
27 | if ((len % 8) == 0) {
28 | fixcnt = 0;
29 | blocks = len / 8;
30 |
31 | } else {
32 | fixcnt = len % 8;
33 | blocks = len / 8 + 1;
34 | }
35 |
36 | retlen = blocks * 8;
37 |
38 | out = malloc(retlen);
39 | if (!out) {
40 | beast_write_log(beast_log_error,
41 | "Out of memory when allocate `%d' size by encrypt(DES)", retlen);
42 | return -1;
43 | }
44 |
45 | for (i = 0; i < blocks; i++) {
46 | memset(input, 0, 8);
47 |
48 | /* The last block not enough 8 bytes, fix me */
49 | if (i + 1 == blocks && fixcnt > 0) {
50 | memcpy(input, &inbuf[i*8], fixcnt);
51 | } else {
52 | memcpy(input, &inbuf[i*8], 8);
53 | }
54 |
55 | DES_encipher(input, output, key);
56 |
57 | memcpy(&out[i * 8], output, 8);
58 | }
59 |
60 | *outbuf = out;
61 | *outlen = retlen;
62 |
63 | return 0;
64 | }
65 |
66 |
67 | int des_decrypt_handler(char *inbuf, int len,
68 | char **outbuf, int *outlen)
69 | {
70 | int blocks, retlen, i;
71 | char *out;
72 |
73 | if (len % 8 == 0) {
74 | blocks = len / 8;
75 | } else {
76 | blocks = len / 8 + 1;
77 | }
78 |
79 | retlen = blocks * 8;
80 |
81 | out = malloc(retlen);
82 | if (!out) {
83 | beast_write_log(beast_log_error,
84 | "Out of memory when allocate `%d' size by decrypt(DES)", retlen);
85 | return -1;
86 | }
87 |
88 | for (i = 0; i < blocks; i++) {
89 | DES_decipher(&inbuf[i*8], &out[i*8], key);
90 | }
91 |
92 | *outbuf = out;
93 | *outlen = retlen;
94 |
95 | return 0;
96 | }
97 |
98 |
99 | void des_free_handler(void *ptr)
100 | {
101 | if (ptr) {
102 | free(ptr);
103 | }
104 | }
105 |
106 | struct beast_ops des_handler_ops = {
107 | "des-algo",
108 | des_encrypt_handler,
109 | des_decrypt_handler,
110 | des_free_handler,
111 | NULL
112 | };
113 |
--------------------------------------------------------------------------------
/des_algo_lib.c:
--------------------------------------------------------------------------------
1 | /*****************************************************************************
2 | * *
3 | * --------------------------------- des.c -------------------------------- *
4 | * *
5 | *****************************************************************************/
6 |
7 | #include
8 | #include
9 | #include
10 | #include
11 |
12 | /*****************************************************************************
13 | * *
14 | * -------------------------------- bit_get ------------------------------- *
15 | * *
16 | *****************************************************************************/
17 |
18 | int bit_get(const unsigned char *bits, int pos) {
19 |
20 | unsigned char mask;
21 |
22 | int i;
23 |
24 | /*****************************************************************************
25 | * *
26 | * Set a mask for the bit to get. *
27 | * *
28 | *****************************************************************************/
29 |
30 | mask = 0x80;
31 |
32 | for (i = 0; i < (pos % 8); i++)
33 | mask = mask >> 1;
34 |
35 | /*****************************************************************************
36 | * *
37 | * Get the bit. *
38 | * *
39 | *****************************************************************************/
40 |
41 | return (((mask & bits[(int)(pos / 8)]) == mask) ? 1 : 0);
42 |
43 | }
44 |
45 | /*****************************************************************************
46 | * *
47 | * -------------------------------- bit_set ------------------------------- *
48 | * *
49 | *****************************************************************************/
50 |
51 | void bit_set(unsigned char *bits, int pos, int state) {
52 |
53 | unsigned char mask;
54 |
55 | int i;
56 |
57 | /*****************************************************************************
58 | * *
59 | * Set a mask for the bit to set. *
60 | * *
61 | *****************************************************************************/
62 |
63 | mask = 0x80;
64 |
65 | for (i = 0; i < (pos % 8); i++)
66 | mask = mask >> 1;
67 |
68 | /*****************************************************************************
69 | * *
70 | * Set the bit. *
71 | * *
72 | *****************************************************************************/
73 |
74 | if (state)
75 | bits[pos / 8] = bits[pos / 8] | mask;
76 | else
77 | bits[pos / 8] = bits[pos / 8] & (~mask);
78 |
79 | return;
80 |
81 | }
82 |
83 | /*****************************************************************************
84 | * *
85 | * -------------------------------- bit_xor ------------------------------- *
86 | * *
87 | *****************************************************************************/
88 |
89 | void bit_xor(const unsigned char *bits1, const unsigned char *bits2, unsigned
90 | char *bitsx, int size) {
91 |
92 | int i;
93 |
94 | /*****************************************************************************
95 | * *
96 | * Compute the bitwise XOR (exclusive OR) of the two buffers. *
97 | * *
98 | *****************************************************************************/
99 |
100 | for (i = 0; i < size; i++) {
101 |
102 | if (bit_get(bits1, i) != bit_get(bits2, i))
103 | bit_set(bitsx, i, 1);
104 | else
105 | bit_set(bitsx, i, 0);
106 |
107 | }
108 |
109 | return;
110 |
111 | }
112 |
113 | /*****************************************************************************
114 | * *
115 | * ----------------------------- bit_rot_left ----------------------------- *
116 | * *
117 | *****************************************************************************/
118 |
119 | void bit_rot_left(unsigned char *bits, int size, int count) {
120 |
121 | int fbit,
122 | lbit,
123 | i,
124 | j;
125 |
126 | /*****************************************************************************
127 | * *
128 | * Rotate the buffer to the left the specified number of bits. *
129 | * *
130 | *****************************************************************************/
131 |
132 | if (size > 0) {
133 |
134 | for (j = 0; j < count; j++) {
135 |
136 | for (i = 0; i <= ((size - 1) / 8); i++) {
137 |
138 | /********************************************************************
139 | * *
140 | * Get the bit about to be shifted off the current byte. *
141 | * *
142 | ********************************************************************/
143 |
144 | lbit = bit_get(&bits[i], 0);
145 |
146 | if (i == 0) {
147 |
148 | /*****************************************************************
149 | * *
150 | * Save the bit shifted off the first byte for later. *
151 | * *
152 | *****************************************************************/
153 |
154 | fbit = lbit;
155 |
156 | }
157 |
158 | else {
159 |
160 | /*****************************************************************
161 | * *
162 | * Set the rightmost bit of the previous byte to the leftmost *
163 | * bit about to be shifted off the current byte. *
164 | * *
165 | *****************************************************************/
166 |
167 | bit_set(&bits[i - 1], 7, lbit);
168 |
169 | }
170 |
171 | /********************************************************************
172 | * *
173 | * Shift the current byte to the left. *
174 | * *
175 | ********************************************************************/
176 |
177 | bits[i] = bits[i] << 1;
178 |
179 | }
180 |
181 | /***********************************************************************
182 | * *
183 | * Set the rightmost bit of the buffer to the bit shifted off the *
184 | * first byte. *
185 | * *
186 | ***********************************************************************/
187 |
188 | bit_set(bits, size - 1, fbit);
189 |
190 | }
191 |
192 | }
193 |
194 | return;
195 |
196 | }
197 |
198 | /*****************************************************************************
199 | * *
200 | * Define a mapping for the key transformation. *
201 | * *
202 | *****************************************************************************/
203 |
204 | static const int DesTransform[56] = {
205 |
206 | 57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18,
207 | 10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36,
208 | 63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22,
209 | 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4
210 |
211 | };
212 |
213 | /*****************************************************************************
214 | * *
215 | * Define the number of rotations for computing subkeys. *
216 | * *
217 | *****************************************************************************/
218 |
219 | static const int DesRotations[16] = {
220 |
221 | 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
222 |
223 | };
224 |
225 | /*****************************************************************************
226 | * *
227 | * Define a mapping for the permuted choice for subkeys. *
228 | * *
229 | *****************************************************************************/
230 |
231 | static const int DesPermuted[48] = {
232 |
233 | 14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10,
234 | 23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2,
235 | 41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48,
236 | 44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32
237 |
238 | };
239 |
240 | /*****************************************************************************
241 | * *
242 | * Define a mapping for the initial permutation of data blocks. *
243 | * *
244 | *****************************************************************************/
245 |
246 | static const int DesInitial[64] = {
247 |
248 | 58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4,
249 | 62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8,
250 | 57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3,
251 | 61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7
252 |
253 | };
254 |
255 | /*****************************************************************************
256 | * *
257 | * Define a mapping for the expansion permutation of data blocks. *
258 | * *
259 | *****************************************************************************/
260 |
261 | static const int DesExpansion[48] = {
262 |
263 | 32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9,
264 | 8, 9, 10, 11, 12, 13, 12, 13, 14, 15, 16, 17,
265 | 16, 17, 18, 19, 20, 21, 20, 21, 22, 23, 24, 25,
266 | 24, 25, 26, 27, 28, 29, 28, 29, 30, 31, 32, 1
267 |
268 | };
269 |
270 | /*****************************************************************************
271 | * *
272 | * Define tables for the S-box substitutions performed for data blocks. *
273 | * *
274 | *****************************************************************************/
275 |
276 | static const int DesSbox[8][4][16] = {
277 |
278 | {
279 | {14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7},
280 | { 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8},
281 | { 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0},
282 | {15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13},
283 | },
284 |
285 | {
286 | {15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10},
287 | { 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5},
288 | { 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15},
289 | {13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9},
290 | },
291 |
292 | {
293 | {10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8},
294 | {13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1},
295 | {13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7},
296 | { 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12},
297 | },
298 |
299 | {
300 | { 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15},
301 | {13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9},
302 | {10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4},
303 | { 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14},
304 | },
305 |
306 | {
307 | { 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9},
308 | {14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6},
309 | { 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14},
310 | {11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3},
311 | },
312 |
313 | {
314 | {12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11},
315 | {10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8},
316 | { 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6},
317 | { 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13},
318 | },
319 |
320 | {
321 | { 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1},
322 | {13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6},
323 | { 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2},
324 | { 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12},
325 | },
326 |
327 | {
328 | {13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7},
329 | { 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2},
330 | { 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8},
331 | { 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11},
332 | },
333 |
334 | };
335 |
336 | /*****************************************************************************
337 | * *
338 | * Define a mapping for the P-box permutation of data blocks. *
339 | * *
340 | *****************************************************************************/
341 |
342 | static const int DesPbox[32] = {
343 |
344 | 16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10,
345 | 2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25
346 |
347 | };
348 |
349 | /*****************************************************************************
350 | * *
351 | * Define a mapping for the final permutation of data blocks. *
352 | * *
353 | *****************************************************************************/
354 |
355 | static const int DesFinal[64] = {
356 |
357 | 40, 8, 48, 16, 56, 24, 64, 32, 39, 7, 47, 15, 55, 23, 63, 31,
358 | 38, 6, 46, 14, 54, 22, 62, 30, 37, 5, 45, 13, 53, 21, 61, 29,
359 | 36, 4, 44, 12, 52, 20, 60, 28, 35, 3, 43, 11, 51, 19, 59, 27,
360 | 34, 2, 42, 10, 50, 18, 58, 26, 33, 1, 41, 9, 49, 17, 57, 25
361 |
362 | };
363 |
364 | /*****************************************************************************
365 | * *
366 | * Define a type for whether to encipher or decipher data. *
367 | * *
368 | *****************************************************************************/
369 |
370 | typedef enum DesEorD_ {encipher, decipher} DesEorD;
371 |
372 | /*****************************************************************************
373 | * *
374 | * -------------------------------- permute ------------------------------- *
375 | * *
376 | *****************************************************************************/
377 |
378 | static void permute(unsigned char *bits, const int *mapping, int n) {
379 |
380 | unsigned char temp[8];
381 |
382 | int i;
383 |
384 | /*****************************************************************************
385 | * *
386 | * Permute the buffer using an n-entry mapping. *
387 | * *
388 | *****************************************************************************/
389 |
390 | memset(temp, 0, (int)ceil(n / 8));
391 |
392 | for (i = 0; i < n; i++)
393 | bit_set(temp, i, bit_get(bits, mapping[i] - 1));
394 |
395 | memcpy(bits, temp, (int)ceil(n / 8));
396 |
397 | return;
398 |
399 | }
400 |
401 | /*****************************************************************************
402 | * *
403 | * ------------------------------- des_main ------------------------------- *
404 | * *
405 | *****************************************************************************/
406 |
407 | static int DES_main(const unsigned char *source, unsigned char *target, const
408 | unsigned char *key, DesEorD direction) {
409 |
410 | static unsigned char subkeys[16][7];
411 |
412 | unsigned char temp[8],
413 | lkey[4],
414 | rkey[4],
415 | lblk[6],
416 | rblk[6],
417 | fblk[6],
418 | xblk[6],
419 | sblk;
420 |
421 | int row,
422 | col,
423 | i,
424 | j,
425 | k,
426 | p;
427 |
428 | /*****************************************************************************
429 | * *
430 | * If key is NULL, use the subkeys as computed in a previous call. *
431 | * *
432 | *****************************************************************************/
433 |
434 | if (key != NULL) {
435 |
436 | /**************************************************************************
437 | * *
438 | * Make a local copy of the key. *
439 | * *
440 | **************************************************************************/
441 |
442 | memcpy(temp, key, 8);
443 |
444 | /**************************************************************************
445 | * *
446 | * Permute and compress the key into 56 bits. *
447 | * *
448 | **************************************************************************/
449 |
450 | permute(temp, DesTransform, 56);
451 |
452 | /**************************************************************************
453 | * *
454 | * Split the key into two 28-bit blocks. *
455 | * *
456 | **************************************************************************/
457 |
458 | memset(lkey, 0, 4);
459 | memset(rkey, 0, 4);
460 |
461 | for (j = 0; j < 28; j++)
462 | bit_set(lkey, j, bit_get(temp, j));
463 |
464 | for (j = 0; j < 28; j++)
465 | bit_set(rkey, j, bit_get(temp, j + 28));
466 |
467 | /**************************************************************************
468 | * *
469 | * Compute the subkeys for each round. *
470 | * *
471 | **************************************************************************/
472 |
473 | for (i = 0; i < 16; i++) {
474 |
475 | /***********************************************************************
476 | * *
477 | * Rotate each block according to its round. *
478 | * *
479 | ***********************************************************************/
480 |
481 | bit_rot_left(lkey, 28, DesRotations[i]);
482 | bit_rot_left(rkey, 28, DesRotations[i]);
483 |
484 | /***********************************************************************
485 | * *
486 | * Concatenate the blocks into a single subkey. *
487 | * *
488 | ***********************************************************************/
489 |
490 | for (j = 0; j < 28; j++)
491 | bit_set(subkeys[i], j, bit_get(lkey, j));
492 |
493 | for (j = 0; j < 28; j++)
494 | bit_set(subkeys[i], j + 28, bit_get(rkey, j));
495 |
496 | /***********************************************************************
497 | * *
498 | * Do the permuted choice permutation. *
499 | * *
500 | ***********************************************************************/
501 |
502 | permute(subkeys[i], DesPermuted, 48);
503 |
504 | }
505 |
506 | }
507 |
508 | /*****************************************************************************
509 | * *
510 | * Make a local copy of the source text. *
511 | * *
512 | *****************************************************************************/
513 |
514 | memcpy(temp, source, 8);
515 |
516 | /*****************************************************************************
517 | * *
518 | * Do the initial permutation. *
519 | * *
520 | *****************************************************************************/
521 |
522 | permute(temp, DesInitial, 64);
523 |
524 | /*****************************************************************************
525 | * *
526 | * Split the source text into a left and right block of 32 bits. *
527 | * *
528 | *****************************************************************************/
529 |
530 | memcpy(lblk, &temp[0], 4);
531 | memcpy(rblk, &temp[4], 4);
532 |
533 | /*****************************************************************************
534 | * *
535 | * Encipher or decipher the source text. *
536 | * *
537 | *****************************************************************************/
538 |
539 | for (i = 0; i < 16; i++) {
540 |
541 | /**************************************************************************
542 | * *
543 | * Begin the computation of f. *
544 | * *
545 | **************************************************************************/
546 |
547 | memcpy(fblk, rblk, 4);
548 |
549 | /**************************************************************************
550 | * *
551 | * Permute and expand the copy of the right block into 48 bits. *
552 | * *
553 | **************************************************************************/
554 |
555 | permute(fblk, DesExpansion, 48);
556 |
557 | /**************************************************************************
558 | * *
559 | * Apply the appropriate subkey for the round. *
560 | * *
561 | **************************************************************************/
562 |
563 | if (direction == encipher) {
564 |
565 | /***********************************************************************
566 | * *
567 | * For enciphering, subkeys are applied in increasing order. *
568 | * *
569 | ***********************************************************************/
570 |
571 | bit_xor(fblk, subkeys[i], xblk, 48);
572 | memcpy(fblk, xblk, 6);
573 |
574 | }
575 |
576 | else {
577 |
578 | /***********************************************************************
579 | * *
580 | * For deciphering, subkeys are applied in decreasing order. *
581 | * *
582 | ***********************************************************************/
583 |
584 | bit_xor(fblk, subkeys[15 - i], xblk, 48);
585 | memcpy(fblk, xblk, 6);
586 |
587 | }
588 |
589 | /**************************************************************************
590 | * *
591 | * Do the S-box substitutions. *
592 | * *
593 | **************************************************************************/
594 |
595 | p = 0;
596 |
597 | for (j = 0; j < 8; j++) {
598 |
599 | /***********************************************************************
600 | * *
601 | * Compute a row and column into the S-box tables. *
602 | * *
603 | ***********************************************************************/
604 |
605 | row = (bit_get(fblk, (j * 6)+0) * 2) + (bit_get(fblk, (j * 6)+5) * 1);
606 | col = (bit_get(fblk, (j * 6)+1) * 8) + (bit_get(fblk, (j * 6)+2) * 4) +
607 | (bit_get(fblk, (j * 6)+3) * 2) + (bit_get(fblk, (j * 6)+4) * 1);
608 |
609 | /***********************************************************************
610 | * *
611 | * Do the S-box substitution for the current six-bit block. *
612 | * *
613 | ***********************************************************************/
614 |
615 | sblk = (unsigned char)DesSbox[j][row][col];
616 |
617 | for (k = 4; k < 8; k++) {
618 |
619 | bit_set(fblk, p, bit_get(&sblk, k));
620 | p++;
621 |
622 | }
623 |
624 | }
625 |
626 | /**************************************************************************
627 | * *
628 | * Do the P-box permutation to complete f. *
629 | * *
630 | **************************************************************************/
631 |
632 | permute(fblk, DesPbox, 32);
633 |
634 | /**************************************************************************
635 | * *
636 | * Compute the XOR of the left block and f. *
637 | * *
638 | **************************************************************************/
639 |
640 | bit_xor(lblk, fblk, xblk, 32);
641 |
642 | /**************************************************************************
643 | * *
644 | * Set the left block for the round. *
645 | * *
646 | **************************************************************************/
647 |
648 | memcpy(lblk, rblk, 4);
649 |
650 | /**************************************************************************
651 | * *
652 | * Set the right block for the round. *
653 | * *
654 | **************************************************************************/
655 |
656 | memcpy(rblk, xblk, 4);
657 |
658 | }
659 |
660 | /*****************************************************************************
661 | * *
662 | * Set the target text to the rejoined final right and left blocks. *
663 | * *
664 | *****************************************************************************/
665 |
666 | memcpy(&target[0], rblk, 4);
667 | memcpy(&target[4], lblk, 4);
668 |
669 | /*****************************************************************************
670 | * *
671 | * Do the final permutation. *
672 | * *
673 | *****************************************************************************/
674 |
675 | permute(target, DesFinal, 64);
676 |
677 | return 0;
678 |
679 | }
680 |
681 | /*****************************************************************************
682 | * *
683 | * ----------------------------- DES_encipher ----------------------------- *
684 | * *
685 | *****************************************************************************/
686 |
687 | void DES_encipher(const unsigned char *plaintext, unsigned char *ciphertext,
688 | const unsigned char *key) {
689 |
690 | DES_main(plaintext, ciphertext, key, encipher);
691 |
692 | return;
693 |
694 | }
695 |
696 | /*****************************************************************************
697 | * *
698 | * ----------------------------- DES_decipher ----------------------------- *
699 | * *
700 | *****************************************************************************/
701 |
702 | void DES_decipher(const unsigned char *ciphertext, unsigned char *plaintext,
703 | const unsigned char *key) {
704 |
705 | DES_main(ciphertext, plaintext, key, decipher);
706 |
707 | return;
708 |
709 | }
710 |
711 |
--------------------------------------------------------------------------------
/file_handler.h:
--------------------------------------------------------------------------------
1 | #ifndef __FILE_HANDLER_H
2 | #define __FILE_HANDLER_H
3 |
4 | #include
5 |
6 | #define BEAST_FILE_HANDLER_FP 1
7 | #define BEAST_FILE_HANDLER_FD 2
8 |
9 | struct file_handler {
10 | char *name;
11 | int type;
12 | void *ctx;
13 | int (*check)();
14 | int (*open)(struct file_handler *self);
15 | int (*write)(struct file_handler *self, char *buf, int size);
16 | int (*rewind)(struct file_handler *self);
17 | int (*get_fd)(struct file_handler *self);
18 | FILE *(*get_fp)(struct file_handler *self);
19 | int (*destroy)(struct file_handler *self);
20 | };
21 |
22 | #endif
23 |
--------------------------------------------------------------------------------
/file_handler_switch.c:
--------------------------------------------------------------------------------
1 |
2 | char *file_handler_switch = "tmpfile";
3 |
--------------------------------------------------------------------------------
/global_algo_modules.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include "beast_module.h"
3 |
4 | extern struct beast_ops des_handler_ops;
5 | extern struct beast_ops aes_handler_ops;
6 | extern struct beast_ops base64_handler_ops;
7 |
8 | struct beast_ops *ops_handler_list[] = {
9 | &des_handler_ops,
10 | &aes_handler_ops,
11 | &base64_handler_ops,
12 | NULL,
13 | };
14 |
--------------------------------------------------------------------------------
/header.c:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * You can modify this sign to disguise your encrypt file
4 | */
5 | char encrypt_file_header_sign[] = {
6 | 0xe8, 0x16, 0xa4, 0x0c,
7 | 0xf2, 0xb2, 0x60, 0xee
8 | };
9 |
10 | int encrypt_file_header_length = sizeof(encrypt_file_header_sign);
11 |
--------------------------------------------------------------------------------
/images/beast1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liexusong/php-beast/4549b2a642a9b04408b4bfbb3af64131c7f1f2dd/images/beast1.png
--------------------------------------------------------------------------------
/images/beast2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liexusong/php-beast/4549b2a642a9b04408b4bfbb3af64131c7f1f2dd/images/beast2.png
--------------------------------------------------------------------------------
/images/pay.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liexusong/php-beast/4549b2a642a9b04408b4bfbb3af64131c7f1f2dd/images/pay.jpg
--------------------------------------------------------------------------------
/networkcards.c:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | /*
4 | * Allow network card. if this list empty, this feature was closed!
5 | */
6 |
7 | char *allow_networkcards[] = {
8 | NULL,
9 | };
10 |
--------------------------------------------------------------------------------
/php_beast.h:
--------------------------------------------------------------------------------
1 | /*
2 | +----------------------------------------------------------------------+
3 | | PHP Version 5 |
4 | +----------------------------------------------------------------------+
5 | | Copyright (c) 1997-2007 The PHP Group |
6 | +----------------------------------------------------------------------+
7 | | This source file is subject to version 3.01 of the PHP license, |
8 | | that is bundled with this package in the file LICENSE, and is |
9 | | available through the world-wide-web at the following url: |
10 | | http://www.php.net/license/3_01.txt |
11 | | If you did not receive a copy of the PHP license and are unable to |
12 | | obtain it through the world-wide-web, please send a note to |
13 | | license@php.net so we can mail you a copy immediately. |
14 | +----------------------------------------------------------------------+
15 | | Author: |
16 | +----------------------------------------------------------------------+
17 | */
18 |
19 | /* $Id: header,v 1.16.2.1.2.1 2007/01/01 19:32:09 iliaa Exp $ */
20 |
21 | #ifndef PHP_BEAST_H
22 | #define PHP_BEAST_H
23 |
24 | extern zend_module_entry beast_module_entry;
25 | #define phpext_beast_ptr &beast_module_entry
26 |
27 | #ifdef PHP_WIN32
28 | #define PHP_BEAST_API __declspec(dllexport)
29 | #else
30 | #define PHP_BEAST_API
31 | #endif
32 |
33 | #ifdef ZTS
34 | #include "TSRM.h"
35 | #endif
36 |
37 | PHP_MINIT_FUNCTION(beast);
38 | PHP_MSHUTDOWN_FUNCTION(beast);
39 | PHP_RINIT_FUNCTION(beast);
40 | PHP_RSHUTDOWN_FUNCTION(beast);
41 | PHP_MINFO_FUNCTION(beast);
42 |
43 | PHP_FUNCTION(beast_encode_file);
44 | PHP_FUNCTION(beast_avail_cache);
45 | PHP_FUNCTION(beast_support_filesize);
46 | PHP_FUNCTION(beast_file_expire);
47 | PHP_FUNCTION(beast_clean_cache);
48 |
49 | /*
50 | Declare any global variables you may need between the BEGIN
51 | and END macros here:
52 |
53 | ZEND_BEGIN_MODULE_GLOBALS(beast)
54 | long global_value;
55 | char *global_string;
56 | ZEND_END_MODULE_GLOBALS(beast)
57 | */
58 |
59 | /* In every utility function you add that needs to use variables
60 | in php_beast_globals, call TSRMLS_FETCH(); after declaring other
61 | variables used by that function, or better yet, pass in TSRMLS_CC
62 | after the last function argument and declare your utility function
63 | with TSRMLS_DC after the last declared argument. Always refer to
64 | the globals in your function as BEAST_G(variable). You are
65 | encouraged to rename these macros something shorter, see
66 | examples in any other php module directory.
67 | */
68 |
69 | #ifdef ZTS
70 | #define BEAST_G(v) TSRMG(beast_globals_id, zend_beast_globals *, v)
71 | #else
72 | #define BEAST_G(v) (beast_globals.v)
73 | #endif
74 |
75 | #endif /* PHP_BEAST_H */
76 |
77 |
78 | /*
79 | * Local variables:
80 | * tab-width: 4
81 | * c-basic-offset: 4
82 | * End:
83 | * vim600: noet sw=4 ts=4 fdm=marker expandtab
84 | * vim<600: noet sw=4 ts=4
85 | */
86 |
--------------------------------------------------------------------------------
/pipe_file_handler.c:
--------------------------------------------------------------------------------
1 |
2 | #ifndef PHP_WIN32
3 |
4 | #include
5 | #include
6 | #include
7 | #include "file_handler.h"
8 |
9 | struct pipe_handler_ctx {
10 | int fd[2];
11 | };
12 |
13 | int pipe_handler_check()
14 | {
15 | return 64 * 1024;
16 | }
17 |
18 | int pipe_handler_open(struct file_handler *self)
19 | {
20 | struct pipe_handler_ctx *ctx = self->ctx;
21 |
22 | if (pipe(ctx->fd) == -1) {
23 | ctx->fd[0] = -1;
24 | ctx->fd[1] = -1;
25 | return -1;
26 | }
27 |
28 | return 0;
29 | }
30 |
31 | int pipe_handler_write(struct file_handler *self, char *buf, int size)
32 | {
33 | struct pipe_handler_ctx *ctx = self->ctx;
34 |
35 | if (write(ctx->fd[1], buf, size) == size) {
36 | return 0;
37 | }
38 |
39 | return -1;
40 | }
41 |
42 | int pipe_handler_rewind(struct file_handler *self)
43 | {
44 | return 0;
45 | }
46 |
47 | FILE *pipe_handler_get_fp(struct file_handler *self)
48 | {
49 | return NULL;
50 | }
51 |
52 | int pipe_handler_get_fd(struct file_handler *self)
53 | {
54 | struct pipe_handler_ctx *ctx = self->ctx;
55 | int retval;
56 |
57 | retval = ctx->fd[0];
58 |
59 | close(ctx->fd[1]); /* Closed write pipe */
60 |
61 | ctx->fd[0] = -1;
62 | ctx->fd[1] = -1;
63 |
64 | return retval;
65 | }
66 |
67 | int pipe_handler_destroy(struct file_handler *self)
68 | {
69 | struct pipe_handler_ctx *ctx = self->ctx;
70 |
71 | if (ctx->fd[0] != -1)
72 | close(ctx->fd[0]);
73 | if (ctx->fd[1] != -1)
74 | close(ctx->fd[1]);
75 |
76 | ctx->fd[0] = -1;
77 | ctx->fd[1] = -1;
78 |
79 | return 0;
80 | }
81 |
82 | static struct pipe_handler_ctx _ctx = {
83 | {-1, -1}
84 | };
85 |
86 | struct file_handler pipe_handler = {
87 | "pipe",
88 | BEAST_FILE_HANDLER_FD,
89 | &_ctx,
90 | pipe_handler_check,
91 | pipe_handler_open,
92 | pipe_handler_write,
93 | pipe_handler_rewind,
94 | pipe_handler_get_fd,
95 | pipe_handler_get_fp,
96 | pipe_handler_destroy
97 | };
98 |
99 | #endif
100 |
--------------------------------------------------------------------------------
/shm.c:
--------------------------------------------------------------------------------
1 | #include "shm.h"
2 |
3 | #ifdef PHP_WIN32
4 | #include
5 | #else
6 | #include
7 |
8 | #ifndef MAP_NOSYNC
9 | #define MAP_NOSYNC 0
10 | #endif
11 | #endif
12 |
13 | void *beast_shm_alloc(size_t size)
14 | {
15 | void *p;
16 | #ifdef PHP_WIN32
17 | HANDLE hMapFile = CreateFileMapping(INVALID_HANDLE_VALUE,
18 | NULL, PAGE_READWRITE, 0, size, NULL);
19 |
20 | if (hMapFile == INVALID_HANDLE_VALUE) {
21 | return NULL;
22 | }
23 |
24 | p = MapViewOfFile(
25 | hMapFile,
26 | FILE_MAP_ALL_ACCESS,
27 | 0,
28 | 0,
29 | size);
30 | CloseHandle(hMapFile);
31 |
32 | #else
33 |
34 | p = mmap(NULL,
35 | size,
36 | PROT_READ|PROT_WRITE,
37 | MAP_SHARED|MAP_ANON,
38 | -1,
39 | 0);
40 |
41 | #endif
42 | return p;
43 | }
44 |
45 | int beast_shm_free(void *p, size_t size)
46 | {
47 | #ifdef PHP_WIN32
48 | return UnmapViewOfFile(p) ? 0 : -1;
49 | #else
50 | return munmap(p, size);
51 | #endif
52 | }
53 |
54 |
--------------------------------------------------------------------------------
/shm.h:
--------------------------------------------------------------------------------
1 | #ifndef __SHM_H
2 | #define __SHM_H
3 |
4 | #include
5 |
6 | void *beast_shm_alloc(size_t size);
7 | int beast_shm_free(void *p, size_t size);
8 |
9 | #endif
10 |
--------------------------------------------------------------------------------
/spinlock.c:
--------------------------------------------------------------------------------
1 | /*
2 | +----------------------------------------------------------------------+
3 | | PHP Version 5 |
4 | +----------------------------------------------------------------------+
5 | | Copyright (c) 1997-2007 The PHP Group |
6 | +----------------------------------------------------------------------+
7 | | This source file is subject to version 3.01 of the PHP license, |
8 | | that is bundled with this package in the file LICENSE, and is |
9 | | available through the world-wide-web at the following url: |
10 | | http://www.php.net/license/3_01.txt |
11 | | If you did not receive a copy of the PHP license and are unable to |
12 | | obtain it through the world-wide-web, please send a note to |
13 | | license@php.net so we can mail you a copy immediately. |
14 | +----------------------------------------------------------------------+
15 | | Author: Liexusong <280259971@qq.com> |
16 | +----------------------------------------------------------------------+
17 | */
18 |
19 | #include
20 | #include "spinlock.h"
21 | #ifdef PHP_WIN32
22 | #include
23 | #else
24 | #include
25 | #endif
26 | #include "beast_log.h"
27 |
28 | #ifdef PHP_WIN32
29 | #define compare_and_swap(lock, o, n) \
30 | (InterlockedCompareExchange(lock, n, o) == n)
31 | #define pause() YieldProcessor()
32 | #define yield() SwitchToThread()
33 | #else
34 | #define compare_and_swap(lock, o, n) \
35 | __sync_bool_compare_and_swap(lock, o, n)
36 | #ifdef __arm__
37 | #define pause() __asm__("NOP");
38 | #elif __aarch64__
39 | #define pause() __asm__("NOP");
40 | #else
41 | #define pause() __asm__("pause")
42 | #endif
43 | #define yield() sched_yield()
44 | #endif
45 |
46 | extern int beast_ncpu;
47 |
48 | void beast_spinlock(beast_atomic_t *lock, int pid)
49 | {
50 | int i, n;
51 |
52 | for ( ;; ) {
53 | if (compare_and_swap(lock, 0, pid)) {
54 | return;
55 | }
56 |
57 | if (beast_ncpu > 1) {
58 |
59 | for (n = 1; n < 129; n <<= 1) {
60 |
61 | if (compare_and_swap(lock, 0, pid)) {
62 | return;
63 | }
64 |
65 | for (i = 0; i < n; i++) {
66 | pause();
67 | }
68 | }
69 | }
70 |
71 | yield();
72 | }
73 | }
74 |
75 | void beast_spinunlock(beast_atomic_t *lock, int pid)
76 | {
77 | compare_and_swap(lock, pid, 0);
78 | }
79 |
--------------------------------------------------------------------------------
/spinlock.h:
--------------------------------------------------------------------------------
1 | #ifndef __BEAST_SPINLOCK_H
2 | #define __BEAST_SPINLOCK_H
3 |
4 | typedef volatile unsigned int beast_atomic_t;
5 |
6 | void beast_spinlock(beast_atomic_t *lock, int pid);
7 | void beast_spinunlock(beast_atomic_t *lock, int pid);
8 |
9 | #endif
10 |
--------------------------------------------------------------------------------
/tests/001.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Check for beast presence
3 | --SKIPIF--
4 |
5 | --FILE--
6 |
20 | --EXPECT--
21 | beast extension is available
22 |
--------------------------------------------------------------------------------
/tests/encrypt.php:
--------------------------------------------------------------------------------
1 |
2 | #include
3 | #include "file_handler.h"
4 |
5 | struct tmpfile_handler_ctx {
6 | FILE *fp;
7 | };
8 |
9 | int tmpfile_handler_check()
10 | {
11 | return 0;
12 | }
13 |
14 | int tmpfile_handler_open(struct file_handler *self)
15 | {
16 | struct tmpfile_handler_ctx *ctx = self->ctx;
17 |
18 | ctx->fp = tmpfile();
19 | if (!ctx->fp) {
20 | return -1;
21 | }
22 |
23 | return 0;
24 | }
25 |
26 | int tmpfile_handler_write(struct file_handler *self, char *buf, int size)
27 | {
28 | struct tmpfile_handler_ctx *ctx = self->ctx;
29 |
30 | if (fwrite(buf, 1, size, ctx->fp) == size) {
31 | return 0;
32 | }
33 |
34 | return -1;
35 | }
36 |
37 | int tmpfile_handler_rewind(struct file_handler *self)
38 | {
39 | struct tmpfile_handler_ctx *ctx = self->ctx;
40 |
41 | rewind(ctx->fp);
42 |
43 | return 0;
44 | }
45 |
46 | FILE *tmpfile_handler_get_fp(struct file_handler *self)
47 | {
48 | struct tmpfile_handler_ctx *ctx = self->ctx;
49 | FILE *retval;
50 |
51 | retval = ctx->fp;
52 | ctx->fp = NULL;
53 |
54 | return retval;
55 | }
56 |
57 | int tmpfile_handler_get_fd(struct file_handler *self)
58 | {
59 | return -1;
60 | }
61 |
62 | int tmpfile_handler_destroy(struct file_handler *self)
63 | {
64 | struct tmpfile_handler_ctx *ctx = self->ctx;
65 |
66 | if (ctx->fp) {
67 | fclose(ctx->fp);
68 | }
69 |
70 | ctx->fp = NULL;
71 |
72 | return 0;
73 | }
74 |
75 | static struct tmpfile_handler_ctx _ctx = {
76 | NULL
77 | };
78 |
79 | struct file_handler tmpfile_handler = {
80 | "tmpfile",
81 | BEAST_FILE_HANDLER_FP,
82 | &_ctx,
83 | tmpfile_handler_check,
84 | tmpfile_handler_open,
85 | tmpfile_handler_write,
86 | tmpfile_handler_rewind,
87 | tmpfile_handler_get_fd,
88 | tmpfile_handler_get_fp,
89 | tmpfile_handler_destroy
90 | };
91 |
--------------------------------------------------------------------------------
/tools/configure.ini:
--------------------------------------------------------------------------------
1 | ; source path
2 | src_path = ""
3 |
4 | ; destination path
5 | dst_path = ""
6 |
7 | ; expire time
8 | expire = ""
9 |
10 | ; encrypt type
11 | encrypt_type = "DES"
12 |
--------------------------------------------------------------------------------
/tools/encode_file.php:
--------------------------------------------------------------------------------
1 | 0)
76 | {
77 | if ($expire > 0) {
78 | $result = beast_encode_file($path, $new_path,
79 | $expire, $type);
80 | } else {
81 | $result = beast_encode_file($path, $new_path, 0, $type);
82 | }
83 |
84 | if (!$result) {
85 | echo "Failed to encode file `{$path}'\n";
86 | }
87 |
88 | $finish++;
89 |
90 | $percent = intval($finish / $nfiles * 100);
91 |
92 | printf("\rProcessed encrypt files [%d%%] - 100%%", $percent);
93 |
94 | } else {
95 | copy($path, $new_path);
96 | }
97 | }
98 | }
99 |
100 | closedir($handle);
101 | }
102 |
103 | //////////////////////////////// run here ////////////////////////////////////
104 |
105 | $conf = parse_ini_file(dirname(__FILE__) . '/configure.ini');
106 | if (!$conf) {
107 | exit("Fatal: failed to read configure.ini file\n");
108 | }
109 |
110 | $src_path = trim($conf['src_path']);
111 | $dst_path = trim($conf['dst_path']);
112 | $expire = trim($conf['expire']);
113 | $encrypt_type = strtoupper(trim($conf['encrypt_type']));
114 |
115 | if (empty($src_path) || !is_dir($src_path)) {
116 | exit("Fatal: source path `{$src_path}' not exists\n\n");
117 | }
118 |
119 | if (empty($dst_path)
120 | || (!is_dir($dst_path)
121 | && !mkdir($dst_path, 0777)))
122 | {
123 | exit("Fatal: can not create directory `{$dst_path}'\n\n");
124 | }
125 |
126 | switch ($encrypt_type)
127 | {
128 | case 'AES':
129 | $entype = BEAST_ENCRYPT_TYPE_AES;
130 | break;
131 | case 'BASE64':
132 | $entype = BEAST_ENCRYPT_TYPE_BASE64;
133 | break;
134 | case 'DES':
135 | default:
136 | $entype = BEAST_ENCRYPT_TYPE_DES;
137 | break;
138 | }
139 |
140 | printf("Source code path: %s\n", $src_path);
141 | printf("Destination code path: %s\n", $dst_path);
142 | printf("Expire time: %s\n", $expire);
143 | printf("------------- start process -------------\n");
144 |
145 | $expire_time = 0;
146 | if ($expire) {
147 | $expire_time = strtotime($expire);
148 | }
149 |
150 | $time = microtime(TRUE);
151 |
152 | calculate_directory_schedule($src_path);
153 | encrypt_directory($src_path, $dst_path, $expire_time, $entype);
154 |
155 | $used = microtime(TRUE) - $time;
156 |
157 | printf("\nFinish processed encrypt files, used %f seconds\n", $used);
158 |
--------------------------------------------------------------------------------