/* This source code is protected under the GNU General Public License (GPL), found at http://www.gnu.org/licenses/gpl.html */ #include #include #include "s-pluginapi.h" #define RL 32 // This plugin will hold 32 records of <{REGHASH} "IP Address"> static uint32 pwr(uint16 base, uint8 exp); typedef struct { uint32 Seed; uint32 ipMin; uint32 ipMax; } HostMgr, *HostMgrPtr; static uint8 RegHash[] = { 4, //A 5, //B 6, //C 7, //D 0, //E 1, //F 2, //G 3, //H 12, //I 0, //J 0, //K 0, //L 8, //M 9, //N 10, //O 11 //P }; static uint8 VldChrs[] = { '{', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'M', 'N', 'O', 'P', '}', ' ', '\t', '\"', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '*', '.', 0 }; static char *config; static uint8 nbrRecs; static HostMgr Recs[RL]; AnyType initializeServerPlugin(PluginID pluginID, int argc, char *argv[]) { setPluginUserInfoSize(pluginID, sizeof(char)); if (argc > 1) { config = argv[1]; } FormattedLogMessage(NULL, "HostManager©", "v1.0 (Limit: %d) (2004-2005) by Paul Taylor (Janus) ", RL); scheduleTimerEvent(pluginID, 0, 0); return (AnyType) pluginID; } void noteUserCreation(ServerState *state, AnyType pluginDat, ServerUserRec *user) { *((char *)getPluginUserInfo((PluginID) pluginDat, user)) = 0; } /* If you ask why I didn't code the user verification system into the ClientMsg function, here's why. Verifying this way allows all other plugin security, including the server itself to verify a user's information that has been sent is valid. Other issues I got into just grew tiresome and boring. There's nothing wrong with the way I did this here *wink* // Janus */ void noteUserRoomEntry(ServerState *state, AnyType pluginDat, ServerUserRec *user, ServerRoomRec *room) { char *Checked = (char *)getPluginUserInfo((PluginID) pluginDat, user); if (!(*Checked) && user->loggedOn) { (*Checked)++; uint16 i; uint32 ipAdr = htonl(user->feIPAddr); /* Show me da SEED! // Janus */ uint32 Seed = user->crc ^ user->counter ^ 0x9602C9BFL; for (i = 0; i < nbrRecs; i++) { if (Seed == Recs[i].Seed && ipAdr >= Recs[i].ipMin && ipAdr <= Recs[i].ipMax) { /* Sets wiz/god (op/admin) flags to 3, OR forces these bits to TRUE // Janus */ user->flags |= 3; /* Since the client doesn't always use null bytes at the end of a username, also considering strings are considered terminated by a null character, we force the user's name to end with a null byte (if it's length is less than 31)! // Janus */ Checked = user->user.name; if (*Checked < 31) { user->user.name[*Checked + 1] = 0; } /* Lets leave a special note that indeed, an Admin was here. // Janus */ FormattedLogMessage(user, "HostManager©", "(Reigstered Host Admin)"); sendMsgUserStatus(toUser(user), user, user->flags, ""); /* Alert the staff that it's just a friend, not an intruder. // Janus */ PerformPage(user, "Attention on the deck! A Host Admin has come aboard!"); UserMessage(user, "Welcome Host Admin %0.31s!", ++Checked); break; } } } } void handleTimerEvent(ServerState *state, AnyType pluginDat, AnyType timerDat) { uint8 iBfr[64]; uint8 e, m, i, j, k; char *lBfr, *Ptr; nbrRecs = 0; FILE *STDIN = fopen(config, "r"); /* Required, incase permissions are wrong, trying to read from a file that's permissioned off would crash our server! // Janus */ if (STDIN != NULL) { ReadErr: while (!feof(STDIN) && nbrRecs < RL) { m = 0; lBfr = iBfr; fgets(iBfr, 63, STDIN); Recs[nbrRecs].Seed = 0; Recs[nbrRecs].ipMin = 0; Recs[nbrRecs].ipMax = 0; while (*lBfr) { if (*lBfr == '#') { goto ReadErr; } e = 0; for (i = 0; i < strlen(VldChrs); i++) { if (*lBfr == VldChrs[i]) { e = 1; break; } } if (e == 0) { goto ReadErr; } switch (m) { case 0: /* This section resets the previous input record entry for the SEED. // Janus */ if (*lBfr == '{') { m++; j = 0; } break; case 1: /* This section builds the Reg SEED from the Hash in the bless file. // Janus */ if (*lBfr == '}') { m++; break; } if (*lBfr >= 'A' && *lBfr <= 'P' && j < 9) { Recs[nbrRecs].Seed += (RegHash[*lBfr - 'A'] * pwr(13, j++)); // 'A' = 65 // Janus } else { goto ReadErr; } break; case 2: /* This section resets the previous input record entry for the ipMin/ipMax. // Janus */ if (*lBfr == '\"') { m++; j = 4; Ptr = lBfr + 1; } break; case 3: /* This section builds the ipMin/ipMax ranges [(#/*).(#/*).(#/*).(#/*)]. // Janus */ if (!j) { goto ReadErr; } if (*lBfr == '.' || *lBfr == '\"') { /* This part may not be neccessary since atoi() only converts integers. // Janus */ if (*lBfr == '.') { *lBfr = 0; } if (*Ptr == '*') { if (Ptr == (lBfr - 1)) { /* Since this is a range, only increase the upper value. // Janus */ Recs[nbrRecs].ipMax += (255 * pwr(256, --j)); } else { /* Somebody didn't use the range (*) character properly. // Janus */ goto ReadErr; } } else { /* Since this is a range, this builds up both the upper/lower values. // Janus */ k = atoi(Ptr); Recs[nbrRecs].ipMin += (k * pwr(256, --j)); Recs[nbrRecs].ipMax += (k * pwr(256, j)); } Ptr = lBfr + 1; } if (*lBfr == '\"') { /* All security/format checks passed, we're clear to try another round/line of the file! // Janus */ ++nbrRecs; goto ReadErr; } break; } ++lBfr; } } fclose(STDIN); } /* Reloads the hostmgr.bless file every 2.5 minutes (150 seconds) = 1 Swatch Time Beat (Swiss Time) // Janus */ scheduleTimerEvent((PluginID) pluginDat, 0, 150); } /* I know has a pow() function, but our server didn't like using pow(), so, I rigged up my own! // Janus */ static uint32 pwr(uint16 base, uint8 exp) { uint32 i = 1; while (exp--) { i *= base; } return i; } /* I would like to thank OpenText for not butting into palace development projects in the works, even if Phalanx does suck. I would like to thank my crew, past and present from MPP/PEG, Aephix, Aephix Core, Gemini Project, and now ThePalaceHost! Specifically Darryl, Richard, Patrick, and Scott. You guys are the best and you've always been there in spirit. I didn't make the initial plugin SDK so I'm not going to open source that, but if you can find a copy, I wish you the best of luck, might have to switch the linker as I did from ELF (Solaris/Linux) to OSF (Unix). Aight! PEACE! // Janus PS To Joe (owner of PalaceBox), unlike you, I enjoy sharing knowledge. */