<link rel="icon" href="./Pictures/dot.png">
<link rel="stylesheet" href="./Styles/styles.css">
<?php require_once('./php/config.php'); ?>
- <?php require_once('./php/dd.php'); ?>
+ <?php require_once('./php/dd2.php'); ?>
+
<link rel="author" href="mailto:email@dpolakovic.space">
<meta name="description" content="personal website and git server">
<meta name="author" content="David Polakovic, 2023">
<br>
A dead drop is a spy technique used for anonymous information exchange. When you stash your
message in a dead drop, it will be hidden from anyone who doesn't know its location. It
- also uses MD5 hashing and AES-256-CBC encryption to keep it hidden from the hosting provider
+ also uses SHA-256 hashing and AES-256-CBC encryption to keep it hidden from the hosting provider
and webmaster as well. Enter the coordinates of a dead drop to check if it's hot (has stashed message)
or if it's cold (empty).
<!-- Still, it's a good idea to keep your message brief in case the dead drop location is ever compromised. -->
<p>
<i>
<?php countActiveDrops(); ?>
- Every dead drop goes cold after 18 hours.
+ Every dead drop goes cold after one sol.
<br><br>
</i>
</p>
--- /dev/null
+<?php
+// === captcha.php ===
+
+function captcha($token, $w3w) {
+ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['captchaTry'])) {
+ $userInput = strtolower(preg_replace('/[^a-z0-9]/', '', $_POST['captchaTry']));
+ if (isset($_SESSION['captcha']) && $userInput === $_SESSION['captcha']) {
+ return 'YAY';
+ }
+ echo "Wrong captcha. Try again.<br>";
+ }
+
+ echo "<form method='post'>";
+ echo "<input type='hidden' name='csrf_token' value='" . htmlentities($token) . "'>";
+ echo "<input type='hidden' name='inputString' value='" . htmlentities($w3w) . "'>";
+ generatePicture();
+ echo "<br><input type='text' name='captchaTry' placeholder='Type the characters' required>";
+ echo "<input type='submit' value='Verify'>";
+ echo "</form>";
+ return null;
+}
+
+function generatePicture() {
+ $width = 95;
+ $height = 30;
+
+ $image = imagecreatetruecolor($width, $height);
+
+ $isWhite = rand(0, 1) === 1;
+ $bgColor = $isWhite ? imagecolorallocate($image, 255, 255, 255) : imagecolorallocate($image, 0, 0, 0);
+ imagefilledrectangle($image, 0, 0, $width, $height, $bgColor);
+
+ $charset = 'abcdefghijklmnpqrstuvwxyz123456789';
+ $randomStr = '';
+ for ($i = 0; $i < 4; $i++) {
+ $randomStr .= $charset[rand(0, strlen($charset) - 1)];
+ }
+
+ $_SESSION['captcha'] = $randomStr;
+
+ $fontSize = 5;
+ $charWidth = imagefontwidth($fontSize);
+ $charHeight = imagefontheight($fontSize);
+ $textWidth = $charWidth * strlen($randomStr);
+ $x = ($width - $textWidth) / 2;
+ $y = ($height - $charHeight) / 2;
+
+ $colors = [
+ imagecolorallocate($image, 255, 0, 0),
+ imagecolorallocate($image, 0, 0, 255),
+ imagecolorallocate($image, 0, 255, 0),
+ imagecolorallocate($image, 255, 0, 255),
+ imagecolorallocate($image, 0, 255, 255)
+ ];
+
+ for ($i = 0; $i < strlen($randomStr); $i++) {
+ $char = $randomStr[$i];
+ $charColor = $colors[array_rand($colors)];
+ imagestring($image, $fontSize, $x + $i * $charWidth, $y, $char, $charColor);
+ }
+
+ ob_start();
+ imagepng($image);
+ $imageData = ob_get_clean();
+ imagedestroy($image);
+
+ $base64 = base64_encode($imageData);
+ echo '<img src="data:image/png;base64,' . $base64 . '" alt="Random Image">';
+}
+++ /dev/null
-<?php
-
-function countActiveDrops() {
- $directory = "./Dead-drops";
-
- // Check if the directory exists
- if (is_dir($directory)) {
- // Scan the directory and get all files
- $files = scandir($directory);
-
- // Filter out the current (.) and parent (..) directories
- $files = array_diff($files, array('.', '..'));
-
- // Count the number of files
- $fileCount = count($files);
-
- // Echo the result
- if ($fileCount == 0){
- echo "There is no hot drop on this domain right now.";
- }
-
- if ($fileCount == 1){
- echo "There is exactly one hot drop on this domain right now.";
- }
-
- if ($fileCount > 1){
- echo "There are $fileCount hot drops on this domain right now.";
- }
-
- } else {
- echo "Directory '$directory' does not exist.";
- }
-
-}
-
-function cleanTheCity() {
- $directory = "./Dead-drops";
- $now = time();
- $expiry = 18 * 3600;
-
- if (is_dir($directory)) {
- $files = scandir($directory);
- foreach ($files as $file) {
- // Skip the specific file by name
- if ($file == '75cfce5a009d44910a23bd55a3f8f0bd') {
- continue;
- }
-
- $filePath = $directory . DIRECTORY_SEPARATOR . $file;
- if (is_file($filePath)) {
- $fileAge = $now - filemtime($filePath);
- if ($fileAge > $expiry) {
- unlink($filePath);
- }
- }
- }
- } else {
- echo "<p><strong>Error:</strong> Folder <code>./Locations</code> not found.</p>";
- }
-}
-
-
-
-function deadDropUI() {
- session_start();
- $csrf_lifetime = 600;
- $session_id_key = 'csrf_token_session_id';
-
- if (!isset($_SESSION['csrf_token'], $_SESSION['csrf_token_time'], $_SESSION[$session_id_key]) ||
- session_id() !== $_SESSION[$session_id_key] ||
- time() - $_SESSION['csrf_token_time'] > $csrf_lifetime) {
- $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
- $_SESSION['csrf_token_time'] = time();
- $_SESSION[$session_id_key] = session_id();
- }
-
- $token = $_SESSION['csrf_token'];
- $result = deadDropLogic();
- $dropCount = count(glob('./Dead-drops/*'));
-
- if (($result['mode'] === 'initial' && $dropCount < 501) ||
- ($result['mode'] === 'readonly' && $result['status'] === 'invalid')) {
- echo <<<HTML
- <style>input[type="text"],input[type="submit"] { font-size: 16.5px; }</style>
- <form method="post">
- <label><a href="https://en.wikipedia.org/wiki/W3w#Design" target="_blank">?</a> </label>
- <input type="hidden" name="csrf_token" value="{$token}">
- <input type="text" id="inputString" name="inputString" placeholder="///what.three.words" size="30" maxlength="50" required>
- <input type="submit" value="Check">
- </form>
- HTML;
- } elseif ($result['mode'] === 'initial' && $dropCount >= 501) {
- echo "This domain is too hot. Come back later when there won't be so much heat";
- }
-
- if ($result['mode'] === 'readonly') {
- if ($result['status'] === 'hot') {
- echo "<pre>" . htmlspecialchars($result['decrypted'], ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8') . "</pre>";
- echo <<<HTML
- <form method="post">
- <input type="hidden" name="csrf_token" value="{$token}">
- <input type="hidden" name="burnW3W" value="{$result['w3w']}">
- <input type="submit" value="Burn message">
- </form>
- HTML;
- } elseif ($result['status'] === 'cold') {
- echo "<h3>" . htmlentities($result['w3w']) ."</h3>This drop is cold. You can stash your message here.<br><br>";
- echo <<<HTML
- <form method="post">
- <input type="hidden" name="csrf_token" value="{$token}">
- <input type="hidden" name="originalW3W" value="{$result['w3w']}">
- <textarea name="stashContent" maxlength="4096" rows="10" cols="60" placeholder="max 4096 chars" required></textarea><br><br>
- <input type="submit" value="Stash">
- </form>
- HTML;
- } elseif ($result['status'] === 'invalid') {
- echo "<br>{$result['message']}";
- }
- } elseif ($result['mode'] === 'stashed') {
- echo "<h3>Message stashed at " . htmlentities($result['w3w']) ."</h3>Your dead drop is hot.";
- }
-}
-
-function deadDropLogic() {
- session_start();
- $csrf_lifetime = 600;
- $session_id_key = 'csrf_token_session_id';
-
- if ($_SERVER['REQUEST_METHOD'] === 'POST') {
- if (!isset($_POST['csrf_token'], $_SESSION['csrf_token'], $_SESSION['csrf_token_time'], $_SESSION[$session_id_key]) ||
- $_POST['csrf_token'] !== $_SESSION['csrf_token'] ||
- session_id() !== $_SESSION[$session_id_key] ||
- time() - $_SESSION['csrf_token_time'] > $csrf_lifetime) {
- die('CSRF token invalid or expired. Reload the website, that usually helps...');
- }
-
- if (isset($_POST['burnW3W'])) {
- $input = trim($_POST['burnW3W']);
- $hashed = md5($input);
- if (!isValidHash($hashed)) die('Invalid hash');
- $file = './Dead-drops/' . $hashed;
- if (file_exists($file)) unlink($file);
- header("Location: https://www.dpolakovic.space/dead-drop");
- exit;
- }
-
- if (isset($_POST['stashContent'], $_POST['originalW3W'])) {
- $input = trim($_POST['originalW3W']);
- $hashed_w3w = md5($input);
- if (!isValidHash($hashed_w3w)) die('Invalid hash');
- $plaintext = $_POST['stashContent'];
-
- if (strlen($plaintext) > 4096) {
- return ['mode' => 'readonly', 'w3w' => $input, 'status' => 'invalid', 'message' => 'ERROR: Message too long.'];
- }
-
- $filepath = "./Dead-drops/{$hashed_w3w}";
- if (file_exists($filepath)) {
- return ['mode' => 'readonly', 'w3w' => $input, 'status' => 'hot'];
- }
-
- $cipher = "AES-256-CBC";
- $key = hash('sha256', $input);
- $iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length($cipher));
- $encrypted = openssl_encrypt($plaintext, $cipher, $key, 0, $iv);
- $output = base64_encode($iv . $encrypted);
- file_put_contents($filepath, $output);
- return ['mode' => 'stashed', 'w3w' => $input];
- }
-
- if (isset($_POST['inputString'])) {
- $input = trim($_POST['inputString']);
- if (!validateString($input)) {
- return ['mode' => 'readonly', 'w3w' => $input, 'status' => 'invalid', 'message' => 'ERROR: Invalid coordinates format.'];
- }
- if (!validateStringW3W($input)) {
- return ['mode' => 'readonly', 'w3w' => $input, 'status' => 'invalid', 'message' => 'ERROR: Place you are looking for doesn\'t exist.'];
- }
- $hashed = md5($input);
- if (!isValidHash($hashed)) die('Invalid hash');
- $dropPath = './Dead-drops/' . $hashed;
- if (file_exists($dropPath)) {
- $raw = file_get_contents($dropPath);
- $data = base64_decode($raw);
- $iv_len = openssl_cipher_iv_length("AES-256-CBC");
- $iv = substr($data, 0, $iv_len);
- $ciphertext = substr($data, $iv_len);
- $key = hash('sha256', $input);
- $decrypted = openssl_decrypt($ciphertext, "AES-256-CBC", $key, 0, $iv);
- return [
- 'mode' => 'readonly',
- 'w3w' => $input,
- 'status' => 'hot',
- 'decrypted' => $decrypted
- ];
- } else {
- return [
- 'mode' => 'readonly',
- 'w3w' => $input,
- 'status' => 'cold'
- ];
- }
- }
- }
-
- return ['mode' => 'initial'];
-}
-
-function isValidHash($hash) {
- return preg_match('/^[a-f0-9]{32}$/', $hash) === 1;
-}
-
-
-
-
-
-
-
-
-
-
-
-function validateString($str) {
- if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
- return false;
- }
-
- if (substr($str, 0, 3) !== "///") {
- return false;
- }
-
- $parts = substr($str, 3);
- if (substr_count($parts, ".") !== 2) {
- return false;
- }
-
- if (!preg_match('/^[a-z]+\.[a-z]+\.[a-z]+$/', $parts)) {
- return false;
- }
-
- return true;
-}
-
-function validateStringW3W($str) {
- if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
- return false;
- }
-
- $API_KEY = '747757BO';
- $cleaned = substr($str, 3);
- $url = 'https://api.what3words.com/v3/autosuggest?input=' . urlencode($cleaned) . '&key=' . urlencode($API_KEY);
-
- $ch = curl_init();
- curl_setopt($ch, CURLOPT_URL, $url);
- curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
- $response = curl_exec($ch);
-
- if (curl_errno($ch)) {
- echo "Curl error: " . curl_error($ch);
- return false;
- }
-
- curl_close($ch);
- $result = json_decode($response, true);
-
- if (isset($result['suggestions']) && count($result['suggestions']) > 0) {
- foreach ($result['suggestions'] as $suggestion) {
- if (strcasecmp($suggestion['words'], $cleaned) === 0) {
- return true;
- }
- }
- }
-
- return false;
-}
\ No newline at end of file
--- /dev/null
+<?php
+
+define('API_KEY', 'ABC123#@!');
+define('DROP_EXPIRY_SECONDS', (24 * 3600) + 2375); // 24h 39min 35sec (one martian day)
+define('DEAD_DROP_DIR', './Dead-drops');
+define('DROP_LIMIT', 1024); // maximum amount of hot dead drops
+define('CSRF_TOKEN_LIFETIME', 600);
+define('IGNORED_DROPS', [ // list permanent drops (test purposes)
+ '62a5bced62e7219c8e164d64fdae67900476ed54f39c5851a07bb65b590e04df'
+]);
+
+require_once 'captcha.php';
+
+// === main.php ===
+
+function countActiveDrops() {
+ if (is_dir(DEAD_DROP_DIR)) {
+ $files = scandir(DEAD_DROP_DIR);
+ $files = array_diff($files, array('.', '..'));
+ $fileCount = count($files);
+
+ if ($fileCount == 0) {
+ echo "There is no hot drop on this domain right now.";
+ } elseif ($fileCount == 1) {
+ echo "There is exactly one hot drop on this domain right now.";
+ } else {
+ echo "There are $fileCount hot drops on this domain right now.";
+ }
+ } else {
+ echo "Directory '" . DEAD_DROP_DIR . "' does not exist.";
+ }
+}
+
+function cleanTheCity() {
+ $now = time();
+ if (is_dir(DEAD_DROP_DIR)) {
+ $files = scandir(DEAD_DROP_DIR);
+ foreach ($files as $file) {
+ if (in_array($file, IGNORED_DROPS)) continue;
+
+ $filePath = DEAD_DROP_DIR . DIRECTORY_SEPARATOR . $file;
+ if (is_file($filePath)) {
+ $fileAge = $now - filemtime($filePath);
+ if ($fileAge > DROP_EXPIRY_SECONDS) {
+ unlink($filePath);
+ }
+ }
+ }
+ } else {
+ echo "<p><strong>Error:</strong> Folder <code>" . DEAD_DROP_DIR . "</code> not found.</p>";
+ }
+}
+
+function deadDropUI() {
+ session_start();
+ $session_id_key = 'csrf_token_session_id';
+
+ if (!isset($_SESSION['csrf_token'], $_SESSION['csrf_token_time'], $_SESSION[$session_id_key]) ||
+ session_id() !== $_SESSION[$session_id_key] ||
+ time() - $_SESSION['csrf_token_time'] > CSRF_TOKEN_LIFETIME) {
+ $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
+ $_SESSION['csrf_token_time'] = time();
+ $_SESSION[$session_id_key] = session_id();
+ }
+
+ $token = $_SESSION['csrf_token'];
+ $result = deadDropLogic();
+ $dropFiles = glob(DEAD_DROP_DIR . '/*');
+ $dropCount = count($dropFiles);
+
+ if ($result['mode'] === 'readonly' && $result['status'] === 'cold') {
+ if ($dropCount > DROP_LIMIT) {
+ echo "There is too much heat on this domain right now to stash a new message. Come back later.";
+ return;
+ }
+ $slowDown = checkDropRate();
+ if ($slowDown) {
+ if (captcha($token, $result['w3w']) !== 'YAY') return;
+ }
+ echo "<h3>" . htmlentities($result['w3w']) ."</h3>This drop is cold. You can stash your message here.<br><br>";
+ echo <<<HTML
+<form method="post">
+<input type="hidden" name="csrf_token" value="{$token}">
+<input type="hidden" name="originalW3W" value="{$result['w3w']}">
+<textarea name="stashContent" maxlength="4096" rows="10" cols="60" placeholder="max 4096 chars" required></textarea><br>
+<input type="submit" value="Stash">
+</form>
+HTML;
+ return;
+ }
+
+ if ($result['mode'] === 'initial' ||
+ ($result['mode'] === 'readonly' && $result['status'] === 'invalid')) {
+ echo <<<HTML
+<style>input[type="text"],input[type="submit"] { font-size: 16.5px; }</style>
+<form method="post">
+<label><a href="https://www.what3words.com/" target="_blank">?</a> </label>
+<input type="hidden" name="csrf_token" value="{$token}">
+<input type="text" id="inputString" name="inputString" placeholder="///what.three.words (English)" size="30" maxlength="50" required>
+<input type="submit" value="Check">
+</form>
+HTML;
+ }
+
+ if ($result['mode'] === 'readonly') {
+ if ($result['status'] === 'hot') {
+ echo "<pre>" . htmlspecialchars($result['decrypted'], ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8') . "</pre>";
+ echo <<<HTML
+<form method="post">
+<input type="hidden" name="csrf_token" value="{$token}">
+<input type="hidden" name="burnW3W" value="{$result['w3w']}">
+<input type="submit" value="Burn message">
+</form>
+HTML;
+ } elseif ($result['status'] === 'invalid') {
+ echo "<br>{$result['message']}";
+ }
+ } elseif ($result['mode'] === 'stashed') {
+ echo "<h3>Message stashed at " . htmlentities($result['w3w']) ."</h3>Your dead drop is hot.";
+ }
+}
+
+function deadDropLogic() {
+ session_start();
+ $session_id_key = 'csrf_token_session_id';
+
+ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
+ if (!isset($_POST['csrf_token'], $_SESSION['csrf_token'], $_SESSION['csrf_token_time'], $_SESSION[$session_id_key]) ||
+ $_POST['csrf_token'] !== $_SESSION['csrf_token'] ||
+ session_id() !== $_SESSION[$session_id_key] ||
+ time() - $_SESSION['csrf_token_time'] > CSRF_TOKEN_LIFETIME) {
+ die('CSRF token invalid or expired. Reload the website, that usually helps...');
+ }
+
+ if (isset($_POST['burnW3W'])) {
+ $input = trim($_POST['burnW3W']);
+ $hashed = hash('sha256', $input);
+ if (!isValidHash($hashed)) die('Invalid hash');
+ $file = DEAD_DROP_DIR . '/' . $hashed;
+ if (file_exists($file)) unlink($file);
+ header("Location: https://www.dpolakovic.space/dead-drop");
+ exit;
+ }
+
+ if (isset($_POST['stashContent'], $_POST['originalW3W'])) {
+ $input = trim($_POST['originalW3W']);
+ $hashed_w3w = hash('sha256', $input);
+ if (!isValidHash($hashed_w3w)) die('Invalid hash');
+ $plaintext = $_POST['stashContent'];
+
+ if (strlen($plaintext) > 4096) {
+ return ['mode' => 'readonly', 'w3w' => $input, 'status' => 'invalid', 'message' => 'ERROR: Message too long.'];
+ }
+
+ $filepath = DEAD_DROP_DIR . "/{$hashed_w3w}";
+ if (file_exists($filepath)) {
+ return ['mode' => 'readonly', 'w3w' => $input, 'status' => 'hot'];
+ }
+
+ $cipher = "AES-256-CBC";
+ $key = hash('sha256', $input);
+ $iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length($cipher));
+ $encrypted = openssl_encrypt($plaintext, $cipher, $key, 0, $iv);
+ $output = base64_encode($iv . $encrypted);
+ file_put_contents($filepath, $output);
+ return ['mode' => 'stashed', 'w3w' => $input];
+ }
+
+ if (isset($_POST['inputString'])) {
+ $input = trim($_POST['inputString']);
+ if (!validateString($input)) {
+ return ['mode' => 'readonly', 'w3w' => $input, 'status' => 'invalid', 'message' => 'ERROR: Invalid coordinates format.'];
+ }
+ if (!validateStringW3W($input)) {
+ return ['mode' => 'readonly', 'w3w' => $input, 'status' => 'invalid', 'message' => 'ERROR: Place you are looking for doesn\'t exist.'];
+ }
+ $hashed = hash('sha256', $input);
+ if (!isValidHash($hashed)) die('Invalid hash');
+ $dropPath = DEAD_DROP_DIR . '/' . $hashed;
+ if (file_exists($dropPath)) {
+ $raw = file_get_contents($dropPath);
+ $data = base64_decode($raw);
+ $iv_len = openssl_cipher_iv_length("AES-256-CBC");
+ $iv = substr($data, 0, $iv_len);
+ $ciphertext = substr($data, $iv_len);
+ $key = hash('sha256', $input);
+ $decrypted = openssl_decrypt($ciphertext, "AES-256-CBC", $key, 0, $iv);
+ return [
+ 'mode' => 'readonly',
+ 'w3w' => $input,
+ 'status' => 'hot',
+ 'decrypted' => $decrypted
+ ];
+ } else {
+ return [
+ 'mode' => 'readonly',
+ 'w3w' => $input,
+ 'status' => 'cold'
+ ];
+ }
+ }
+ }
+
+ return ['mode' => 'initial'];
+}
+
+function isValidHash($hash) {
+ return preg_match('/^[a-f0-9]{64}$/', $hash) === 1;
+}
+
+function validateString($str) {
+ if ($_SERVER['REQUEST_METHOD'] !== 'POST') return false;
+ if (substr($str, 0, 3) !== "///") return false;
+ $parts = substr($str, 3);
+ if (substr_count($parts, ".") !== 2) return false;
+ if (!preg_match('/^[a-z]+\.[a-z]+\.[a-z]+$/', $parts)) return false;
+ return true;
+}
+
+function validateStringW3W($str) {
+ if ($_SERVER['REQUEST_METHOD'] !== 'POST') return false;
+ $cleaned = substr($str, 3);
+ $url = 'https://api.what3words.com/v3/autosuggest?input=' . urlencode($cleaned) . '&key=' . urlencode(API_KEY);
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_URL, $url);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+ $response = curl_exec($ch);
+ if (curl_errno($ch)) {
+ echo "Curl error: " . curl_error($ch);
+ return false;
+ }
+ curl_close($ch);
+ $result = json_decode($response, true);
+ if (isset($result['suggestions']) && count($result['suggestions']) > 0) {
+ foreach ($result['suggestions'] as $suggestion) {
+ if (strcasecmp($suggestion['words'], $cleaned) === 0) return true;
+ }
+ }
+ return false;
+}
+
+function checkDropRate() {
+ $files = glob(DEAD_DROP_DIR . '/*');
+ usort($files, function($a, $b) {
+ return filemtime($b) - filemtime($a);
+ });
+
+ $now = time();
+ $recentFiles = array_filter($files, fn($f) => $now - filemtime($f) <= 60);
+
+ if (count($recentFiles) > 50) return true;
+
+ if (count($files) >= 2) {
+ $t1 = filemtime($files[0]);
+ $t2 = filemtime($files[1]);
+ if (abs($t1 - $t2) < 2) return true;
+ }
+
+ return false;
+}
<link rel="icon" href="./Pictures/dot.png">
<link rel="stylesheet" href="./Styles/styles.css">
<?php require_once('./php/config.php');?>
+ <?php require_once('./php/captcha.php');?>
<link rel="author" href="mailto:email@dpolakovic.space">
<meta name="description" content="personal website and git server">
<meta name="author" content="David Polakovic, 2023">
<ul>
<li><a href="https://dpolakovic.space">About</a></li>
<li><a href="https://dpolakovic.space/blog.php">Blog</a></li>
- <!-- <li><a href="https://dpolakovic.space/dir.html">My web directory</a></li> -->
- <li><a href="https://dpolakovic.space/lib.html">My library</a></li>
- <li><a href="https://dpolakovic.space/test.html">TEST</a></li>
+ <li><a href="https://dpolakovic.space/mars-clock.html">Mars clock</a></li>
+ <li><a href="https://dpolakovic.space/dead-drop.html">dead-drop</a></li>
+ <li><a href="https://dpolakovic.space/test.html">TEST</a></li>
<li><a class="gitserver" href="https://git.dpolakovic.space">Git server</a>
</li>
</ul>
</p>
<p>
- <img src="https://c.tenor.com/qKwcziL1dhAAAAAi/alien-dancing.gif" alt="cool dancing alien" class="bee-gifs">
+ <!-- <img src="https://dpolakovic.space/Pictures/donkey-kong-country-eyes.gif" alt="cool dancing alien"> -->
+ <img src="https://dpolakovic.space/Pictures/bonzi-buddy.gif" alt="cool dancing alien">
</p>
<p>
<form action="https://www.paypal.com/donate" method="post" target="_top">
<img alt="" border="0" src="https://www.paypal.com/en_SK/i/scr/pixel.gif" width="1" height="1" />
</form>
</p>
- <p>
- <center>
- <img src="./Pictures/6brickcombo.png"/>
- </center>
+ <p>
+ <a href="">DOWNLOAD NOW</a>
</p>
-
-
- <a href="https://www.dpolakovic.space/Mars24.jar">DOWNLOAD NOW</a>
+
+ <br><br>
</main>
<!-- footer -->
Copyright <?php printYear() ?> David Polakovic -
Content of this web is licensed under
<a href="https://creativecommons.org/licenses/by-nc-nd/3.0/">CC BY-NC-ND 3.0</a>.
- <br>
- This site is javascript and cookie free. The source code is available
- <a href="https://git.dpolakovic.space/?p=my-website;a=tree">here</a>
- under
- <a href="https://www.gnu.org/licenses/gpl-3.0.en.html">GPLv3 license</a>.
+ <br>rubdeansheadwaitundernewton
</footer>
</body>