mirror of
https://github.com/GravitLauncher/Launcher
synced 2024-12-22 16:41:46 +03:00
Авторизация сервера
This commit is contained in:
parent
b77e22ce9f
commit
e77a848843
6 changed files with 205 additions and 5 deletions
|
@ -5,6 +5,7 @@
|
|||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import ru.gravit.launcher.LauncherAPI;
|
||||
import ru.gravit.launchserver.response.auth.AuthServerResponse;
|
||||
import ru.gravit.utils.helper.LogHelper;
|
||||
import ru.gravit.launcher.request.RequestException;
|
||||
import ru.gravit.launcher.request.RequestType;
|
||||
|
@ -53,6 +54,7 @@ public static void registerResponses() {
|
|||
registerResponse(RequestType.UPDATE_LIST.getNumber(), UpdateListResponse::new);
|
||||
registerResponse(RequestType.UPDATE.getNumber(), UpdateResponse::new);
|
||||
registerResponse(RequestType.PROFILES.getNumber(), ProfilesResponse::new);
|
||||
registerResponse(RequestType.SERVERAUTH.getNumber(), AuthServerResponse::new);
|
||||
}
|
||||
|
||||
@LauncherAPI
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
import javax.crypto.BadPaddingException;
|
||||
import javax.crypto.IllegalBlockSizeException;
|
||||
|
||||
import ru.gravit.launchserver.socket.Client;
|
||||
import ru.gravit.utils.helper.IOHelper;
|
||||
import ru.gravit.utils.helper.LogHelper;
|
||||
import ru.gravit.utils.helper.SecurityHelper;
|
||||
|
@ -60,6 +61,8 @@ public void reply() throws Exception {
|
|||
debug("Login: '%s', Password: '%s'", login, echo(password.length()));
|
||||
AuthProviderResult result;
|
||||
AuthProvider provider = server.config.authProvider[auth_id];
|
||||
Client clientData = server.sessionManager.getClient(session);
|
||||
clientData.type = Client.Type.USER;
|
||||
try {
|
||||
if (server.limiter.isLimit(ip)) {
|
||||
AuthProvider.authError(server.config.authRejectString);
|
||||
|
@ -71,10 +74,17 @@ public void reply() throws Exception {
|
|||
return;
|
||||
}
|
||||
Collection<SignedObjectHolder<ClientProfile>> profiles = server.getProfiles();
|
||||
for (SignedObjectHolder<ClientProfile> p : profiles)
|
||||
if (p.object.getTitle().equals(client))
|
||||
if (!p.object.isWhitelistContains(login))
|
||||
for (SignedObjectHolder<ClientProfile> p : profiles) {
|
||||
if (p.object.getTitle().equals(client)) {
|
||||
if (!p.object.isWhitelistContains(login)) {
|
||||
throw new AuthException(server.config.whitelistRejectString);
|
||||
}
|
||||
clientData.profile = p.object;
|
||||
}
|
||||
}
|
||||
if(clientData.profile == null) {
|
||||
throw new AuthException("You profile not found");
|
||||
}
|
||||
server.config.hwidHandler.check(HWID.gen(hwid_hdd, hwid_bios, hwid_cpu), result.username);
|
||||
} catch (AuthException | HWIDException e) {
|
||||
requestError(e.getMessage());
|
||||
|
@ -85,6 +95,7 @@ public void reply() throws Exception {
|
|||
return;
|
||||
}
|
||||
debug("Auth: '%s' -> '%s', '%s'", login, result.username, result.accessToken);
|
||||
clientData.isAuth = true;
|
||||
// Authenticate on server (and get UUID)
|
||||
UUID uuid;
|
||||
try {
|
||||
|
|
|
@ -0,0 +1,95 @@
|
|||
package ru.gravit.launchserver.response.auth;
|
||||
|
||||
import ru.gravit.launcher.profiles.ClientProfile;
|
||||
import ru.gravit.launcher.serialize.HInput;
|
||||
import ru.gravit.launcher.serialize.HOutput;
|
||||
import ru.gravit.launcher.serialize.SerializeLimits;
|
||||
import ru.gravit.launcher.serialize.signed.SignedObjectHolder;
|
||||
import ru.gravit.launchserver.LaunchServer;
|
||||
import ru.gravit.launchserver.auth.AuthException;
|
||||
import ru.gravit.launchserver.auth.hwid.HWID;
|
||||
import ru.gravit.launchserver.auth.hwid.HWIDException;
|
||||
import ru.gravit.launchserver.auth.provider.AuthProvider;
|
||||
import ru.gravit.launchserver.auth.provider.AuthProviderResult;
|
||||
import ru.gravit.launchserver.response.Response;
|
||||
import ru.gravit.launchserver.response.profile.ProfileByUUIDResponse;
|
||||
import ru.gravit.launchserver.socket.Client;
|
||||
import ru.gravit.utils.helper.IOHelper;
|
||||
import ru.gravit.utils.helper.LogHelper;
|
||||
import ru.gravit.utils.helper.SecurityHelper;
|
||||
import ru.gravit.utils.helper.VerifyHelper;
|
||||
|
||||
import javax.crypto.BadPaddingException;
|
||||
import javax.crypto.IllegalBlockSizeException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.UUID;
|
||||
|
||||
public final class AuthServerResponse extends Response {
|
||||
private static String echo(int length) {
|
||||
char[] chars = new char[length];
|
||||
Arrays.fill(chars, '*');
|
||||
return new String(chars);
|
||||
}
|
||||
|
||||
public AuthServerResponse(LaunchServer server, long session, HInput input, HOutput output, String ip) {
|
||||
super(server, session, input, output, ip);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reply() throws Exception {
|
||||
String login = input.readString(SerializeLimits.MAX_LOGIN);
|
||||
String client = input.readString(SerializeLimits.MAX_CLIENT);
|
||||
int auth_id = input.readInt();
|
||||
if(auth_id + 1 > server.config.authProvider.length || auth_id < 0) auth_id = 0;
|
||||
byte[] encryptedPassword = input.readByteArray(SecurityHelper.CRYPTO_MAX_LENGTH);
|
||||
// Decrypt password
|
||||
String password;
|
||||
try {
|
||||
password = IOHelper.decode(SecurityHelper.newRSADecryptCipher(server.privateKey).
|
||||
doFinal(encryptedPassword));
|
||||
} catch (IllegalBlockSizeException | BadPaddingException ignored) {
|
||||
requestError("ServerPassword decryption error");
|
||||
return;
|
||||
}
|
||||
if(client.length() == 0) requestError("Request error. You is cheater?");
|
||||
// Authenticate
|
||||
debug("ServerLogin: '%s', Password: '%s'", login, echo(password.length()));
|
||||
AuthProviderResult result;
|
||||
AuthProvider provider = server.config.authProvider[auth_id];
|
||||
Client clientData = server.sessionManager.getClient(session);
|
||||
try {
|
||||
if (server.limiter.isLimit(ip)) {
|
||||
AuthProvider.authError(server.config.authRejectString);
|
||||
return;
|
||||
}
|
||||
result = provider.auth(login, password, ip);
|
||||
if (!VerifyHelper.isValidUsername(result.username)) {
|
||||
AuthProvider.authError(String.format("Illegal result: '%s'", result.username));
|
||||
return;
|
||||
}
|
||||
Collection<SignedObjectHolder<ClientProfile>> profiles = server.getProfiles();
|
||||
for (SignedObjectHolder<ClientProfile> p : profiles) {
|
||||
if (p.object.getTitle().equals(client)) {
|
||||
if (!p.object.isWhitelistContains(login)) {
|
||||
throw new AuthException(server.config.whitelistRejectString);
|
||||
}
|
||||
clientData.profile = p.object;
|
||||
}
|
||||
}
|
||||
if(clientData.profile == null) {
|
||||
throw new AuthException("You profile not found");
|
||||
}
|
||||
clientData.type = Client.Type.SERVER;
|
||||
} catch (AuthException | HWIDException e) {
|
||||
requestError(e.getMessage());
|
||||
return;
|
||||
} catch (Exception e) {
|
||||
LogHelper.error(e);
|
||||
requestError("Internal auth provider error");
|
||||
return;
|
||||
}
|
||||
debug("ServerAuth: '%s' -> '%s', '%s'", login, result.username, result.accessToken);
|
||||
clientData.isAuth = true;
|
||||
}
|
||||
}
|
|
@ -1,16 +1,28 @@
|
|||
package ru.gravit.launchserver.socket;
|
||||
|
||||
import ru.gravit.launcher.profiles.ClientProfile;
|
||||
|
||||
public class Client {
|
||||
public long session;
|
||||
|
||||
public long timestamp;
|
||||
public Type type;
|
||||
public ClientProfile profile;
|
||||
public boolean isAuth;
|
||||
|
||||
public Client(long session) {
|
||||
this.session = session;
|
||||
timestamp = System.currentTimeMillis();
|
||||
type = Type.USER;
|
||||
isAuth = false;
|
||||
}
|
||||
|
||||
//Данные ваторизации
|
||||
public void up() {
|
||||
timestamp = System.currentTimeMillis();
|
||||
}
|
||||
public enum Type
|
||||
{
|
||||
SERVER,
|
||||
USER
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
package ru.gravit.launcher.request.auth;
|
||||
|
||||
import ru.gravit.launcher.Launcher;
|
||||
import ru.gravit.launcher.LauncherAPI;
|
||||
import ru.gravit.launcher.LauncherConfig;
|
||||
import ru.gravit.launcher.profiles.PlayerProfile;
|
||||
import ru.gravit.launcher.request.Request;
|
||||
import ru.gravit.launcher.request.RequestType;
|
||||
import ru.gravit.launcher.serialize.HInput;
|
||||
import ru.gravit.launcher.serialize.HOutput;
|
||||
import ru.gravit.launcher.serialize.SerializeLimits;
|
||||
import ru.gravit.utils.helper.JVMHelper;
|
||||
import ru.gravit.utils.helper.SecurityHelper;
|
||||
import ru.gravit.utils.helper.VerifyHelper;
|
||||
import ru.zaxar163.GuardBind;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public final class ServerAuthRequest extends Request<ServerAuthRequest.Result> {
|
||||
public static final class Result {
|
||||
@LauncherAPI
|
||||
public final PlayerProfile pp;
|
||||
@LauncherAPI
|
||||
public final String accessToken;
|
||||
|
||||
private Result(PlayerProfile pp, String accessToken) {
|
||||
this.pp = pp;
|
||||
this.accessToken = accessToken;
|
||||
}
|
||||
}
|
||||
|
||||
private final String login;
|
||||
|
||||
private final byte[] encryptedPassword;
|
||||
private final int auth_id;
|
||||
|
||||
@LauncherAPI
|
||||
public ServerAuthRequest(LauncherConfig config, String login, byte[] encryptedPassword) {
|
||||
super(config);
|
||||
this.login = VerifyHelper.verify(login, VerifyHelper.NOT_EMPTY, "Login can't be empty");
|
||||
this.encryptedPassword = encryptedPassword.clone();
|
||||
auth_id = 0;
|
||||
}
|
||||
@LauncherAPI
|
||||
public ServerAuthRequest(LauncherConfig config, String login, byte[] encryptedPassword, int auth_id) {
|
||||
super(config);
|
||||
this.login = VerifyHelper.verify(login, VerifyHelper.NOT_EMPTY, "Login can't be empty");
|
||||
this.encryptedPassword = encryptedPassword.clone();
|
||||
this.auth_id = auth_id;
|
||||
}
|
||||
|
||||
@LauncherAPI
|
||||
public ServerAuthRequest(String login, byte[] encryptedPassword) {
|
||||
this(null, login, encryptedPassword);
|
||||
}
|
||||
@LauncherAPI
|
||||
public ServerAuthRequest(String login, byte[] encryptedPassword, int auth_id) {
|
||||
this(null, login, encryptedPassword,auth_id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getType() {
|
||||
return RequestType.SERVERAUTH.getNumber();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Result requestDo(HInput input, HOutput output) throws IOException {
|
||||
output.writeString(login, SerializeLimits.MAX_LOGIN);
|
||||
output.writeString(Launcher.profile.getTitle(), SerializeLimits.MAX_CLIENT);
|
||||
output.writeInt(auth_id);
|
||||
output.writeByteArray(encryptedPassword, SecurityHelper.CRYPTO_MAX_LENGTH);
|
||||
output.flush();
|
||||
|
||||
// Read UUID and access token
|
||||
readError(input);
|
||||
PlayerProfile pp = new PlayerProfile(input);
|
||||
String accessToken = input.readASCII(-SecurityHelper.TOKEN_STRING_LENGTH);
|
||||
return new Result(pp, accessToken);
|
||||
}
|
||||
}
|
|
@ -11,7 +11,7 @@ public enum RequestType implements EnumSerializer.Itf {
|
|||
LAUNCHER(1), UPDATE(2), UPDATE_LIST(3), // Update requests
|
||||
AUTH(4), JOIN_SERVER(5), CHECK_SERVER(6), // Auth requests
|
||||
PROFILE_BY_USERNAME(7), PROFILE_BY_UUID(8), BATCH_PROFILE_BY_USERNAME(9), // Profile requests
|
||||
PROFILES(10),
|
||||
PROFILES(10),SERVERAUTH(11),
|
||||
CUSTOM(255); // Custom requests
|
||||
private static final EnumSerializer<RequestType> SERIALIZER = new EnumSerializer<>(RequestType.class);
|
||||
|
||||
|
|
Loading…
Reference in a new issue