From b0b3d375a3ff14b14bb1bc459fcbcc027126c0a8 Mon Sep 17 00:00:00 2001 From: "psyc://loupsycedyglgamf.onion/~lynX" Date: Tue, 11 Jul 2017 18:31:40 +0200 Subject: [PATCH 1/3] per-room web challenges and an ancient bug fixed --- CHANGESTODO | 2 ++ world/net/http/server.c | 5 +++-- world/net/include/place.gen | 29 +++++++++++++++++++++++++++++ 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/CHANGESTODO b/CHANGESTODO index 18aadbc..4176212 100644 --- a/CHANGESTODO +++ b/CHANGESTODO @@ -14,6 +14,8 @@ vim:nosmarttab:syntax=diff ________________________________________________________________________ == NUISANCES worth fixing, possibly ==================================== ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ +- how is it that /join #foo.bar tries to connect a host called foo.bar? + - offline messages not being output (which *can* work even with OTR!) <<< did i fix that recently? diff --git a/world/net/http/server.c b/world/net/http/server.c index 8e8ca3a..ab206a2 100644 --- a/world/net/http/server.c +++ b/world/net/http/server.c @@ -168,8 +168,7 @@ process() { P4(("found cookie: %O\n", t)) if (t && sscanf(t, "psyced=\"%s\"", t)) { P3(("got cookie: %O\n", t)) - query = url_parse_query(query, t); - P4(("parsed cookie: %O\n", query)) + qs = qs ? t+"&"+qs : t; } #ifdef GENERIC_COOKIES // we might need them someday..? // if within the same domain other cookies are being used, like @@ -197,6 +196,8 @@ process() { query = url_parse_query(query, body); } P4(("parsed query: %O\n", query)) + // remember original form of item in headers mapping + headers["item"] = item; switch (item) { case "/favicon.ico": #if 0 diff --git a/world/net/include/place.gen b/world/net/include/place.gen index c8fe462..6376a81 100644 --- a/world/net/include/place.gen +++ b/world/net/include/place.gen @@ -610,6 +610,35 @@ htget(prot, query, headers, qs) { } #endif +#ifdef CHALLENGE_MATCH +#include + +htget(prot, query, headers, qs, data, noprocess) { + if (query["challenge"] == "complete") + return ::htget(prot, query, headers, qs, data, noprocess); + string item = headers[item] || "/@"+ MYNICK; + if (query["challenge"] == "given" && +# if __EFUN_DEFINED__(regmatch) + stringp(query["answer"]) && + regmatch(lower_case(query["answer"]), CHALLENGE_MATCH, RE_MATCH_SUBS) +# else + query["answer"] == CHALLENGE_MATCH +# endif + ) { + htredirect(prot, item, "Reload, please", 0, "Set-Cookie: psyced=\"challenge=complete\"; path="+ item +";\n"); + return 1; + } + sTextPath(query["layout"], query["lang"], "html"); + // could add a timeout here... + htok3(prot, 0, "Set-Cookie: psyced=\"challenge=given\"; path="+ item +";\n"); + w("_PAGES_group_challenge", 0, + ([ "_challenge" : htquote(CHALLENGE_QUESTION), + "_nick_place" : MYNICK ]) ); + printf("%O (%O) in %O\n", query, qs, headers); + return 1; +} +#endif + #ifdef HISTORY # if defined(HISTORY_METHOD) || defined(HISTORY_MAY_LOG) mayLog(mc) { From 79d7ed3549dca2a56c9b50e9bf6cef40b5fca52d Mon Sep 17 00:00:00 2001 From: "psyc://loupsycedyglgamf.onion/~lynX" Date: Wed, 12 Jul 2017 17:34:26 +0200 Subject: [PATCH 2/3] non trivially hackable challenge ;) --- world/default/en/html.textdb | 16 ++++++++++++++++ world/net/include/place.gen | 29 ++++++++++++++++++----------- 2 files changed, 34 insertions(+), 11 deletions(-) diff --git a/world/default/en/html.textdb b/world/default/en/html.textdb index 15519f1..11d9dc1 100644 --- a/world/default/en/html.textdb +++ b/world/default/en/html.textdb @@ -1005,6 +1005,22 @@ _PAGES_error | |{_HTML_tail} +_PAGES_group_challenge +|challenge for [_nick_place]@{_VAR_host} +| +|{_HTML_head} +|
+|

[_challenge]

