Merge branch 'master' of github.com:GravitLauncher/Launcher

This commit is contained in:
Gravit 2018-10-09 18:54:26 +07:00
commit 16f12d54f9
No known key found for this signature in database
GPG key ID: 061981E1E85D3216
6 changed files with 81 additions and 36 deletions

View file

@ -72,6 +72,12 @@ public void setProjectName(String name) {
body.append("\";"); body.append("\";");
} }
public void setSecretKey(String key) {
body.append("this.secretKeyClient = \"");
body.append(key);
body.append("\";");
}
public void setPort(int port) { public void setPort(int port) {
body.append("this.port = "); body.append("this.port = ");
body.append(port); body.append(port);

View file

@ -165,6 +165,7 @@ private void stdBuild() throws IOException {
jaConfigurator.setAddress(server.config.getAddress()); jaConfigurator.setAddress(server.config.getAddress());
jaConfigurator.setPort(server.config.port); jaConfigurator.setPort(server.config.port);
jaConfigurator.setProjectName(server.config.projectName); jaConfigurator.setProjectName(server.config.projectName);
jaConfigurator.setSecretKey(SecurityHelper.randomStringToken());
server.buildHookManager.registerAllClientModuleClass(jaConfigurator); server.buildHookManager.registerAllClientModuleClass(jaConfigurator);
try (ZipInputStream input = new ZipInputStream( try (ZipInputStream input = new ZipInputStream(
IOHelper.newInput(IOHelper.getResourceURL("Launcher.jar")))) { IOHelper.newInput(IOHelper.getResourceURL("Launcher.jar")))) {

View file

@ -109,7 +109,7 @@ public Params(byte[] launcherSign, Path assetDir, Path clientDir, PlayerProfile
} }
@LauncherAPI @LauncherAPI
public Params(HInput input) throws IOException { public Params(HInput input) throws Exception {
launcherSign = input.readByteArray(-SecurityHelper.RSA_KEY_LENGTH); launcherSign = input.readByteArray(-SecurityHelper.RSA_KEY_LENGTH);
// Client paths // Client paths
assetDir = IOHelper.toPath(input.readString(0)); assetDir = IOHelper.toPath(input.readString(0));
@ -122,7 +122,9 @@ public Params(HInput input) throws IOException {
} }
// Client params // Client params
pp = new PlayerProfile(input); pp = new PlayerProfile(input);
accessToken = SecurityHelper.verifyToken(input.readASCII(-SecurityHelper.TOKEN_STRING_LENGTH)); byte[] encryptedAccessToken = input.readByteArray(SecurityHelper.CRYPTO_MAX_LENGTH);
String accessTokenD = new String(SecurityHelper.decrypt(Launcher.getConfig().secretKeyClient.getBytes(),encryptedAccessToken));
accessToken = SecurityHelper.verifyToken(accessTokenD);
autoEnter = input.readBoolean(); autoEnter = input.readBoolean();
fullScreen = input.readBoolean(); fullScreen = input.readBoolean();
ram = input.readVarInt(); ram = input.readVarInt();
@ -143,7 +145,11 @@ public void write(HOutput output) throws IOException {
} }
// Client params // Client params
pp.write(output); pp.write(output);
output.writeASCII(accessToken, -SecurityHelper.TOKEN_STRING_LENGTH); try {
output.writeByteArray(SecurityHelper.encrypt(Launcher.getConfig().secretKeyClient.getBytes(),accessToken.getBytes()), SecurityHelper.CRYPTO_MAX_LENGTH);
} catch (Exception e) {
LogHelper.error(e);
}
output.writeBoolean(autoEnter); output.writeBoolean(autoEnter);
output.writeBoolean(fullScreen); output.writeBoolean(fullScreen);
output.writeVarInt(ram); output.writeVarInt(ram);
@ -287,11 +293,11 @@ public static Process launch(
SignedObjectHolder<ClientProfile> profile, Params params, boolean pipeOutput) throws Throwable { SignedObjectHolder<ClientProfile> profile, Params params, boolean pipeOutput) throws Throwable {
// Write params file (instead of CLI; Mustdie32 API can't handle command line > 32767 chars) // Write params file (instead of CLI; Mustdie32 API can't handle command line > 32767 chars)
LogHelper.debug("Writing ClientLauncher params"); LogHelper.debug("Writing ClientLauncher params");
Path paramsFile = Files.createTempFile("ClientLauncherParams", ".bin");
CommonHelper.newThread("Client params writter", false, () -> CommonHelper.newThread("Client params writter", false, () ->
{ {
try { try {
try (ServerSocket socket = new ServerSocket()) { try (ServerSocket socket = new ServerSocket()) {
socket.setReuseAddress(true); socket.setReuseAddress(true);
socket.bind(new InetSocketAddress(SOCKET_HOST, SOCKET_PORT)); socket.bind(new InetSocketAddress(SOCKET_HOST, SOCKET_PORT));
Socket client = socket.accept(); Socket client = socket.accept();
@ -301,17 +307,11 @@ public static Process launch(
assetHDir.write(output); assetHDir.write(output);
clientHDir.write(output); clientHDir.write(output);
} }
} }
} catch (Exception e) { } catch (IOException e) {
LogHelper.error(e); LogHelper.error(e);
try (HOutput output = new HOutput(IOHelper.newOutput(paramsFile))) {
params.write(output);
profile.write(output);
assetHDir.write(output);
clientHDir.write(output);
} catch (IOException e1) {
LogHelper.error(e1);
}
} }
}).start(); }).start();
// Resolve java bin and set permissions // Resolve java bin and set permissions
@ -356,7 +356,6 @@ public static Process launch(
//if(wrapper) //if(wrapper)
//Collections.addAll(args, "-Djava.class.path=".concat(classPathString.toString())); // Add Class Path //Collections.addAll(args, "-Djava.class.path=".concat(classPathString.toString())); // Add Class Path
Collections.addAll(args, ClientLauncher.class.getName()); Collections.addAll(args, ClientLauncher.class.getName());
Collections.addAll(args, paramsFile.toString());
// Print commandline debug message // Print commandline debug message
LogHelper.debug("Commandline: " + args); LogHelper.debug("Commandline: " + args);
@ -391,9 +390,6 @@ public static void main(String... args) throws Throwable {
checkJVMBitsAndVersion(); checkJVMBitsAndVersion();
JVMHelper.verifySystemProperties(ClientLauncher.class, true); JVMHelper.verifySystemProperties(ClientLauncher.class, true);
LogHelper.printVersion("Client Launcher"); LogHelper.printVersion("Client Launcher");
// Resolve params file
VerifyHelper.verifyInt(args.length, l -> l >= 1, "Missing args: <paramsFile>");
Path paramsFile = IOHelper.toPath(args[0]);
// Read and delete params file // Read and delete params file
LogHelper.debug("Reading ClientLauncher params"); LogHelper.debug("Reading ClientLauncher params");
Params params; Params params;
@ -414,16 +410,8 @@ public static void main(String... args) throws Throwable {
} }
} catch (IOException ex) { } catch (IOException ex) {
LogHelper.error(ex); LogHelper.error(ex);
try (HInput input = new HInput(IOHelper.newInput(paramsFile))) { System.exit(-98);
params = new Params(input); return;
profile = new SignedObjectHolder<>(input, publicKey, ClientProfile.RO_ADAPTER);
// Read hdirs
assetHDir = new SignedObjectHolder<>(input, publicKey, HashedDir::new);
clientHDir = new SignedObjectHolder<>(input, publicKey, HashedDir::new);
} finally {
Files.delete(paramsFile);
}
} }
Launcher.profile = profile.object; Launcher.profile = profile.object;
Launcher.modulesManager.initModules(); Launcher.modulesManager.initModules();

View file

@ -5,6 +5,7 @@ public class AutogenConfig {
public String address; public String address;
public int port; public int port;
private boolean isInitModules; private boolean isInitModules;
public String secretKeyClient;
AutogenConfig() { AutogenConfig() {

View file

@ -34,6 +34,7 @@ public static AutogenConfig getAutogenConfig() {
public final InetSocketAddress address; public final InetSocketAddress address;
@LauncherAPI @LauncherAPI
public final String projectname; public final String projectname;
public String secretKeyClient;
@LauncherAPI @LauncherAPI
public final RSAPublicKey publicKey; public final RSAPublicKey publicKey;
@ -47,6 +48,7 @@ public LauncherConfig(HInput input) throws IOException, InvalidKeySpecException
ADDRESS_OVERRIDE == null ? localAddress : ADDRESS_OVERRIDE, config.port); ADDRESS_OVERRIDE == null ? localAddress : ADDRESS_OVERRIDE, config.port);
publicKey = SecurityHelper.toPublicRSAKey(input.readByteArray(SecurityHelper.CRYPTO_MAX_LENGTH)); publicKey = SecurityHelper.toPublicRSAKey(input.readByteArray(SecurityHelper.CRYPTO_MAX_LENGTH));
projectname = config.projectname; projectname = config.projectname;
secretKeyClient = config.secretKeyClient;
// Read signed runtime // Read signed runtime
int count = input.readLength(0); int count = input.readLength(0);
Map<String, byte[]> localResources = new HashMap<>(count); Map<String, byte[]> localResources = new HashMap<>(count);

View file

@ -1,5 +1,6 @@
package ru.gravit.utils.helper; package ru.gravit.utils.helper;
import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.net.URL; import java.net.URL;
@ -25,7 +26,10 @@
import java.util.Random; import java.util.Random;
import javax.crypto.Cipher; import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException; import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import ru.gravit.launcher.LauncherAPI; import ru.gravit.launcher.LauncherAPI;
@ -97,6 +101,7 @@ public byte[] verify(byte[] digest) {
// Certificate constants // Certificate constants
@LauncherAPI @LauncherAPI
public static final String HEX = "0123456789abcdef"; public static final String HEX = "0123456789abcdef";
public static final byte[] NUMBERS = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
@LauncherAPI @LauncherAPI
public static final SecureRandom secureRandom = new SecureRandom(); public static final SecureRandom secureRandom = new SecureRandom();
@ -463,4 +468,46 @@ public static String verifyToken(String token) {
private SecurityHelper() { private SecurityHelper() {
} }
//AES
public static byte[] encrypt(String seed, byte[] cleartext) throws Exception {
byte[] rawKey = getRawKey(seed.getBytes());
byte[] result = encrypt(rawKey, cleartext);
return result;
}
public static byte[] encrypt(String seed, String cleartext) throws Exception {
return encrypt(seed, cleartext.getBytes());
}
private static byte[] getRawKey(byte[] seed) throws Exception {
KeyGenerator kGen = KeyGenerator.getInstance("AES");
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
sr.setSeed(seed);
kGen.init(128, sr); // 192 and 256 bits may not be available
SecretKey sKey = kGen.generateKey();
return sKey.getEncoded();
}
public static byte[] encrypt(byte[] raw, byte[] clear) throws Exception {
SecretKeySpec sKeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, sKeySpec);
return cipher.doFinal(clear);
}
public static byte[] decrypt(byte[] raw, byte[] encrypted) throws Exception {
SecretKeySpec sKeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, sKeySpec);
return cipher.doFinal(encrypted);
}
public static byte[] HexToByte(String hexString) {
int len = hexString.length() / 2;
byte[] result = new byte[len];
for (int i = 0; i < len; i++) {
result[i] = Integer.valueOf(hexString.substring(2 * i, 2 * i + 2), 16).byteValue();
}
return result;
}
} }