aboutsummaryrefslogtreecommitdiffstats
path: root/tool/mastodonwch
diff options
context:
space:
mode:
Diffstat (limited to 'tool/mastodonwch')
-rw-r--r--tool/mastodonwch/README.md105
-rw-r--r--tool/mastodonwch/cron.php80
-rw-r--r--tool/mastodonwch/index.php136
3 files changed, 321 insertions, 0 deletions
diff --git a/tool/mastodonwch/README.md b/tool/mastodonwch/README.md
new file mode 100644
index 00000000..0740a887
--- /dev/null
+++ b/tool/mastodonwch/README.md
@@ -0,0 +1,105 @@
+### Shared on Mastodon
+
+Who is sharing most Cloudflare links to other people?
+Oh, it's you?
+
+Congratulations, you are ranked in the top 50 of...
+
+![](https://codeberg.org/crimeflare/stop_cloudflare/raw/branch/master/image/clapclapclap.gif)
+
+(_Sarcasm? Of course. Stop sharing CF links already!_)
+
+What you can do? Tell them to stop using Cloudflare!
+
+
+### Some public reaction
+
+```
+'your little protest bot is making people upset,
+and i'm worried it might cause people to defederate from the instance,
+please tone it down'
+
+We need a new word for describing how fucked up this is,
+insanity just isn't doing it anymore.
+
+No shit it makes people upset *that's the fucking point*
+```
+-- [Jeff Cliff](http://qhtn4w2q36dojls2.onion/)
+
+
+```
+The bot doesn't care about you personally.
+It's doing a public service for your readers, who you otherwise sent into
+a netneutrality-hostile privacy-abusive walled-garden.
+
+It's to protect them so they are warned and have a trustworthy link to follow.
+```
+-- [resist1984](https://social.privacytools.io/@resist1984)
+
+
+```
+It doesn't matter if it is still online if I can't access it...
+so the bot is appreciated.
+```
+-- [Thufie](https://social.pixie.town/@thufie)
+
+
+### Code
+
+- [index.php](index.php): Main website to show the result
+- [cron.php](cron.php): Use it with your cronjob
+
+
+### Database
+
+- toot_cfsaid: Tweet URL which CF link was observed
+```
+id varchar(40) UNIQUE
+who varchar(80) INDEX
+url varchar(200) INDEX
+ym int(6) INDEX
+```
+
+- toot_notcf_fqdn: Unknown FQDN which was not listed as Cloudflare
+```
+fqdn varchar(200) UNIQUE
+dl int(1) INDEX
+```
+
+- toot_scanned: To make sure not to analyze same tweet again
+```
+id varchar(40) UNIQUE
+who varchar(80) INDEX
+iscf int(1) INDEX
+ym int(6) INDEX
+```
+
+- toot_sharefqdn: Just for counting FQDN
+```
+id varchar(40) UNIQUE
+fqdn varchar(200) INDEX
+ym int(6) INDEX
+```
+
+
+### Live demo
+
+If you want to see this in action: [Onion](http://stopcloudflare@avrynpc2q7pknqa3ucf5tvjcwad5nxvxgwnzvl2b6dx6uo4f7nc7zzqd.onion/mastodon/)
+
+
+
+### Live API
+
+`http://(onion)/mastodon/?who=a&json`
+
+`who`:
+- `a`, Show Top 100 (Shared any links)
+- `c`, Show Top 100 (Shared Cloudflare links)
+- `f`, Show Top 100 (Shared FQDN)
+- `u`, About Mastodon Users
+- `s`, About Mastodon Servers
+
+Example:
+`curl -x socks5h://127.0.0.1:9050 -G -H "Authorization: Basic c3RvcGNsb3VkZmxhcmU6" "http://-----.onion/mastodon/" -d "who=c" -d "json"`
+
+> `[{"rank":1,"who":"xxx","toots":"xxx"},{"rank":2,...` \ No newline at end of file
diff --git a/tool/mastodonwch/cron.php b/tool/mastodonwch/cron.php
new file mode 100644
index 00000000..b6a26f67
--- /dev/null
+++ b/tool/mastodonwch/cron.php
@@ -0,0 +1,80 @@
+<?php
+ignore_user_abort(true);
+set_time_limit(120);
+$toots = [];
+$mastodon_servers = ['your.server.fqdn' => 'https://your.server.fqdn/write_this_block_yourself', 'yours2.fqdn' => 'https://...'];
+shuffle_assoc($mastodon_servers);
+$date_ym = gmdate('Ym');
+$sqlme = @new mysqli('localhost', 'sseeccrreett', 'sseeccrreett', 'sseeccrreett');
+if ($sqlme->connect_errno)
+{
+ exit;
+}
+foreach ($mastodon_servers as $svF => $svU)
+{
+ $got = @json_decode(wget($svU) , true);
+ if (!is_array($got) || count($got) < 10 || !isset($got[0]))
+ {
+ continue;
+ }
+ foreach ($got as $g)
+ {
+ if (!isset($g['url']) || !preg_match("/write_this_block_yourself/", $g['url']))
+ {
+ continue;
+ }
+ if (!isset($g['content']) || strlen($g['content']) < 8)
+ {
+ continue;
+ }
+ if (!isset($g['account']) || !isset($g['account']['acct']) || !preg_match("/write_this_block_yourself/", $g['account']['acct']))
+ {
+ continue;
+ }
+ if (strpos($g['account']['acct'], '@') === false)
+ {
+ $g['account']['acct'] = $g['account']['acct'] . '@' . $svF;
+ }
+ $txt = array_unique(array_filter(array_map(function ($l)
+ {
+ $isURL = (preg_match("/write_this_block_yourself/", $l) && !preg_match("/write_this_block_yourself/", $l)) ? true : false;
+ return $isURL ? explode('/', explode('://', $l, 2) [1], 2) [0] : '';
+ }
+ , explode('"', strip_tags($g['content'], '<a>')))));
+ if (count($txt) == 0)
+ {
+ continue;
+ }
+ $cfFound = 0;
+ foreach ($txt as $fqdn)
+ {
+ $tmp_id2 = sha1($g['url'] . ';' . $fqdn);
+ $junk = $sqlme->query("INSERT IGNORE INTO toot_sharefqdn (id,fqdn,ym) VALUES ('{$tmp_id2}','{$fqdn}','{$date_ym}');");
+ if (is_known_cf(get_domainname($fqdn) [1]))
+ {
+ $cfFound = 1;
+ }
+ else
+ {
+ $junk = $sqlme->query("INSERT IGNORE INTO toot_notcf_fqdn (fqdn,dl) VALUES ('{$fqdn}','0');");
+ }
+ }
+ $toots[sha1($g['url']) ] = [$g['account']['acct'], $g['url'], $cfFound];
+ }
+}
+foreach ($toots as $k => $v)
+{
+ $junk = $sqlme->query("INSERT IGNORE INTO toot_scanned (id,who,iscf,ym) VALUES ('{$k}','{$v[0]}','{$v[2]}','{$date_ym}');");
+ if ($v[2] == 1)
+ {
+ $junk = $sqlme->query("INSERT IGNORE INTO toot_cfsaid (id,who,url,ym) VALUES ('{$k}','{$v[0]}','{$v[1]}','{$date_ym}');");
+ }
+}
+if (gmdate('G') == 0)
+{
+ $date_ym = gmdate('Ym', strtotime('7 months ago'));
+ $junk = $sqlme->query("DELETE FROM toot_scanned WHERE ym = '{$date_ym}';");
+ $junk = $sqlme->query("DELETE FROM toot_cfsaid WHERE ym = '{$date_ym}';");
+ $junk = $sqlme->query("DELETE FROM toot_sharefqdn WHERE ym = '{$date_ym}';");
+}
+file_put_contents('/onion/sseeccrreett/data/mastodon.toot.scan', ''); \ No newline at end of file
diff --git a/tool/mastodonwch/index.php b/tool/mastodonwch/index.php
new file mode 100644
index 00000000..39503053
--- /dev/null
+++ b/tool/mastodonwch/index.php
@@ -0,0 +1,136 @@
+<?php
+$sqlme = @new mysqli('localhost', 'sseeccrreett', 'sseeccrreett', 'sseeccrreett');
+if ($sqlme->connect_errno)
+{
+ exit;
+}
+$count_all = - 1;
+if ($r = $sqlme->query("SELECT count(id) FROM toot_scanned;"))
+{
+ $rr = mysqli_fetch_assoc($r);
+ $r->free();
+ $count_all = $rr['count(id)'];
+}
+$count_cf = - 1;
+if ($r = $sqlme->query("SELECT count(id) FROM toot_scanned WHERE iscf=1;"))
+{
+ $rr = mysqli_fetch_assoc($r);
+ $r->free();
+ $count_cf = $rr['count(id)'];
+}
+if ($count_all == - 1 || $count_cf == - 1)
+{
+ exit;
+}
+$count_acpct = round(($count_cf * 100) / $count_all, 2);
+$count_all = number_format($count_all);
+$count_cf = number_format($count_cf);
+$count_waitask = - 1;
+if ($r = $sqlme->query("SELECT count(fqdn) FROM toot_notcf_fqdn WHERE dl=0;"))
+{
+ $rr = mysqli_fetch_assoc($r);
+ $r->free();
+ $count_waitask = $rr['count(fqdn)'];
+}
+$count_waitask = number_format($count_waitask);
+$lastuptime = humanTiming(filemtime('/onion/sseeccrreett/data/mastodon.toot.scan'));
+$var_who = htmlspecialchars($_GET['who'], ENT_QUOTES);
+$resultHTML = '';
+if (write_this_block_yourself)
+{
+ $var_who = '';
+}
+if (preg_match("/write_this_block_yourself/", $var_who))
+{
+ $resultHTML .= '<br><table border=1>';
+ $person_a = 0;
+ if ($r = $sqlme->query("SELECT count(id) FROM toot_scanned WHERE who='{$var_who}';"))
+ {
+ $rr = mysqli_fetch_assoc($r);
+ $r->free();
+ $person_a = $rr['count(id)'];
+ }
+ $person_b = 0;
+ if ($r = $sqlme->query("SELECT count(id) FROM toot_scanned WHERE who='{$var_who}' AND iscf=1;"))
+ {
+ $rr = mysqli_fetch_assoc($r);
+ $r->free();
+ $person_b = $rr['count(id)'];
+ }
+ $person_c = round(($person_b * 100) / $person_a, 2);
+ if (is_nan($person_c))
+ {
+ $person_c = 0;
+ }
+ $person_a = number_format($person_a);
+ $person_b = number_format($person_b);
+ $resultHTML .= "<tr><th>About</th><th>{$var_who}</th></tr>";
+ $resultHTML .= "<tr><td>Toots has links</td><td>{$person_a}</td></tr>";
+ $resultHTML .= "<tr><td>&#11169; Toots has Cloudflare link</td><td>{$person_b} [<i>{$person_c}</i>%]</td></tr>";
+ $resultHTML .= "<tr><td> </td><td>Detected (LIMIT 100)</td></tr>";
+ if ($r = $sqlme->query("SELECT url FROM toot_cfsaid WHERE who='{$var_who}' LIMIT 100;"))
+ {
+ while ($row = mysqli_fetch_assoc($r))
+ {
+ $vurl = htmlspecialchars($row['url'], ENT_QUOTES);
+ $resultHTML .= "<tr><td></td><td><a href=\"{$vurl}\" target=\"_blank\">{$vurl}</a></td></tr>";
+ }
+ }
+ $resultHTML .= '</table>';
+}
+elseif ($var_who == 'a')
+{
+ $resultHTML .= '<br><table border=1><tr><th>Shared any links</th><th>Toots</th></tr>';
+ if ($r = $sqlme->query("SELECT who,count(*) as count FROM toot_scanned GROUP BY who ORDER BY count DESC LIMIT 100;"))
+ {
+ while ($row = mysqli_fetch_assoc($r))
+ {
+ $rcount = number_format($row['count']);
+ $resultHTML .= "<tr><td><a href=\"./?who={$row['who']}\">{$row['who']}</a></td><td>{$rcount}</td></tr>";
+ }
+ }
+ $resultHTML .= '</table>';
+}
+elseif ($var_who == 'c')
+{
+ $resultHTML .= '<br><table border=1><tr><th>Shared Cloudflare links</th><th>Toots</th></tr>';
+ if ($r = $sqlme->query("SELECT who,count(*) as count FROM toot_scanned WHERE iscf=1 GROUP BY who ORDER BY count DESC LIMIT 100;"))
+ {
+ while ($row = mysqli_fetch_assoc($r))
+ {
+ $rcount = number_format($row['count']);
+ $resultHTML .= "<tr><td><a href=\"./?who={$row['who']}\">{$row['who']}</a></td><td>{$rcount}</td></tr>";
+ }
+ }
+ $resultHTML .= '</table>';
+}
+elseif ($var_who == 'f')
+{
+ $resultHTML .= '<br><table border=1><tr><th>Shared FQDN</th><th>Cloudflare</th><th>Found in Toots</th></tr>';
+ if ($r = $sqlme->query("SELECT fqdn,count(*) as count FROM toot_sharefqdn GROUP BY fqdn ORDER BY count DESC LIMIT 50;"))
+ {
+ while ($row = mysqli_fetch_assoc($r))
+ {
+ $rcount = number_format($row['count']);
+ $riscf = is_known_cf(get_domainname($row['fqdn']) [1]) ? '<font color="red">Yes</font>' : 'No';
+ $resultHTML .= "<tr><td>{$row['fqdn']}</td><td>{$riscf}</td><td>{$rcount}</td></tr>";
+ }
+ }
+ $resultHTML .= '</table>';
+}
+else
+{
+ $resultHTML .= '<ul><li> <a href="./?who=a">Show Top 100 (Shared any links)</a></li>';
+ $resultHTML .= '<li> <a href="./?who=c">Show Top 100 (Shared Cloudflare links)</a></li>';
+ $resultHTML .= '<li> <a href="./?who=f">Show Top 50 (Shared FQDN)</a></li>';
+ $resultHTML .= '<li> <a href="#" onclick="location.href=\'./?who=\'+(prompt(\'user@example.com\')||\'\');">Search by Mastodon ID</a></li></ul>';
+}
+$finalpage = <<<HTMLRESULT
+<html><title>Shared on Mastodon</title><br><br><div>
+[ <a href="./">INDEX</a> ] Update <i>{$lastuptime} ago</i><br>
+<b>Toots has links</b>: {$count_all}<br>
+&#11169; <b>Toots has Cloudflare link</b>: {$count_cf} [<i>{$count_acpct}</i>%]<br>
+<b>Pending Investigation</b>: {$count_waitask}<br>
+<hr>{$resultHTML}</div></html>
+HTMLRESULT;
+echo (str_replace("\n", '', $finalpage)); \ No newline at end of file