+| +|## action="/@[_nick_place]" doesn't make it better +|
+| +| +|
+| +|
+|{_HTML_tail} + _PAGES_group_scratchpad |scratchpad for [_nick_place]@{_VAR_host} | diff --git a/world/net/include/place.gen b/world/net/include/place.gen index 6376a81..0331277 100644 --- a/world/net/include/place.gen +++ b/world/net/include/place.gen @@ -614,25 +614,32 @@ htget(prot, query, headers, qs) { #include htget(prot, query, headers, qs, data, noprocess) { - if (query["challenge"] == "complete") + // could use a hash of the password instead + if (stringp(headers["cookie"]) && regmatch(headers["cookie"], + "challenge=complete&answer=" CHALLENGE_MATCH)) return ::htget(prot, query, headers, qs, data, noprocess); string item = headers[item] || "/@"+ MYNICK; - if (query["challenge"] == "given" && -# if __EFUN_DEFINED__(regmatch) - stringp(query["answer"]) && - regmatch(lower_case(query["answer"]), CHALLENGE_MATCH, RE_MATCH_SUBS) -# else - query["answer"] == CHALLENGE_MATCH -# endif - ) { - htredirect(prot, item, "Reload, please", 0, "Set-Cookie: psyced=\"challenge=complete\"; path="+ item +";\n"); + if (stringp(query["answer"]) && + regmatch(headers["cookie"], "challenge=given") && + regmatch(lower_case(query["answer"]), CHALLENGE_MATCH, + RE_MATCH_SUBS)) { + // lazy me could have used referer here ;) + string nu = stringp(query["parameters"]) && + strlen(query["parameters"]) ? + item +"?"+ query["parameters"] : item; + htredirect(prot, nu, "Reload, please", 0, "Set-Cookie: psycplace=\"challenge=complete&answer=" CHALLENGE_MATCH "\"; path="+ item +";\n"); return 1; } 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: psyced=\"challenge=given\"; path="+ item +";\n"); + htok3(prot, 0, "Set-Cookie: psycplace=\"challenge=given\"; path="+ item +";\n"); 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, "_nick_place" : MYNICK ]) ); printf("%O (%O) in %O\n", query, qs, headers); return 1; From 9e02ba080c009d1fe326f1844b3fdbc37ce3b4d4 Mon Sep 17 00:00:00 2001 From: "psyc://loupsycedyglgamf.onion/~lynX" Date: Wed, 12 Jul 2017 20:15:30 +0200 Subject: [PATCH 3/3] htchallenge: md5 can handle any regmatch --- world/net/include/place.gen | 17 ++++++++++------- world/net/place/archetype.gen | 1 + 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/world/net/include/place.gen b/world/net/include/place.gen index 0331277..db72af8 100644 --- a/world/net/include/place.gen +++ b/world/net/include/place.gen @@ -613,21 +613,24 @@ htget(prot, query, headers, qs) { #ifdef CHALLENGE_MATCH #include +// maybe this all belongs into archetype.gen.. chesmo! htget(prot, query, headers, qs, data, noprocess) { - // could use a hash of the password instead if (stringp(headers["cookie"]) && regmatch(headers["cookie"], - "challenge=complete&answer=" CHALLENGE_MATCH)) + "challenge=complete&answer="+ md5(CHALLENGE_MATCH))) +# ifdef HTGET + return HTGET; +# else return ::htget(prot, query, headers, qs, data, noprocess); +# endif string item = headers[item] || "/@"+ MYNICK; - if (stringp(query["answer"]) && + if (stringp(query["answer"]) && headers["cookie"] && regmatch(headers["cookie"], "challenge=given") && - regmatch(lower_case(query["answer"]), CHALLENGE_MATCH, - RE_MATCH_SUBS)) { + 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; - htredirect(prot, nu, "Reload, please", 0, "Set-Cookie: psycplace=\"challenge=complete&answer=" CHALLENGE_MATCH "\"; path="+ item +";\n"); + htredirect(prot, nu, "Reload, please", 0, "Set-Cookie: psycplace=\"challenge=complete&answer="+ md5(CHALLENGE_MATCH) +"\"; path="+ item +";\n"); return 1; } sTextPath(query["layout"], query["lang"], "html"); @@ -641,7 +644,7 @@ htget(prot, query, headers, qs, data, noprocess) { // we maintain the original qs for next attempt: "_parameters" : query["parameters"] || qs, "_nick_place" : MYNICK ]) ); - printf("%O (%O) in %O\n", query, qs, headers); + // printf("%O vs %O\n", query, headers); return 1; } #endif diff --git a/world/net/place/archetype.gen b/world/net/place/archetype.gen index 1471b61..6991f04 100644 --- a/world/net/place/archetype.gen +++ b/world/net/place/archetype.gen @@ -670,6 +670,7 @@ htget(prot, query, headers, qs, data, noprocess) { write("\n\nYou are looking at the "+MYNICK+" default page.\n"); # endif # endif + //printf("%O: %O (%O) in %O\n", this_interactive(), query, qs, headers); return 1; } #endif