/** * Load data associated with a user. */ public function getData($username) { $result = db_select('ga_login')->fields('ga_login', array('keydata'))->condition('name', $username)->execute()->fetchAssoc(); // Check the result. if (!$result) { return FALSE; } // Decrypt the data, if a plugin in available. if (module_exists('aes')) { return aes_decrypt($result["keydata"]); } elseif (module_exists('encrypt')) { return decrypt($result["keydata"]); } return $result["keydata"]; }
/** * This service will expect a JSON POST data of: * ["data"] => {"nonce": "randomString", "message": "cipherText", "signature": "abcdef"} * Signature will be a sha256 of the message pre-encrypt with nonce appended to the end * ie * {JSON} + nonce + sharedhash * Note: sharedhash should NOT be the sharedkey that is used to encrypt the message * * * Unencrypted cipherText will look like * {"output": "stdout of run", "time_taken": 10, "result": 0} * Just like in most modern programs - a result of anything but 0 indicates an error * * @param $jobId */ public function upload($jobId) { if ($jobId && is_numeric($jobId)) { /** @var \application\models\Jobs $job */ $job = \application\models\Jobs::getByField("id", $jobId); if (!$job) { echo ""; return; } $job = $job[0]; //decrypt message $data = json_decode($_POST["data"], true); $rawMessage = aes_decrypt($job->sharedkey, $data["message"]); /*$rawMessage = str_replace("\\n", "", $rawMessage); $rawMessage = str_replace("\\r", "", $rawMessage); $rawMessage = str_replace("\\", "", $rawMessage);*/ $rawMessage = preg_replace('/[^(\\x20-\\x7F)]*/', '', $rawMessage); // if decryption was successful - // check signature if (hash("sha256", $rawMessage . $data["nonce"] . $job->hash) == $data["signature"]) { // the message is verified $message = json_decode($rawMessage, true); $replayAttackCheck = DB::fetch("SELECT id FROM histories WHERE jobs_id = ? AND nonce = ?", [$job->id, $data["nonce"]]); if (count($replayAttackCheck) == 0) { $history = \application\models\Histories::create($message); $history->run_date = date("Y-m-d H:i:s"); $history->jobs_id = $job->id; $history->nonce = $data["nonce"]; $history->save(); $job->last_result = $history->result; $job->last_run = $history->run_date; $job->save(); } } } }
function dfrn_notify_post(&$a) { $dfrn_id = x($_POST, 'dfrn_id') ? notags(trim($_POST['dfrn_id'])) : ''; $dfrn_version = x($_POST, 'dfrn_version') ? (double) $_POST['dfrn_version'] : 2.0; $challenge = x($_POST, 'challenge') ? notags(trim($_POST['challenge'])) : ''; $data = x($_POST, 'data') ? $_POST['data'] : ''; $key = x($_POST, 'key') ? $_POST['key'] : ''; $dissolve = x($_POST, 'dissolve') ? intval($_POST['dissolve']) : 0; $perm = x($_POST, 'perm') ? notags(trim($_POST['perm'])) : 'r'; $ssl_policy = x($_POST, 'ssl_policy') ? notags(trim($_POST['ssl_policy'])) : 'none'; $page = x($_POST, 'page') ? intval($_POST['page']) : 0; $forum = $page == 1 ? 1 : 0; $prv = $page == 2 ? 1 : 0; $writable = -1; if ($dfrn_version >= 2.21) { $writable = $perm === 'rw' ? 1 : 0; } $direction = -1; if (strpos($dfrn_id, ':') == 1) { $direction = intval(substr($dfrn_id, 0, 1)); $dfrn_id = substr($dfrn_id, 2); } $r = q("SELECT * FROM `challenge` WHERE `dfrn-id` = '%s' AND `challenge` = '%s' LIMIT 1", dbesc($dfrn_id), dbesc($challenge)); if (!count($r)) { logger('dfrn_notify: could not match challenge to dfrn_id ' . $dfrn_id . ' challenge=' . $challenge); xml_status(3); } $r = q("DELETE FROM `challenge` WHERE `dfrn-id` = '%s' AND `challenge` = '%s' LIMIT 1", dbesc($dfrn_id), dbesc($challenge)); // find the local user who owns this relationship. $sql_extra = ''; switch ($direction) { case -1: $sql_extra = sprintf(" AND ( `issued-id` = '%s' OR `dfrn-id` = '%s' ) ", dbesc($dfrn_id), dbesc($dfrn_id)); break; case 0: $sql_extra = sprintf(" AND `issued-id` = '%s' AND `duplex` = 1 ", dbesc($dfrn_id)); break; case 1: $sql_extra = sprintf(" AND `dfrn-id` = '%s' AND `duplex` = 1 ", dbesc($dfrn_id)); break; default: xml_status(3); break; // NOTREACHED } // be careful - $importer will contain both the contact information for the contact // sending us the post, and also the user information for the person receiving it. // since they are mixed together, it is easy to get them confused. $r = q("SELECT\t`contact`.*, `contact`.`uid` AS `importer_uid`, \n\t\t\t\t\t`contact`.`pubkey` AS `cpubkey`, \n\t\t\t\t\t`contact`.`prvkey` AS `cprvkey`, \n\t\t\t\t\t`contact`.`thumb` AS `thumb`, \n\t\t\t\t\t`contact`.`url` as `url`,\n\t\t\t\t\t`contact`.`name` as `senderName`,\n\t\t\t\t\t`user`.* \n\t\t\tFROM `contact` \n\t\t\tLEFT JOIN `user` ON `contact`.`uid` = `user`.`uid` \n\t\t\tWHERE `contact`.`blocked` = 0 AND `contact`.`pending` = 0 \n\t\t\t\tAND `user`.`nickname` = '%s' AND `user`.`account_expired` = 0 {$sql_extra} LIMIT 1", dbesc($a->argv[1])); if (!count($r)) { logger('dfrn_notify: contact not found for dfrn_id ' . $dfrn_id); xml_status(3); //NOTREACHED } // $importer in this case contains the contact record for the remote contact joined with the user record of our user. $importer = $r[0]; if ($writable != -1 && $writable != $importer['writable'] || $importer['forum'] != $forum || $importer['prv'] != $prv) { q("UPDATE `contact` SET `writable` = %d, forum = %d, prv = %d WHERE `id` = %d LIMIT 1", intval($writable == -1 ? $importer['writable'] : $writable), intval($forum), intval($prv), intval($importer['id'])); if ($writable != -1) { $importer['writable'] = $writable; } $importer['forum'] = $page; } // if contact's ssl policy changed, update our links fix_contact_ssl_policy($importer, $ssl_policy); logger('dfrn_notify: received notify from ' . $importer['name'] . ' for ' . $importer['username']); logger('dfrn_notify: data: ' . $data, LOGGER_DATA); if ($dissolve == 1) { /** * Relationship is dissolved permanently */ require_once 'include/Contact.php'; contact_remove($importer['id']); logger('relationship dissolved : ' . $importer['name'] . ' dissolved ' . $importer['username']); xml_status(0); } // If we are setup as a soapbox we aren't accepting input from this person if ($importer['page-flags'] == PAGE_SOAPBOX) { xml_status(0); } if (strlen($key)) { $rawkey = hex2bin(trim($key)); logger('rino: md5 raw key: ' . md5($rawkey)); $final_key = ''; if ($dfrn_version >= 2.1) { if ($importer['duplex'] && strlen($importer['cprvkey']) || !strlen($importer['cpubkey'])) { openssl_private_decrypt($rawkey, $final_key, $importer['cprvkey']); } else { openssl_public_decrypt($rawkey, $final_key, $importer['cpubkey']); } } else { if ($importer['duplex'] && strlen($importer['cpubkey']) || !strlen($importer['cprvkey'])) { openssl_public_decrypt($rawkey, $final_key, $importer['cpubkey']); } else { openssl_private_decrypt($rawkey, $final_key, $importer['cprvkey']); } } logger('rino: received key : ' . $final_key); $data = aes_decrypt(hex2bin($data), $final_key); logger('rino: decrypted data: ' . $data, LOGGER_DATA); } $ret = local_delivery($importer, $data); xml_status($ret); // NOTREACHED }
/** * 密码解密 * @param string $pwd * @return string */ public function pwdDecrypt($pwd) { return aes_decrypt($pwd, C('CRYPT_KEY_PWD')); }
/** * 通信信息解密 * @param string $id * @return string */ function act_decrypt($id = '') { if (!$id) { return ''; } return str_replace(session_id(), '', aes_decrypt(substr($id, strlen('encrypt_act-')), C('CRYPT_KEY_ACT'))); }
function dfrn_notify_post(&$a) { logger(__FUNCTION__, LOGGER_TRACE); $dfrn_id = x($_POST, 'dfrn_id') ? notags(trim($_POST['dfrn_id'])) : ''; $dfrn_version = x($_POST, 'dfrn_version') ? (double) $_POST['dfrn_version'] : 2.0; $challenge = x($_POST, 'challenge') ? notags(trim($_POST['challenge'])) : ''; $data = x($_POST, 'data') ? $_POST['data'] : ''; $key = x($_POST, 'key') ? $_POST['key'] : ''; $rino_remote = x($_POST, 'rino') ? intval($_POST['rino']) : 0; $dissolve = x($_POST, 'dissolve') ? intval($_POST['dissolve']) : 0; $perm = x($_POST, 'perm') ? notags(trim($_POST['perm'])) : 'r'; $ssl_policy = x($_POST, 'ssl_policy') ? notags(trim($_POST['ssl_policy'])) : 'none'; $page = x($_POST, 'page') ? intval($_POST['page']) : 0; $forum = $page == 1 ? 1 : 0; $prv = $page == 2 ? 1 : 0; $writable = -1; if ($dfrn_version >= 2.21) { $writable = $perm === 'rw' ? 1 : 0; } $direction = -1; if (strpos($dfrn_id, ':') == 1) { $direction = intval(substr($dfrn_id, 0, 1)); $dfrn_id = substr($dfrn_id, 2); } $r = q("SELECT * FROM `challenge` WHERE `dfrn-id` = '%s' AND `challenge` = '%s' LIMIT 1", dbesc($dfrn_id), dbesc($challenge)); if (!count($r)) { logger('dfrn_notify: could not match challenge to dfrn_id ' . $dfrn_id . ' challenge=' . $challenge); xml_status(3); } $r = q("DELETE FROM `challenge` WHERE `dfrn-id` = '%s' AND `challenge` = '%s'", dbesc($dfrn_id), dbesc($challenge)); // find the local user who owns this relationship. $sql_extra = ''; switch ($direction) { case -1: $sql_extra = sprintf(" AND ( `issued-id` = '%s' OR `dfrn-id` = '%s' ) ", dbesc($dfrn_id), dbesc($dfrn_id)); break; case 0: $sql_extra = sprintf(" AND `issued-id` = '%s' AND `duplex` = 1 ", dbesc($dfrn_id)); break; case 1: $sql_extra = sprintf(" AND `dfrn-id` = '%s' AND `duplex` = 1 ", dbesc($dfrn_id)); break; default: xml_status(3); break; // NOTREACHED } // be careful - $importer will contain both the contact information for the contact // sending us the post, and also the user information for the person receiving it. // since they are mixed together, it is easy to get them confused. $r = q("SELECT\t`contact`.*, `contact`.`uid` AS `importer_uid`,\n\t\t\t\t\t`contact`.`pubkey` AS `cpubkey`,\n\t\t\t\t\t`contact`.`prvkey` AS `cprvkey`,\n\t\t\t\t\t`contact`.`thumb` AS `thumb`,\n\t\t\t\t\t`contact`.`url` as `url`,\n\t\t\t\t\t`contact`.`name` as `senderName`,\n\t\t\t\t\t`user`.*\n\t\t\tFROM `contact`\n\t\t\tLEFT JOIN `user` ON `contact`.`uid` = `user`.`uid`\n\t\t\tWHERE `contact`.`blocked` = 0 AND `contact`.`pending` = 0\n\t\t\t\tAND `user`.`nickname` = '%s' AND `user`.`account_expired` = 0 AND `user`.`account_removed` = 0 {$sql_extra} LIMIT 1", dbesc($a->argv[1])); if (!count($r)) { logger('dfrn_notify: contact not found for dfrn_id ' . $dfrn_id); xml_status(3); //NOTREACHED } // $importer in this case contains the contact record for the remote contact joined with the user record of our user. $importer = $r[0]; logger("Remote rino version: " . $rino_remote . " for " . $importer["url"], LOGGER_DEBUG); if ($writable != -1 && $writable != $importer['writable'] || $importer['forum'] != $forum || $importer['prv'] != $prv) { q("UPDATE `contact` SET `writable` = %d, forum = %d, prv = %d WHERE `id` = %d", intval($writable == -1 ? $importer['writable'] : $writable), intval($forum), intval($prv), intval($importer['id'])); if ($writable != -1) { $importer['writable'] = $writable; } $importer['forum'] = $page; } // if contact's ssl policy changed, update our links fix_contact_ssl_policy($importer, $ssl_policy); logger('dfrn_notify: received notify from ' . $importer['name'] . ' for ' . $importer['username']); logger('dfrn_notify: data: ' . $data, LOGGER_DATA); if ($dissolve == 1) { /** * Relationship is dissolved permanently */ require_once 'include/Contact.php'; contact_remove($importer['id']); logger('relationship dissolved : ' . $importer['name'] . ' dissolved ' . $importer['username']); xml_status(0); } // If we are setup as a soapbox we aren't accepting input from this person // This behaviour is deactivated since it really doesn't make sense to even disallow comments // The check if someone is a friend or simply a follower is done in a later place so it needn't to be done here //if($importer['page-flags'] == PAGE_SOAPBOX) // xml_status(0); $rino = get_config('system', 'rino_encrypt'); $rino = intval($rino); // use RINO1 if mcrypt isn't installed and RINO2 was selected if ($rino == 2 and !function_exists('mcrypt_create_iv')) { $rino = 1; } logger("Local rino version: " . $rino, LOGGER_DEBUG); if (strlen($key)) { // if local rino is lower than remote rino, abort: should not happen! // but only for $remote_rino > 1, because old code did't send rino version if ($rino_remote_version > 1 && $rino < $rino_remote) { logger("rino version '{$rino_remote}' is lower than supported '{$rino}'"); xml_status(0, "rino version '{$rino_remote}' is lower than supported '{$rino}'"); } $rawkey = hex2bin(trim($key)); logger('rino: md5 raw key: ' . md5($rawkey)); $final_key = ''; if ($dfrn_version >= 2.1) { if ($importer['duplex'] && strlen($importer['cprvkey']) || !strlen($importer['cpubkey'])) { openssl_private_decrypt($rawkey, $final_key, $importer['cprvkey']); } else { openssl_public_decrypt($rawkey, $final_key, $importer['cpubkey']); } } else { if ($importer['duplex'] && strlen($importer['cpubkey']) || !strlen($importer['cprvkey'])) { openssl_public_decrypt($rawkey, $final_key, $importer['cpubkey']); } else { openssl_private_decrypt($rawkey, $final_key, $importer['cprvkey']); } } #logger('rino: received key : ' . $final_key); switch ($rino_remote) { case 0: case 1: // we got a key. old code send only the key, without RINO version. // we assume RINO 1 if key and no RINO version $data = aes_decrypt(hex2bin($data), $final_key); break; case 2: try { $data = Crypto::decrypt(hex2bin($data), $final_key); } catch (InvalidCiphertext $ex) { // VERY IMPORTANT // Either: // 1. The ciphertext was modified by the attacker, // 2. The key is wrong, or // 3. $ciphertext is not a valid ciphertext or was corrupted. // Assume the worst. logger('The ciphertext has been tampered with!'); xml_status(0, 'The ciphertext has been tampered with!'); } catch (Ex\CryptoTestFailed $ex) { logger('Cannot safely perform dencryption'); xml_status(0, 'CryptoTestFailed'); } catch (Ex\CannotPerformOperation $ex) { logger('Cannot safely perform decryption'); xml_status(0, 'Cannot safely perform decryption'); } break; default: logger("rino: invalid sent verision '{$rino_remote}'"); xml_status(0); } logger('rino: decrypted data: ' . $data, LOGGER_DATA); } $ret = local_delivery($importer, $data); xml_status($ret); // NOTREACHED }
function sessionuse() { global $global_sessionexpiry; // check cookies exist and are not void if (!isset($_COOKIE['TOKEN1'])) { return; } if (!isset($_COOKIE['TOKEN2'])) { return; } if ($_COOKIE['TOKEN1'] == "0") { return; } if ($_COOKIE['TOKEN2'] == "0") { return; } // decrypt the cookies $cookie1 = aes_decrypt($_COOKIE['TOKEN1']); $cookie2 = aes_decrypt($_COOKIE['TOKEN2']); // break up the cookies $bits = explode("|||", $cookie1); $ipaddress = $bits[0]; $sessiontoken1 = $bits[1]; $userID = $bits[2]; $bits = explode("&&&", $cookie2); $sessiontoken2 = $bits[0]; $useragent = $bits[1]; // check cookie values match current http values if (!($ipaddress == $_SERVER['REMOTE_ADDR'])) { header("Location: /public/expired.php"); return; } if (!($useragent = substr($_SERVER['HTTP_USER_AGENT'], 0, 64))) { header("Location: /public/expired.php"); return; } // get database values and check they match $result = doSQL("select userID, email, sessiontoken1, sessiontoken2, sessionipaddress, sessionuseragent, timestampdiff(second, sessionlastdateSQL, now()) as inactivetime from users where userID=?;", $userID) or die("ERR"); // userID found? if (!is_array($result)) { header("Location: /public/expired.php"); return; } // check fields are populated if ($result[0]['sessionipaddress'] == '' || $result[0]['sessionuseragent'] == '' || $result[0]['sessiontoken1'] == '' || $result[0]['sessiontoken2'] == '') { header("Location: /public/expired.php"); return; } // has session expired? if ($result[0]['inactivetime'] > $global_sessionexpiry) { header("Location: /public/expired.php"); return; } // values match? if (!($ipaddress == $result[0]['sessionipaddress'])) { header("Location: /public/expired.php"); return; } if (!($useragent == $result[0]['sessionuseragent'])) { header("Location: /public/expired.php"); return; } if (!($sessiontoken1 == $result[0]['sessiontoken1'])) { header("Location: /public/expired.php"); return; } if (!($sessiontoken2 == $result[0]['sessiontoken2'])) { header("Location: /public/expired.php"); return; } // all ok, set '$S' session array $S = array(); $S['userID'] = $result[0]['userID']; $S['email'] = $result[0]['email']; // to add more session variables: // add a column to the users table // select that column in the query above // add it to the $S array // also update the sessionsave() and sessionend() functions return $S; }