mirror of
https://github.com/lax1dude/origin-blacklist-1.8.git
synced 2024-12-21 23:04:14 -08:00
bungee impl mostly completed
This commit is contained in:
commit
0d901c0daa
|
@ -0,0 +1,381 @@
|
||||||
|
package net.lax1dude.eaglercraft.v1_8.plugin.origin_blacklist;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileReader;
|
||||||
|
import java.io.FileWriter;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.net.HttpURLConnection;
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.net.URLConnection;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
import java.util.regex.PatternSyntaxException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2022-2024 lax1dude. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||||
|
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class OriginBlacklist {
|
||||||
|
|
||||||
|
private final OriginBlacklistLoggerAdapter logger;
|
||||||
|
private String kickMessage = null;
|
||||||
|
private boolean blockClientsWithNoOriginHeader = false;
|
||||||
|
public final Collection<Pattern> regexBlacklist = new ArrayList();
|
||||||
|
public final Collection<Pattern> regexLocalBlacklist = new ArrayList();
|
||||||
|
public final Collection<Pattern> regexBlacklistReplit = new ArrayList();
|
||||||
|
public final Collection<String> simpleWhitelist = new ArrayList();
|
||||||
|
private File localBlacklist = null;
|
||||||
|
private String subscriptionDownloadUserAgent = null;
|
||||||
|
private Collection<String> blacklistSubscriptions = null;
|
||||||
|
private boolean blockOfflineDownload = false;
|
||||||
|
private boolean blockAllReplits = false;
|
||||||
|
private boolean localWhitelistMode = false;
|
||||||
|
private boolean simpleWhitelistMode = false;
|
||||||
|
private final HashSet<String> brokenURLs = new HashSet();
|
||||||
|
private final HashSet<String> brokenRegex = new HashSet();
|
||||||
|
|
||||||
|
public static final HashSet<String> regexBlacklistReplitInternalStrings = new HashSet();
|
||||||
|
public static final Collection<Pattern> regexBlacklistReplitInternal = new ArrayList();
|
||||||
|
|
||||||
|
static {
|
||||||
|
regexBlacklistReplitInternalStrings.add(".*repl(it)?\\..{1,5}$");
|
||||||
|
for(String s : regexBlacklistReplitInternalStrings) {
|
||||||
|
regexBlacklistReplitInternal.add(Pattern.compile(s));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int updateRate = 15 * 60 * 1000;
|
||||||
|
private long lastLocalUpdate = 0l;
|
||||||
|
private long lastUpdate = 0;
|
||||||
|
|
||||||
|
public OriginBlacklist(OriginBlacklistLoggerAdapter log) {
|
||||||
|
logger = log;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getKickMessage() {
|
||||||
|
return kickMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getBlockClientsWithNoOriginHeader() {
|
||||||
|
return blockClientsWithNoOriginHeader;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean test(String origin) {
|
||||||
|
synchronized(regexBlacklist) {
|
||||||
|
if(blockOfflineDownload && origin.equalsIgnoreCase("null")) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if(simpleWhitelistMode) {
|
||||||
|
for(String st : simpleWhitelist) {
|
||||||
|
if(origin.equalsIgnoreCase(st)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(localWhitelistMode || simpleWhitelistMode) {
|
||||||
|
if(!blockOfflineDownload && origin.equalsIgnoreCase("null")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for(Pattern m : regexLocalBlacklist) {
|
||||||
|
if(m.matcher(origin).matches()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}else {
|
||||||
|
if(blockAllReplits) {
|
||||||
|
for(Pattern m : regexBlacklistReplitInternal) {
|
||||||
|
if(m.matcher(origin).matches()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(Pattern m : regexBlacklistReplit) {
|
||||||
|
if(m.matcher(origin).matches()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(Pattern m : regexBlacklist) {
|
||||||
|
if(m.matcher(origin).matches()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(Pattern m : regexLocalBlacklist) {
|
||||||
|
if(m.matcher(origin).matches()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void init(OriginBlacklistConfigAdapter cfg) {
|
||||||
|
synchronized(regexBlacklist) {
|
||||||
|
brokenURLs.clear();
|
||||||
|
brokenRegex.clear();
|
||||||
|
regexBlacklist.clear();
|
||||||
|
regexLocalBlacklist.clear();
|
||||||
|
regexBlacklistReplit.clear();
|
||||||
|
simpleWhitelist.clear();
|
||||||
|
localBlacklist = cfg.getLocalBlacklistFile();
|
||||||
|
kickMessage = cfg.getKickMessage();
|
||||||
|
blockClientsWithNoOriginHeader = cfg.getBlockClientsWithNoOriginHeader();
|
||||||
|
subscriptionDownloadUserAgent = cfg.getSubscriptionDownloadUserAgent();
|
||||||
|
blacklistSubscriptions = cfg.getBlacklistURLs();
|
||||||
|
blockOfflineDownload = cfg.shouldBlacklistOfflineDownload();
|
||||||
|
blockAllReplits = cfg.shouldBlacklistReplits();
|
||||||
|
simpleWhitelistMode = cfg.isSimpleWhitelistEnabled();
|
||||||
|
simpleWhitelist.addAll(cfg.getBlacklistSimpleWhitelist());
|
||||||
|
lastLocalUpdate = 0l;
|
||||||
|
lastUpdate = System.currentTimeMillis() - updateRate - 1000l;
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void update() {
|
||||||
|
long ct = System.currentTimeMillis();
|
||||||
|
if((int)(ct - lastUpdate) > updateRate) {
|
||||||
|
lastUpdate = ct;
|
||||||
|
synchronized(regexBlacklist) {
|
||||||
|
if(blacklistSubscriptions != null) {
|
||||||
|
ArrayList<Pattern> newBlacklist = new ArrayList();
|
||||||
|
ArrayList<Pattern> newReplitBlacklist = new ArrayList();
|
||||||
|
HashSet<String> newBlacklistSet = new HashSet();
|
||||||
|
newBlacklistSet.addAll(regexBlacklistReplitInternalStrings);
|
||||||
|
for(String str : blacklistSubscriptions) {
|
||||||
|
try {
|
||||||
|
URL u;
|
||||||
|
try {
|
||||||
|
u = new URL(str);
|
||||||
|
}catch(MalformedURLException e) {
|
||||||
|
if(brokenURLs.add(str)) {
|
||||||
|
logger.error("The blacklist subscription URL '" + str + "' is invalid");
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
URLConnection cc = u.openConnection();
|
||||||
|
if(cc instanceof HttpURLConnection) {
|
||||||
|
HttpURLConnection ccc = (HttpURLConnection)cc;
|
||||||
|
ccc.setRequestProperty("Accept", "text/plain,text/html,application/xhtml+xml,application/xml");
|
||||||
|
ccc.setRequestProperty("User-Agent", subscriptionDownloadUserAgent);
|
||||||
|
}
|
||||||
|
cc.connect();
|
||||||
|
try(BufferedReader is = new BufferedReader(new InputStreamReader(cc.getInputStream()))) {
|
||||||
|
String firstLine = is.readLine();
|
||||||
|
if(firstLine == null) {
|
||||||
|
is.close();
|
||||||
|
throw new IOException("Could not read line");
|
||||||
|
}
|
||||||
|
firstLine = firstLine.trim();
|
||||||
|
if(!firstLine.startsWith("#") || !firstLine.substring(1).trim().toLowerCase().startsWith("eaglercraft domain blacklist")) {
|
||||||
|
throw new IOException("File does not contain a list of domains");
|
||||||
|
}
|
||||||
|
String ss;
|
||||||
|
while((ss = is.readLine()) != null) {
|
||||||
|
if((ss = ss.trim()).length() > 0) {
|
||||||
|
if(ss.startsWith("#")) {
|
||||||
|
ss = ss.substring(1).trim();
|
||||||
|
if(ss.startsWith("replit-wildcard:")) {
|
||||||
|
ss = ss.substring(16).trim();
|
||||||
|
if(newBlacklistSet.add(ss)) {
|
||||||
|
try {
|
||||||
|
newReplitBlacklist.add(Pattern.compile(ss));
|
||||||
|
}catch(PatternSyntaxException shit) {
|
||||||
|
if(brokenRegex.add(ss)) {
|
||||||
|
logger.error("the blacklist replit wildcard regex '" + ss + "' is invalid");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
brokenRegex.remove(ss);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(newBlacklistSet.add(ss)) {
|
||||||
|
try {
|
||||||
|
newBlacklist.add(Pattern.compile(ss));
|
||||||
|
}catch(PatternSyntaxException shit) {
|
||||||
|
if(brokenRegex.add(ss)) {
|
||||||
|
logger.error("the blacklist regex '" + ss + "' is invalid");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
brokenRegex.remove(ss);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
brokenURLs.remove(str);
|
||||||
|
}catch(Throwable t) {
|
||||||
|
if(brokenURLs.add(str)) {
|
||||||
|
logger.error("the blacklist subscription URL '" + str + "' is invalid");
|
||||||
|
}
|
||||||
|
t.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!newBlacklist.isEmpty()) {
|
||||||
|
regexBlacklist.clear();
|
||||||
|
regexBlacklist.addAll(newBlacklist);
|
||||||
|
}
|
||||||
|
if(!newReplitBlacklist.isEmpty()) {
|
||||||
|
regexBlacklistReplit.clear();
|
||||||
|
regexBlacklistReplit.addAll(newReplitBlacklist);
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
brokenURLs.clear();
|
||||||
|
brokenRegex.clear();
|
||||||
|
regexBlacklist.clear();
|
||||||
|
lastLocalUpdate = 0l;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(localBlacklist.exists()) {
|
||||||
|
long lastLocalEdit = localBlacklist.lastModified();
|
||||||
|
if(lastLocalEdit != lastLocalUpdate) {
|
||||||
|
lastLocalUpdate = lastLocalEdit;
|
||||||
|
synchronized(regexBlacklist) {
|
||||||
|
try(BufferedReader is = new BufferedReader(new FileReader(localBlacklist))) {
|
||||||
|
regexLocalBlacklist.clear();
|
||||||
|
localWhitelistMode = false;
|
||||||
|
boolean foundWhitelistStatement = false;
|
||||||
|
String ss;
|
||||||
|
while((ss = is.readLine()) != null) {
|
||||||
|
try {
|
||||||
|
if((ss = ss.trim()).length() > 0) {
|
||||||
|
if(!ss.startsWith("#")) {
|
||||||
|
regexLocalBlacklist.add(Pattern.compile(ss));
|
||||||
|
}else {
|
||||||
|
String st = ss.substring(1).trim();
|
||||||
|
if(st.startsWith("whitelistMode:")) {
|
||||||
|
foundWhitelistStatement = true;
|
||||||
|
String str = st.substring(14).trim().toLowerCase();
|
||||||
|
localWhitelistMode = str.equals("true") || str.equals("on") || str.equals("1");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}catch(PatternSyntaxException shit) {
|
||||||
|
logger.error("the local " + (localWhitelistMode ? "whitelist" : "blacklist") + " regex '" + ss + "' is invalid");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
is.close();
|
||||||
|
if(!foundWhitelistStatement) {
|
||||||
|
List<String> newLines = new ArrayList();
|
||||||
|
newLines.add("#whitelistMode: false");
|
||||||
|
newLines.add("");
|
||||||
|
try(BufferedReader is2 = new BufferedReader(new FileReader(localBlacklist))) {
|
||||||
|
while((ss = is2.readLine()) != null) {
|
||||||
|
newLines.add(ss);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
try(PrintWriter os = new PrintWriter(new FileWriter(localBlacklist))) {
|
||||||
|
for(String str : newLines) {
|
||||||
|
os.println(str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lastLocalUpdate = localBlacklist.lastModified();
|
||||||
|
}
|
||||||
|
logger.info("Reloaded '" + localBlacklist.getName() + "'.");
|
||||||
|
}catch(IOException ex) {
|
||||||
|
regexLocalBlacklist.clear();
|
||||||
|
logger.error("failed to read local " + (localWhitelistMode ? "whitelist" : "blacklist") + " file '" + localBlacklist.getName() + "'");
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
synchronized(regexBlacklist) {
|
||||||
|
if(!regexLocalBlacklist.isEmpty()) {
|
||||||
|
logger.warn("the blacklist file '" + localBlacklist.getName() + "' has been deleted");
|
||||||
|
}
|
||||||
|
regexLocalBlacklist.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addLocal(String o) {
|
||||||
|
String p = "^" + Pattern.quote(o.trim()) + "$";
|
||||||
|
ArrayList<String> lines = new ArrayList();
|
||||||
|
if(localBlacklist.exists()) {
|
||||||
|
try(BufferedReader is = new BufferedReader(new FileReader(localBlacklist))) {
|
||||||
|
String ss;
|
||||||
|
while((ss = is.readLine()) != null) {
|
||||||
|
if((ss = ss.trim()).length() > 0) {
|
||||||
|
lines.add(ss);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}catch(IOException ex) {
|
||||||
|
// ?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(lines.isEmpty()) {
|
||||||
|
lines.add("#whitelist false");
|
||||||
|
lines.add("");
|
||||||
|
}
|
||||||
|
if(!lines.contains(p)) {
|
||||||
|
lines.add(p);
|
||||||
|
try(PrintWriter os = new PrintWriter(new FileWriter(localBlacklist))) {
|
||||||
|
for(String s : lines) {
|
||||||
|
os.println(s);
|
||||||
|
}
|
||||||
|
lastLocalUpdate = 0l;
|
||||||
|
update();
|
||||||
|
}catch(IOException ex) {
|
||||||
|
// ?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean removeLocal(String o) {
|
||||||
|
String p = "^" + Pattern.quote(o.trim()) + "$";
|
||||||
|
ArrayList<String> lines = new ArrayList();
|
||||||
|
if(localBlacklist.exists()) {
|
||||||
|
try(BufferedReader is = new BufferedReader(new FileReader(localBlacklist))) {
|
||||||
|
String ss;
|
||||||
|
while((ss = is.readLine()) != null) {
|
||||||
|
if((ss = ss.trim()).length() > 0) {
|
||||||
|
lines.add(ss);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}catch(IOException ex) {
|
||||||
|
// ?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(lines.contains(p)) {
|
||||||
|
lines.remove(p);
|
||||||
|
try {
|
||||||
|
try(PrintWriter os = new PrintWriter(new FileWriter(localBlacklist))) {
|
||||||
|
for(String s : lines) {
|
||||||
|
os.println(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lastLocalUpdate = 0l;
|
||||||
|
update();
|
||||||
|
return true;
|
||||||
|
}catch(IOException ex) {
|
||||||
|
logger.error("Failed to save '" + localBlacklist.getName() + "'");
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
package net.lax1dude.eaglercraft.v1_8.plugin.origin_blacklist;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2024 lax1dude. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||||
|
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public interface OriginBlacklistConfigAdapter {
|
||||||
|
|
||||||
|
File getLocalBlacklistFile();
|
||||||
|
|
||||||
|
String getKickMessage();
|
||||||
|
|
||||||
|
boolean getBlockClientsWithNoOriginHeader();
|
||||||
|
|
||||||
|
String getSubscriptionDownloadUserAgent();
|
||||||
|
|
||||||
|
Collection<String> getBlacklistURLs();
|
||||||
|
|
||||||
|
boolean shouldBlacklistOfflineDownload();
|
||||||
|
|
||||||
|
boolean shouldBlacklistReplits();
|
||||||
|
|
||||||
|
boolean isSimpleWhitelistEnabled();
|
||||||
|
|
||||||
|
Collection<String> getBlacklistSimpleWhitelist();
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
package net.lax1dude.eaglercraft.v1_8.plugin.origin_blacklist;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2024 lax1dude. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||||
|
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public interface OriginBlacklistLoggerAdapter {
|
||||||
|
|
||||||
|
void info(String msg);
|
||||||
|
|
||||||
|
void warn(String msg);
|
||||||
|
|
||||||
|
void error(String msg);
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,111 @@
|
||||||
|
package net.lax1dude.eaglercraft.v1_8.plugin.origin_blacklist.bungee;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import net.lax1dude.eaglercraft.v1_8.plugin.gateway_bungeecord.EaglerXBungee;
|
||||||
|
import net.lax1dude.eaglercraft.v1_8.plugin.origin_blacklist.OriginBlacklistConfigAdapter;
|
||||||
|
import net.md_5.bungee.config.Configuration;
|
||||||
|
import net.md_5.bungee.config.ConfigurationProvider;
|
||||||
|
import net.md_5.bungee.config.YamlConfiguration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2024 lax1dude. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||||
|
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class OriginBlacklistConfigBungee implements OriginBlacklistConfigAdapter {
|
||||||
|
|
||||||
|
public static OriginBlacklistConfigBungee loadConfig(File dataDir) throws IOException {
|
||||||
|
if(!dataDir.isDirectory() && !dataDir.mkdirs()) {
|
||||||
|
throw new IOException("Could not create directory: " + dataDir.getAbsolutePath());
|
||||||
|
}
|
||||||
|
File configFile = new File(dataDir, "config.yml");
|
||||||
|
if(!configFile.exists()) {
|
||||||
|
try(InputStream defaultConf = OriginBlacklistConfigBungee.class.getResourceAsStream("../default_config.yml")) {
|
||||||
|
try(OutputStream os = new FileOutputStream(configFile)) {
|
||||||
|
byte[] copyBuffer = new byte[1024];
|
||||||
|
int i;
|
||||||
|
while((i = defaultConf.read(copyBuffer)) != -1) {
|
||||||
|
os.write(copyBuffer, 0, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Configuration conf = ConfigurationProvider.getProvider(YamlConfiguration.class).load(configFile);
|
||||||
|
return new OriginBlacklistConfigBungee(dataDir, conf);
|
||||||
|
}
|
||||||
|
|
||||||
|
private final File dataDir;
|
||||||
|
private final Configuration conf;
|
||||||
|
|
||||||
|
private OriginBlacklistConfigBungee(File dataDir, Configuration conf) {
|
||||||
|
this.dataDir = dataDir;
|
||||||
|
this.conf = conf;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public File getLocalBlacklistFile() {
|
||||||
|
return new File(dataDir, "origin_blacklist.txt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getKickMessage() {
|
||||||
|
return conf.getString("origin_blacklist_kick_message", "End of stream");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean getBlockClientsWithNoOriginHeader() {
|
||||||
|
return conf.getBoolean("origin_blacklist_block_missing_origin_header", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getSubscriptionDownloadUserAgent() {
|
||||||
|
return "Mozilla/5.0 EaglerXBungee/" + EaglerXBungee.getEagler().getDescription().getVersion();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<String> getBlacklistURLs() {
|
||||||
|
boolean enableSubscribe = conf.getBoolean("enable_web_origin_blacklist", false);
|
||||||
|
if(!enableSubscribe) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return (Collection<String>)conf.getList("origin_blacklist_subscriptions", new ArrayList<String>());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean shouldBlacklistOfflineDownload() {
|
||||||
|
return conf.getBoolean("origin_blacklist_block_offline_download", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean shouldBlacklistReplits() {
|
||||||
|
return conf.getBoolean("origin_blacklist_block_replit_clients", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isSimpleWhitelistEnabled() {
|
||||||
|
return conf.getBoolean("origin_blacklist_use_simple_whitelist", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<String> getBlacklistSimpleWhitelist() {
|
||||||
|
return (Collection<String>)conf.getList("origin_blacklist_simple_whitelist", new ArrayList<String>());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,59 @@
|
||||||
|
package net.lax1dude.eaglercraft.v1_8.plugin.origin_blacklist.bungee;
|
||||||
|
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
import net.lax1dude.eaglercraft.v1_8.plugin.gateway_bungeecord.server.EaglerInitialHandler;
|
||||||
|
import net.lax1dude.eaglercraft.v1_8.plugin.origin_blacklist.OriginBlacklist;
|
||||||
|
import net.md_5.bungee.api.chat.TextComponent;
|
||||||
|
import net.md_5.bungee.api.event.LoginEvent;
|
||||||
|
import net.md_5.bungee.api.plugin.Listener;
|
||||||
|
import net.md_5.bungee.event.EventHandler;
|
||||||
|
import net.md_5.bungee.event.EventPriority;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2024 lax1dude. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||||
|
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class OriginBlacklistListenerBungee implements Listener {
|
||||||
|
|
||||||
|
private final OriginBlacklistPluginBungee plugin;
|
||||||
|
|
||||||
|
public OriginBlacklistListenerBungee(OriginBlacklistPluginBungee plugin) {
|
||||||
|
this.plugin = plugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.HIGHEST)
|
||||||
|
public void handleLoginEvent(LoginEvent evt) {
|
||||||
|
if(evt.getConnection() instanceof EaglerInitialHandler) {
|
||||||
|
EaglerInitialHandler eaglerCon = (EaglerInitialHandler)evt.getConnection();
|
||||||
|
String origin = eaglerCon.getOrigin();
|
||||||
|
OriginBlacklist blacklist = plugin.list;
|
||||||
|
boolean shouldKick = true;
|
||||||
|
try {
|
||||||
|
shouldKick = (origin == null && blacklist.getBlockClientsWithNoOriginHeader()) || blacklist.test(origin);
|
||||||
|
}catch(Throwable t) {
|
||||||
|
plugin.getLogger().log(Level.SEVERE, "Failed to check origin blacklist for: " + origin, t);
|
||||||
|
}
|
||||||
|
if(shouldKick) {
|
||||||
|
plugin.getLogger().info("Disconnecting a player who joined from blacklisted origin: " + origin);
|
||||||
|
evt.setCancelled(true);
|
||||||
|
String msg = blacklist.getKickMessage();
|
||||||
|
if(msg != null) {
|
||||||
|
evt.setReason(new TextComponent());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,106 @@
|
||||||
|
package net.lax1dude.eaglercraft.v1_8.plugin.origin_blacklist.bungee;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Timer;
|
||||||
|
import java.util.TimerTask;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import net.lax1dude.eaglercraft.v1_8.plugin.origin_blacklist.OriginBlacklist;
|
||||||
|
import net.lax1dude.eaglercraft.v1_8.plugin.origin_blacklist.OriginBlacklistConfigAdapter;
|
||||||
|
import net.lax1dude.eaglercraft.v1_8.plugin.origin_blacklist.OriginBlacklistLoggerAdapter;
|
||||||
|
import net.md_5.bungee.api.plugin.Plugin;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2024 lax1dude. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||||
|
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class OriginBlacklistPluginBungee extends Plugin {
|
||||||
|
|
||||||
|
private static OriginBlacklistPluginBungee instance = null;
|
||||||
|
|
||||||
|
public final OriginBlacklist list;
|
||||||
|
|
||||||
|
private Timer updateOriginBlacklistTimer = null;
|
||||||
|
|
||||||
|
public OriginBlacklistPluginBungee() {
|
||||||
|
instance = this;
|
||||||
|
list = new OriginBlacklist(new OriginBlacklistLoggerAdapter() {
|
||||||
|
@Override
|
||||||
|
public void warn(String msg) {
|
||||||
|
OriginBlacklistPluginBungee.this.getLogger().warning(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void info(String msg) {
|
||||||
|
OriginBlacklistPluginBungee.this.getLogger().info(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void error(String msg) {
|
||||||
|
OriginBlacklistPluginBungee.this.getLogger().severe(msg);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLoad() {
|
||||||
|
reloadConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void reloadConfig() {
|
||||||
|
OriginBlacklistConfigAdapter cfg;
|
||||||
|
try {
|
||||||
|
cfg = OriginBlacklistConfigBungee.loadConfig(getDataFolder());
|
||||||
|
}catch(IOException ex) {
|
||||||
|
throw new RuntimeException("Could not load origin blacklist config file!", ex);
|
||||||
|
}
|
||||||
|
list.init(cfg);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onEnable() {
|
||||||
|
if(updateOriginBlacklistTimer == null) {
|
||||||
|
updateOriginBlacklistTimer = new Timer("EaglerXBungee: Origin Blacklist Updater");
|
||||||
|
updateOriginBlacklistTimer.scheduleAtFixedRate(new TimerTask() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
list.update();
|
||||||
|
}catch(Throwable t) {
|
||||||
|
OriginBlacklistPluginBungee.this.getLogger().log(Level.SEVERE, "Could not update origin blacklist!", t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, 0, 6000l);
|
||||||
|
}
|
||||||
|
getProxy().getPluginManager().registerListener(this, new OriginBlacklistListenerBungee(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDisable() {
|
||||||
|
if(updateOriginBlacklistTimer != null) {
|
||||||
|
updateOriginBlacklistTimer.cancel();
|
||||||
|
updateOriginBlacklistTimer = null;
|
||||||
|
}
|
||||||
|
getProxy().getPluginManager().unregisterListeners(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static OriginBlacklistPluginBungee getPlugin() {
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Logger logger() {
|
||||||
|
return instance.getLogger();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
package net.lax1dude.eaglercraft.v1_8.plugin.origin_blacklist.bungee.command;
|
||||||
|
|
||||||
|
public class CommandDomainBlock {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
package net.lax1dude.eaglercraft.v1_8.plugin.origin_blacklist.bungee.command;
|
||||||
|
|
||||||
|
public class CommandDomainBlockDomain {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
package net.lax1dude.eaglercraft.v1_8.plugin.origin_blacklist.bungee.command;
|
||||||
|
|
||||||
|
public class CommandDomainUnblock {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
origin_blacklist_kick_message: 'End of stream'
|
||||||
|
origin_blacklist_block_missing_origin_header: false
|
||||||
|
origin_blacklist_block_offline_download: false
|
||||||
|
origin_blacklist_block_replit_clients: false
|
||||||
|
enable_web_origin_blacklist: false
|
||||||
|
origin_blacklist_subscriptions:
|
||||||
|
- 'add url here'
|
||||||
|
origin_blacklist_use_simple_whitelist: false
|
||||||
|
origin_blacklist_simple_whitelist:
|
||||||
|
- 'type the name of your client\'s domain here'
|
||||||
|
- '(if \'origin_blacklist_use_simple_whitelist\' is true)'
|
5
src/main/resources/plugin.yml
Normal file
5
src/main/resources/plugin.yml
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
name: OriginBlacklist
|
||||||
|
main: net.lax1dude.eaglercraft.v1_8.plugin.origin_blacklist.bungee.OriginBlacklistPluginBungee
|
||||||
|
version: 1.0.0
|
||||||
|
description: Plugin for EaglercraftXBungee servers to add the "origin blacklist" feature from 1.5.2
|
||||||
|
author: lax1dude
|
Loading…
Reference in New Issue
Block a user