anope- supernets anope source code & configuration |
git clone git://git.acid.vegas/anope.git |
Log | Files | Refs | Archive | README |
index.cpp (3652B)
1 /* 2 * (C) 2003-2022 Anope Team 3 * Contact us at team@anope.org 4 * 5 * Please read COPYING and README for further details. 6 */ 7 8 #include "../webcpanel.h" 9 10 class WebpanelRequest : public IdentifyRequest 11 { 12 HTTPReply reply; 13 HTTPMessage message; 14 Reference<HTTPProvider> server; 15 Anope::string page_name; 16 Reference<HTTPClient> client; 17 TemplateFileServer::Replacements replacements; 18 19 public: 20 WebpanelRequest(Module *o, HTTPReply &r, HTTPMessage &m, HTTPProvider *s, const Anope::string &p_n, HTTPClient *c, TemplateFileServer::Replacements &re, const Anope::string &user, const Anope::string &pass) : IdentifyRequest(o, user, pass), reply(r), message(m), server(s), page_name(p_n), client(c), replacements(re) { } 21 22 void OnSuccess() anope_override 23 { 24 if (!client || !server) 25 return; 26 NickAlias *na = NickAlias::Find(this->GetAccount()); 27 if (!na) 28 { 29 this->OnFail(); 30 return; 31 } 32 33 if (na->nc->HasExt("NS_SUSPENDED")) 34 { 35 this->OnFail(); 36 return; 37 } 38 39 // Rate limit logins to 1/sec 40 time_t *last_login = na->nc->GetExt<time_t>("webcpanel_last_login"); 41 if (last_login != NULL && Anope::CurTime == *last_login) 42 { 43 this->OnFail(); 44 return; 45 } 46 47 Anope::string id; 48 for (int i = 0; i < 64; ++i) 49 { 50 char c; 51 do 52 c = 48 + (rand() % 75); 53 while (!isalnum(c)); 54 id += c; 55 } 56 57 na->Extend<Anope::string>("webcpanel_id", id); 58 na->Extend<Anope::string>("webcpanel_ip", client->GetIP()); 59 na->nc->Extend<time_t>("webcpanel_last_login", Anope::CurTime); 60 61 { 62 HTTPReply::cookie c; 63 c.push_back(std::make_pair("account", na->nick)); 64 c.push_back(std::make_pair("Path", "/")); 65 reply.cookies.push_back(c); 66 } 67 68 { 69 HTTPReply::cookie c; 70 c.push_back(std::make_pair("id", id)); 71 c.push_back(std::make_pair("Path", "/")); 72 reply.cookies.push_back(c); 73 } 74 75 reply.error = HTTP_FOUND; 76 reply.headers["Location"] = Anope::string("http") + (server->IsSSL() ? "s" : "") + "://" + message.headers["Host"] + "/nickserv/info"; 77 78 client->SendReply(&reply); 79 } 80 81 void OnFail() anope_override 82 { 83 if (!client || !server) 84 return; 85 replacements["INVALID_LOGIN"] = "Invalid username or password"; 86 TemplateFileServer page("login.html"); 87 page.Serve(server, page_name, client, message, reply, replacements); 88 89 client->SendReply(&reply); 90 } 91 }; 92 93 bool WebCPanel::Index::OnRequest(HTTPProvider *server, const Anope::string &page_name, HTTPClient *client, HTTPMessage &message, HTTPReply &reply) 94 { 95 TemplateFileServer::Replacements replacements; 96 const Anope::string &user = message.post_data["username"], &pass = message.post_data["password"]; 97 98 replacements["TITLE"] = page_title; 99 100 if (!user.empty() && !pass.empty()) 101 { 102 // Rate limit check. 103 Anope::string ip = client->clientaddr.addr(); 104 105 Anope::hash_map<time_t>::iterator it = last_login_attempt.find(ip); 106 if (it != last_login_attempt.end()) 107 { 108 time_t last_time = it->second; 109 110 if (last_time == Anope::CurTime) 111 { 112 replacements["INVALID_LOGIN"] = "Rate limited"; 113 TemplateFileServer page("login.html"); 114 page.Serve(server, page_name, client, message, reply, replacements); 115 return true; 116 } 117 } 118 119 // don't let ip hash grow too long 120 if (Anope::CurTime > last_clear + FLUSH_TIME) 121 { 122 last_login_attempt.clear(); 123 last_clear = Anope::CurTime; 124 } 125 126 last_login_attempt[ip] = Anope::CurTime; 127 128 WebpanelRequest *req = new WebpanelRequest(me, reply, message, server, page_name, client, replacements, user, pass); 129 FOREACH_MOD(OnCheckAuthentication, (NULL, req)); 130 req->Dispatch(); 131 return false; 132 } 133 134 TemplateFileServer page("login.html"); 135 page.Serve(server, page_name, client, message, reply, replacements); 136 return true; 137 }