1 <?php
2 /**
3  * -----------------------------------------------------------------------
4  * vBSSO is a solution which helps you connect to different software platforms
5  * via secure Single Sign-On.
6  *
7  * Copyright (c) 2011-2017 vBSSO. All Rights Reserved.
8  * This software is the proprietary information of vBSSO.
9  *
10  * Author URI: http://www.vbsso.com
11  * License: GPL version 2 or later - http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
12  * -----------------------------------------------------------------------
13  *
14  */
15 
16 if (!defined('SHAREDAPI')) {
17     define ('SHAREDAPI_PRODUCT_VERSION_1_9', '1.9');
18     define ('SHAREDAPI_PRODUCT_VERSION_1_8', '1.8');
19     define ('SHAREDAPI_PRODUCT_VERSION_1_7', '1.7');
20     define ('SHAREDAPI_PRODUCT_VERSION_1_6', '1.6');
21     define ('SHAREDAPI_PRODUCT_VERSION_1_5', '1.5');
22     define ('SHAREDAPI_PRODUCT_VERSION_1_4', '1.4');
23     define ('SHAREDAPI_PRODUCT_VERSION_1_3', '1.3');
24     define ('SHAREDAPI_PRODUCT_VERSION_1_2', '1.2');
25     define ('SHAREDAPI_PRODUCT_VERSION_1_1', '1.1');
26     define ('SHAREDAPI_PRODUCT_VERSION_1_0', '1.0');
27 
28     define ('SHAREDAPI', SHAREDAPI_PRODUCT_VERSION_1_9);
29 
30     define ('SHAREDAPI_PRODUCT_ID', 'sharedapi');
31     define ('SHAREDAPI_PRODUCT_NAME', 'SharedAPI');
32     define ('SHAREDAPI_PRODUCT_VERSION', SHAREDAPI);
33 
34     define ('SHAREDAPI_DEFAULT_API_KEY', 'simplekey');
35     define ('SHAREDAPI_WRONG_API_KEY_MESSAGE', 'Wrong Shared Password');
36 
37 
38     define ('SHAREDAPI_EVENT_FIELD_EVENT', 'e');
39     define ('SHAREDAPI_EVENT_FIELD_PRODUCT', 'product');
40     define ('SHAREDAPI_EVENT_FIELD_VERSION', 'version');
41     define ('SHAREDAPI_EVENT_FIELD_PLUGIN_VERSION', 'plugin_version');
42     define ('SHAREDAPI_EVENT_FIELD_PLUGIN_REVISION', 'plugin_revision');
43     define ('SHAREDAPI_EVENT_FIELD_VERIFY', 'verify');
44     define ('SHAREDAPI_EVENT_FIELD_PHP_VERSION', 'php');
45     define ('SHAREDAPI_EVENT_FIELD_MEMORY_LIMIT', 'memory_limit');
46     define ('SHAREDAPI_EVENT_FIELD_WP_MEMORY_LIMIT', 'wp_memory_limit');
47 
48     define ('SHAREDAPI_EVENT_FIELD_API_KEY', 'apikey');
49     define ('SHAREDAPI_EVENT_FIELD_LID', 'lid');
50     define ('SHAREDAPI_EVENT_FIELD_LISTENER_URL', 'listener_url');
51     define ('SHAREDAPI_EVENT_FIELD_BAA_USERNAME', 'baa_username');
52     define ('SHAREDAPI_EVENT_FIELD_BAA_PASSWORD', 'baa_password');
53 
54     define ('SHAREDAPI_EVENT_FIELD_LOGIN_VBULLETIN_URL', 'login_vbulletin_url');
55     define ('SHAREDAPI_EVENT_FIELD_LOGIN_URL', 'login_url');
56     define ('SHAREDAPI_EVENT_FIELD_LOGOUT_URL', 'logout_url');
57     define ('SHAREDAPI_EVENT_FIELD_REGISTER_URL', 'register_url');
58     define ('SHAREDAPI_EVENT_FIELD_LOSTPASSWORD_URL', 'lostpassword_url');
59     define ('SHAREDAPI_EVENT_FIELD_AVATAR_URL', 'avatar_url');
60     define ('SHAREDAPI_EVENT_FIELD_PROFILE_URL', 'profile_url');
61     define ('SHAREDAPI_EVENT_FIELD_USERGROUPS_URL', 'usergroups_url');
62     define ('SHAREDAPI_EVENT_FIELD_USER_UNREAD_STATS_URL', 'user_unread_stats_url');
63     define ('SHAREDAPI_EVENT_FIELD_STATS_URL', 'stats_url');
64 
65     define ('SHAREDAPI_EVENT_FIELD_STAT_PM', 'pm'); //personal messages
66     define ('SHAREDAPI_EVENT_FIELD_STAT_VM', 'vm'); //visitors messages
67     define ('SHAREDAPI_EVENT_FIELD_STAT_FR', 'fr'); //friend requests
68     define ('SHAREDAPI_EVENT_FIELD_STAT_PC', 'pc'); //pictures comments
69 
70     define ('SHAREDAPI_EVENT_FIELD_DESTINATION', 'd');
71     define ('SHAREDAPI_EVENT_FIELD_TIMEOUT', 'timeout');
72     define ('SHAREDAPI_EVENT_FIELD_MUID', 'muid');
73     define ('SHAREDAPI_EVENT_FIELD_REMEMBERME', 'remember-me');
74 
75     define ('SHAREDAPI_EVENT_FIELD_DATA', 'data');
76     define ('SHAREDAPI_EVENT_FIELD_ERROR', 'error');
77     define ('SHAREDAPI_EVENT_FIELD_ERROR_CODE', 'code');
78     define ('SHAREDAPI_EVENT_FIELD_ERROR_MESSAGE', 'message');
79     define ('SHAREDAPI_EVENT_FIELD_ERROR_DATA', 'data');
80 
81     define ('SHAREDAPI_EVENT_FIELD_USERLIST', 'userlist');
82     define ('SHAREDAPI_EVENT_FIELD_USERID', 'userid');
83     define ('SHAREDAPI_EVENT_FIELD_USERGROUPS', 'usergroup');
84     define ('SHAREDAPI_EVENT_FIELD_USERGROUPS2', 'usergroup2');
85     define ('SHAREDAPI_EVENT_FIELD_USERNAME', 'username');
86     define ('SHAREDAPI_EVENT_FIELD_USERNAME2', 'username2');
87     define ('SHAREDAPI_EVENT_FIELD_EMAIL', 'email');
88     define ('SHAREDAPI_EVENT_FIELD_EMAIL2', 'email2');
89     define ('SHAREDAPI_EVENT_FIELD_PASSWORD', 'password');
90 
91     define ('SHAREDAPI_EVENT_FIELD_PROFILE_FIELDS', 'profile_fields');
92     define ('SHAREDAPI_EVENT_FIELD_PROFILE_FIRST_NAME', 'profile_firstname');
93     define ('SHAREDAPI_EVENT_FIELD_PROFILE_LAST_NAME', 'profile_lastname');
94     define ('SHAREDAPI_EVENT_FIELD_PROFILE_COUNTRY', 'profile_country');
95     define ('SHAREDAPI_EVENT_FIELD_PROFILE_CITY', 'profile_city');
96     define ('SHAREDAPI_EVENT_FIELD_PROFILE_PHONE', 'profile_phone');
97     define ('SHAREDAPI_EVENT_FIELD_PROFILE_BIRTH', 'profile_birth');
98 
99     define ('SHAREDAPI_EVENT_UNKNOWN', 0);
100     define ('SHAREDAPI_EVENT_VERIFY', 1);
101 
102     define ('SHAREDAPI_EVENT_LOGIN', 2);
103     define ('SHAREDAPI_EVENT_AUTHENTICATION', 3);
104     define ('SHAREDAPI_EVENT_SESSION', 4);
105     define ('SHAREDAPI_EVENT_LOGOUT', 5);
106     define ('SHAREDAPI_EVENT_REGISTER', 6);
107     define ('SHAREDAPI_EVENT_CREDENTIALS', 7);
108     define ('SHAREDAPI_EVENT_PROFILE_FIELDS', 8);
109     define ('SHAREDAPI_EVENT_CONFLICT_USERS', 9);
110 
111     define ('SHAREDAPI_EVENT_LAST', 50);
112 
113     function sharedapi_get_events() {
114         static $events;
115 
116         if (!$events) {
117             $events = array(
118                 SHAREDAPI_EVENT_UNKNOWN => 'unknown',
119                 SHAREDAPI_EVENT_VERIFY => 'verify',
120                 SHAREDAPI_EVENT_LOGIN => 'login',
121                 SHAREDAPI_EVENT_AUTHENTICATION => 'i',
122                 SHAREDAPI_EVENT_SESSION => 'session',
123                 SHAREDAPI_EVENT_LOGOUT => 'o',
124                 SHAREDAPI_EVENT_REGISTER => 'register',
125                 SHAREDAPI_EVENT_CREDENTIALS => 'credentials',
126                 SHAREDAPI_EVENT_PROFILE_FIELDS => 'profile-fields',
127                 SHAREDAPI_EVENT_CONFLICT_USERS => 'conflict_users'
128             );
129         }
130 
131         return $events;
132     }
133 
134     /**
135      * Product constants
136      */
137     define ('SHAREDAPI_PLATFORM_UNKNOWN', 0);
138     define ('SHAREDAPI_PLATFORM_VBULLETIN', 1);
139     define ('SHAREDAPI_PLATFORM_INTERSPIRESHOPPINGCART', 2);
140     define ('SHAREDAPI_PLATFORM_MOODLE', 3);
141     define ('SHAREDAPI_PLATFORM_WORDPRESS', 4);
142     define ('SHAREDAPI_PLATFORM_JOOMLA', 5);
143     define ('SHAREDAPI_PLATFORM_DRUPAL', 6);
144     define ('SHAREDAPI_PLATFORM_PRESTASHOP', 7);
145     define ('SHAREDAPI_PLATFORM_MAGENTO', 8);
146     define ('SHAREDAPI_PLATFORM_MEDIAWIKI', 9);
147     define ('SHAREDAPI_PLATFORM_DOKUWIKI', 10);
148 
149     function sharedapi_get_platforms($platform = null) {
150         static $platforms;
151 
152         if (!$platforms) {
153             $platforms = array(
154                 SHAREDAPI_PLATFORM_UNKNOWN => 'Unknown',
155                 SHAREDAPI_PLATFORM_VBULLETIN => 'vBulletin',
156                 SHAREDAPI_PLATFORM_INTERSPIRESHOPPINGCART => 'Interspire Shopping Cart',
157                 SHAREDAPI_PLATFORM_MOODLE => 'Moodle',
158                 SHAREDAPI_PLATFORM_WORDPRESS => 'WordPress',
159                 SHAREDAPI_PLATFORM_JOOMLA => 'Joomla',
160                 SHAREDAPI_PLATFORM_DRUPAL => 'Drupal',
161                 SHAREDAPI_PLATFORM_PRESTASHOP => 'Prestashop',
162                 SHAREDAPI_PLATFORM_MAGENTO => 'Magento',
163                 SHAREDAPI_PLATFORM_MEDIAWIKI => 'Mediawiki',
164                 SHAREDAPI_PLATFORM_DOKUWIKI => 'DokuWiki'
165             );
166         }
167 
168         return $platform ? $platforms[$platform] : $platforms;
169     }
170 
171     function sharedapi_get_platforms_ids() {
172         static $platforms;
173 
174         if (!$platforms) {
175             $platforms = array(
176                 SHAREDAPI_PLATFORM_UNKNOWN => 'unknown',
177                 SHAREDAPI_PLATFORM_VBULLETIN => 'vbulletin',
178                 SHAREDAPI_PLATFORM_INTERSPIRESHOPPINGCART => 'interspireshoppingcart',
179                 SHAREDAPI_PLATFORM_MOODLE => 'moodle',
180                 SHAREDAPI_PLATFORM_WORDPRESS => 'wordpress',
181                 SHAREDAPI_PLATFORM_JOOMLA => 'joomla',
182                 SHAREDAPI_PLATFORM_DRUPAL => 'drupal',
183                 SHAREDAPI_PLATFORM_PRESTASHOP => 'prestashop',
184                 SHAREDAPI_PLATFORM_MAGENTO => 'magento',
185                 SHAREDAPI_PLATFORM_MEDIAWIKI => 'mediawiki',
186                 SHAREDAPI_PLATFORM_DOKUWIKI => 'dokuwiki'
187             );
188         }
189 
190         return $platforms;
191     }
192 
193     function SHAREDAPI_NAME_DEFINITION($brand, $definition) {
194         return $brand . '_' . $definition;
195     }
196 
197     /**
198      * GPC helpers.
199      **/
200     function sharedapi_extract_gpc_variable($source, $name, $default = '') {
201         $v = $default;
202 
203         if (is_array($name)) {
204             $v = array();
205             foreach ($name as $n) {
206                 if (isset($source[$n])) {
207                     $v[$n] = $source[$n];
208                 }
209             }
210         } else {
211             if (isset($source[$name])) {
212                 $v = $source[$name];
213             }
214         }
215 
216         return $v;
217     }
218 
219     function sharedapi_gpc_variable($name, $default = '', $r = 'g') {
220         $v = $default;
221 
222         switch ($r) {
223             case 'g':
224                 $v = sharedapi_extract_gpc_variable($_GET, $name, $default);
225                 break;
226             case 'p':
227                 $v = sharedapi_extract_gpc_variable($_POST, $name, $default);
228                 break;
229             case 'c':
230                 $v = sharedapi_extract_gpc_variable($_COOKIE, $name, $default);
231                 break;
232             case 's':
233                 $v = sharedapi_extract_gpc_variable($_SERVER, $name, $default);
234                 break;
235         }
236 
237         return $v;
238     }
239 
240     /**
241      * Trying to extract destination from the following sources in a certain order.
242      * Check in url(destination)
243      * Check in header(referer)
244      * Check in session
245      * */
246     function sharedapi_capture_gpc_variable($name, $gname, $event, $r = 'r', $reset = false) {
247         $variable = '';
248 
249         for ($i = 0; $i < strlen($r); $i++) {
250             $ch = $r[$i];
251             switch ($ch) {
252                 case 'r':
253                     if (empty($variable) && isset($_SERVER['HTTP_REFERER'])) {
254                         $variable = $_SERVER['HTTP_REFERER'];
255                     }
256                     break;
257                 case 's':
258                     if (empty($variable) && isset($_SESSION[$name])) {
259                         $variable = $_SESSION[$name];
260                     }
261                     break;
262                 case 'c':
263                     if (empty($variable) && isset($_COOKIE[$name])) {
264                         $variable = sharedapi_gpc_variable($name, '', 'c');
265                     }
266                     break;
267                 case 'g':
268                     if (empty($variable) && isset($_GET[$gname])) {
269                         $variable = sharedapi_gpc_variable($gname, '', 'g');
270                     }
271                     break;
272                 case 'p':
273                     if (empty($variable) && isset($_GET[$gname])) {
274                         $variable = sharedapi_gpc_variable($gname, '', 'p');
275                     }
276                     break;
277             }
278         }
279 
280         if ($reset) {
281             setcookie($name, $_SESSION[$name] = '', 0, '/');
282         }
283 
284         if (strpos($variable, $event . ':') !== false) {
285             $variable = substr($variable, strlen($event . ':'));
286         } else /*if (SHAREDAPI_EVENT_UNKNOWN == $event)*/ {
287             if (preg_match('/^\d+:(.*)/', $variable, $matches)) {
288                 $variable = $matches[1];
289             }
290         }
291 
292         return $variable;
293     }
294 
295     function sharedapi_get_destination($pid, $event, $r = 'r', $reset = false) {
296         return sharedapi_capture_gpc_variable(SHAREDAPI_NAME_DEFINITION($pid, SHAREDAPI_EVENT_FIELD_DESTINATION), SHAREDAPI_EVENT_FIELD_DESTINATION, $event, $r, $reset);
297     }
298 
299     function sharedapi_get_final_destination($pid, $event) {
300         sharedapi_get_final_lid($pid, $event);
301         return sharedapi_capture_gpc_variable(SHAREDAPI_NAME_DEFINITION($pid, SHAREDAPI_EVENT_FIELD_DESTINATION), SHAREDAPI_EVENT_FIELD_DESTINATION, $event, 'sc', true);
302     }
303 
304     function sharedapi_get_lid($pid, $event, $r = 'r', $reset = false) {
305         return sharedapi_capture_gpc_variable(SHAREDAPI_NAME_DEFINITION($pid, SHAREDAPI_EVENT_FIELD_LID), SHAREDAPI_EVENT_FIELD_LID, $event, $r, $reset);
306     }
307 
308     function sharedapi_get_final_lid($pid, $event) {
309         return sharedapi_capture_gpc_variable(SHAREDAPI_NAME_DEFINITION($pid, SHAREDAPI_EVENT_FIELD_LID), SHAREDAPI_EVENT_FIELD_LID, $event, 'sc', true);
310     }
311 
312     function sharedapi_capture_destination($pid, $event, $api_path) {
313         $expire = time() + 60 * 4; // expire in 4 minutes.
314 
315         $destination = sharedapi_get_destination($pid, $event, 'gr');
316         if (!empty($destination) && strpos($destination, $api_path) === false) {
317             setcookie(SHAREDAPI_NAME_DEFINITION($pid, SHAREDAPI_EVENT_FIELD_DESTINATION), $_SESSION[SHAREDAPI_NAME_DEFINITION($pid, SHAREDAPI_EVENT_FIELD_DESTINATION)] = $event . ':' . $destination, $expire, '/');
318         }
319 
320         $lid = sharedapi_get_lid($pid, $event, 'g');
321         if (!empty($lid)) {
322             setcookie(SHAREDAPI_NAME_DEFINITION($pid, SHAREDAPI_EVENT_FIELD_LID), $_SESSION[SHAREDAPI_NAME_DEFINITION($pid, SHAREDAPI_EVENT_FIELD_LID)] = $event . ':' . $lid, $expire, '/');
323         }
324     }
325 
326     /**
327      * Encryption helpers.
328      **/
329     function sharedapi_encrypt($key, $data) {
330         $key = sharedapi_get_valid_key($key);
331         return trim(base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $data, MCRYPT_MODE_ECB, mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_ECB), MCRYPT_RAND))));
332     }
333 
334     function sharedapi_decrypt($key, $data) {
335         $key = sharedapi_get_valid_key($key);
336         return trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, base64_decode($data), MCRYPT_MODE_ECB, mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_ECB), MCRYPT_RAND)));
337     }
338 
339     function sharedapi_encode_data($key, $json) {
340         $data = json_encode($json);
341         return sharedapi_encrypt($key, $data);
342     }
343 
344     function sharedapi_decode_data($key, $data) {
345         $data = sharedapi_decrypt($key, $data);
346         return json_decode($data, true);
347     }
348 
349     /*
350      * The fuction returns key with proper length. Only 16, 24, 32 accepted since PHP 5.6 for MCRYPT_RIJNDAEL_128
351      * Invalid key and iv sizes are no longer accepted.
352      */
353     function sharedapi_get_valid_key($key) {
354         $accepted_length = array(16, 24, 32);
355 
356         //1st case: key has valid length
357         if (in_array(strlen($key), $accepted_length)) {
358             return $key;
359         }
360 
361         //2nd case: key length is less than MAX allowed
362         foreach ($accepted_length as $length) {
363             if (strlen($key) < $length) {
364                 return str_pad($key, $length, "\0");
365             }
366         }
367 
368         //3d case: key length is greater than MAX allowed
369         if (strlen($key) > end($accepted_length)) {
370             return substr($key, 0, end($accepted_length));
371         }
372     }
373 
374     /**
375      * DATA helpers.
376      **/
377     function sharedapi_is_error_data_item($data) {
378         return is_array($data) && isset($data[SHAREDAPI_EVENT_FIELD_ERROR_MESSAGE]);
379     }
380 
381     function sharedapi_data_handler($product, $version, $vbsso_version, $shared_key, $callback) {
382         $ret = null;
383 
384         sharedapi_set_cookie_policy();
385 
386         $json = sharedapi_accept_data($shared_key);
387         if (is_array($json) && isset($json[SHAREDAPI_EVENT_FIELD_EVENT])) {
388             if (array_key_exists($json[SHAREDAPI_EVENT_FIELD_EVENT], $callback) && function_exists($callback[$json[SHAREDAPI_EVENT_FIELD_EVENT]])) {
389                 $ret = call_user_func($callback[$json[SHAREDAPI_EVENT_FIELD_EVENT]], $json);
390             }
391         } else {
392             $ret[SHAREDAPI_EVENT_FIELD_ERROR] = $json;
393         }
394 
395         $ret = $ret && is_array($ret) ? $ret : null;
396 
397         echo sharedapi_build_response($product, $version, $vbsso_version,
398             $ret && isset($ret[SHAREDAPI_EVENT_FIELD_DATA]) ? $ret[SHAREDAPI_EVENT_FIELD_DATA] : null,
399             $ret && isset($ret[SHAREDAPI_EVENT_FIELD_ERROR]) ? $ret[SHAREDAPI_EVENT_FIELD_ERROR] : null,
400             $shared_key);
401         exit;
402     }
403 
404     function sharedapi_accept_data($key, $data = '', $is_response = false) {
405         //Removes UTF-8 Byte order mark (BOM)
406         if (substr($data, 0, 3) == pack('CCC', 239, 187, 191)) {
407             $data = substr($data, 3);
408         }
409 
410         if (empty($data)) {
411             $data = isset($_REQUEST[SHAREDAPI_EVENT_FIELD_DATA]) ? $_REQUEST[SHAREDAPI_EVENT_FIELD_DATA] : '';
412         }
413 
414         $json = array();
415         if (!empty($data)) {
416             $json = $is_response ? json_decode($data, true) : sharedapi_decode_data($key, $data);
417             $json = ($json) ? $json : SHAREDAPI_WRONG_API_KEY_MESSAGE;
418         }
419 
420         if (is_array($json) && isset($json[SHAREDAPI_EVENT_FIELD_PRODUCT]) && isset($json[SHAREDAPI_EVENT_FIELD_DATA])) {
421             $json[SHAREDAPI_EVENT_FIELD_DATA] = sharedapi_decode_data($key, $json[SHAREDAPI_EVENT_FIELD_DATA]);
422         }
423 
424 //        return is_array($json) && (isset($json[SHAREDAPI_EVENT_FIELD_EVENT]) || isset($json[SHAREDAPI_EVENT_FIELD_PRODUCT]))
425 //            ? $json : false;
426         return $json;
427     }
428 
429     function sharedapi_build_data_item($key, $data) {
430         return array(SHAREDAPI_EVENT_FIELD_DATA => sharedapi_encode_data($key, $data));
431     }
432 
433     function sharedapi_build_response($product, $version, $vbsso_version, $data = null, $error = null, $key = null) {
434         $response = array(
435             SHAREDAPI_EVENT_FIELD_PRODUCT => $product,
436             SHAREDAPI_EVENT_FIELD_VERSION => $version,
437             SHAREDAPI_EVENT_FIELD_PLUGIN_VERSION => $vbsso_version,
438         );
439 
440         if ($error) {
441             $response[SHAREDAPI_EVENT_FIELD_ERROR] = $error;
442         }
443 
444         if ($data) {
445             $data = json_encode($data);
446             if ($key) {
447                 $data = sharedapi_encrypt($key, $data);
448             }
449 
450             $response[SHAREDAPI_EVENT_FIELD_DATA] = $data;
451         }
452 
453         if (defined('PHP_VERSION')) {
454             $response[SHAREDAPI_EVENT_FIELD_PHP_VERSION] = PHP_VERSION;
455         }
456         $response[SHAREDAPI_EVENT_FIELD_MEMORY_LIMIT] = ini_get('memory_limit');
457         if (defined('WP_MEMORY_LIMIT')) {
458             $response[SHAREDAPI_EVENT_FIELD_WP_MEMORY_LIMIT] = WP_MEMORY_LIMIT;
459         }
460 
461 
462         return json_encode($response);
463     }
464 
465     function sharedapi_post($url, $fields, $username = '', $password = '', $timeout = 5, $connecttimeout = 5) {
466         $ch = curl_init();
467 
468         curl_setopt($ch, CURLOPT_URL, $url);
469 
470         if (!empty($username)) {
471             curl_setopt($ch, CURLOPT_USERPWD, "$username:$password");
472         }
473 
474         curl_setopt($ch, CURLOPT_POST, 1);
475         curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);
476         curl_setopt($ch, CURLOPT_HTTPHEADER, array('User-Agent: vBSSO'));
477         curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
478         curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
479         curl_setopt($ch, CURLOPT_HEADER, 0);
480         curl_setopt($ch, CURLOPT_TIMEOUT, intval($timeout));
481         curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, intval($connecttimeout));
482 
483         $data = curl_exec($ch);
484 
485         $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
486         $error_string = ($code != 200) ? curl_error($ch) : '';
487         curl_close($ch);
488 
489         return array('code' => $code, 'response' => $data, 'error_string' => $error_string);
490     }
491 
492     function sharedapi_http_status_error($status) {
493         $status = intval($status);
494         return $status >= 400;
495     }
496 
497     function sharedapi_log($data, $file = 'default', $path = null) {
498         if (!$path) {
499             $path = dirname(__FILE__);
500         }
501 
502         if ($file == 'default') {
503             $file = 'sharedapi.log';
504         }
505 
506         $handle = fopen($path . '/' . $file, "a+");
507 
508         $output = '';
509         if (is_array($data)) {
510             foreach ($data as $key => $value) {
511                 $output .= $key . '=' . $value . '&';
512             }
513         } else if (is_bool($data)) {
514             $output = $data ? 'true' : 'false';
515         } else {
516             $output = $data;
517         }
518 
519         $datetime = date('Y-m-d_H-i-s', time());
520         fwrite($handle, $datetime . ': ' . $output . "\n");
521         fclose($handle);
522     }
523 
524     /**
525      * URL helpers.
526      **/
527     function sharedapi_url_add_destination($url, $capture_referrer = true, $default = '', $lid = '', $query = '') {
528         if (!empty($url)) {
529             $referrer = '';
530 
531             if ($capture_referrer === true || $capture_referrer > 0) {
532                 $referrer = sharedapi_gpc_variable('HTTP_REFERER', '', 's');
533             } else if ($capture_referrer !== false && $capture_referrer !== 0) {
534                 $referrer = sharedapi_get_server_url();
535             }
536 
537             if (empty($referrer) && $default && !empty($default)) {
538                 $referrer = $default;
539             }
540 
541             if (empty($referrer)) {
542                 $referrer = sharedapi_get_server_url();
543             }
544 
545             if (!empty($referrer)) {
546                 $url = sharedapi_url_add_query($url, SHAREDAPI_EVENT_FIELD_DESTINATION . '=' . urlencode($referrer));
547 
548                 if ($lid && !empty($lid)) {
549                     $url = sharedapi_url_add_query($url, SHAREDAPI_EVENT_FIELD_LID . '=' . $lid);
550                 }
551 
552                 if ($query && !empty($query) && is_string($query)) {
553                     $url = sharedapi_url_add_query($url, $query);
554                 }
555             }
556         }
557 
558         return $url;
559     }
560 
561     function sharedapi_url_get_referrer() {
562         return sharedapi_gpc_variable('HTTP_REFERER', '', 's');
563     }
564 
565     function sharedapi_url_add_lid($url, $lid = '', $query = '') {
566         if (!empty($url)) {
567             if ($lid && !empty($lid)) {
568                 $url = sharedapi_url_add_query($url, SHAREDAPI_EVENT_FIELD_LID . '=' . $lid);
569             }
570 
571             if ($query && !empty($query) && is_string($query)) {
572                 $url = sharedapi_url_add_query($url, $query);
573             }
574         }
575 
576         return $url;
577     }
578 
579     function sharedapi_url_add_query($url, $query) {
580         if (!empty($url)) {
581             if (strpos($url, '?') === false) {
582                 $url .= '?';
583             } else {
584                 $url .= '&';
585             }
586         }
587 
588         return $url . $query;
589     }
590 
591     function sharedapi_url_redirect($url) {
592         if (!empty($url)) {
593             header('Location: ' . $url);
594         }
595     }
596 
597     function sharedapi_get_server_url($uri = true) {
598         if ($_SERVER['SERVER_PORT'] == '80') {
599             $url = 'http://' . $_SERVER['SERVER_NAME'] . '';
600         } else if (isset($_SERVER['HTTPS'])) {
601             $url = 'https://' . $_SERVER['SERVER_NAME'] . '';
602         } else {
603             $url = 'http://' . $_SERVER['SERVER_NAME'] . ':' . $_SERVER['SERVER_PORT'] . '';
604         }
605 
606         if ($uri === true) {
607             $url .= $_SERVER['REQUEST_URI'];
608         } else if (is_string($uri)) {
609             $url .= $uri;
610         }
611 
612         return $url;
613     }
614 
615     //rsf is register_shutdown_function. Some hosting providers disable it for security reasons.
616     function sharedapi_is_rsf_disabled() {
617         return in_array('register_shutdown_function', explode(',', ini_get('disable_functions')));
618     }
619 
620     function sharedapi_get_primary_domain($url) {
621         if (empty($url)) {
622             return '';
623         }
624 
625         $url_host = parse_url(strtolower($url), PHP_URL_HOST);
626         if (strpos('www.', $url_host) === 0) {
627             $url_host = substr($url_host, 4);
628         }
629 
630         $dots_count = substr_count('.', $url_host);
631         if ($dots_count < 2 OR ($dots_count == 4 && ip2long($url_host))) {
632             return $url_host;
633         }
634 
635         $domainArray = explode('.', $url_host);
636         $topLevelDomainArray = array(array_pop($domainArray), array_pop($domainArray));
637         krsort($topLevelDomainArray);
638         return strtolower(join('.', $topLevelDomainArray));
639     }
640 
641     function sharedapi_set_cookie_policy(){
642         $referer_primary_domain = sharedapi_get_primary_domain(sharedapi_gpc_variable('HTTP_REFERER', '', 's'));
643         $server_primary_domain = sharedapi_get_primary_domain(sharedapi_get_server_url());
644 
645         if ($referer_primary_domain !== $server_primary_domain) {
646             header("p3p:CP=\"NOI ADM DEV COM NAV OUR STP\"");
647         }
648     }
649 }