From 0a7f208a72ee3563beb4c2f069e38311c332f72d Mon Sep 17 00:00:00 2001 From: "psyc://loupsycedyglgamf.onion/~lynX" Date: Fri, 23 Oct 2020 13:22:39 +0200 Subject: [PATCH] fake redirection by iframe... --- place/remotor.c | 2 +- world/net/http/header.i | 10 ++- world/net/http/library.i | 13 +++- world/net/include/place.gen | 113 +++++++++++++++++++++++++++------- world/net/jabber/server.c | 7 ++- world/net/place/archetype.gen | 4 +- 6 files changed, 114 insertions(+), 35 deletions(-) diff --git a/place/remotor.c b/place/remotor.c index 4943852..8efe6ce 100644 --- a/place/remotor.c +++ b/place/remotor.c @@ -1,5 +1,5 @@ // this place is configured in a suitable way for receiving -// syslog events from the syslog2psyc tool in perlpsyc +// tor router events from the remotor tool in perlpsyc // #include diff --git a/world/net/http/header.i b/world/net/http/header.i index 21f6dd5..c6095b3 100644 --- a/world/net/http/header.i +++ b/world/net/http/header.i @@ -24,18 +24,16 @@ varargs http_error(string prot, int code, string comment, string html) { P2(("hterror(%O,%O,%O,%O) in %O\n", prot,code,comment,html, ME)) #if defined(T) // use the textdb if available - out = psyctext( T("_PAGES_error", - "[_code]\n" - "

[_comment]

\n"), + out = psyctext( T("_PAGES_error", "Error [_code]

[_code]

[_comment]
"), ([ "_comment": comment, "_code": code ]) ); #else // use some hardcoded defaults - out = "\n"; + out = "\n"; if (html) out = sprintf("%s\n%s%s", comment, out, html); else out = sprintf("\ -error %d\n\ +Error %d\n\ %s\n\ -


\n\n\ +


\n\n\ %s\n\n\

