mirror of
https://github.com/ChronosX88/psyced.git
synced 2024-11-09 20:11:00 +00:00
net/spyc is not looking good :-(
This commit is contained in:
parent
40e7a625ee
commit
a4e16cd2c4
73
CHANGESTODO
73
CHANGESTODO
@ -4,6 +4,10 @@ This file contains TODO and CHANGES (at EOF) rolled into one.
|
|||||||
Essentially: whenever you fix something, move that line to the end of file.
|
Essentially: whenever you fix something, move that line to the end of file.
|
||||||
- marks bugs & fixes, + marks new features, ? marks issues, * marks big stuff
|
- marks bugs & fixes, + marks new features, ? marks issues, * marks big stuff
|
||||||
________________________________________________________________________
|
________________________________________________________________________
|
||||||
|
== NEXT RELEASE ========================================================
|
||||||
|
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
|
||||||
|
? support tls multiplexing on all suitable ports
|
||||||
|
________________________________________________________________________
|
||||||
== currently being inspected ===========================================
|
== currently being inspected ===========================================
|
||||||
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
|
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
|
||||||
- remote IRC place does not send names listing on /join
|
- remote IRC place does not send names listing on /join
|
||||||
@ -60,22 +64,18 @@ ________________________________________________________________________
|
|||||||
- REGISTERED_USERS_ONLY does not behave properly on IRC port
|
- REGISTERED_USERS_ONLY does not behave properly on IRC port
|
||||||
(see also NO_NEWBIES ... clean up and rename?)
|
(see also NO_NEWBIES ... clean up and rename?)
|
||||||
|
|
||||||
- still UTF8 problems, once a day typically:
|
|
||||||
[Thu Jul 31 22:10:57 2008] C:xmpp:somewhere "*regexp: bad UTF-8 data
|
|
||||||
" "<message to='michael@somewhere' type='groupchat' from='*dev@psyced.org/fippo'><body>/me würde auf '96 tippen</body></message>
|
|
||||||
|
|
||||||
? tg reports inconsistent display of availability states in friend contextes
|
? tg reports inconsistent display of availability states in friend contextes
|
||||||
so far unable to reproduce
|
so far unable to reproduce
|
||||||
________________________________________________________________________
|
________________________________________________________________________
|
||||||
== NEXT RELEASE ========================================================
|
|
||||||
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
|
|
||||||
+ before doing an announced new release, psyced should accept old psyc
|
|
||||||
syntax but send new psyc syntax by default!
|
|
||||||
|
|
||||||
? support tls multiplexing on all suitable ports
|
|
||||||
________________________________________________________________________
|
|
||||||
== psyced 1.0 ==========================================================
|
== psyced 1.0 ==========================================================
|
||||||
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
|
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
|
||||||
|
SPYC (implementation of http://about.psyc.eu/Specification)
|
||||||
|
* to activate spyc support, defined USE_SPYC
|
||||||
|
it will attempt to use new syntax on outgoing links by default
|
||||||
|
* to debug verification, define USE_VERIFICATION
|
||||||
|
* to spend an extra round trip time negotiating, define USE_FEATURES
|
||||||
|
- net/spyc is buggy and incomplete
|
||||||
|
|
||||||
INVITE ISSUES
|
INVITE ISSUES
|
||||||
- remote /invite is shown without uniform, just #nick_place
|
- remote /invite is shown without uniform, just #nick_place
|
||||||
remote invite thus doesn't work for ircers..
|
remote invite thus doesn't work for ircers..
|
||||||
@ -173,16 +173,10 @@ see also http://about.psyc.eu/subscription
|
|||||||
________________________________________________________________________
|
________________________________________________________________________
|
||||||
== TOP DELEGATES for 1.0 ===============================================
|
== TOP DELEGATES for 1.0 ===============================================
|
||||||
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
|
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
|
||||||
- bartman sagt: psyconf erkennt keine absoluten pfade bei _path_PEM_key und _path_PEM_certificate
|
|
||||||
|
|
||||||
- world/static/index.html should be generated to contain applet port
|
- world/static/index.html should be generated to contain applet port
|
||||||
- fix member list in applet
|
- fix member list in applet
|
||||||
* see also APPLET, ANNOUNCEMENT, JABBER, FILE TRANSFER
|
* see also APPLET, ANNOUNCEMENT, JABBER, FILE TRANSFER
|
||||||
|
|
||||||
- el: und irc bekommt keinen join fuer den raum
|
|
||||||
welche? bei newsräumen ist das richtig so
|
|
||||||
.. obwohl? überhaupt keine bestätigung!?
|
|
||||||
|
|
||||||
+ login message that tells you about amount of pending/offered friendships etc.
|
+ login message that tells you about amount of pending/offered friendships etc.
|
||||||
|
|
||||||
+ Fix the /surf HTML code, see http://about.psyc.eu/Talk:Style
|
+ Fix the /surf HTML code, see http://about.psyc.eu/Talk:Style
|
||||||
@ -1030,6 +1024,7 @@ ________________________________________________________________________
|
|||||||
|
|
||||||
+ elmex says: ./install.sh -d(efault)/-l(astrun) to skip all the questions?
|
+ elmex says: ./install.sh -d(efault)/-l(astrun) to skip all the questions?
|
||||||
just ask? "Would you like to skip the questions and use last run's inputs?"
|
just ask? "Would you like to skip the questions and use last run's inputs?"
|
||||||
|
? but why? you shouldn't need to run install.sh more than once!
|
||||||
|
|
||||||
+ rpms! debs! ebuilds fertig machen und submitten!
|
+ rpms! debs! ebuilds fertig machen und submitten!
|
||||||
- psyced.ebuild: saga meint wir sollten conf.d verwenden statt
|
- psyced.ebuild: saga meint wir sollten conf.d verwenden statt
|
||||||
@ -2029,11 +2024,6 @@ thoughts from buddy-heggy.txt:
|
|||||||
+ /set speakactionpossessive Meinung ist
|
+ /set speakactionpossessive Meinung ist
|
||||||
Jemandens Meinung ist: ach leck mich doch
|
Jemandens Meinung ist: ach leck mich doch
|
||||||
|
|
||||||
== INTEGRATION OF VIDEO/TELEPHONY ======================================
|
|
||||||
+ support launch of video chat apps using infos provided by UNLs
|
|
||||||
das ding hier wollte ich einfach mal aufschreiben..
|
|
||||||
is natürlich politisch inkorrekt: www.telwell.de
|
|
||||||
|
|
||||||
== OPTIONAL PERFORMANCE IMPROVEMENTS ===================================
|
== OPTIONAL PERFORMANCE IMPROVEMENTS ===================================
|
||||||
- replace(args[2], "%", "@"); would probably be faster if done as
|
- replace(args[2], "%", "@"); would probably be faster if done as
|
||||||
i = index(str, '%'); if (i >= 0) str[i] = '@';
|
i = index(str, '%'); if (i >= 0) str[i] = '@';
|
||||||
@ -2099,49 +2089,10 @@ MISCELLANEOUS STUFF:
|
|||||||
was ich mir wünschen würde wäre eine if-ueberpruefung, ob ne var
|
was ich mir wünschen würde wäre eine if-ueberpruefung, ob ne var
|
||||||
gesetzt ist
|
gesetzt ist
|
||||||
|
|
||||||
? befehl zum (re)starten/stoppen des muves (kill -1 ..)..
|
|
||||||
wird von psyconf nach etc/init.d erzeugt
|
|
||||||
könnte aber auch nach bin.. aber dann braucht er einen anderen namen
|
|
||||||
|
|
||||||
? nei suggests we should pass encrypted jabber messages on to other protocols.
|
|
||||||
irc clients may be able to decrypt them. i think the problem only exists
|
|
||||||
for PGP while OTR should work.
|
|
||||||
this is currently blocked by the ldmud which has problems handling large tcp
|
|
||||||
packets
|
|
||||||
|
|
||||||
? fippo findet, psyc sollte zumindest das nodeprep von xmpp übernehmen
|
? fippo findet, psyc sollte zumindest das nodeprep von xmpp übernehmen
|
||||||
am besten auch noch saslprep benutzen, nameprep sowies.
|
am besten auch noch saslprep benutzen, nameprep sowies.
|
||||||
Bahnhof? http://about.psyc.eu/Stringprep
|
Bahnhof? http://about.psyc.eu/Stringprep
|
||||||
|
|
||||||
== LDMUD ISSUES ========================================================
|
|
||||||
... normally belong into http://mantis.bearnip.com - but it isn't always
|
|
||||||
up and running. and maybe we should keep a list of _our_ issues with it
|
|
||||||
ourselves, anyway
|
|
||||||
|
|
||||||
- #define MAX_OUTCONN 5 /* TODO: Move this into config.h */
|
|
||||||
- minor: these defines in pkg-tls.h should go into ./configure & settings
|
|
||||||
#define TLS_DEFAULT_KEYFILE "key.pem"
|
|
||||||
#define TLS_DEFAULT_CERTFILE "cert.pem"
|
|
||||||
#define TLS_DEFAULT_TRUSTDIRECTORY "/etc/ssl/certs"
|
|
||||||
|
|
||||||
== XML ISSUES ==========================================================
|
|
||||||
Ein kleines Parser-Issue:
|
|
||||||
» C:xmpp:amessage.de
|
|
||||||
<stream:stream xmlns:stream='http://etherx.jabber.org/streams'
|
|
||||||
id='49f73b6a6b16a12d45af52be2b48444757d88b5a'
|
|
||||||
xmlns='jabber:server'
|
|
||||||
xmlns:db='jabber:server:dialback'
|
|
||||||
version='1.0'>
|
|
||||||
C:xmpp:amessage.de active for "amessage.de". opening with
|
|
||||||
([ /* #1 */
|
|
||||||
"stream": "http://etherx.jabber.org/streams",
|
|
||||||
"version": "1.0",
|
|
||||||
"id": "49f73b6a6b16a12d45af52be2b48444757d88b5a",
|
|
||||||
"xmlns": "jabber:server",
|
|
||||||
"db": "jabber:server:dialback"
|
|
||||||
])
|
|
||||||
Wie kommt er hier an das "db" im Parameter-Mapping?
|
|
||||||
|
|
||||||
== MOBILE APPS / GPRS / PSYCobile ======================================
|
== MOBILE APPS / GPRS / PSYCobile ======================================
|
||||||
Similar Projexx:
|
Similar Projexx:
|
||||||
http://freshmeat.net/projects/jimm/
|
http://freshmeat.net/projects/jimm/
|
||||||
|
@ -346,7 +346,12 @@ object compile_object(string file) {
|
|||||||
return rob;
|
return rob;
|
||||||
}
|
}
|
||||||
if (abbrev("psyc:", file)) {
|
if (abbrev("psyc:", file)) {
|
||||||
|
# ifdef USE_SPYC
|
||||||
|
# echo Using SPYC by default! Yeeha!
|
||||||
|
rob = clone_object(SPYC_PATH "active");
|
||||||
|
# else
|
||||||
rob = clone_object(PSYC_PATH "active");
|
rob = clone_object(PSYC_PATH "active");
|
||||||
|
# endif
|
||||||
D2(if (rob) PP(("NAMED CLONE: %O => %s\n", rob, file));)
|
D2(if (rob) PP(("NAMED CLONE: %O => %s\n", rob, file));)
|
||||||
return rob;
|
return rob;
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,12 @@
|
|||||||
#include <net.h>
|
#include <net.h>
|
||||||
#include <services.h>
|
#include <services.h>
|
||||||
|
|
||||||
|
#ifdef SPYC
|
||||||
|
inherit SPYC_PATH "circuit";
|
||||||
|
#else
|
||||||
inherit PSYC_PATH "circuit";
|
inherit PSYC_PATH "circuit";
|
||||||
|
#endif
|
||||||
|
|
||||||
inherit NET_PATH "circuit";
|
inherit NET_PATH "circuit";
|
||||||
|
|
||||||
volatile object super;
|
volatile object super;
|
||||||
@ -37,7 +42,11 @@ int logon(int failure) {
|
|||||||
if (port && port != PSYC_SERVICE) peeraddr += ":"+port;
|
if (port && port != PSYC_SERVICE) peeraddr += ":"+port;
|
||||||
// circuit::logon now also implies a full greeting
|
// circuit::logon now also implies a full greeting
|
||||||
// therefore it needs peeraddr, and the emit is redundant
|
// therefore it needs peeraddr, and the emit is redundant
|
||||||
|
# ifdef SPYC
|
||||||
|
SPYC_PATH "circuit"::logon(failure);
|
||||||
|
# else
|
||||||
PSYC_PATH "circuit"::logon(failure);
|
PSYC_PATH "circuit"::logon(failure);
|
||||||
|
# endif
|
||||||
#endif
|
#endif
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -1127,7 +1127,7 @@ vamixed startParse(string a) {
|
|||||||
restart();
|
restart();
|
||||||
if (isServer()) greet();
|
if (isServer()) greet();
|
||||||
}
|
}
|
||||||
# ifdef SPYC_PATH
|
# if defined(SPYC_PATH) && defined(USE_SPYC)
|
||||||
else if (a == "|") { // new S_GLYPH_PACKET_DELIMITER
|
else if (a == "|") { // new S_GLYPH_PACKET_DELIMITER
|
||||||
object o = clone_object(SPYC_PATH "server");
|
object o = clone_object(SPYC_PATH "server");
|
||||||
unless (o && exec(o, ME) && o->logon(0)) {
|
unless (o && exec(o, ME) && o->logon(0)) {
|
||||||
|
@ -25,7 +25,7 @@ volatile string netloc;
|
|||||||
|
|
||||||
// this is completely anti-psyc. it should take mcs as arguments
|
// this is completely anti-psyc. it should take mcs as arguments
|
||||||
// and look up the actual message from textdb.. FIXME
|
// and look up the actual message from textdb.. FIXME
|
||||||
#define CIRCUITERROR(reason) { debug_message("PSYC CIRCUIT ERROR: " reason); \
|
#define CIRCUITERROR(reason) { debug_message("SPYC CIRCUIT: " reason "\n"); \
|
||||||
croak("_error_circuit", "circuit error: " \
|
croak("_error_circuit", "circuit error: " \
|
||||||
reason); \
|
reason); \
|
||||||
return 0; \
|
return 0; \
|
||||||
@ -61,6 +61,25 @@ varargs mixed croak(string mc, string data, vamapping vars, vamixed source) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef USE_VERIFICATION
|
||||||
|
// request sender authentication and/or target acknowledgement
|
||||||
|
// from the remote side
|
||||||
|
void sender_verification(array(string) sourcehosts, array(string) targethosts)
|
||||||
|
{
|
||||||
|
// FIXME: wrong variables here
|
||||||
|
mapping vars = ([ "_list_sources_hosts" : sourcehosts,
|
||||||
|
"_list_targets_hosts" : targethosts,
|
||||||
|
"_tag" : RANDHEXSTRING ]);
|
||||||
|
// assumption: we have already resolved all targethosts and
|
||||||
|
// they point to the remote ip
|
||||||
|
foreach(string ho : targethosts) {
|
||||||
|
sAuthenticated(ho);
|
||||||
|
}
|
||||||
|
|
||||||
|
msg(0, "_request_verification", 0, vars);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// gets called during socket logon
|
// gets called during socket logon
|
||||||
int logon(int failure) {
|
int logon(int failure) {
|
||||||
sAuthHosts(([ ])); // reset authhosts
|
sAuthHosts(([ ])); // reset authhosts
|
||||||
@ -134,7 +153,20 @@ int logon(int failure) {
|
|||||||
// FIXME
|
// FIXME
|
||||||
unless(isServer()) {
|
unless(isServer()) {
|
||||||
emit("|\n"); // initial greeting
|
emit("|\n"); // initial greeting
|
||||||
|
#ifdef USE_FEATURES
|
||||||
|
// we have no features to request or offer
|
||||||
msg(0, "_request_features", 0);
|
msg(0, "_request_features", 0);
|
||||||
|
#else
|
||||||
|
# ifdef USE_VERIFICATION
|
||||||
|
// start hostname verification
|
||||||
|
// rather: look at Q and look for the hostnames we need
|
||||||
|
sender_verification(({ SERVER_HOST }), ({ peerhost }));
|
||||||
|
# else
|
||||||
|
if (function_exists("runQ")) {
|
||||||
|
runQ();
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -192,23 +224,6 @@ mapping process_header(mixed varops) {
|
|||||||
#define PSYC_TCP
|
#define PSYC_TCP
|
||||||
#include "dispatch.i"
|
#include "dispatch.i"
|
||||||
|
|
||||||
// request sender authentication and/or target acknowledgement
|
|
||||||
// from the remote side
|
|
||||||
void sender_verification(array(string) sourcehosts, array(string) targethosts)
|
|
||||||
{
|
|
||||||
// FIXME: wrong variables here
|
|
||||||
mapping vars = ([ "_list_sources_hosts" : sourcehosts,
|
|
||||||
"_list_targets_hosts" : targethosts,
|
|
||||||
"_tag" : RANDHEXSTRING ]);
|
|
||||||
// assumption: we have already resolved all targethosts and
|
|
||||||
// they point to the remote ip
|
|
||||||
foreach(string ho : targethosts) {
|
|
||||||
sAuthenticated(ho);
|
|
||||||
}
|
|
||||||
|
|
||||||
msg(0, "_request_verification", 0, vars);
|
|
||||||
}
|
|
||||||
|
|
||||||
// receives a msg from the remote side
|
// receives a msg from the remote side
|
||||||
// note: this is circuit-messaging
|
// note: this is circuit-messaging
|
||||||
void circuit_msg(string mc, mapping vars, string data) {
|
void circuit_msg(string mc, mapping vars, string data) {
|
||||||
@ -245,13 +260,13 @@ void circuit_msg(string mc, mapping vars, string data) {
|
|||||||
} else {
|
} else {
|
||||||
// FIXME!!!!
|
// FIXME!!!!
|
||||||
CIRCUITERROR("sorry, no more than one element in _list_sources_hosts currently");
|
CIRCUITERROR("sorry, no more than one element in _list_sources_hosts currently");
|
||||||
|
P0(("more than one element in _list_sources_hosts: %O\n", vars["_list_sources_hosts"]))
|
||||||
}
|
}
|
||||||
// keep tag if present!!!
|
// keep tag if present!!!
|
||||||
// resolve all of _list_sources_hosts
|
// resolve all of _list_sources_hosts
|
||||||
// look at _list_targets_hosts and determine localhostiness
|
// look at _list_targets_hosts and determine localhostiness
|
||||||
} else {
|
} else {
|
||||||
CIRCUITERROR("_request_verification is not allowed on TLS circuits.");
|
CIRCUITERROR("_request_verification is not allowed on TLS circuits.");
|
||||||
// _request_verification is not allowed on tls circuits
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "_notice_features":
|
case "_notice_features":
|
||||||
@ -262,15 +277,19 @@ void circuit_msg(string mc, mapping vars, string data) {
|
|||||||
flags -= TCP_PENDING_TIMEOUT;
|
flags -= TCP_PENDING_TIMEOUT;
|
||||||
}
|
}
|
||||||
sTextPath();
|
sTextPath();
|
||||||
|
#ifdef USE_FEATURES
|
||||||
if (tls_query_connection_state(ME) == 0) {
|
if (tls_query_connection_state(ME) == 0) {
|
||||||
|
# ifdef USE_VERIFICATION
|
||||||
// start hostname verification
|
// start hostname verification
|
||||||
// rather: look at Q and look for the hostnames we need
|
// rather: look at Q and look for the hostnames we need
|
||||||
sender_verification(({ SERVER_HOST }), ({ peerhost }));
|
sender_verification(({ SERVER_HOST }), ({ peerhost }));
|
||||||
|
# endif
|
||||||
} else {
|
} else {
|
||||||
if (function_exists("runQ")) {
|
if (function_exists("runQ")) {
|
||||||
runQ();
|
runQ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
case "_notice_verification":
|
case "_notice_verification":
|
||||||
P0(("_notice verification with %O\n", vars))
|
P0(("_notice verification with %O\n", vars))
|
||||||
|
@ -29,14 +29,16 @@ void dispatch(mixed header_vars, mixed varops, mixed method, mixed body) {
|
|||||||
if ((t = vars["_context"] || vars["_source"])) {
|
if ((t = vars["_context"] || vars["_source"])) {
|
||||||
array(mixed) u;
|
array(mixed) u;
|
||||||
unless (u = parse_uniform(t)) {
|
unless (u = parse_uniform(t)) {
|
||||||
DISPATCHERROR("logical source is not an uniform\n")
|
DISPATCHERROR("logical source is not a uniform\n")
|
||||||
}
|
}
|
||||||
#ifdef PSYC_TCP
|
#ifdef USE_VERIFICATION
|
||||||
|
# ifdef PSYC_TCP
|
||||||
unless (qAuthenticated(NAMEPREP(u[UHost]))) {
|
unless (qAuthenticated(NAMEPREP(u[UHost]))) {
|
||||||
DISPATCHERROR("non-authenticated host\n")
|
DISPATCHERROR("non-authenticated host\n")
|
||||||
}
|
}
|
||||||
#else
|
# else
|
||||||
// TODO?
|
// TODO?
|
||||||
|
# endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
// check that _target is hosted by us
|
// check that _target is hosted by us
|
||||||
|
Loading…
Reference in New Issue
Block a user