Dieser Commit ist enthalten in:
Lixfel 2022-09-26 16:10:39 +02:00
Ursprung acd392b891
Commit 77ae329d6e
6 geänderte Dateien mit 25 neuen und 27 gelöschten Zeilen

Datei anzeigen

@ -27,9 +27,6 @@ dependencies {
compileOnly 'org.spigotmc:spigot-api:1.19-R0.1-SNAPSHOT' compileOnly 'org.spigotmc:spigot-api:1.19-R0.1-SNAPSHOT'
compileOnly 'io.netty:netty-all:4.1.68.Final' compileOnly 'io.netty:netty-all:4.1.68.Final'
//compileOnly swdep("Spigot-1.8") files("${rootDir}/lib/${s}.jar")
//compileOnly swdep("Spigot-1.19") files("${rootDir}/lib/${s}.jar")
compileOnly 'org.projectlombok:lombok:1.18.22' compileOnly 'org.projectlombok:lombok:1.18.22'
testCompileOnly 'org.projectlombok:lombok:1.18.22' testCompileOnly 'org.projectlombok:lombok:1.18.22'
annotationProcessor 'org.projectlombok:lombok:1.18.22' annotationProcessor 'org.projectlombok:lombok:1.18.22'

Datei anzeigen

@ -21,10 +21,13 @@ public class AltAuthBungee extends Plugin implements Listener {
@Override @Override
public void onEnable() { public void onEnable() {
File config = new File(getDataFolder(), "config.yml"); File dataFolder = getDataFolder();
File config = new File(dataFolder, "config.yml");
ConfigurationProvider provider = ConfigurationProvider.getProvider(YamlConfiguration.class); ConfigurationProvider provider = ConfigurationProvider.getProvider(YamlConfiguration.class);
if(!config.exists()) { if(!config.exists()) {
dataFolder.mkdir();
try (InputStream in = getResourceAsStream("config.yml")) { try (InputStream in = getResourceAsStream("config.yml")) {
try (FileOutputStream out = new FileOutputStream(config)) { try (FileOutputStream out = new FileOutputStream(config)) {
int read; int read;
@ -33,7 +36,7 @@ public class AltAuthBungee extends Plugin implements Listener {
out.write(buffer, 0, read); out.write(buffer, 0, read);
} }
} catch (IOException e) { } catch (IOException e) {
throw new IllegalStateException("Could not create config"); throw new IllegalStateException("Could not create config", e);
} }
} }

Datei anzeigen

@ -34,7 +34,7 @@ import java.util.List;
import java.util.UUID; import java.util.UUID;
import java.util.logging.Level; import java.util.logging.Level;
public class AltAuthHandler extends MessageToMessageCodec<PacketWrapper, PacketWrapper> { public class AltAuthHandler extends MessageToMessageCodec<PacketWrapper, DefinedPacket> {
private static final Class<?> InitialHandler = ReflectionUtil.getClass("net.md_5.bungee.connection.InitialHandler"); private static final Class<?> InitialHandler = ReflectionUtil.getClass("net.md_5.bungee.connection.InitialHandler");
private static final ReflectionUtil.FieldWrapper<ChannelWrapper> CH = ReflectionUtil.getField(InitialHandler, ChannelWrapper.class, 0); private static final ReflectionUtil.FieldWrapper<ChannelWrapper> CH = ReflectionUtil.getField(InitialHandler, ChannelWrapper.class, 0);
@ -54,17 +54,14 @@ public class AltAuthHandler extends MessageToMessageCodec<PacketWrapper, PacketW
ChannelWrapper ch = CH.get(connection); ChannelWrapper ch = CH.get(connection);
ch.addBefore(PipelineUtils.BOSS_HANDLER, "altauth", this); ch.addBefore(PipelineUtils.BOSS_HANDLER, "altauth", this);
//ch.addBefore(PipelineUtils.PACKET_ENCODER, "altauth", this);
} }
@Override @Override
protected void encode(ChannelHandlerContext ctx, PacketWrapper packetWrapper, List<Object> out) { protected void encode(ChannelHandlerContext ctx, DefinedPacket packet, List<Object> out) {
DefinedPacket packet = packetWrapper.packet;
if(packet instanceof EncryptionRequest) if(packet instanceof EncryptionRequest)
((EncryptionRequest)packet).setServerId(altAuthUrl); ((EncryptionRequest)packet).setServerId(altAuthUrl);
out.add(packetWrapper); out.add(packet);
} }
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
@ -76,6 +73,7 @@ public class AltAuthHandler extends MessageToMessageCodec<PacketWrapper, PacketW
return; return;
} }
packetWrapper.trySingleRelease();
ChannelWrapper ch = CH.get(connection); ChannelWrapper ch = CH.get(connection);
ch.getHandle().pipeline().remove(this); ch.getHandle().pipeline().remove(this);

Datei anzeigen

@ -1,4 +1,3 @@
# SPDX-License-Identifier: MIT
accessWidener v1 named accessWidener v1 named
mutable field net/minecraft/server/MinecraftServer apiServices Lnet/minecraft/util/ApiServices; mutable field net/minecraft/server/MinecraftServer apiServices Lnet/minecraft/util/ApiServices;
accessible field net/minecraft/client/gui/screen/ConnectScreen connection Lnet/minecraft/network/ClientConnection; accessible field net/minecraft/client/gui/screen/ConnectScreen connection Lnet/minecraft/network/ClientConnection;

Datei anzeigen

@ -9,12 +9,10 @@ import de.chaoscaot.altauth.fabric.config.ClientConfig;
import net.fabricmc.api.EnvType; import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment; import net.fabricmc.api.Environment;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.ConfirmScreen;
import net.minecraft.client.gui.screen.ConnectScreen; import net.minecraft.client.gui.screen.ConnectScreen;
import net.minecraft.client.gui.screen.DisconnectedScreen; import net.minecraft.client.gui.screen.DisconnectedScreen;
import net.minecraft.client.network.ClientLoginNetworkHandler; import net.minecraft.client.network.ClientLoginNetworkHandler;
import net.minecraft.network.packet.s2c.login.LoginHelloS2CPacket; import net.minecraft.network.packet.s2c.login.LoginHelloS2CPacket;
import net.minecraft.screen.ScreenTexts;
import net.minecraft.text.Text; import net.minecraft.text.Text;
import org.joor.Reflect; import org.joor.Reflect;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -50,10 +48,10 @@ public class LoginRequestMixin {
} else { } else {
if(MinecraftClient.getInstance().currentScreen instanceof ConnectScreen cs) { if(MinecraftClient.getInstance().currentScreen instanceof ConnectScreen cs) {
ci.cancel(); ci.cancel();
cs.connectingCancelled = true; /*cs.connectingCancelled = true;
if( cs.connection != null) { if( cs.connection != null) {
cs.connection.disconnect(Text.translatable("connect.aborted")); cs.connection.disconnect(Text.translatable("connect.aborted"));
} }*/
MinecraftClient.getInstance().execute(() -> client.setScreen(new TrustServerScreen(server, cs.parent))); MinecraftClient.getInstance().execute(() -> client.setScreen(new TrustServerScreen(server, cs.parent)));
} }

25
proxy.py Normale Datei → Ausführbare Datei
Datei anzeigen

@ -1,6 +1,7 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# SPDX-License-Identifier: MIT # SPDX-License-Identifier: MIT
from traceback import format_exc
from collections import namedtuple from collections import namedtuple
from typing import Dict from typing import Dict
from json import dumps, loads from json import dumps, loads
@ -14,7 +15,9 @@ from http.server import ThreadingHTTPServer, BaseHTTPRequestHandler
# Set this to True if behind an ip masking proxy (with X-Forwarded-For support) while using prevent-proxy-connections # Set this to True if behind an ip masking proxy (with X-Forwarded-For support) while using prevent-proxy-connections
behind_proxy = False behind_proxy = True
# Address and port to listen to
bind_to = ('127.0.0.1', 8080)
# Should mojang accounts be allowed to join with this AltAuth proxy # Should mojang accounts be allowed to join with this AltAuth proxy
allow_mojang_accounts = True allow_mojang_accounts = True
# Should banned microsoft accounts ("UserBannedException") be allowed to join? # Should banned microsoft accounts ("UserBannedException") be allowed to join?
@ -67,7 +70,7 @@ class AltAuthRequestHandler(BaseHTTPRequestHandler):
content_length = int(self.headers['Content-Length']) content_length = int(self.headers['Content-Length'])
if content_length > 1024: if content_length > 1024:
raise Exception() raise Exception("Unusual large request (malicious actor?)")
request = loads(self.rfile.read(content_length)) request = loads(self.rfile.read(content_length))
access_token = request["accessToken"] access_token = request["accessToken"]
@ -78,12 +81,12 @@ class AltAuthRequestHandler(BaseHTTPRequestHandler):
now = time() now = time()
use_altauth = False use_altauth = False
if token["exp"] >= now: # check token expiration date if token["exp"] <= now: # check token expiration date
raise Exception() raise Exception("Expired token")
if token["iss"] == "Yggdrasil-Auth" and allow_mojang_accounts: # Mojang account if token["iss"] == "Yggdrasil-Auth" and allow_mojang_accounts: # Mojang account
if token["spr"] != selected_profile: if token["spr"] != selected_profile:
raise Exception() raise Exception("UUIDs don't match (malicious actor?)")
# Valid token (even on other ip): 204 # Valid token (even on other ip): 204
# Invalid token: 403 {"error": "ForbiddenOperationException", "errorMessage": "Invalid token"} # Invalid token: 403 {"error": "ForbiddenOperationException", "errorMessage": "Invalid token"}
@ -91,7 +94,7 @@ class AltAuthRequestHandler(BaseHTTPRequestHandler):
"accessToken": access_token "accessToken": access_token
}) })
if code != 204: if code != 204:
raise Exception() raise Exception("Token invalid for unknown reasons")
use_altauth = True use_altauth = True
@ -124,7 +127,7 @@ class AltAuthRequestHandler(BaseHTTPRequestHandler):
if code != 204 and data: if code != 204 and data:
self.wfile.write(data) self.wfile.write(data)
except BaseException as e: except BaseException as e:
print(e) self.log_message("Exception handling request: %s", format_exc())
# The client continues the login process with a 500 response, therefore 403 instead # The client continues the login process with a 500 response, therefore 403 instead
self.send_response(HTTPStatus.FORBIDDEN) self.send_response(HTTPStatus.FORBIDDEN)
@ -151,7 +154,7 @@ class AltAuthRequestHandler(BaseHTTPRequestHandler):
if altauth_client and "ip" in query: if altauth_client and "ip" in query:
if query.pop("ip") != cached_profile.ip: if query.pop("ip") != cached_profile.ip:
raise Exception() raise Exception("IPs don't match (prevent-proxy-connections)")
if altauth_client and cached_profile.use_altauth: if altauth_client and cached_profile.use_altauth:
code, data = moj_request( code, data = moj_request(
@ -161,7 +164,7 @@ class AltAuthRequestHandler(BaseHTTPRequestHandler):
if data: if data:
profile = loads(data) profile = loads(data)
if profile["name"] != username: # Disarm server_id hash collisions and prevent username spoofing if profile["name"] != username: # Disarm server_id hash collisions and prevent username spoofing
raise Exception() raise Exception("Usernames don't match (potential hash collision)")
elif "ip" in query: elif "ip" in query:
code, data = moj_request( code, data = moj_request(
f"https://sessionserver.mojang.com/session/minecraft/hasJoined?username={username}&serverId={server_id}&ip={query['ip']}" f"https://sessionserver.mojang.com/session/minecraft/hasJoined?username={username}&serverId={server_id}&ip={query['ip']}"
@ -175,7 +178,7 @@ class AltAuthRequestHandler(BaseHTTPRequestHandler):
self.end_headers() self.end_headers()
self.wfile.write(data) self.wfile.write(data)
except BaseException as e: except BaseException as e:
print(e) self.log_message("Exception handling request: %s", format_exc())
self.send_response(HTTPStatus.FORBIDDEN) self.send_response(HTTPStatus.FORBIDDEN)
self.end_headers() self.end_headers()
@ -183,4 +186,4 @@ class AltAuthRequestHandler(BaseHTTPRequestHandler):
if __name__ == '__main__': if __name__ == '__main__':
Thread(target=timeout_cleaner, name="TimeoutCleanup", daemon=True).start() Thread(target=timeout_cleaner, name="TimeoutCleanup", daemon=True).start()
ThreadingHTTPServer(('127.0.0.1', 8080), AltAuthRequestHandler).serve_forever() ThreadingHTTPServer(bind_to, AltAuthRequestHandler).serve_forever()