\n\ ", diff --git a/world/net/http/library.i b/world/net/http/library.i index 214ed0b..d123a34 100644 --- a/world/net/http/library.i +++ b/world/net/http/library.i @@ -95,12 +95,19 @@ varargs string htredirect(string prot, string target, string comment, int perman printf("%s %d %s\n%s", HTTP_SVERS, permanent ? R_MOVED : R_FOUND, comment, htheaders()); } + // this page might actually be visible + // if content-disposition: attachment is given + // or redirects are otherwise intercepted by plugin + // so a proper _PAGES form could be appropriate printf("\ Location: %s\n%s\ \n\ -%s.\n\ -", - target, extra, target, comment); +%s\n\ +\n\ +%s\n", + // exposing the link to end-user may not be intended: + // %s. + target, extra, comment, comment); return 0; } diff --git a/world/net/include/place.gen b/world/net/include/place.gen index feb6660..d2b9c88 100644 --- a/world/net/include/place.gen +++ b/world/net/include/place.gen @@ -18,6 +18,10 @@ #include #include +#ifndef HT_LOGO +# define HT_LOGO DEFAULT_HT_LOGO +#endif + #ifdef BRAIN # ifdef SLAVE @@ -610,8 +614,9 @@ htget(prot, query, headers, qs) { } #endif -#ifdef CHALLENGE_MATCH +#ifdef CHALLENGE_QUESTION // should make media player etc work also w/o challenge FIXME #include +#include "ht/http.h" #define CHALOG(verb) log_file("CHALLENGE", "%s %s %O A:%O P:%O C:%O\n", \ MYNICK, verb, query_ip_name(), \ @@ -619,14 +624,47 @@ htget(prot, query, headers, qs) { // maybe this all belongs into archetype.gen.. chesmo! htget(prot, query, headers, qs, data, noprocess) { - string item = headers[item] || "/@"+ MYNICK; - if (stringp(headers["cookie"]) && regmatch(headers["cookie"], - "challenge=complete&answer="+ md5(CHALLENGE_MATCH))) { + if (probably_private(this_interactive()) <= PRIVACY_SURVEILLED) { + hterror(prot, R_PAYMENTREQ, "To protect against abuse in this nasty world this function needs 'https' instead of 'http'."); + htnotify(query, headers, "_challenge_disabled_encryption", + "[_nick_place] sees no TLS by [_web_on] from [_web_from]."); + return 0; + } + string item = "/@"+ MYNICK; + if ( +# ifdef CHALLENGE_AGENT + stringp(headers["user-agent"]) && + regmatch(lower_case(headers["user-agent"]), CHALLENGE_AGENT) +# else +# ifdef CHALLENGE_ACCOUNTS +# define CHALLENGE_CHECK CHALLENGE_ACCOUNTS +# else +# ifdef CHALLENGE_MATCH +# define CHALLENGE_CHECK CHALLENGE_MATCH +# endif +# endif + stringp(headers["cookie"]) && regmatch(headers["cookie"], + "challenge=complete&answer="+ md5(CHALLENGE_CHECK)) +# endif + ) { CHALOG("completes"); - htnotify(query, headers, "_accomplished_web", + htnotify(query, headers, "_challenge_accomplished_web", "Challenge accomplished in [_nick_place] by [_web_on] coming from [_web_from]."); # ifdef CHALLENGE_REDIRECT - return htredirect(prot, CHALLENGE_REDIRECT, "There you go", 0, "Set-Cookie: psycplace=\"challenge=done\"; Path="+ item +"; Secure; Max-Age=9\n"); +# ifdef CHALLENGE_REDIRECT_TITLE +# ifdef CHALLENGE_QUESTION + htok3(prot, 0, "Set-Cookie: psycplace=\"challenge=done\"; Path="+ item +"; Secure; Max-Age=9\n"); +# else + htok(); +# endif + w("_PAGES_frame_redirect", 0, + ([ "_uniform_page" : CHALLENGE_REDIRECT, + "_title_page" : CHALLENGE_REDIRECT_TITLE, + "_nick_place" : MYNICK ]) ); + return 1; +# else + return htredirect(prot, CHALLENGE_REDIRECT, "Download or redirect initiated", 0, "Content-Disposition: attachment\nSet-Cookie: psycplace=\"challenge=done\"; Path="+ item +"; Secure; Max-Age=9\n"); +# endif # else # ifdef HTGET // you may want to output a player iframe instead of a redirect... @@ -636,33 +674,66 @@ htget(prot, query, headers, qs, data, noprocess) { # endif # endif } - if (stringp(query["answer"]) && headers["cookie"] && - regmatch(headers["cookie"], "challenge=given") && - regmatch(lower_case(query["answer"]), CHALLENGE_MATCH)) { - // lazy me could have used referer here ;) - string nu = stringp(query["parameters"]) && - strlen(query["parameters"]) ? - item +"?"+ query["parameters"] : item; - CHALOG("reloads"); - htredirect(prot, nu, "Reload, please", 0, "Set-Cookie: psycplace=\"challenge=complete&answer="+ md5(CHALLENGE_MATCH) +"\"; Path="+ item +"; Secure; Max-Age=99\n"); - return 1; +# if defined(CHALLENGE_MATCH) || defined(CHALLENGE_ACCOUNTS) + if (stringp(query["answer"])) { + unless (headers["cookie"]) { + CHALOG("disabled"); + hterror(prot, R_PAYMENTREQ, "To protect against abuse in this nasty world this function needs just temporarily enabled cookies. There are no de-anonymizing purposes involved. Or did you just lowercase my name in the URL?"); + htnotify(query, headers, "_challenge_disabled_web", + "[_nick_place] sees no cookies by [_web_on] from [_web_from]."); + return 1; + } + string acct; + if (regmatch(headers["cookie"], "challenge=given")) { + if (query["answer"] && +# ifdef CHALLENGE_ACCOUNTS + (acct = CHALLENGE_ACCOUNTS->consult(query["answer"])) +# else + regmatch(lower_case(query["answer"]), CHALLENGE_MATCH) +# endif + ) { + // lazy me could have used referer here ;) + string nu = stringp(query["parameters"]) && + strlen(query["parameters"]) && + query["parameters"] != "0" ? + item +"?"+ query["parameters"] : item; + CHALOG(acct? ("authenticates as "+ acct): "reloads"); + htredirect(prot, nu, "Reload, please", 0, "Set-Cookie: psycplace=\"challenge=complete&answer="+ md5(CHALLENGE_CHECK) +"\"; Path="+ item +"; Secure; Max-Age=99\n"); + if (acct) htnotify(query, headers, "_challenge_authenticated_web", + "[_web_on] authenticated for [_nick_place] coming from [_web_from].", acct); + return 1; + } else { + CHALOG("fails"); + htnotify(query, headers, "_challenge_failed_web", + "[_nick_place] sees [_web_on] from [_web_from] fail the challenge."); + } + } + } else +# endif + { + CHALOG("challenges"); + htnotify(query, headers, "_challenge_presented_web", + "[_nick_place] challenges [_web_on] coming from [_web_from]."); + // (query [_web_query], cookie [_web_cookie])."); } + // If you have trouble reloading the HTML template + // look out for both 'ht' and 'html' textdbs! sTextPath(query["layout"], query["lang"], "html"); // using a non-psyced cookie here so that you can't construct a // url that allows other people to bypass the challenge. - // could add a timeout here... htok3(prot, 0, "Set-Cookie: psycplace=\"challenge=given\"; Path="+ item +"; Secure; Max-Age=999\n"); - CHALOG("challenges"); +# ifndef CHALLENGE_REDIRECT_TITLE +# define CHALLENGE_REDIRECT_TITLE "Challenge for " MYNICK +# endif w("_PAGES_group_challenge", 0, ([ "_challenge" : htquote(CHALLENGE_QUESTION), // if the user failed the challenge, // we maintain the original qs for next attempt: "_parameters" : query["parameters"] || qs, + "_uniform_logo" : HT_LOGO, + "_title_page" : CHALLENGE_REDIRECT_TITLE, "_nick_place" : MYNICK ]) ); // printf("%O vs %O\n", query, headers); - htnotify(query, headers, "_challenged_web", - "[_nick_place] challenges [_web_on] coming from [_web_from]."); - // (query [_web_query], cookie [_web_cookie])."); return 1; } #endif diff --git a/world/net/jabber/server.c b/world/net/jabber/server.c index c78481f..038a496 100644 --- a/world/net/jabber/server.c +++ b/world/net/jabber/server.c @@ -191,7 +191,7 @@ jabberMsg(XMLNode node) { // super dirty.. this should all be in textdb packet = sprintf("" "" - "Registration by XMPP not permitted.", id); #else packet = sprintf("" @@ -235,7 +235,10 @@ jabberMsg(XMLNode node) { // QUIT } else { #if defined(_flag_disable_unauthenticated_users_XMPP) || defined(_flag_disable_registration_XMPP) - // TODO: generate some error as above + emit(sprintf("" + "" + "Registration by XMPP not permitted.", + id)); #else user -> vSet("password", t[Cdata]); if (t = helper["/email"]) { diff --git a/world/net/place/archetype.gen b/world/net/place/archetype.gen index 67dfa6a..07fa50e 100644 --- a/world/net/place/archetype.gen +++ b/world/net/place/archetype.gen @@ -474,7 +474,7 @@ _request_set_topic(source, mc, data, vars, b) { #if HAS_PORT(HTTP_PORT, HTTP_PATH) || HAS_PORT(HTTPS_PORT, HTTP_PATH) // for GDPR compliance server owners are expected not to log these messages -htnotify(query, headers, mc, fmt) { +htnotify(query, headers, mc, fmt, acct) { if (query["from"] == "") query["from"] = 0; if (query["location"] == "") query["location"] = 0; @@ -484,7 +484,7 @@ htnotify(query, headers, mc, fmt) { ([ "_web_referrer" : query["from"] || "bookmark", "_web_page" : query["location"] || headers["referer"] || "", "_web_browser" : headers["user-agent"] || "", - "_web_on" : query["location"] || headers["referer"] || + "_web_on" : acct || query["location"] || headers["referer"] || headers["user-agent"] || "", "_web_from" : query["from"] || query_ip_name(this_interactive()) ||