00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "inspircd.h"
00018 #include "transport.h"
00019
00022 class cmd_fingerprint : public Command
00023 {
00024 public:
00025 cmd_fingerprint (InspIRCd* Instance) : Command(Instance,"FINGERPRINT", 0, 1)
00026 {
00027 this->source = "m_ssl_oper_cert.so";
00028 syntax = "<nickname>";
00029 }
00030
00031 CmdResult Handle (const std::vector<std::string> ¶meters, User *user)
00032 {
00033 User* target = ServerInstance->FindNick(parameters[0]);
00034 if (target)
00035 {
00036 ssl_cert* cert;
00037 if (target->GetExt("ssl_cert",cert))
00038 {
00039 if (cert->GetFingerprint().length())
00040 {
00041 user->WriteServ("NOTICE %s :Certificate fingerprint for %s is %s",user->nick.c_str(),target->nick.c_str(),cert->GetFingerprint().c_str());
00042 return CMD_SUCCESS;
00043 }
00044 else
00045 {
00046 user->WriteServ("NOTICE %s :Certificate fingerprint for %s does not exist!", user->nick.c_str(),target->nick.c_str());
00047 return CMD_FAILURE;
00048 }
00049 }
00050 else
00051 {
00052 user->WriteServ("NOTICE %s :Certificate fingerprint for %s does not exist!", user->nick.c_str(), target->nick.c_str());
00053 return CMD_FAILURE;
00054 }
00055 }
00056 else
00057 {
00058 user->WriteNumeric(401, "%s %s :No such nickname", user->nick.c_str(), parameters[0].c_str());
00059 return CMD_FAILURE;
00060 }
00061 }
00062 };
00063
00064
00065
00066 class ModuleOperSSLCert : public Module
00067 {
00068 ssl_cert* cert;
00069 bool HasCert;
00070 cmd_fingerprint* mycommand;
00071 ConfigReader* cf;
00072 public:
00073
00074 ModuleOperSSLCert(InspIRCd* Me)
00075 : Module(Me)
00076 {
00077 mycommand = new cmd_fingerprint(ServerInstance);
00078 ServerInstance->AddCommand(mycommand);
00079 cf = new ConfigReader(ServerInstance);
00080 Implementation eventlist[] = { I_OnPreCommand, I_OnRehash };
00081 ServerInstance->Modules->Attach(eventlist, this, 2);
00082 }
00083
00084 virtual ~ModuleOperSSLCert()
00085 {
00086 delete cf;
00087 }
00088
00089
00090 virtual void OnRehash(User* user, const std::string ¶meter)
00091 {
00092 delete cf;
00093 cf = new ConfigReader(ServerInstance);
00094 }
00095
00096 bool OneOfMatches(const char* host, const char* ip, const char* hostlist)
00097 {
00098 std::stringstream hl(hostlist);
00099 std::string xhost;
00100 while (hl >> xhost)
00101 {
00102 if (InspIRCd::Match(host, xhost) || InspIRCd::MatchCIDR(ip, xhost))
00103 {
00104 return true;
00105 }
00106 }
00107 return false;
00108 }
00109
00110 virtual int OnPreCommand(std::string &command, std::vector<std::string> ¶meters, User *user, bool validated, const std::string &original_line)
00111 {
00112 irc::string cmd = command.c_str();
00113
00114 if ((cmd == "OPER") && (validated))
00115 {
00116 char TheHost[MAXBUF];
00117 char TheIP[MAXBUF];
00118 std::string LoginName;
00119 std::string Password;
00120 std::string OperType;
00121 std::string HostName;
00122 std::string HashType;
00123 std::string FingerPrint;
00124 bool SSLOnly;
00125 char* dummy;
00126
00127 snprintf(TheHost,MAXBUF,"%s@%s",user->ident.c_str(),user->host.c_str());
00128 snprintf(TheIP, MAXBUF,"%s@%s",user->ident.c_str(),user->GetIPString());
00129
00130 HasCert = user->GetExt("ssl_cert",cert);
00131
00132 for (int i = 0; i < cf->Enumerate("oper"); i++)
00133 {
00134 LoginName = cf->ReadValue("oper", "name", i);
00135 Password = cf->ReadValue("oper", "password", i);
00136 OperType = cf->ReadValue("oper", "type", i);
00137 HostName = cf->ReadValue("oper", "host", i);
00138 HashType = cf->ReadValue("oper", "hash", i);
00139 FingerPrint = cf->ReadValue("oper", "fingerprint", i);
00140 SSLOnly = cf->ReadFlag("oper", "sslonly", i);
00141
00142 if (FingerPrint.empty() && !SSLOnly)
00143 continue;
00144
00145 if (LoginName != parameters[0])
00146 continue;
00147
00148 if (!OneOfMatches(TheHost, TheIP, HostName.c_str()))
00149 continue;
00150
00151 if (Password.length() && ServerInstance->PassCompare(user, Password.c_str(),parameters[1].c_str(), HashType.c_str()))
00152 continue;
00153
00154 if (SSLOnly && !user->GetExt("ssl", dummy))
00155 {
00156 user->WriteNumeric(491, "%s :This oper login name requires an SSL connection.", user->nick.c_str());
00157 return 1;
00158 }
00159
00160
00161
00162
00163 if ((!cert) || (cert->GetFingerprint() != FingerPrint))
00164 {
00165 user->WriteNumeric(491, "%s :This oper login name requires a matching key fingerprint.",user->nick.c_str());
00166 ServerInstance->SNO->WriteToSnoMask('o',"'%s' cannot oper, does not match fingerprint", user->nick.c_str());
00167 ServerInstance->Logs->Log("m_ssl_oper_cert",DEFAULT,"OPER: Failed oper attempt by %s!%s@%s: credentials valid, but wrong fingerprint.", user->nick.c_str(), user->ident.c_str(), user->host.c_str());
00168 return 1;
00169 }
00170 }
00171 }
00172
00173
00174 return 0;
00175 }
00176
00177 virtual Version GetVersion()
00178 {
00179 return Version("$Id: m_ssl_oper_cert.cpp 10782 2008-11-01 20:22:48Z w00t $", VF_VENDOR, API_VERSION);
00180 }
00181 };
00182
00183 MODULE_INIT(ModuleOperSSLCert)
00184