diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/LaunchServer.java b/LaunchServer/src/main/java/pro/gravit/launchserver/LaunchServer.java index 9c09cb40..44c716a7 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/LaunchServer.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/LaunchServer.java @@ -266,7 +266,7 @@ public void invoke(String... args) throws Exception { } pair.core.close(); pair.core = new RejectAuthCoreProvider(); - pair.core.init(instance); + pair.core.init(instance, pair); } }; commands.put("resetauth", resetauth); diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/AuthProviderPair.java b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/AuthProviderPair.java index 72c198f2..5234718b 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/AuthProviderPair.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/AuthProviderPair.java @@ -74,7 +74,7 @@ public T isSupport(Class clazz) { public void init(LaunchServer srv, String name) { this.name = name; if (links != null) link(srv); - core.init(srv); + core.init(srv, this); features = new HashSet<>(); getFeatures(core.getClass(), features); if(mixes != null) { diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/core/AbstractSQLCoreProvider.java b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/core/AbstractSQLCoreProvider.java index c469990a..1ebc1939 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/core/AbstractSQLCoreProvider.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/core/AbstractSQLCoreProvider.java @@ -9,6 +9,7 @@ import pro.gravit.launcher.base.request.auth.password.AuthPlainPassword; import pro.gravit.launchserver.LaunchServer; import pro.gravit.launchserver.auth.AuthException; +import pro.gravit.launchserver.auth.AuthProviderPair; import pro.gravit.launchserver.auth.MySQLSourceConfig; import pro.gravit.launchserver.auth.SQLSourceConfig; import pro.gravit.launchserver.auth.password.PasswordVerifier; @@ -66,7 +67,6 @@ public abstract class AbstractSQLCoreProvider extends AuthCoreProvider { public transient String updateAuthSQL; public transient String updateServerIDSQL; - public transient LaunchServer server; public abstract SQLSourceConfig getSQLConfig(); @@ -183,8 +183,8 @@ public boolean joinServer(Client client, String username, UUID uuid, String acce } @Override - public void init(LaunchServer server) { - this.server = server; + public void init(LaunchServer server, AuthProviderPair pair) { + super.init(server, pair); if (getSQLConfig() == null) logger.error("SQLHolder cannot be null"); if (uuidColumn == null) logger.error("uuidColumn cannot be null"); if (usernameColumn == null) logger.error("usernameColumn cannot be null"); diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/core/AuthCoreProvider.java b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/core/AuthCoreProvider.java index 50042661..bdf060ee 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/core/AuthCoreProvider.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/core/AuthCoreProvider.java @@ -4,7 +4,10 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import pro.gravit.launcher.base.Launcher; +import pro.gravit.launcher.base.events.RequestEvent; +import pro.gravit.launcher.base.events.request.AuthRequestEvent; import pro.gravit.launcher.base.events.request.GetAvailabilityAuthRequestEvent; +import pro.gravit.launcher.base.profiles.PlayerProfile; import pro.gravit.launcher.base.request.auth.AuthRequest; import pro.gravit.launcher.base.request.auth.details.AuthPasswordDetails; import pro.gravit.launcher.base.request.auth.password.AuthPlainPassword; @@ -12,16 +15,19 @@ import pro.gravit.launchserver.LaunchServer; import pro.gravit.launchserver.Reconfigurable; import pro.gravit.launchserver.auth.AuthException; +import pro.gravit.launchserver.auth.AuthProviderPair; import pro.gravit.launchserver.auth.core.interfaces.UserHardware; import pro.gravit.launchserver.auth.core.interfaces.provider.AuthSupportGetAllUsers; import pro.gravit.launchserver.auth.core.interfaces.provider.AuthSupportHardware; import pro.gravit.launchserver.auth.core.interfaces.provider.AuthSupportRegistration; +import pro.gravit.launchserver.auth.core.interfaces.provider.AuthSupportSudo; import pro.gravit.launchserver.manangers.AuthManager; import pro.gravit.launchserver.socket.Client; import pro.gravit.launchserver.socket.response.auth.AuthResponse; import pro.gravit.utils.ProviderMap; import pro.gravit.utils.command.Command; import pro.gravit.utils.command.SubCommand; +import pro.gravit.utils.helper.VerifyHelper; import java.io.IOException; import java.lang.reflect.Type; @@ -29,6 +35,7 @@ import java.util.List; import java.util.Map; import java.util.UUID; +import java.util.concurrent.atomic.AtomicBoolean; /* All-In-One provider @@ -37,6 +44,8 @@ public abstract class AuthCoreProvider implements AutoCloseable, Reconfigurable public static final ProviderMap providers = new ProviderMap<>("AuthCoreProvider"); private static final Logger logger = LogManager.getLogger(); private static boolean registredProviders = false; + protected transient LaunchServer server; + protected transient AuthProviderPair pair; public static void registerProviders() { if (!registredProviders) { @@ -71,7 +80,10 @@ public AuthManager.AuthReport authorize(User user, AuthResponse.AuthContext cont return authorize(user.getUsername(), context, password, minecraftAccess); } - public abstract void init(LaunchServer server); + public void init(LaunchServer server, AuthProviderPair pair) { + this.server = server; + this.pair = pair; + } public List getDetails(Client client) { return List.of(new AuthPasswordDetails()); @@ -260,6 +272,72 @@ public void invoke(String... args) throws Exception { }); } } + { + var instance = isSupport(AuthSupportSudo.class); + if(instance != null) { + map.put("sudo", new SubCommand("[connectUUID] [username/uuid] [isShadow] (CLIENT/API)", "Authorize connectUUID as another user without password") { + @Override + public void invoke(String... args) throws Exception { + verifyArgs(args, 3); + UUID connectUUID = UUID.fromString(args[0]); + String login = args[1]; + boolean isShadow = Boolean.parseBoolean(args[2]); + AuthResponse.ConnectTypes type; + if(args.length > 3) { + type = AuthResponse.ConnectTypes.valueOf(args[3]); + } else { + type = AuthResponse.ConnectTypes.CLIENT; + } + User user; + if(login.length() == 36) { + UUID uuid = UUID.fromString(login); + user = getUserByUUID(uuid); + } else { + user = getUserByUsername(login); + } + if(user == null) { + logger.error("User {} not found", login); + return; + } + AtomicBoolean founded = new AtomicBoolean(); + server.nettyServerSocketHandler.nettyServer.service.forEachActiveChannels((ch, fh) -> { + var client = fh.getClient(); + if(client == null || !connectUUID.equals(fh.getConnectUUID())) { + return; + } + logger.info("Found connectUUID {} with IP {}", fh.getConnectUUID(), fh.context == null ? "null" : fh.context.ip); + var lock = server.config.netty.performance.disableThreadSafeClientObject ? null : client.writeLock(); + if(lock != null) { + lock.lock(); + } + try { + var report = instance.sudo(user, isShadow); + User user1 = report.session().getUser(); + server.authManager.internalAuth(client, type, pair, user1.getUsername(), user1.getUUID(), user1.getPermissions(), true); + client.sessionObject = report.session(); + client.coreObject = report.session().getUser(); + PlayerProfile playerProfile = server.authManager.getPlayerProfile(client); + AuthRequestEvent request = new AuthRequestEvent(user1.getPermissions(), playerProfile, + report.minecraftAccessToken(), null, null, + new AuthRequestEvent.OAuthRequestEvent(report.oauthAccessToken(), report.oauthRefreshToken(), report.oauthExpire())); + request.requestUUID = RequestEvent.eventUUID; + server.nettyServerSocketHandler.nettyServer.service.sendObject(ch, request); + } catch (Throwable e) { + logger.error("Sudo error", e); + } finally { + if(lock != null) { + lock.unlock(); + } + founded.set(true); + } + }); + if(!founded.get()) { + logger.error("ConnectUUID {} not found", connectUUID); + } + } + }); + } + } return map; } diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/core/MemoryAuthCoreProvider.java b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/core/MemoryAuthCoreProvider.java index f8d8cc93..280ae084 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/core/MemoryAuthCoreProvider.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/core/MemoryAuthCoreProvider.java @@ -6,6 +6,7 @@ import pro.gravit.launcher.base.request.auth.details.AuthLoginOnlyDetails; import pro.gravit.launchserver.LaunchServer; import pro.gravit.launchserver.auth.AuthException; +import pro.gravit.launchserver.auth.core.interfaces.provider.AuthSupportSudo; import pro.gravit.launchserver.manangers.AuthManager; import pro.gravit.launchserver.socket.Client; import pro.gravit.launchserver.socket.response.auth.AuthResponse; @@ -18,7 +19,7 @@ import java.util.Objects; import java.util.UUID; -public class MemoryAuthCoreProvider extends AuthCoreProvider { +public class MemoryAuthCoreProvider extends AuthCoreProvider implements AuthSupportSudo { private transient final List memory = new ArrayList<>(16); @Override @@ -114,13 +115,13 @@ public boolean joinServer(Client client, String username, UUID uuid, String acce } @Override - public void init(LaunchServer server) { + public void close() { } @Override - public void close() { - + public AuthManager.AuthReport sudo(User user, boolean shadow) throws IOException { + return authorize(user.getUsername(), null, null, true); } public static class MemoryUser implements User { diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/core/MergeAuthCoreProvider.java b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/core/MergeAuthCoreProvider.java index a0d83fd7..e69eb086 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/core/MergeAuthCoreProvider.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/core/MergeAuthCoreProvider.java @@ -5,6 +5,7 @@ import pro.gravit.launcher.base.request.auth.AuthRequest; import pro.gravit.launchserver.LaunchServer; import pro.gravit.launchserver.auth.AuthException; +import pro.gravit.launchserver.auth.AuthProviderPair; import pro.gravit.launchserver.manangers.AuthManager; import pro.gravit.launchserver.socket.Client; import pro.gravit.launchserver.socket.response.auth.AuthResponse; @@ -72,7 +73,7 @@ public boolean joinServer(Client client, String username, UUID uuid, String acce } @Override - public void init(LaunchServer server) { + public void init(LaunchServer server, AuthProviderPair pair1) { for(var e : list) { var pair = server.config.auth.get(e); if(pair != null) { diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/core/MySQLCoreProvider.java b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/core/MySQLCoreProvider.java index 13781df9..84c0ce3c 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/core/MySQLCoreProvider.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/core/MySQLCoreProvider.java @@ -3,6 +3,7 @@ import pro.gravit.launcher.base.ClientPermissions; import pro.gravit.launcher.base.request.secure.HardwareReportRequest; import pro.gravit.launchserver.LaunchServer; +import pro.gravit.launchserver.auth.AuthProviderPair; import pro.gravit.launchserver.auth.MySQLSourceConfig; import pro.gravit.launchserver.auth.SQLSourceConfig; import pro.gravit.launchserver.auth.core.interfaces.UserHardware; @@ -41,8 +42,8 @@ public SQLSourceConfig getSQLConfig() { } @Override - public void init(LaunchServer server) { - super.init(server); + public void init(LaunchServer server, AuthProviderPair pair) { + super.init(server, pair); String userInfoCols = makeUserCols(); String hardwareInfoCols = "id, hwDiskId, baseboardSerialNumber, displayId, bitness, totalMemory, logicalProcessors, physicalProcessors, processorMaxFreq, battery, id, graphicCard, banned, publicKey"; if (sqlFindHardwareByPublicKey == null) diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/core/RejectAuthCoreProvider.java b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/core/RejectAuthCoreProvider.java index 38f3864a..509abef5 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/core/RejectAuthCoreProvider.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/core/RejectAuthCoreProvider.java @@ -41,11 +41,6 @@ public AuthManager.AuthReport authorize(String login, AuthResponse.AuthContext c throw new AuthException("Please configure AuthCoreProvider"); } - @Override - public void init(LaunchServer server) { - - } - @Override public User checkServer(Client client, String username, String serverID) throws IOException { return null; diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/core/interfaces/provider/AuthSupportSudo.java b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/core/interfaces/provider/AuthSupportSudo.java new file mode 100644 index 00000000..377bbe7f --- /dev/null +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/core/interfaces/provider/AuthSupportSudo.java @@ -0,0 +1,10 @@ +package pro.gravit.launchserver.auth.core.interfaces.provider; + +import pro.gravit.launchserver.auth.core.User; +import pro.gravit.launchserver.manangers.AuthManager; + +import java.io.IOException; + +public interface AuthSupportSudo { + AuthManager.AuthReport sudo(User user, boolean shadow) throws IOException; +} diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/Client.java b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/Client.java index 41b99f05..7ef57961 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/Client.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/Client.java @@ -10,6 +10,7 @@ import java.util.HashMap; import java.util.Map; import java.util.UUID; +import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; @@ -86,6 +87,14 @@ public pro.gravit.launchserver.auth.core.User getUser() { return coreObject; } + public Lock readLock() { + return lock.readLock(); + } + + public Lock writeLock() { + return lock.writeLock(); + } + public static class TrustLevel { public byte[] verifySecureKey; public boolean keyChecked;