/** * Geolocate an IP address using the database * * @param $IP the ip to fetch the country for * @return the country of origin */ public static function geoip($IP) { static $IPs = array(); if (isset($IPs[$IP])) { return $IPs[$IP]; } if (is_number($IP)) { $Long = $IP; } else { $Long = Tools::ip_to_unsigned($IP); } if (!$Long || $Long == 2130706433) { // No need to check cc for 127.0.0.1 return false; } $QueryID = G::$DB->get_query_id(); G::$DB->query("\n\t\t\tSELECT EndIP, Code\n\t\t\tFROM geoip_country\n\t\t\tWHERE {$Long} >= StartIP\n\t\t\tORDER BY StartIP DESC\n\t\t\tLIMIT 1"); if (!(list($EndIP, $Country) = G::$DB->next_record()) || $EndIP < $Long) { $Country = '?'; } G::$DB->set_query_id($QueryID); $IPs[$IP] = $Country; return $Country; }
function log_attempt($UserID) { global $DB, $Cache, $AttemptID, $Attempts, $Bans, $BannedUntil; $IPStr = $_SERVER['REMOTE_ADDR']; $IPA = substr($IPStr, 0, strcspn($IPStr, '.')); $IP = Tools::ip_to_unsigned($IPStr); if ($AttemptID) { // User has attempted to log in recently $Attempts++; if ($Attempts > 5) { // Only 6 allowed login attempts, ban user's IP $BannedUntil = time_plus(60 * 60 * 6); $DB->query("\n\t\t\t\t\tUPDATE login_attempts\n\t\t\t\t\tSET\n\t\t\t\t\t\tLastAttempt = '" . sqltime() . "',\n\t\t\t\t\t\tAttempts = '" . db_string($Attempts) . "',\n\t\t\t\t\t\tBannedUntil = '" . db_string($BannedUntil) . "',\n\t\t\t\t\t\tBans = Bans + 1\n\t\t\t\t\tWHERE ID = '" . db_string($AttemptID) . "'"); if ($Bans > 9) { // Automated bruteforce prevention $DB->query("\n\t\t\t\t\t\tSELECT Reason\n\t\t\t\t\t\tFROM ip_bans\n\t\t\t\t\t\tWHERE {$IP} BETWEEN FromIP AND ToIP"); if ($DB->has_results()) { //Ban exists already, only add new entry if not for same reason list($Reason) = $DB->next_record(MYSQLI_BOTH, false); if ($Reason != 'Automated ban per >60 failed login attempts') { $DB->query("\n\t\t\t\t\t\t\t\tUPDATE ip_bans\n\t\t\t\t\t\t\t\tSET Reason = CONCAT('Automated ban per >60 failed login attempts AND ', Reason)\n\t\t\t\t\t\t\t\tWHERE FromIP = {$IP}\n\t\t\t\t\t\t\t\t\tAND ToIP = {$IP}"); } } else { //No ban $DB->query("\n\t\t\t\t\t\t\tINSERT IGNORE INTO ip_bans\n\t\t\t\t\t\t\t\t(FromIP, ToIP, Reason)\n\t\t\t\t\t\t\tVALUES\n\t\t\t\t\t\t\t\t('{$IP}','{$IP}', 'Automated ban per >60 failed login attempts')"); $Cache->delete_value("ip_bans_{$IPA}"); } } } else { // User has attempted fewer than 6 logins $DB->query("\n\t\t\t\t\tUPDATE login_attempts\n\t\t\t\t\tSET\n\t\t\t\t\t\tLastAttempt = '" . sqltime() . "',\n\t\t\t\t\t\tAttempts = '" . db_string($Attempts) . "',\n\t\t\t\t\t\tBannedUntil = '0000-00-00 00:00:00'\n\t\t\t\t\tWHERE ID = '" . db_string($AttemptID) . "'"); } } else { // User has not attempted to log in recently $Attempts = 1; $DB->query("\n\t\t\t\tINSERT INTO login_attempts\n\t\t\t\t\t(UserID, IP, LastAttempt, Attempts)\n\t\t\t\tVALUES\n\t\t\t\t\t('" . db_string($UserID) . "', '" . db_string($IPStr) . "', '" . sqltime() . "', 1)"); } }
$NewInvites = $Invites - DONOR_INVITES; } else { $NewInvites = 0; $Message .= ' They had already used at least one of their donation gained invites.'; } $DB->query("\n\t\t\t\t\tUPDATE users_main\n\t\t\t\t\tSET Invites = {$NewInvites}\n\t\t\t\t\tWHERE ID = '" . $_POST['custom'] . "'"); $DB->query(' UPDATE users_info SET Donor = \'0\' WHERE UserID = \'' . $_POST['custom'] . '\''); $Cache->begin_transaction('user_info_' . $_POST['custom']); $Cache->update_row(false, array('Donor' => 0)); $Cache->commit_transaction(0); $Cache->begin_transaction('user_info_heavy_' . $_POST['custom']); $Cache->update_row(false, array('Invites' => $Invites)); $Cache->commit_transaction(0); Misc::send_pm($_POST['custom'], 0, 'Notice of donation failure', 'PapPal has just notified us that the donation you sent from ' . $_POST['payer_email'] . ' of ' . $TotalDonated . ' ' . PAYPAL_CURRENCY . ' at ' . $DonationTime . ' UTC has been revoked. Because of this your special privileges have been revoked, and your invites removed.'); send_irc("PRIVMSG " . BOT_REPORT_CHAN . " :{$Message}"); } } } $DB->query("\n\t\tUPDATE users_info\n\t\tSET AdminComment = CONCAT('" . sqltime() . " - User donated " . db_string($_POST['mc_gross']) . " " . db_string(PAYPAL_CURRENCY) . " from " . db_string($_POST['payer_email']) . ".\n',AdminComment)\n\t\tWHERE UserID = '" . $_POST['custom'] . "'"); $DB->query("\n\t\tINSERT INTO donations\n\t\t\t(UserID, Amount, Email, Time)\n\t\tVALUES\n\t\t\t('" . $_POST['custom'] . "', '" . db_string($_POST['mc_gross']) . "', '" . db_string($_POST['payer_email']) . "', '" . sqltime() . "')"); } else { $DB->query("\n\t\tINSERT INTO ip_bans\n\t\t\t(FromIP, ToIP, Reason)\n\t\tVALUES\n\t\t\t('" . Tools::ip_to_unsigned($_SERVER['REMOTE_ADDR']) . "', '" . ip2long($_SERVER['REMOTE_ADDR']) . "', 'Attempted to exploit donation system.')"); } fclose($Socket); if (check_perms('site_debug')) { include SERVER_ROOT . '/sections/donate/donate.php'; } $Cache->cache_value('debug_donate', array($Result, $_POST), 0);
$UsersDonor = explode('|', $UsersDonor); $UsersWarned = explode('|', $UsersWarned); } ?> <tr class="rowa"> <td> <?php echo $IP; ?> (<?php echo Tools::get_country_code_by_ajax($IP); ?> )<?php if ($CanManageIPBans) { if (!isset($IPs[$IP])) { $sql = "\n\t\t\t\tSELECT ID, FromIP, ToIP\n\t\t\t\tFROM ip_bans\n\t\t\t\tWHERE '" . Tools::ip_to_unsigned($IP) . "' BETWEEN FromIP AND ToIP\n\t\t\t\tLIMIT 1"; $DB->query($sql); if ($DB->has_results()) { $IPs[$IP] = true; ?> <strong>[Banned]</strong> <?php } else { $IPs[$IP] = false; ?> <a id="<?php echo $counter; ?> " href="#" onclick="Ban('<?php echo $IP; ?>
$DB->query("\n\t\t\t\tINSERT INTO ip_bans\n\t\t\t\t\t(FromIP, ToIP, Reason)\n\t\t\t\tVALUES\n\t\t\t\t\t('{$Start}','{$End}', '{$Notes}')"); } $Cache->delete_value('ip_bans_' . $IPA); } } define('BANS_PER_PAGE', '20'); list($Page, $Limit) = Format::page_limit(BANS_PER_PAGE); $sql = "\n\tSELECT\n\t\tSQL_CALC_FOUND_ROWS\n\t\tID,\n\t\tFromIP,\n\t\tToIP,\n\t\tReason\n\tFROM ip_bans "; if (!empty($_REQUEST['notes'])) { $sql .= "WHERE Reason LIKE '%" . db_string($_REQUEST['notes']) . "%' "; } if (!empty($_REQUEST['ip']) && preg_match('/' . IP_REGEX . '/', $_REQUEST['ip'])) { if (!empty($_REQUEST['notes'])) { $sql .= "AND '" . Tools::ip_to_unsigned($_REQUEST['ip']) . "' BETWEEN FromIP AND ToIP "; } else { $sql .= "WHERE '" . Tools::ip_to_unsigned($_REQUEST['ip']) . "' BETWEEN FromIP AND ToIP "; } } $sql .= "ORDER BY FromIP ASC"; $sql .= " LIMIT " . $Limit; $Bans = $DB->query($sql); $DB->query('SELECT FOUND_ROWS()'); list($Results) = $DB->next_record(); $PageLinks = Format::get_pages($Page, $Results, BANS_PER_PAGE, 11); View::show_header('IP Address Bans'); $DB->set_query_id($Bans); ?> <div class="header"> <h2>IP Address Bans</h2> </div>
<?php if (!check_perms('admin_manage_ipbans')) { error(403); } if (isset($_GET['perform'])) { $IPA = substr($_GET['ip'], 0, strcspn($_GET['ip'], '.')); if ($_GET['perform'] == 'delete') { if (!is_number($_GET['id']) || $_GET['id'] == '') { error(0); } $DB->query('DELETE FROM ip_bans WHERE ID=' . $_GET['id']); $Bans = $Cache->delete_value('ip_bans_' . $IPA); } elseif ($_GET['perform'] == 'create') { $Notes = db_string($_GET['notes']); $IP = Tools::ip_to_unsigned($_GET['ip']); //Sanitized by Validation regex $DB->query("\n\t\t\tINSERT INTO ip_bans (FromIP, ToIP, Reason)\n\t\t\tVALUES ('{$IP}','{$IP}', '{$Notes}')"); $Cache->delete_value('ip_bans_' . $IPA); } }