Compare commits

...

2 Commits

Author SHA1 Message Date
gravel 75d67a7c95
Use untracked list for hardcoded servers 2 weeks ago
gravel 33904e2c2d
Fix cURL result discard 2 weeks ago

5
.gitignore vendored

@ -1,3 +1,8 @@
#!
#! Do not forget to add items you do not want cleaned
#! to .gitpreserve as well!
#!
# Fetched room info
output/servers.json
output/tags.json

@ -0,0 +1,3 @@
[https://open.getsession.org]
pubkey=a03c383cf63c3c4efe67acc52112a6dd734b3a946b9545f488aaa93da7991238
icon=session

@ -1,2 +1,22 @@
[room+1234]
; server-wide overrides
[66666666]
rating=nsfw
; room overrides
[room+12345678]
staff_count=4
safety=nsfw
[room+23456789]
stickied=true
[room+3456789a]
feedback_room=true
[test+12345678]
testing=true
[bad+66666666]
rating=unsafe

@ -12,3 +12,5 @@ cache-lt
# Custom Doxyfile configuration
Doxyfile
# Custom content
custom/**

@ -9,6 +9,7 @@
require_once 'getenv.php';
require_once 'utils/getopt.php';
require_once 'utils/utils.php';
require_once 'utils/read-config.php';
require_once 'servers/known-servers.php';
require_once 'servers/servers-rooms.php';
require_once 'servers/sources.php';
@ -27,11 +28,13 @@
*/
function main() {
global $PROJECT_ROOT, $CACHE_ROOT, $ROOMS_FILE, $TAGS_FILE,
$KNOWN_SERVERS, $KNOWN_PUBKEYS, $DO_DRY_RUN, $DO_ARCHIVE_FILES;
$DO_DRY_RUN, $DO_ARCHIVE_FILES;
// Create default directories..
file_exists($CACHE_ROOT) or mkdir($CACHE_ROOT, 0700);
$local_config = LocalConfig::get_instance();
// Query our sources and store the resulting HTML.
$sources = new CommunitySources();
@ -41,7 +44,10 @@
$servers = CommunityServer::from_join_urls($sources->get_join_urls());
// Add known hosts.
$servers = [...CommunityServer::from_known_hosts($KNOWN_SERVERS, $KNOWN_PUBKEYS), ...$servers];
$servers = [
...CommunityServer::from_known_hosts($local_config->get_known_servers()),
...$servers
];
// Merge servers with the same URL.
$servers = CommunityServer::dedupe_by_url($servers);

@ -4,71 +4,6 @@
* Provide hardcoded information on Community servers and Communities.
*/
/**
* @var $KNOWN_SERVERS
* Hardcoded Community server URLs.
*/
$KNOWN_SERVERS = array(
// Official server
"https://open.getsession.org",
// Found with shodan.io:
"http://164.92.176.135",
"http://176.119.147.102",
"http://60a9fc9.online-server.cloud",
"http://93.95.230.10",
"http://94.176.239.60",
"http://captain.geekgalaxy.com",
"http://session.hwreload.it",
"http://sogs.k9net.org",
"https://gaohuangse.work",
// Found via Reddit:
"http://5.39.117.98",
// Found on Session:
// "http://88.212.53.198:4080",
// legacy
// "http://3.69.29.128", // former https://reccacon.com
// Offline:
// "http://13.233.251.36:8081",
// Removed by request:
// "http://116.203.51.179",
// "http://bitcoincash.tokyo/",
// Removed out of decency:
// [redacted]
);
/**
* @var $KNOWN_PUBKEYS
* Associative array of SOGS public keys by server hostname.
* Keys are sorted alphabetically.
*/
$KNOWN_PUBKEYS = array(
"116.203.51.179" => "39016f991400c35a46e11e06cb2a64d6d8ab6652e484a556b14f7cf57ed7e73a",
"13.233.251.36:8081" => "efcaecf00aebf5b75e62cf1fd550c6052842e1415a9339406e256c8b27cd2039",
"164.92.176.135" => "e529311ec8fb6fdb950aaa4fb71fc4da3ea59c6c9ba2886708b9538eea6aa213",
"176.119.147.102" => "e093994156ec92e4c13d0387208bfa48ae56dd88b8f60a03980d9ef048af1e3f",
"3.69.29.128" => "02bdb3f74b59355724b1a59676127729602b5e34261efb965a94ccac94cd6a62",
"5.39.117.98" => "4bec6d6c7b502a819b47b3af75272c0774ab1214fba33fb5ec29949f864eb028",
"60a9fc9.online-server.cloud" => "7908bcd748313355f99e62f9c1f11c395d04019410edb7ee1618dbe26a423c4f",
"88.212.53.198:4080" => "7c5908efd053e7d4634f606328d0a3e50b86e4bef5f76ab84658435321110600",
"93.95.230.10" => "b501f2dc7dc912aa0981b0ba10f2ba739d2f729a7d9b37022aee505aaf72807c",
"94.176.239.60" => "2cbde327e9da216af9a69876bc57e16cc0c540b0aa2dfecdd1c115e67993b040",
"captain.geekgalaxy.com" => "7242ad657dc2dd20e902a6fa82c34465907b67e80daf50173f38d5745abbaa24",
"gaohuangse.work" => "2cd535b2e6a1fb40d1166910561d85a027782b1d751118897eca6056f4738a10",
"open.getsession.org" => "a03c383cf63c3c4efe67acc52112a6dd734b3a946b9545f488aaa93da7991238",
"session.hwreload.it" => "4b3e75eedd2116b4dab0bcb6443b0e9fbfce7bcf1d35970bdad8a57a0113fb20",
"sogs.k9net.org" => "fdcb047eb78520e925fda512a45ae74c6e2de9e0df206b3c0471bf1509919559",
);
/**
* @var string[] $ICON_ALLOWLIST
* Hostnames considered to have safe room icons.

@ -405,11 +405,9 @@
* @return int
*/
function get_staff_count(): int {
$room_id = $this->get_room_identifier();
return (
LocalConfig::get_instance()
->get_room_staff_count_override($room_id)
->get_room_staff_count_override($this)
?? count($this->get_staff())
);
}
@ -912,7 +910,7 @@
* when the servers are in correct order, interchangeable, or in reverse order,
* respectively.
*/
static function compare_by_url($a, $b): int {
static function compare_by_url(CommunityServer $a, CommunityServer $b): int {
return strcmp(
$a->get_hostname(),
$b->get_hostname()
@ -1125,27 +1123,25 @@
/**
* Create server instances located on hardcoded hosts.
* @param string[] $hosts Array of base URLs for known servers.
* @param string[] $pubkeys
* Associative array from hostnames to SOGS public keys.
* @param string[] $hosts Array from server base URLs to array including pubkey.
* @return CommunityServer[] Array of resulting Community servers.
*/
static function from_known_hosts(array $hosts, array $pubkeys) {
static function from_known_hosts(array $known_servers) {
$servers = [];
foreach ($hosts as $base_url) {
foreach ($known_servers as $base_url => $server_details) {
$server = new CommunityServer();
$server->base_url = $base_url;
$hostname = url_get_base($base_url, false);
if (!isset($pubkeys[$hostname])) {
if (!isset($server_details['pubkey'])) {
log_error("Known server $hostname has no known pubkey.");
throw new Error("Known server $hostname has no known pubkey");
}
$server->set_pubkey($pubkeys[$hostname]);
$server->set_pubkey($server_details['pubkey']);
$servers[] = $server;
}
@ -1698,10 +1694,10 @@
* Checks whether this server belongs to Session / Oxen Privacy Tech Foundation.
*/
function is_official_server() {
global $KNOWN_PUBKEYS;
$config = LocalConfig::get_instance();
return (
$this->base_url == "https://open.getsession.org" &&
$this->get_pubkey() == $KNOWN_PUBKEYS['open.getsession.org']
$this->get_pubkey() == $config->get_known_servers()['https://open.getsession.org']['pubkey']
);
}
}

@ -288,12 +288,11 @@
do {
$curlm_status = curl_multi_exec($this->transfers, $curlm_active_transfer);
if ($curlm_active_transfer) {
// Block 1 second for pending transfers
// Block 1 second for active transfers
curl_multi_select($this->transfers, timeout: 1.0);
// curl_multi_select($transfers, timeout: 6.0);
}
$this->process_curl_activity();
} while ($curlm_active_transfer && $curlm_status == CURLM_OK);
$activity = $this->process_curl_activity();
} while (($activity || $curlm_active_transfer) && $curlm_status == CURLM_OK);
return $curlm_status;
}
@ -324,8 +323,10 @@
* Respond to new activity on enroled transfers.
*/
private function process_curl_activity() {
$activity = 0;
while (false !== ($info = curl_multi_info_read($this->transfers))) {
if ($info['msg'] != CURLMSG_DONE) continue;
$activity = 1;
/**
* @var CurlHandle $handle
*/
@ -338,6 +339,8 @@
$this->coroutines[$coroutine_id]->advance($handle);
$this->poll_coroutine_for_transfer($coroutine_id);
}
return $activity;
}
}

@ -6,11 +6,40 @@ require_once 'php/utils/logging.php';
* @var string $CONFIG_ROOT
*/
function config_requiring_type(
mixed $value,
bool $int = false,
bool $string = false,
bool $bool = false,
bool $float = false,
bool $null = true
) {
if (is_int($value) && $int) return $value;
if (is_bool($value) && $bool) return $value;
if (is_string($value) && $string) return $value;
if (is_float($value) && $float) return $value;
if (is_null($value) && $null) return $value;
$realtype = get_debug_type($value);
throw new Error("Unexpected configuration option type: $realtype");
}
/**
* Provides custom configuration values.
*/
class LocalConfig {
private function __construct() {
$this->room_overrides =
$room_overrides =
LocalConfig::maybe_parse_ini_file(LocalConfig::ROOM_OVERRIDES_CONFIG)
?? array();
// Sort room overrides last
uksort($room_overrides, function($identifier_a, $identifier_b) {
return str_contains($identifier_b, "+") - str_contains($identifier_a, "+");
});
$this->room_overrides = $room_overrides;
$this->room_overrides_computed = array();
$this->known_servers =
LocalConfig::maybe_parse_ini_file(LocalConfig::KNOWN_SERVERS_CONFIG)
?? array();
}
private static LocalConfig | null $instance = null;
@ -24,9 +53,14 @@ class LocalConfig {
}
private const ROOM_OVERRIDES_CONFIG = "room-overrides.ini";
private const KNOWN_SERVERS_CONFIG = "known-servers.ini";
private readonly array $room_overrides;
private array $room_overrides_computed;
private readonly array $known_servers;
private static function maybe_parse_ini_file(string $filename): array | null {
global $CONFIG_ROOT;
$file = "$CONFIG_ROOT/$filename";
@ -36,7 +70,7 @@ class LocalConfig {
return null;
}
return parse_ini_file($file, process_sections: true, scanner_mode: INI_SCANNER_RAW);
return parse_ini_file($file, process_sections: true, scanner_mode: INI_SCANNER_TYPED);
}
/**
@ -46,13 +80,92 @@ class LocalConfig {
return new LocalConfig();
}
private function get_room_override(string $room_id, string $override_key) {
$room_overrides = $this->room_overrides[$room_id] ?? array();
return $room_overrides[$override_key] ?? null;
private function get_room_overrides(CommunityRoom $room) {
$room_id = $room->get_room_identifier();
if (isset($this->room_overrides_computed[$room_id])) {
return $this->room_overrides_computed[$room_id];
}
$room_overrides = array();
foreach ($this->room_overrides as $identifier => $overrides) {
if ($room->matched_by_identifier($identifier)) {
$room_overrides = [...$room_overrides, ...$overrides];
}
}
return $this->room_overrides_computed[$room_id] = $room_overrides;
}
public function get_room_staff_count_override(CommunityRoom $room): int | null {
return config_requiring_type(
$this->get_room_overrides($room)['staff_count'],
int: true,
);
}
public function get_room_safety_override(CommunityRoom $room): RoomSafety {
return RoomSafety::from_keyword(
$this->get_room_overrides($room)['safety']
);
}
private function get_bool_override_value(CommunityRoom $room, string $override_key) {
return config_requiring_type(
$this->get_room_overrides($room)[$override_key] === true,
bool: true
) === true;
}
public function is_testing_room(CommunityRoom $room): bool {
return $this->get_bool_override_value($room, 'testing');
}
public function is_stickied_room(CommunityRoom $room): bool {
return $this->get_bool_override_value($room, 'stickied');
}
public function get_known_servers(): array {
return $this->known_servers;
}
}
class RoomSafety {
private function __construct(int $value) {
$this->safety = $value;
}
private readonly int $safety;
private const UNSAFE = -2;
private const NOT_SAFE_FOR_WORK = -1;
private const UNSET = 0;
private const SAFE_FOR_WORK = 1;
public static function from_keyword(string|null $keyword) {
if (null == $keyword) {
return new RoomSafety(RoomSafety::UNSET);
}
switch (mb_strtolower($keyword)) {
case "unsafe":
return new RoomSafety(RoomSafety::UNSAFE);
case "nsfw":
return new RoomSafety(RoomSafety::NOT_SAFE_FOR_WORK);
case "sfw":
return new RoomSafety(RoomSafety::SAFE_FOR_WORK);
default:
throw new Error("Unknown safety class: $keyword");
}
}
private function is_set() {
return $this->safety !== RoomSafety::UNSET;
}
public function get_room_staff_count_override(string $room_id) {
return $this->get_room_override($room_id, 'staff_count');
public function rated_nsfw(): bool | null {
if (!$this->is_set()) return null;
return $this->safety <= RoomSafety::NOT_SAFE_FOR_WORK;
}
}

Loading…
Cancel
Save