1<?php
2
3/**
4 * Initial setup
5 * @package framework
6 * @subpackage setup
7 */
8
9define('VERSION', .1);
10
11/* load the framework */
12require APP_PATH.'lib/module.php';
13require APP_PATH.'lib/modules.php';
14require APP_PATH.'lib/modules_exec.php';
15require APP_PATH.'lib/config.php';
16require APP_PATH.'lib/auth.php';
17require APP_PATH.'lib/oauth2.php';
18require APP_PATH.'lib/session_base.php';
19require APP_PATH.'lib/session_php.php';
20require APP_PATH.'lib/session_db.php';
21require APP_PATH.'lib/session_memcached.php';
22require APP_PATH.'lib/session_redis.php';
23require APP_PATH.'lib/format.php';
24require APP_PATH.'lib/dispatch.php';
25require APP_PATH.'lib/request.php';
26require APP_PATH.'lib/cache.php';
27require APP_PATH.'lib/output.php';
28require APP_PATH.'lib/crypt.php';
29require APP_PATH.'lib/crypt_sodium.php';
30require APP_PATH.'lib/sodium_compat.php';
31require APP_PATH.'lib/db.php';
32require APP_PATH.'lib/servers.php';
33require APP_PATH.'lib/api.php';
34require APP_PATH.'lib/webdav_formats.php';
35
36/* load random bytes polyfill if needed */
37if (!function_exists('random_bytes')) {
38    require VENDOR_PATH.'paragonie/random_compat/lib/random.php';
39}
40
41/* check for and load the correct libsodium interface */
42if (!defined('LIBSODIUM')) {
43    if (extension_loaded('libsodium') && function_exists('\Sodium\crypto_pwhash_str_verify')) {
44        define('LIBSODIUM', true);
45        class Hm_Sodium_Compat extends Hm_Sodium_PECL {}
46    }
47    if (!defined('LIBSODIUM') && extension_loaded('sodium') && function_exists('sodium_crypto_pwhash_str_verify')) {
48        define('LIBSODIUM', true);
49        class Hm_Sodium_Compat extends Hm_Sodium_PHP {}
50    }
51    if (!defined('LIBSODIUM')) {
52        define('LIBSODIUM', false);
53    }
54}
55
56if (!class_exists('Hm_Functions')) {
57    /**
58     * Used to override built in functions that break unit tests
59     * @package framework
60     * @subpackage setup
61     */
62    class Hm_Functions {
63
64        /**
65         * @param string $name
66         * @param string $value
67         * @return boolean
68         */
69        public static function setcookie($name, $value, $lifetime=0, $path='', $domain='', $secure=false, $html_only=false) {
70            $prefix = $lifetime != 0 && $lifetime < time() ? 'Deleting' : 'Setting';
71            Hm_Debug::add(sprintf('%s cookie: name: %s, lifetime: %s, path: %s, domain: %s, secure: %s, html_only %s',
72                $prefix, $name, $lifetime, $path, $domain, $secure, $html_only));
73            if ((float) substr(phpversion(), 0, 3) >= 7.3) {
74                return setcookie($name, $value, array(
75                    'expires' => $lifetime,
76                    'path' => $path,
77                    'domain' => $domain,
78                    'secure' => $secure,
79                    'httponly' => $html_only,
80                    'samesite' => 'Strict')
81                );
82            }
83            else {
84                return setcookie($name, $value, $lifetime, $path, $domain, $secure, $html_only);
85            }
86        }
87
88        /**
89         * @param string $header
90         * @return void
91         */
92        public static function header($header) {
93            header($header);
94        }
95
96        /**
97         * @param string $msg
98         * @return null
99         */
100        public static function cease($msg='') {
101            die($msg);
102        }
103
104        /**
105         * @return boolean
106         */
107        public static function session_destroy() {
108            if (session_status() === PHP_SESSION_ACTIVE) {
109                return session_destroy();
110            }
111            return false;
112        }
113
114        /**
115         * @return boolean
116         */
117        public static function session_start() {
118            return session_start();
119        }
120
121        /**
122         * @return boolean
123         */
124        public static function error_log($str) {
125            return error_log($str);
126        }
127
128        /**
129         * @param resource|false $handle
130         * @param integer $name
131         */
132        public static function c_setopt($handle, $name, $value) {
133            if ($handle !== false) {
134                curl_setopt($handle, $name, $value);
135            }
136        }
137
138        /**
139         * @return resource|false
140         */
141        public static function c_init() {
142            return curl_init();
143        }
144
145        /**
146         * @param resource $handle
147         */
148        public static function c_exec($handle) {
149            return curl_exec($handle);
150        }
151
152        /**
153         * @param resource $handle
154         */
155        public static function c_status($ch) {
156            return curl_getinfo($ch, CURLINFO_HTTP_CODE);
157        }
158
159        /**
160         * @param string $func
161         */
162        public static function function_exists($func) {
163            return function_exists($func);
164        }
165
166        /**
167         * @param string $class
168         */
169        public static function class_exists($class) {
170            return class_exists($class, false);
171        }
172
173        /**
174         * @param integer $size
175         */
176        public static function random_bytes($size) {
177            return random_bytes($size);
178        }
179
180        /**
181         * @return Memcached
182         */
183        public static function memcached() {
184            return new Memcached();
185        }
186
187        /**
188         * @return Redis
189         */
190        public static function redis() {
191            return new Redis();
192        }
193
194        /**
195         * @param integer $type input type
196         * @param array $filters filter list
197         * @return array filtered list
198         */
199        public static function filter_input_array($type, $filters) {
200            return filter_input_array($type, $filters, false);
201        }
202
203        /**
204         * @param string $server host to connect to
205         * @param integer $port port to connect to
206         * @param integer $errno error number
207         * @param string $errstr error string
208         * @param integer $mode connection mode
209         * @param resource $ctx context
210         */
211        public static function stream_socket_client($server, $port, &$errno, &$errstr, $timeout, $mode, $ctx) {
212            return @stream_socket_client($server.':'.$port, $errno, $errstr, $timeout, $mode, $ctx);
213        }
214
215        /**
216         * @param resource $resource socket connection
217         * @return boolean
218         */
219        public static function stream_ended($resource) {
220            if (!is_resource($resource) || feof($resource)) {
221                return true;
222            }
223            return false;
224        }
225        /**
226         * @param resource $socket socket connection to flip to TLS
227         * @return boolean
228         */
229        public static function stream_socket_enable_crypto($socket, $type) {
230            return stream_socket_enable_crypto($socket, true, $type);
231        }
232    }
233}
234
235/**
236 * See if a function already exists
237 * @param string $name function name to check
238 * @return boolean
239 */
240function hm_exists($name) {
241    $bt = debug_backtrace();
242    $caller = array_shift($bt);
243    $module = hm_get_module_from_path($caller['file']);
244    if (function_exists($name)) {
245        Hm_Debug::add(sprintf('Function in %s replaced: %s', $module, $name));
246        return true;
247    }
248    return false;
249}
250
251/**
252 * Return the module set name from a file path
253 * @param string $path file path
254 * @return string
255 */
256function hm_get_module_from_path($path) {
257    $data = pathinfo($path);
258    if (!is_array($data) || !array_key_exists('dirname', $data)) {
259        return 'unknown';
260    }
261    $parts = array_reverse(explode(DIRECTORY_SEPARATOR, $data['dirname']));
262    foreach ($parts as $i => $v) {
263        if ($v == 'modules') {
264            return $parts[($i - 1)];
265        }
266    }
267    return 'unknown';
268}
269