mirror of
https://github.com/RetGal/Dayon.git
synced 2024-10-04 10:27:37 +03:00
126 lines
4.0 KiB
PHP
126 lines
4.0 KiB
PHP
<?php
|
|
define('VERSION', "v.1.2");
|
|
// name of the database file (may also be a path)
|
|
define('DB_NAME', "dayon.db");
|
|
// minimal length of the tokens to be generated (33^N-1 variants)
|
|
define('TOKEN_MIN_LENGTH', 4);
|
|
// number of seconds after which the token will be purged
|
|
define('TOKEN_LIFETIME', 604800);
|
|
// maximum number of tokens that can be generated for a single IP
|
|
define('TOKEN_LIMIT', 700);
|
|
// 8<---8<---8<---
|
|
header('Content-type: text/plain');
|
|
if (isset($_GET['port'])) {
|
|
$port = clean($_GET['port'], 6);
|
|
if (isValidPort($port)) {
|
|
$pdo = new PDO('sqlite:'.DB_NAME);
|
|
createDatabase($pdo);
|
|
echo createToken($pdo, $port),"\n";
|
|
if (rand(0, 5) == 5) {
|
|
removeOldTokens($pdo);
|
|
}
|
|
}
|
|
} else if (isset($_GET['token'])) {
|
|
$token = clean($_GET['token'], TOKEN_MIN_LENGTH * 2);
|
|
$pdo = new PDO('sqlite:'.DB_NAME);
|
|
echo readToken($token, $pdo),"\n";
|
|
updateToken($token, $_SERVER['REMOTE_ADDR'], $pdo);
|
|
} else {
|
|
echo VERSION,"\n";
|
|
}
|
|
|
|
function clean($val, $maxLen = "") {
|
|
$val = trim(strip_tags($val));
|
|
if (!empty($maxLen)) {
|
|
$val = substr($val, 0, $maxLen);
|
|
}
|
|
return $val;
|
|
}
|
|
|
|
function isValidPort($port) {
|
|
return is_numeric($port) && $port > 0 && $port < 65536;
|
|
}
|
|
|
|
function createToken($pdo, $port) {
|
|
if (checkAvailable($pdo, $_SERVER['REMOTE_ADDR']) <= 0) {
|
|
return substr(str_shuffle("ABCDEFGHJKLMNPQRSTUVWXYZ123456789"), 0, rand(4, 12))."\n";
|
|
}
|
|
$token = computeToken(TOKEN_MIN_LENGTH);
|
|
$attempt = 0;
|
|
while (!insertToken($token, $_SERVER['REMOTE_ADDR'], $port, $pdo) && $attempt < 10) {
|
|
$length = $attempt < TOKEN_MIN_LENGTH ? TOKEN_MIN_LENGTH : round(TOKEN_MIN_LENGTH+$attempt/2);
|
|
$token = computeToken($length);
|
|
$attempt++;
|
|
}
|
|
return $token;
|
|
}
|
|
|
|
function checkAvailable($pdo, $address) {
|
|
$sql = "SELECT COUNT(*) FROM tokens WHERE assistant = :address";
|
|
$stmt = $pdo->prepare($sql);
|
|
$stmt->bindParam(':address', $address, PDO::PARAM_STR);
|
|
$stmt->execute();
|
|
$stmt->bindColumn(1, $count);
|
|
$stmt->fetch(PDO::FETCH_BOUND);
|
|
return TOKEN_LIMIT - $count;
|
|
}
|
|
|
|
function computeToken($length) {
|
|
$token = substr(str_shuffle("ABCDEFGHJKLMNPQRSTUVWXYZ123456789"), 0, $length-1);
|
|
$token .= strtoupper(substr(sha1($token), -1));
|
|
return $token;
|
|
}
|
|
|
|
function insertToken($token, $address, $port, $pdo) {
|
|
$sql = "INSERT INTO tokens (token,assistant,port,ts) VALUES (:token,:address,:port,:ts)";
|
|
$ts = time();
|
|
$stmt = $pdo->prepare($sql);
|
|
$stmt->bindParam(':token', $token, PDO::PARAM_STR, 7);
|
|
$stmt->bindParam(':address', $address, PDO::PARAM_STR);
|
|
$stmt->bindParam(':port', $port, PDO::PARAM_INT);
|
|
$stmt->bindParam(':ts', $ts, PDO::PARAM_INT);
|
|
$success = $stmt->execute();
|
|
if (!$success) {
|
|
// print_r($stmt->errorInfo());
|
|
return 0;
|
|
} else {
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
function removeOldTokens($pdo) {
|
|
$ts = time();
|
|
$delete = "DELETE FROM tokens WHERE ts < ?";
|
|
$stmt = $pdo->prepare($delete);
|
|
$stmt->execute(array($ts-TOKEN_LIFETIME));
|
|
}
|
|
|
|
function readToken($token, $pdo) {
|
|
$sql = "SELECT assistant,port FROM tokens WHERE token = :token";
|
|
$stmt = $pdo->prepare($sql);
|
|
if ($stmt->execute([":token" => $token])) {
|
|
$stmt->bindColumn(1, $address);
|
|
$stmt->bindColumn(2, $port);
|
|
return $stmt->fetch(PDO::FETCH_BOUND) ? "$address*$port" : "";
|
|
} else {
|
|
return "";
|
|
}
|
|
}
|
|
|
|
function updateToken($token, $address, $pdo) {
|
|
$sql = "UPDATE tokens SET assisted = :address,ts = :ts WHERE token = :token";
|
|
$ts = time();
|
|
$stmt = $pdo->prepare($sql);
|
|
$stmt->bindParam(':address', $address, PDO::PARAM_STR);
|
|
$stmt->bindParam(':ts', $ts, PDO::PARAM_INT);
|
|
$stmt->bindParam(':token', $token, PDO::PARAM_STR, 7);
|
|
$stmt->execute();
|
|
}
|
|
|
|
function createDatabase($pdo) {
|
|
$sql = "CREATE TABLE IF NOT EXISTS `tokens` (`token` TEXT,`assistant` TEXT,`port` INTEGER,`assisted` TEXT,`ts` INTEGER, PRIMARY KEY(`token`))";
|
|
$stmt = $pdo->prepare($sql);
|
|
$stmt->execute();
|
|
// print_r($stmt->errorInfo());
|
|
}
|
|
?>
|