virtual void OnDecodeMetaData(int target_type, void* target, const std::string &extname, const std::string &extdata) { // check if its our metadata key, and its associated with a user if ((target_type == TYPE_USER) && (extname == "ssl")) { User* dest = static_cast<User*>(target); // if they dont already have an ssl flag, accept the remote server's if (!dest->GetExt(extname)) { dest->Extend(extname); } } else if ((target_type == TYPE_USER) && (extname == "ssl_cert")) { User* dest = static_cast<User*>(target); if (dest->GetExt(extname)) return; ssl_cert* cert = new ssl_cert; dest->Extend(extname, cert); std::stringstream s(extdata); std::string v; getline(s,v,' '); cert->invalid = (v.find('v') != std::string::npos); cert->trusted = (v.find('T') != std::string::npos); cert->revoked = (v.find('R') != std::string::npos); cert->unknownsigner = (v.find('s') != std::string::npos); if (v.find('E') != std::string::npos) { getline(s,cert->error,'\n'); } else { getline(s,cert->fingerprint,' '); getline(s,cert->dn,' '); getline(s,cert->issuer,'\n'); } } }
/* SQL Request */ virtual const char* OnRequest(Request* request) { if(strcmp(SQLRESID, request->GetId()) == 0) { SQLresult* res = static_cast<SQLresult*>(request); User* user = GetAssocUser(this, SQLutils, res->id).S().user; UnAssociate(this, SQLutils, res->id).S(); if(user) { if(res->error.Id() == SQL_NO_ERROR) { std::string* wnick; bool result; if(res->Rows()) { int rowcount=res->Rows(),i; /* Clean Custom User Metadata */ user->Shrink("sqlAllowedIdent"); user->Shrink("sqlAllowedHost"); user->Shrink("sqlvHost"); user->Shrink("sqlTitle"); user->Shrink("sqlumodes"); std::string sqlvHost; std::string sqlTitle; std::string sqlumodes; std::string sqlAllowedIdent; std::string sqlAllowedHost; /* Get Data from SQL (using freeform query. "query" in modules.conf) */ for (i=0; i<rowcount; ++i) { SQLfieldList& currow = res->GetRow(); sqlAllowedIdent = currow[1].d.c_str(); sqlAllowedHost = currow[2].d.c_str(); sqlvHost = currow[3].d.c_str(); sqlTitle = currow[4].d.c_str(); sqlumodes = currow[5].d.c_str(); } std::string* pAllowedIdent = new std::string(sqlAllowedIdent); std::string* pAllowedHost = new std::string(sqlAllowedHost); std::string* pvHost = new std::string(sqlvHost); std::string* pTitle = new std::string(sqlTitle); std::string* pumodes = new std::string(sqlumodes); user->Extend("sqlAllowedIdent",pAllowedIdent); user->Extend("sqlAllowedHost",pAllowedHost); user->Extend("sqlvHost",pvHost); user->Extend("sqlTitle",pTitle); user->Extend("sqlumodes",pumodes); /* Check Allowed Ident@Hostname from SQL */ if (sqlAllowedIdent != "" && sqlAllowedHost != "") { char TheHost[MAXBUF]; char TheIP[MAXBUF]; char TheAllowedUHost[MAXBUF]; snprintf(TheHost,MAXBUF,"%s@%s",user->ident.c_str(), user->host.c_str()); snprintf(TheIP, MAXBUF,"%s@%s",user->ident.c_str(), user->GetIPString()); snprintf(TheAllowedUHost, MAXBUF, "%s@%s", sqlAllowedIdent.c_str(), sqlAllowedHost.c_str()); if (!OneOfMatches(TheHost,TheIP,TheAllowedUHost)) { if (killreasonUHost == "") { killreasonUHost = "Your ident or hostmask did not match the one registered to this nickname. Allowed: $allowedident@$allowedhost"; } std::string tmpKillReason = killreasonUHost; SearchAndReplace(tmpKillReason, "$allowedident", sqlAllowedIdent.c_str()); SearchAndReplace(tmpKillReason, "$allowedhost", sqlAllowedHost.c_str()); /* Run Failure SQL Insert Query (For Logging) */ std::string repfquery = failurequery; if (repfquery != "") { if (user->GetExt("wantsnick", wnick)) { SearchAndReplace(repfquery, "$nick", *wnick); } else { SearchAndReplace(repfquery, "$nick", user->nick); } SearchAndReplace(repfquery, "$host", user->host); SearchAndReplace(repfquery, "$ip", user->GetIPString()); SearchAndReplace(repfquery, "$reason", tmpKillReason.c_str()); SQLrequest req = SQLrequest(this, SQLprovider, databaseid, SQLquery(repfquery)); result = req.Send(); } ServerInstance->Users->QuitUser(user, tmpKillReason); user->Extend("sqlauth_failed"); return NULL; } } /* We got a result, auth user */ user->Extend("sqlauthed"); /* possible ghosting? */ if (user->GetExt("wantsnick", wnick)) { /* no need to check ghosting, this is done in OnPreCommand * and if ghosting is off, user wont have the Extend */ User* InUse = ServerInstance->FindNickOnly(wnick->c_str()); if (InUse) { /* change his nick to UUID so we can take it */ //InUse->ForceNickChange(InUse->uuid.c_str()); /* put user on cull list */ ServerInstance->Users->QuitUser(InUse, "Ghosted by connecting user with same nick."); } /* steal the nick ;) */ user->ForceNickChange(wnick->c_str()); user->Shrink("wantsnick"); } /* Set Account Name (for m_services_account +R/+M channels) */ if (setaccount) { std::string* pAccount = new std::string(user->nick.c_str()); user->Extend("accountname",pAccount); } /* Run Success SQL Update Query */ std::string repsquery = successquery; if (successquery != "") { SearchAndReplace(repsquery, "$nick", user->nick); SearchAndReplace(repsquery, "$host", user->host); SearchAndReplace(repsquery, "$ip", user->GetIPString()); SQLrequest req = SQLrequest(this, SQLprovider, databaseid, SQLquery(repsquery)); result = req.Send(); } /* Returned No Rows */ } else { if (verbose) { /* No rows in result, this means there was no record matching the user */ ServerInstance->SNO->WriteToSnoMask('A', "Forbidden connection from %s!%s@%s (SQL query returned no matches)", user->nick.c_str(), user->ident.c_str(), user->host.c_str()); } /* Run Failure SQL Insert Query (For Logging) */ std::string repfquery = failurequery; if (repfquery != "") { if (user->GetExt("wantsnick", wnick)) { SearchAndReplace(repfquery, "$nick", *wnick); } else { SearchAndReplace(repfquery, "$nick", user->nick); } SearchAndReplace(repfquery, "$host", user->host); SearchAndReplace(repfquery, "$ip", user->GetIPString()); SearchAndReplace(repfquery, "$reason", killreason.c_str()); SQLrequest req = SQLrequest(this, SQLprovider, databaseid, SQLquery(repfquery)); result = req.Send(); } /* Kill user that entered invalid credentials */ ServerInstance->Users->QuitUser(user, killreason); user->Extend("sqlauth_failed"); } /* SQL Failure */ } else { if (verbose) { ServerInstance->SNO->WriteToSnoMask('A', "Forbidden connection from %s!%s@%s (SQL query failed: %s)", user->nick.c_str(), user->ident.c_str(), user->host.c_str(), res->error.Str()); } user->Extend("sqlauth_failed"); } } else { return NULL; } if (!user->GetExt("sqlauthed")) { ServerInstance->Users->QuitUser(user, killreason); } return SQLSUCCESS; } return NULL; }