tracker support authkey

This commit is contained in:
xiaomlove
2021-06-03 21:13:59 +08:00
parent 272b716f35
commit ed68efeeea
6 changed files with 117 additions and 20 deletions

View File

@@ -51,8 +51,10 @@ class Test extends Command
public function handle() public function handle()
{ {
$torrentRep = new TorrentRepository(); $torrentRep = new TorrentRepository();
$r = $torrentRep->encryptDownHash(1, 1); $r = $torrentRep->getTrackerReportAuthKey(1, 1, true);
dd($r, $torrentRep->decryptDownHash($r,1)); // $r = $torrentRep->resetTrackerReportAuthKeySecret(1);
// dd($r);
dd($r, $torrentRep->checkTrackerReportAuthKey($r));
} }
} }

View File

@@ -11,8 +11,6 @@ class NexusModel extends Model
public $timestamps = false; public $timestamps = false;
// protected $perPage = 2;
/** /**
* *
* @param \DateTimeInterface $date * @param \DateTimeInterface $date

View File

@@ -0,0 +1,8 @@
<?php
namespace App\Models;
class TorrentSecret extends NexusModel
{
protected $fillable = ['uid', 'torrent_id', 'secret'];
}

View File

@@ -2,6 +2,7 @@
namespace App\Repositories; namespace App\Repositories;
use App\Exceptions\NexusException;
use App\Models\AudioCodec; use App\Models\AudioCodec;
use App\Models\Category; use App\Models\Category;
use App\Models\Codec; use App\Models\Codec;
@@ -13,11 +14,13 @@ use App\Models\Source;
use App\Models\Standard; use App\Models\Standard;
use App\Models\Team; use App\Models\Team;
use App\Models\Torrent; use App\Models\Torrent;
use App\Models\TorrentSecret;
use App\Models\User; use App\Models\User;
use Hashids\Hashids; use Hashids\Hashids;
use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Seeder; use Illuminate\Database\Seeder;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Str;
class TorrentRepository extends BaseRepository class TorrentRepository extends BaseRepository
{ {
@@ -276,25 +279,84 @@ class TorrentRepository extends BaseRepository
return md5($user['passkey'] . date('Ymd') . $user['id']); return md5($user['passkey'] . date('Ymd') . $user['id']);
} }
public function encryptAuthKey($id, $user): string public function getTrackerReportAuthKey($id, $uid, $initializeIfNotExists = false): string
{ {
$key = $this->getEncryptAuthkeyKey($user); $key = $this->getTrackerReportAuthKeySecret($id, $uid, $initializeIfNotExists);
return (new Hashids($key))->encode($id); $hash = (new Hashids($key))->encode(date('Ymd'));
return sprintf('%s|%s|%s', $id, $uid, $hash);
} }
public function decryptAuthKey($downHash, $user) /**
* check tracker report authkey
* if valid, the result will be the date the key generate, else if will be empty string
*
* @date 2021/6/3
* @time 20:29
* @param $authKey
* @return array
* @throws NexusException
*/
public function checkTrackerReportAuthKey($authKey)
{ {
$key = $this->getEncryptAuthkeyKey($user); $arr = explode('|', $authKey);
return (new Hashids($key))->decode($downHash); if (count($arr) != 3) {
} throw new NexusException('Invalid authkey');
private function getEncryptAuthkeyKey($user)
{
if (!is_array($user) || empty($user['passkey']) || empty($user['id'])) {
$user = User::query()->findOrFail(intval($user), ['id', 'passkey'])->toArray();
} }
//down hash is relative to user passkey $id = $arr[0];
return md5($user['passkey'] . date('Ymd') . $user['id']); $uid = $arr[1];
$hash = $arr[2];
$key = $this->getTrackerReportAuthKeySecret($id, $uid);
return (new Hashids($key))->decode($hash);
}
private function getTrackerReportAuthKeySecret($id, $uid, $initializeIfNotExists = false)
{
$secret = TorrentSecret::query()
->where('uid', $uid)
->whereIn('torrent_id', [0, $id])
->orderBy('torrent_id', 'desc')
->first();
if ($secret) {
return $secret->secret;
}
if ($initializeIfNotExists) {
$insert = [
'uid' => $uid,
'torrent_id' => 0,
'secret' => Str::random(),
];
TorrentSecret::query()->insert($insert);
return $insert['secret'];
}
throw new NexusException('No valid report secret, please re-download this torrent.');
}
/**
* reset user tracker report authkey secret
*
* @param $uid
* @param int $torrentId
* @return string
* @todo wrap with transaction
*
* @date 2021/6/3
* @time 20:15
*/
public function resetTrackerReportAuthKeySecret($uid, $torrentId = 0)
{
$insert = [
'uid' => $uid,
'secret' => Str::random(),
'torrent_id' => $torrentId,
];
if ($torrentId > 0) {
return TorrentSecret::query()->insert($insert);
}
TorrentSecret::query()->where('uid', $uid)->delete();
TorrentSecret::query()->insert($insert);
return $insert['secret'];
} }

