Newer
Older
KeeperJerry_Launcher / LaunchServer / source / response / auth / AuthResponse.java
package launchserver.response.auth;

import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import java.util.Arrays;
import java.util.UUID;

import launcher.helper.IOHelper;
import launcher.helper.LogHelper;
import launcher.helper.SecurityHelper;
import launcher.helper.VerifyHelper;
import launcher.request.RequestException;
import launcher.serialize.HInput;
import launcher.serialize.HOutput;
import launchserver.LaunchServer;
import launchserver.auth.AuthException;
import launchserver.response.Response;
import launchserver.response.profile.ProfileByUUIDResponse;

public final class AuthResponse extends Response {
	public AuthResponse(LaunchServer server, HInput input, HOutput output) {
		super(server, input, output);
	}

	@Override
	public void reply() throws Exception {
		String login = input.readString(255);
		byte[] encryptedPassword = input.readByteArray(IOHelper.BUFFER_SIZE);

		// Decrypt password
		String password;
		try {
			password = IOHelper.decode(SecurityHelper.newRSADecryptCipher(server.getPrivateKey()).doFinal(encryptedPassword));
		} catch (IllegalBlockSizeException | BadPaddingException ignored) {
			throw new RequestException("Password decryption error");
		}

		// Authenticate
		LaunchServer.Config config = server.getConfig();
		LogHelper.subDebug("Login: '%s', password: '%s'", login, echo(password.length()));
		String username;
		try {
			username = VerifyHelper.verifyUsername(config.authProvider.auth(login, password));
		} catch (AuthException e) {
			throw new RequestException(e);
		} catch (Exception e) {
			LogHelper.error(e);
			throw new RequestException("Internal auth error", e);
		}
		LogHelper.subDebug("Auth: '%s' -> '%s'", login, username);

		// Authenticate on server (and get UUID)
		String accessToken = SecurityHelper.randomStringToken();
		UUID uuid = config.authHandler.auth(username, accessToken);
		if (uuid == null) {
			throw new RequestException("Can't assign UUID");
		}
		writeNoError(output);

		// Write profile and UUID
		ProfileByUUIDResponse.getProfile(server, uuid, username).write(output);
		output.writeASCII(accessToken, -SecurityHelper.TOKEN_STRING_LENGTH);
	}

	private static String echo(int length) {
		char[] chars = new char[length];
		Arrays.fill(chars, '*');
		return new String(chars);
	}
}