+ ConfigReader Conf;
+ prefix = Conf.ReadValue("cloak","prefix",0);
+
+ std::string modestr = Conf.ReadValue("cloak", "mode", 0);
+ if (modestr == "compat-host")
+ mode = MODE_COMPAT_HOST;
+ else if (modestr == "compat-ip")
+ mode = MODE_COMPAT_IPONLY;
+ else if (modestr == "half")
+ mode = MODE_HALF_CLOAK;
+ else if (modestr == "full")
+ mode = MODE_OPAQUE;
+ else
+ throw ModuleException("Bad value for <cloak:mode>; must be one of compat-host, compat-ip, half, full");
+
+ if (mode == MODE_COMPAT_HOST || mode == MODE_COMPAT_IPONLY)
+ {
+ bool lowercase = Conf.ReadFlag("cloak", "lowercase", 0);
+
+ /* These are *not* using the need_positive parameter of ReadInteger -
+ * that will limit the valid values to only the positive values in a
+ * signed int. Instead, accept any value that fits into an int and
+ * cast it to an unsigned int. That will, a bit oddly, give us the full
+ * spectrum of an unsigned integer. - Special
+ *
+ * We must limit the keys or else we get different results on
+ * amd64/x86 boxes. - psychon */
+ const unsigned int limit = 0x80000000;
+ compatkey[1] = (unsigned int) Conf.ReadInteger("cloak","key1",0,false);
+ compatkey[2] = (unsigned int) Conf.ReadInteger("cloak","key2",0,false);
+ compatkey[3] = (unsigned int) Conf.ReadInteger("cloak","key3",0,false);
+ compatkey[4] = (unsigned int) Conf.ReadInteger("cloak","key4",0,false);
+
+ if (!lowercase)
+ {
+ xtab[0] = "F92E45D871BCA630";
+ xtab[1] = "A1B9D80C72E653F4";
+ xtab[2] = "1ABC078934DEF562";
+ xtab[3] = "ABCDEF5678901234";
+ }
+ else
+ {
+ xtab[0] = "f92e45d871bca630";
+ xtab[1] = "a1b9d80c72e653f4";
+ xtab[2] = "1abc078934def562";
+ xtab[3] = "abcdef5678901234";
+ }
+
+ if (prefix.empty())
+ prefix = ServerInstance->Config->Network;
+
+ if (!compatkey[1] || !compatkey[2] || !compatkey[3] || !compatkey[4] ||
+ compatkey[1] >= limit || compatkey[2] >= limit || compatkey[3] >= limit || compatkey[4] >= limit)
+ {
+ std::string detail;
+ if (!compatkey[1] || compatkey[1] >= limit)
+ detail = "<cloak:key1> is not valid, it may be set to a too high/low value, or it may not exist.";
+ else if (!compatkey[2] || compatkey[2] >= limit)
+ detail = "<cloak:key2> is not valid, it may be set to a too high/low value, or it may not exist.";
+ else if (!compatkey[3] || compatkey[3] >= limit)
+ detail = "<cloak:key3> is not valid, it may be set to a too high/low value, or it may not exist.";
+ else if (!compatkey[4] || compatkey[4] >= limit)
+ detail = "<cloak:key4> is not valid, it may be set to a too high/low value, or it may not exist.";
+
+ throw ModuleException("You have not defined cloak keys for m_cloaking!!! THIS IS INSECURE AND SHOULD BE CHECKED! - " + detail);
+ }
+ }
+ else
+ {
+ key = Conf.ReadFlag("cloak", "key", 0);
+ if (key.empty() || key == "secret")
+ throw ModuleException("You have not defined cloak keys for m_cloaking. Define <cloak:key> as a network-wide secret.");
+ }