View File

@@ -3,10 +3,35 @@ require_once('../include/bittorrent_announce.php');
require_once('../include/benc.php'); require_once('../include/benc.php');
dbconn_announce(); dbconn_announce();
do_log(nexus_json_encode($_SERVER)); do_log(nexus_json_encode($_SERVER));
$log = "";
//1. BLOCK ACCESS WITH WEB BROWSERS AND CHEATS! //1. BLOCK ACCESS WITH WEB BROWSERS AND CHEATS!
$agent = $_SERVER["HTTP_USER_AGENT"]; $agent = $_SERVER["HTTP_USER_AGENT"];
block_browser(); block_browser();
//check authkey
if (!empty($_REQUEST['authkey'])) {
$arr = explode('|', $_REQUEST['authkey']);
if (count($arr) != 3) {
err('Invalid authkey');
}
$torrentId = $arr[0];
$uid = $arr[1];
$torrentRep = new \App\Repositories\TorrentRepository();
try {
$decrypted = $torrentRep->checkTrackerReportAuthKey($_REQUEST['authkey']);
} catch (\Exception $exception) {
err($exception->getMessage());
}
if (empty($decrypted)) {
err('Invalid authkey');
}
$userInfo = \App\Models\User::query()->where('id', $uid)->first(['id', 'passkey']);
if (!$userInfo) {
err('Invalid authkty');
}
$_GET['passkey'] = $userInfo->passkey;
}
//2. GET ANNOUNCE VARIABLES //2. GET ANNOUNCE VARIABLES
// get string type passkey, info_hash, peer_id, event, ip from client // get string type passkey, info_hash, peer_id, event, ip from client
foreach (array("passkey","info_hash","peer_id","event") as $x) foreach (array("passkey","info_hash","peer_id","event") as $x)

View File

@@ -105,9 +105,11 @@ if (strlen($CURUSER['passkey']) != 32) {
sql_query("UPDATE users SET passkey=".sqlesc($CURUSER['passkey'])." WHERE id=".sqlesc($CURUSER['id'])); sql_query("UPDATE users SET passkey=".sqlesc($CURUSER['passkey'])." WHERE id=".sqlesc($CURUSER['id']));
} }
$trackerReportAuthKey = $torrentRep->getTrackerReportAuthKey($id, $CURUSER['id'], true);
$dict = bdec_file($fn, $max_torrent_size); $dict = bdec_file($fn, $max_torrent_size);
//$dict['value']['announce']['value'] = $ssl_torrent . $base_announce_url . "?passkey=$CURUSER[passkey]"; //$dict['value']['announce']['value'] = $ssl_torrent . $base_announce_url . "?passkey=$CURUSER[passkey]";
$dict['value']['announce']['value'] = getSchemeAndHttpHost() . "/announce.php?passkey=$CURUSER[passkey]"; $dict['value']['announce']['value'] = getSchemeAndHttpHost() . "/announce.php?authkey=$trackerReportAuthKey";
$dict['value']['announce']['string'] = strlen($dict['value']['announce']['value']).":".$dict['value']['announce']['value']; $dict['value']['announce']['string'] = strlen($dict['value']['announce']['value']).":".$dict['value']['announce']['value'];
$dict['value']['announce']['strlen'] = strlen($dict['value']['announce']['string']); $dict['value']['announce']['strlen'] = strlen($dict['value']['announce']['string']);
/*if ($announce_urls[1] != "") // add multi-tracker /*if ($announce_urls[1] != "") // add multi-tracker