Skip to content

Commit

Permalink
add user cache to keep track of each user's last 10 (at most) known u…
Browse files Browse the repository at this point in the history
…sernames

add command /whitelist list
add command /blacklist list
optimize command output /bungeesafeguard dump
avoid triggering a bug of BungeeCord where the LoginEvent cannot be cancelled properly with null cancel reason
  • Loading branch information
Luluno01 committed Apr 11, 2021
1 parent 44ac792 commit 36d8b27
Show file tree
Hide file tree
Showing 16 changed files with 484 additions and 92 deletions.
9 changes: 9 additions & 0 deletions .idea/BungeeGuard.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 7 additions & 7 deletions .idea/artifacts/BungeeSafeguard_main_jar.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

60 changes: 57 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ A blacklist and whitelist BungeeCord plugin with support of UUID look up.

This plugin was formerly named BungeeGuard. In order not to conflict with the existing plugin BungeeGuard, this plugin is renamed to BungeeSafeguard from v2.0.

Tested on Waterfall, version: `git:Waterfall-Bootstrap:1.16-R0.4-SNAPSHOT:1d2221d:384`.
Tested on Waterfall, version: `git:Waterfall-Bootstrap:1.16-R0.5-SNAPSHOT:454f9d4:404`.

- [BungeeSafeguard](#bungeesafeguard)
- [Features](#features)
Expand All @@ -24,6 +24,7 @@ Tested on Waterfall, version: `git:Waterfall-Bootstrap:1.16-R0.4-SNAPSHOT:1d2221
- [whitelist on](#whitelist-on)
- [whitelist off](#whitelist-off)
- [whitelist confirm](#whitelist-confirm)
- [whitelist list](#whitelist-list)
- [Blacklist](#blacklist)
- [blacklist add](#blacklist-add)
- [blacklist x-add](#blacklist-x-add)
Expand All @@ -35,6 +36,7 @@ Tested on Waterfall, version: `git:Waterfall-Bootstrap:1.16-R0.4-SNAPSHOT:1d2221
- [blacklist on](#blacklist-on)
- [blacklist off](#blacklist-off)
- [blacklist confirm](#blacklist-confirm)
- [blacklist list](#blacklist-list)
- [Main Command](#main-command)
- [bungeesafeguard load](#bungeesafeguard-load)
- [bungeesafeguard reload](#bungeesafeguard-reload)
Expand Down Expand Up @@ -93,12 +95,12 @@ The configuration file for BungeeSafeguard is `plugins/BungeeSafeguard/config.ym
```yaml
#########################################
# BungeeSafeguard Configuration #
# Version: 2.5 #
# Version: 2.6 #
# Author: Untitled #
#########################################

# You can safely ignore this
version: "2.5"
version: "2.6"

# Message to be sent to the player when that player is blocked for not being whitelisted
whitelist-message: :( You are not whitelisted on this server
Expand Down Expand Up @@ -287,6 +289,31 @@ Confirm the last issued whitelist command:
whitelist confirm
```
#### whitelist list
Alias: `whitelist ls`, `whitelist show` or `whitelist dump`.
Dump whitelist and lazy whitelist with at most 10 last known usernames:
```
whitelist list
```
Example output:
```
Whitelist ENABLED
2 lazy record(s)
foo
bar
3 UUID record(s) and the last known names (in reverse chronological order)
00000000-1111-2222-3333-666666666666 LatestName, OldNameLastMonth, OldNameLastYear
ffffffff-1111-2222-3333-666666666666
eeeeeeee-1111-2222-3333-666666666666 LatestName123
```
*This feature is added as requested by issue #8.*
### Blacklist
Alias: `blist`.
Expand Down Expand Up @@ -428,6 +455,31 @@ Confirm the last issued blacklist command:
blacklist confirm
```
#### blacklist list
Alias: `blacklist ls`, `blacklist show` or `blacklist dump`.
Dump blacklist and lazy blacklist with at most 10 last known usernames:
```
whitelist list
```
Example output:
```
Blacklist ENABLED
2 lazy record(s)
foo
bar
3 UUID record(s) and the last known names (in reverse chronological order)
00000000-1111-2222-3333-666666666666 LatestName, OldNameLastMonth, OldNameLastYear
ffffffff-1111-2222-3333-666666666666
eeeeeeee-1111-2222-3333-666666666666 LatestName123
```
*This feature is added as requested by issue #8.*
### Main Command
Alias: `bsg`.
Expand Down Expand Up @@ -517,3 +569,5 @@ BungeeSafeguard does asynchronous UUID look up when you execute add/remove on th
It's recommended to execute those command only in console, and wait patiently for the completion feedback from the command before executing other commands of BungeeSafeguard.
Offline servers should be able to use this plugin by using lazy lists or supplying BungeeSafeguard with players' UUIDs rather than their usernames. However, offline servers are still suffering from UUID abuse if they have no authentication plugin installed or have no external authentication mechanism. Offline server owners need to fully understand whitelist and blacklist is **NOT** a prevention of UUID abuse.
Last but not least, you should always be prepared for the worst situation, for example, when BungeeCord or BungeeSafeguard somehow, magically, fail to protect your servers. Backup is a good way to counter Murphy's law.
6 changes: 3 additions & 3 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
plugins {
id 'java'
id 'org.jetbrains.kotlin.jvm' version '1.4.20'
id 'org.jetbrains.kotlin.jvm' version '1.4.32'
}

group 'vip.untitled'
version '2.5-SNAPSHOT'
version '2.6-SNAPSHOT'

sourceCompatibility = 1.8

Expand All @@ -18,7 +18,7 @@ repositories {
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
implementation 'com.google.code.gson:gson:2.8.6'
compileOnly "net.md-5:bungeecord-api:1.16-R0.4-SNAPSHOT"
compileOnly "net.md-5:bungeecord-api:1.16-R0.5-SNAPSHOT"
testCompile group: 'junit', name: 'junit', version: '4.12'
}

Expand Down
16 changes: 15 additions & 1 deletion src/main/kotlin/vip/untitled/bungeesafeguard/BungeeSafeguard.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import java.io.IOException


@Suppress("unused")
open class BungeeSafeguard: ConfigHolderPlugin() {
open class BungeeSafeguard: MetaHolderPlugin() {
internal lateinit var events: Events
private lateinit var whitelistCommand: Whitelist
private lateinit var blacklistCommand: Blacklist
Expand All @@ -19,6 +19,7 @@ open class BungeeSafeguard: ConfigHolderPlugin() {
proxy.pluginManager.registerListener(this, events)

loadConfig(null)
loadUserCache()
whitelistCommand = Whitelist(this)
proxy.pluginManager.registerCommand(this, whitelistCommand)
blacklistCommand = Blacklist(this)
Expand Down Expand Up @@ -77,6 +78,10 @@ open class BungeeSafeguard: ConfigHolderPlugin() {
config.reload(sender)
}

open fun reloadUserCache() {
userCache.reload()
}

open fun loadConfig(sender: CommandSender?) {
config = Config(this)
try {
Expand All @@ -85,4 +90,13 @@ open class BungeeSafeguard: ConfigHolderPlugin() {
logger.warning("Unable to read config file \"${config.configInUse}\", please check the config file and if the content of \"${Config.CONFIG_IN_USE}\" is correct")
}
}

open fun loadUserCache() {
userCache = UserCache(this)
try {
userCache.load()
} catch (err: IOException) {
logger.warning("Unable to read user cache file \"${UserCache.CACHE_FILE}\", please check the user cache file or simply delete it")
}
}
}
56 changes: 38 additions & 18 deletions src/main/kotlin/vip/untitled/bungeesafeguard/Events.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@ import net.md_5.bungee.api.plugin.Listener
import net.md_5.bungee.event.EventHandler
import java.util.*

open class Events(val context: ConfigHolderPlugin): Listener {
open class Events(val context: MetaHolderPlugin): Listener {
protected val config: Config
get() = context.config
protected val whitelistMessage: String?
get() = config.whitelistMessage
protected val blacklistMessage: String?
get() = config.blacklistMessage
protected val noUUIDMessage: String?
get() = config.noUUIDMessage
protected val whitelistMessage: String
get() = config.whitelistMessage ?: ""
protected val blacklistMessage: String
get() = config.blacklistMessage ?: ""
protected val noUUIDMessage: String
get() = config.noUUIDMessage ?: ""
protected val enableWhitelist: Boolean
get() = config.enableWhitelist
protected val enableBlacklist: Boolean
Expand Down Expand Up @@ -55,6 +55,27 @@ open class Events(val context: ConfigHolderPlugin): Listener {
return KickReason.DO_NOT_KICK
}

/**
* Update user cache
*
* We only care about the usernames of users in the whitelist or the blacklist
*
* This should be called AFTER `shouldKick`, who might update the two lists,
* because this method will check if the user is in one of the two lists
*
* @param id User's UUID
* @param username Username
*/
open fun updateUserCache(id: UUID, username: String) {
val cache = context.userCache
if (config.inWhitelist(id) || config.inBlacklist(id)) {
cache.addAndSave(id, username)
} else if (cache.contains(id)) {
// Somehow this user is in the cache
cache.removeAndSave(id) // We don't need to know the username of this user anymore
}
}

@EventHandler
open fun onPostLogin(event: PostLoginEvent) {
val player = event.player
Expand All @@ -63,16 +84,15 @@ open class Events(val context: ConfigHolderPlugin): Listener {
when (shouldKick(username, id)) {
KickReason.DO_NOT_KICK -> {}
KickReason.BLACKLISTED -> {
if (blacklistMessage == null) player.disconnect()
else player.disconnect(TextComponent(blacklistMessage))
player.disconnect(TextComponent(blacklistMessage))
context.logger.info("Banned player ${ChatColor.RED}${username} ${ChatColor.BLUE}(${id})${ChatColor.RESET} blocked!")
}
KickReason.NOT_WHITELISTED -> {
if (whitelistMessage == null) player.disconnect()
else player.disconnect(TextComponent(whitelistMessage))
player.disconnect(TextComponent(whitelistMessage))
context.logger.info("Non-whitelisted player ${ChatColor.AQUA}${username} ${ChatColor.BLUE}(${id})${ChatColor.RESET} blocked!")
}
}
updateUserCache(id, username)
}

@EventHandler
Expand All @@ -81,24 +101,25 @@ open class Events(val context: ConfigHolderPlugin): Listener {
val username = connection.name
val id = connection.uniqueId
if (id == null) {
if (noUUIDMessage != null) event.setCancelReason(TextComponent(noUUIDMessage))
event.setCancelReason(TextComponent(noUUIDMessage))
event.isCancelled = true
context.logger.info("${ChatColor.YELLOW}Player ${ChatColor.RED}${username} ${ChatColor.YELLOW}has no UUID, blocked for safety")
return
}
when (shouldKick(username, id)) {
KickReason.DO_NOT_KICK -> {}
KickReason.BLACKLISTED -> {
if (blacklistMessage != null) event.setCancelReason(TextComponent(blacklistMessage))
event.setCancelReason(TextComponent(blacklistMessage))
event.isCancelled = true
context.logger.info("Banned player ${ChatColor.RED}${username} ${ChatColor.BLUE}(${id})${ChatColor.RESET} blocked from logging in!")
}
KickReason.NOT_WHITELISTED -> {
if (whitelistMessage != null) event.setCancelReason(TextComponent(whitelistMessage))
event.setCancelReason(TextComponent(whitelistMessage))
event.isCancelled = true
context.logger.info("Non-whitelisted player ${ChatColor.AQUA}${username} ${ChatColor.BLUE}(${id})${ChatColor.RESET} blocked from logging in!")
}
}
updateUserCache(id, username)
}

@EventHandler
Expand All @@ -110,16 +131,15 @@ open class Events(val context: ConfigHolderPlugin): Listener {
KickReason.DO_NOT_KICK -> {}
KickReason.BLACKLISTED -> {
event.isCancelled = true
if (blacklistMessage == null) player.disconnect()
else player.disconnect(TextComponent(blacklistMessage))
player.disconnect(TextComponent(blacklistMessage))
context.logger.info("Banned player ${ChatColor.RED}${username} ${ChatColor.BLUE}(${id})${ChatColor.RESET} blocked from connecting to server ${ChatColor.GREEN}${event.target.name}!")
}
KickReason.NOT_WHITELISTED -> {
event.isCancelled = true
if (whitelistMessage == null) player.disconnect()
else player.disconnect(TextComponent(whitelistMessage))
player.disconnect(TextComponent(whitelistMessage))
context.logger.info("Non-whitelisted player ${ChatColor.AQUA}${username} ${ChatColor.BLUE}(${id})${ChatColor.RESET} blocked from connecting to server ${ChatColor.GREEN}${event.target.name}!")
}
}
updateUserCache(id, username)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package vip.untitled.bungeesafeguard

import net.md_5.bungee.api.plugin.Plugin

abstract class ConfigHolderPlugin: Plugin() {
abstract class MetaHolderPlugin: Plugin() {
lateinit var config: Config
lateinit var userCache: UserCache
}
Loading

0 comments on commit 36d8b27

Please sign in to comment.