public function deserialize(&$data) { parent::deserialize($data); $size = 0; $this->bytesToInt($size, $data); for ($i = 0; $i < $size; $i++) { $peer = new Peer(); $peer->deserialize($data); $this->peerlist[] = $peer; } }
/** * Delete all old peers from database * * */ public static function deleteOldPeers() { // Deleting old peers from the database foreach (Peer::all() as $peer) { if (time() - strtotime($peer->updated_at) > 10 * 60) { $peer->delete(); } } return true; }
/** * this function hooks cases of keyswap being called with forced mode. * Forced mode can only be used from hosts we trust untill now. * * @see api/xmlrpc/dispatcher.php::keyswap() * * Add : * // PATCH add force mode * if (!empty($params[3])){ // requiring force mode * $mnetlocallib = get_config('docroot').'/local/mnet/lib.php'; * if (file_exists($mnetlocallib)){ * return local_xmlrpc_key_forced_keyswap($wwwroot, $pubkey, $application); * } * return false; * } * // /PATCH * * after $params decoding for enabling forced mode. */ function local_xmlrpc_key_forced_keyswap($wwwroot, $pubkey, $application) { $now = time(); // reinforced security : only known host with still valid key can force us renewal if ($exists = get_records_select_array('host', " wwwroot = '{$wwwroot}' AND deleted = 0 AND publickeyexpires >= {$now} ")) { try { $peer = new Peer(); if ($peer->findByWwwroot($wwwroot)) { $pk = new PublicKey($pubkey, $wwwroot); $peer->publickey = $pk; $peer->commit(); } // Mahara return his own key $openssl = OpenSslRepo::singleton(); return $openssl->certificate; } catch (Exception $e) { throw new SystemException($e->getMessage(), $e->getCode()); } } else { throw new SystemException("Fails exists known {$wwwroot} as wwwroot", 6100); } }
/** * Does this peer notary see the same Merkle root? * * @param Peer $peer * @param string $expectedRoot * @return bool * @throws CouldNotUpdate * @throws PeerSignatureFailed */ protected function checkWithPeer(Peer $peer, string $expectedRoot) : bool { foreach ($peer->getAllURLs('/verify') as $url) { // Challenge nonce: $challenge = Base64UrlSafe::encode(\random_bytes(33)); // Peer's response: $response = $this->hail->postJSON($url, ['challenge' => $challenge]); if ($response['status'] !== 'OK') { $this->log('Upstream error.', LogLevel::EMERGENCY, ['response' => $response]); return false; } // Decode then verify signature $message = Base64UrlSafe::decode($response['response']); $signature = Base64UrlSafe::decode($response['signature']); $isValid = AsymmetricCrypto::verify($message, $peer->getPublicKey(), $signature, true); if (!$isValid) { $this->log('Invalid digital signature (i.e. it was signed with an incorrect key).', LogLevel::EMERGENCY); throw new PeerSignatureFailed('Invalid digital signature (i.e. it was signed with an incorrect key).'); } // Make sure our challenge was signed. $decoded = \json_decode($message, true); if (!\hash_equals($challenge, $decoded['challenge'])) { $this->log('Challenge-response authentication failed.', LogLevel::EMERGENCY); throw new CouldNotUpdate(\__('Challenge-response authentication failed.')); } // Make sure this was a recent signature (it *should* be). // The earliest timestamp we will accept from a peer: $min = (new \DateTime('now'))->sub(new \DateInterval('P01D')); // The timestamp the server provided: $time = new \DateTime($decoded['timestamp']); if ($time < $min) { throw new CouldNotUpdate(\__('Timestamp %s is far too old.', 'default', $decoded['timestamp'])); } // Return TRUE if it matches the expected root. // Return FALSE if it matches. return \hash_equals($expectedRoot, $decoded['root']); } // When all else fails, throw a TransferException throw new TransferException(); }
/** * Gets a field's value by the field's name * * @param string field name * @throws lang.IllegalArgumentException in case the field does not exist */ public function get($field) { if (!isset(Peer::forInstance($this)->types[$field])) { throw new IllegalArgumentException('Field "' . $field . '" does not exist for DataSet ' . $this->getClassName()); } return $this->{$field}; }
/** * Announce code * * @access public * @param $passkey Passkey de l'utilisateur * @return Bencoded response for the torrent client */ public function announce($passkey = null) { // Pas de passkey et pas de freeleech if (Config::get('other.freeleech') == false && $passkey == null) { return Response::make(Bencode::bencode(array('failure reason' => 'Passkey is invalid')), 200, array('Content-Type' => 'text/plain')); } $hash = bin2hex(Input::get('info_hash')); // Get hash if (!Config::get('other.freelech')) { $torrent = Torrent::where('info_hash', '=', $hash)->first(); if (is_null($torrent)) { return Response::make(Bencode::bencode(array('failure reason' => 'Torrent not found')), 200, array('Content-Type' => 'text/plain')); } } else { $torrent = null; } $user = Config::get('other.freelech') == false ? User::where('passkey', '=', $passkey)->first() : null; // Get the user $client = Peer::where('md5_peer_id', '=', md5(Input::get('peer_id')))->first(); // Get the current peer if ($client == null) { $client = new Peer(); } // Crée un nouveau client si non existant Peer::deleteOldPeers(); // Delete olds peers from database $peers = Peer::where('hash', '=', $hash)->take(50)->get()->toArray(); // Liste des pairs $seeders = 0; $leechers = 0; foreach ($peers as &$p) { if ($p['left'] > 0) { $leechers++; } else { $seeders++; } // Compte le nombre de seeders unset($p['uploaded'], $p['downloaded'], $p['left'], $p['seeder'], $p['connectable'], $p['user_id'], $p['torrent_id'], $p['client'], $p['created_at'], $p['updated_at'], $p['md5_peer_id']); } // Get the event of the tracker if (Input::get('event') == 'started' || Input::get('event') == null) { // Set the torrent data $client->peer_id = Input::get('peer_id'); $client->md5_peer_id = md5($client->peer_id); $client->hash = $hash; $client->ip = Request::getClientIp(); $client->port = Input::get('port'); $client->left = Input::get('left'); $client->uploaded = Input::get('uploaded'); $client->downloaded = Input::get('downloaded'); $client->seeder = $client->left == 0 ? true : false; $client->user_id = Config::get('other.freeleech') == false ? $user->id : null; $client->torrent_id = Config::get('other.freeleech') == false ? $torrent->id : null; $client->save(); } elseif (Input::get('event') == 'completed') { if (Config::get('other.freeleech') == false) { $torrent->times_completed++; $torrent->save(); } $client->left = 0; $client->seeder = true; $client->save(); } elseif (Input::get('event') == 'stopped') { $client->delete(); } else { } if (Config::get('other.freeleech') == false && $torrent != null && $user != null) { $torrent->seeders = Peer::whereRaw('torrent_id = ? AND `left` = 0', array($torrent->id))->count(); $torrent->leechers = Peer::whereRaw('torrent_id = ? AND `left` > 0', array($torrent->id))->count(); $torrent->save(); // Modification de l'upload/download de l'utilisateur pour le ratio $user->uploaded += Input::get('uploaded') - $client->uploaded; $user->downloaded += Input::get('downloaded') - $client->downloaded; $user->save(); } $res['interval'] = 60; // Set to 60 for debug $res['min interval'] = 30; // Set to 30 for debug $res['tracker_id'] = $client->md5_peer_id; // A string that the client should send back on its next announcements. $res['complete'] = $seeders; $res['incomplete'] = $leechers; $res['peers'] = $peers; return Response::make(Bencode::bencode($res), 200, array('Content-Type' => 'text/plain')); }
function get_peer($wwwroot, $cache = true) { $wwwroot = (string) $wwwroot; static $peers = array(); if ($cache) { if (isset($peers[$wwwroot])) { return $peers[$wwwroot]; } } require_once get_config('libroot') . 'peer.php'; $peer = new Peer(); if (!$peer->findByWwwroot($wwwroot)) { // Bootstrap unknown hosts? throw new MaharaException("We don't have a record for your webserver ({$wwwroot}) in our database", 6003); } $peers[$wwwroot] = $peer; return $peers[$wwwroot]; }
* (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details: * * http://www.gnu.org/copyleft/gpl.html */ define('INTERNAL', 1); require dirname(dirname(dirname(__FILE__))) . '/init.php'; require_once get_config('docroot') . 'api/xmlrpc/client.php'; require_once get_config('docroot') . 'auth/xmlrpc/lib.php'; require_once get_config('libroot') . 'institution.php'; $remotewwwroot = param_variable('wr'); $instanceid = param_variable('ins'); $wantsurl = param_variable('wantsurl', ''); if (!get_config('enablenetworking')) { throw new AccessTotallyDeniedException(get_string('networkingdisabledonthissite', 'auth.xmlrpc')); } $peer = new Peer(); $peer->findByWwwroot($remotewwwroot); $url = $remotewwwroot . $peer->application->ssolandurl; $providers = get_service_providers($USER->authinstance); $approved = false; $url = start_jump_session($peer, $instanceid, $wantsurl); if (empty($url)) { throw new XmlrpcClientException('DEBUG: Jump session was not started correctly or blank URL returned.'); // TODO: errors } redirect($url);
protected function _onConnectPeer(&$connection) { while (isset($this->connections[$this->connections_dsc])) { $this->connections_dsc++; } if ($peer = new Peer($connection, $this->connections_dsc)) { $peer->setNonBlock(); $this->connections[$this->connections_dsc] =& $peer; if (is_callable($this->event_accept)) { call_user_func_array($this->event_accept, [$peer]); } $peer->onDisconnect(function () use($peer) { error_log('Отсоединился пир ' . $peer->getDsc()); unset($this->connections[$peer->getDsc()]); $this->_onDisconnectPeer($peer); }); return true; } else { trigger_error('Peer connection error'); return false; } }
function keyswap($function, $params) { require_once get_config('libroot') . 'peer.php'; //TODO: Verify params empty($params[0]) ? $wwwroot = null : ($wwwroot = $params[0]); empty($params[1]) ? $pubkey = null : ($pubkey = $params[1]); empty($params[2]) ? $application = null : ($application = $params[2]); if (get_config('promiscuousmode')) { try { $peer = new Peer(); if ($peer->bootstrap($wwwroot, $pubkey, $application)) { $peer->commit(); } } catch (Exception $e) { throw new SystemException($e->getMessage(), $e->getCode()); } } $openssl = OpenSslRepo::singleton(); return $openssl->certificate; }
/** * Returns the fragment SQL * * @param rdbms.DBConnection conn * @param rdbms.Peer peer * @return string */ public function asSql(DBConnection $conn, Peer $peer) { $lhs = $this->lhs instanceof SQLFragment ? $this->lhs : $peer->column($this->lhs); return $conn->prepare('%c ' . str_replace('?', $lhs->getType(), $this->op), $lhs, $this->value); }
/** * Announce code * * @access public * @param $passkey Passkey de l'utilisateur * @return Bencoded response for the torrent client */ public function announce($passkey = null) { //Log::info(Input::all()); // Correct info hash $infoHash = bin2hex(Input::get('info_hash') != null ? Input::get('info_hash') : Input::get('hash_id')); // Finding the torrent on the DB $torrent = Torrent::where('info_hash', '=', $infoHash)->first(); // Is torrent incorrect ? if ($torrent == null) { return Response::make(Bencode::bencode(array('failure reason' => 'This torrent does not exist'), 200, array('Content-Type' => 'text/plain'))); } // Is this a public tracker ? if (Config::get('other.freeleech') == false) { // Finding the user in the DB $user = User::where('passkey', '=', $passkey)->first(); // The user is incorrect ? if ($user == null) { return Response::make(Bencode::bencode(array('failure reason' => 'This user does not exist'), 200, array('Content-Type' => 'text/plain'))); } } // Finding the correct client/peer by the md5 of the peer_id $client = Peer::whereRaw('md5_peer_id = ?', [md5(Input::get('peer_id'))])->first(); // First time the client connect if ($client == null) { $client = new Peer(); } // Deleting old peers from the database foreach (Peer::all() as $peer) { if (time() - strtotime($peer->updated_at) > 50 * 60) { $peer->delete(); } } // Finding peers for this torrent on the database $peers = Peer::whereRaw('torrent_id = ?', array($torrent->id))->take(50)->get()->toArray(); // Removing useless data from the foreach ($peers as $k => $p) { unset($p['uploaded']); unset($p['downloaded']); unset($p['left']); unset($p['seeder']); unset($p['connectable']); unset($p['user_id']); unset($p['torrent_id']); unset($p['client']); unset($p['created_at']); unset($p['updated_at']); unset($p['md5_peer_id']); $peers[$k] = $p; } // Get the event of the tracker if (Input::get('event') == 'started' || Input::get('event') == null) { // Set the torrent data $client->peer_id = Input::get('peer_id'); $client->md5_peer_id = md5($client->peer_id); $client->ip = Request::getClientIp(); $client->port = Input::get('port'); $client->left = Input::get('left'); $client->uploaded = Input::get('uploaded'); $client->downloaded = Input::get('downloaded'); $client->seeder = $client->left > 0 ? false : true; if (Config::get('other.freeleech') == true) { $client->user_id = 0; } else { $client->user_id = $user->id; } $client->torrent_id = $torrent->id; $client->save(); $torrent->seeders = Peer::whereRaw('torrent_id = ? AND `left` = 0', array($torrent->id))->count(); $torrent->leechers = Peer::whereRaw('torrent_id = ? AND `left` > 0', array($torrent->id))->count(); $torrent->save(); } if (Input::get('event') == 'completed') { if ($client == null && $client->left > 0) { return Response::make(Bencode::bencode(array('failure reason' => 'Are you f*****g kidding me ?'), 200, array('Content-Type' => 'text/plain'))); } $torrent->times_completed++; $torrent->save(); $client->left = 0; $client->seeder = 0; $client->save(); } if (Input::get('event') == 'stopped') { if ($client != null) { $client->delete(); } else { return Response::make(Bencode::bencode(array('failure reason' => 'You don\'t have a life'), 200, array('Content-Type' => 'text/plain'))); } } // Savegarde le ratio de l'utilisateur if (Config::get('other.freeleech') == false) { // Modification de l'upload/download de l'utilisateur pour le ratio $user->uploaded += Input::get('uploaded') - $client->uploaded; $user->downloaded += Input::get('downloaded') - $client->downloaded; $user->save(); } $resp['interval'] = 60; // Set to 60 for debug $resp['min interval'] = 30; // Set to 30 for debug $resp['tracker_id'] = $client->md5_peer_id; // A string that the client should send back on its next announcements. $resp['complete'] = $torrent->seeders; $resp['incomplete'] = $torrent->leechers; $resp['peers'] = $peers; //Log::info($resp); return Response::make(Bencode::bencode($resp), 200, array('Content-Type' => 'text/plain')); }
public function unregisterPeerStream(Peer $peer) { $stream = $peer->getStream(); if (!$stream) { return; } unset($this->streams[(int) $stream]); unset($this->streamLookup[(int) $stream]); }
/** @function doTheWork() Returns the info to the client. * @return void */ private function doTheWork() { try { $seeders = 0; $leechers = 0; foreach ($this->getClass('PeerTorrentManager')->find() as $PeerTorrentNew) { $PeerNew = new Peer($PeerTorrentNew->get('peerID')); $interval = $this->nice_date('+' . $this->FOGCore->getSetting('FOG_TORRENT_INTERVAL') + $this->FOGCore->getSetting('FOG_TORRENT_TIMEOUT') . ' seconds'); if ($PeerTorrentNew->get('torrentID') == $this->torrent->get('id') && !$PeerTorrentNew->get('stopped') && strtotime($PeerTorrentNew->get('lastUpdated')) <= strtotime($interval->format('Y-m-d H:i:s')) && $PeerNew->isValid() && $PeerNew->get('id') != $this->peer->get('id')) { $reply[] = array(long2ip($this->FOGCore->resolveHostname($PeerNew->get('ip'))), $PeerNew->get('port'), $PeerNew->get('hash')); } if ($PeerTorrentNew->get('torrentID') == $this->torrent->get('id') && !$PeerTorrentNew->get('stopped') && strtotime($PeerTorrentNew->get('lastUpdated')) <= strtotime($interval->format('Y-m-d H:i:s'))) { $PeerTorrentNew->get('left') > 0 ? $leechers++ : ($PeerTorrentNew->get('left') == 0 ? $seeders++ : null); } } throw new Exception($this->FOGCore->track($reply, $seeders, $leechers)); } catch (Exception $e) { die($e->getMessage()); } }
public static function save_instance_config_options($values, Pieform $form) { if (false === strpos($values['wwwroot'], '://')) { $values['wwwroot'] = 'http://' . $values['wwwroot']; } db_begin(); $authinstance = new stdClass(); $peer = new Peer(); if ($values['instance'] > 0) { $values['create'] = false; $current = get_records_assoc('auth_instance_config', 'instance', $values['instance'], '', 'field, value'); $authinstance->id = $values['instance']; } else { $values['create'] = true; // Get the auth instance with the highest priority number (which is // the instance with the lowest priority). // TODO: rethink 'priority' as a fieldname... it's backwards!! $lastinstance = get_records_array('auth_instance', 'institution', $values['institution'], 'priority DESC', '*', '0', '1'); if ($lastinstance == false) { $authinstance->priority = 0; } else { $authinstance->priority = $lastinstance[0]->priority + 1; } } if (false == $peer->findByWwwroot($values['wwwroot'])) { try { $peer->bootstrap($values['wwwroot'], null, $values['appname'], $values['institution']); } catch (RemoteServerException $e) { $form->set_error('wwwroot', get_string('cantretrievekey', 'auth')); throw new RemoteServerException($e->getMessage(), $e->getCode()); } } $peer->wwwroot = preg_replace("|\\/+\$|", "", $values['wwwroot']); $peer->name = $values['name']; $peer->deleted = $values['deleted']; $peer->appname = $values['appname']; $peer->institution = $values['institution']; if (isset($values['publickey'])) { $peer->publickey = new PublicKey($values['publickey'], $peer->wwwroot); $peer->publickeyexpires = $peer->publickey->expires; } /** * The following properties are not user-updatable $peer->lastconnecttime = $values['lastconnecttime']; */ $peer->commit(); $authinstance->instancename = $values['instancename']; $authinstance->institution = $values['institution']; $authinstance->authname = $values['authname']; if ($values['create']) { $values['instance'] = insert_record('auth_instance', $authinstance, 'id', true); } else { update_record('auth_instance', $authinstance, array('id' => $values['instance'])); } if (empty($current)) { $current = array(); } self::$default_config = array('wwwroot' => $values['wwwroot'], 'parent' => $values['parent'], 'authloginmsg' => $values['authloginmsg'], 'wessoout' => 0, 'theyssoin' => 0, 'theyautocreateusers' => 0, 'weautocreateusers' => 0, 'updateuserinfoonlogin' => 0, 'weimportcontent' => 0); if ($values['ssodirection'] == 'wessoout') { self::$default_config['wessoout'] = 1; self::$default_config['theyautocreateusers'] = $values['theyautocreateusers']; } else { if ($values['ssodirection'] == 'theyssoin') { self::$default_config['theyssoin'] = 1; self::$default_config['updateuserinfoonlogin'] = $values['updateuserinfoonlogin']; self::$default_config['weautocreateusers'] = $values['weautocreateusers']; self::$default_config['weimportcontent'] = $values['weimportcontent']; } } foreach (self::$default_config as $field => $value) { $record = new stdClass(); $record->instance = $values['instance']; $record->field = $field; $record->value = $value; if ($field == 'wwwroot') { $record->value = dropslash($value); } if (empty($value)) { delete_records('auth_instance_config', 'field', $field, 'instance', $values['instance']); } elseif ($values['create'] || !array_key_exists($field, $current)) { insert_record('auth_instance_config', $record); } else { update_record('auth_instance_config', $record, array('instance' => $values['instance'], 'field' => $field)); } } db_commit(); return $values; }
/** * Retrieve associated peer * * @return &rdbms.Peer */ public function getPeer() { return Peer::forName(__CLASS__); }
/** * Returns the fragment SQL * * @param rdbms.DBConnection conn * @param rdbms.Peer peer * @return string * @throws rdbms.SQLStateException */ public function asSql(DBConnection $conn, Peer $peer) { $lhs = $this->lhs instanceof SQLFragment ? $this->lhs : $peer->column($this->lhs); return $conn->prepare('%c between ' . $lhs->getType() . ' and ' . $lhs->getType(), $lhs, $this->lo, $this->hi); }