Initial commit

This commit is contained in:
bytedream 2022-04-28 19:41:28 +02:00
commit 691021ca70
274 changed files with 8929 additions and 0 deletions

3
README.md Normal file
View File

@ -0,0 +1,3 @@
# ⚠️ UNFINISHED PROJECT ⚠️
> A try to create a java based end-to-end encrypted file sharing server with java based clients. But like nearly all of my java projects this didn't go so well. I think that it's not runnable.

BIN
lib/animatefx-1.2.1.jar Normal file

Binary file not shown.

BIN
lib/controlsfx-8.40.17.jar Normal file

Binary file not shown.

BIN
lib/hsqldb/hsqldb.jar Normal file

Binary file not shown.

Binary file not shown.

BIN
lib/hsqldb/sqltool.jar Normal file

Binary file not shown.

BIN
lib/log4j-1.2.17.jar Normal file

Binary file not shown.

View File

@ -0,0 +1,58 @@
package org.blueshard.olymp;
import org.apache.log4j.Logger;
import org.blueshard.olymp.exception.FatalIOException;
import org.blueshard.olymp.logging.EmptyLogger;
import org.blueshard.olymp.logging.ServerLogger;
import org.blueshard.olymp.register_code.RegisterCode;
import org.blueshard.olymp.server.MainServer;
import org.blueshard.olymp.sql.SQL;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.sql.Connection;
import java.sql.SQLException;
public class Main {
private static Connection connection = new SQL().getConnection();
public Logger root = new EmptyLogger().getLogger();
public static void main(String[] args) throws IOException, SQLException {
if (args.length == 1) {
String command = args[0].strip().toLowerCase();
if (command.equals("sql")) {
BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
Connection connection = getConnection();
String SQLQuery;
while (true) {
System.out.print("SQL Query: ");
SQLQuery = input.readLine().strip().toUpperCase();
if (SQLQuery.equals("EXIT")) {
break;
} else {
connection.createStatement().executeQuery(SQLQuery);
}
}
} else if (command.equals("add registercode")) {
try {
RegisterCode.generateNewRegisterCode();
} catch (FatalIOException e) {
e.printStackTrace();
}
}
} else {
MainServer server = new MainServer(8269, new ServerLogger().main());
server.start();
connection.close();
}
}
public static Connection getConnection() {
return connection;
}
}

View File

@ -0,0 +1,20 @@
package org.blueshard.olymp.cli;
import org.blueshard.olymp.exception.FatalIOException;
import org.blueshard.olymp.register_code.RegisterCode;
import java.io.IOException;
import java.sql.SQLException;
public class Main {
public static void main(String[] args) throws IOException, FatalIOException, SQLException {
switch (args[0].strip()) {
case "start":
org.blueshard.olymp.Main.main(new String[0]);
case "add register code":
RegisterCode.generateNewRegisterCode();
}
}
}

View File

@ -0,0 +1,15 @@
package org.blueshard.olymp.cli;
import javax.net.SocketFactory;
import java.io.IOException;
import java.net.Socket;
public class SQLCli {
public static void main(String[] args) throws IOException {
Socket server = SocketFactory.getDefault().createSocket("localhost", 8269);
}
}

View File

@ -0,0 +1,166 @@
package org.blueshard.olymp.data;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
public class Data {
private String dataAsString;
private Map<String, String> data = new HashMap<>();
public Data(String data) {
this.dataAsString = data;
String key = "";
String dataString = dataAsString;
String separator = getSeparator();
try {
if (separator.length() == 1) {
dataString = dataString.substring(dataString.indexOf(",")).strip();
} else {
dataString = dataString.substring(dataString.indexOf(",") + 1).strip();
}
} catch (StringIndexOutOfBoundsException e) {
dataString = "";
}
for (String string: dataString.split(separator)) {
string = string.strip();
if (string.equals(":") || string.equals(",") || string.equals("{") || string.equals("}")) {
continue;
} else if (key.isEmpty()) {
key = string;
} else {
this.data.put(key, string);
key = "";
}
}
}
public int getCode() {
int lenBeforeCode = 1 + getSeparator().length() + 1;
return Integer.parseInt(dataAsString.substring(lenBeforeCode, lenBeforeCode + DataCodes.DATACODESLENGHT));
}
public Map<String, String> getData() {
return data;
}
public String getDataAsString() {
return dataAsString;
}
public String getFromData(String key) {
return data.get(key);
}
private String getSeparator() {
return dataAsString.substring(1).split(":")[0];
}
public static class Builder {
private Map<String, String> data = new HashMap<>();
private int code;
public Builder(int code) {
this.code = code;
}
public String createData() {
String separator = createSeparator();
StringBuilder dataAsString = new StringBuilder("{" + separator + ":" + code);
data.forEach((key, value) -> dataAsString.append(",")
.append(separator)
.append(key)
.append(separator)
.append(":")
.append(separator)
.append(value)
.append(separator));
dataAsString.append("}");
return dataAsString.toString();
}
public String createSeparator() {
char choice;
StringBuilder stringBuilder = new StringBuilder();
String indicator = "'";
char[] choices = {'\'', '"', '^'};
data.forEach((key, value) -> stringBuilder.append(key).append(value));
String string = stringBuilder.toString();
while (true) {
if (string.contains(indicator)) {
switch (indicator) {
case "'":
indicator = "\"";
break;
case "\"":
indicator = "^";
break;
default:
{
choice = choices[new Random().nextInt(choices.length) - 1];
if (indicator.contains("|")) {
String[] splitted_indicator = indicator.split("\\|");
indicator = splitted_indicator[0] + choice + '|' + choice + splitted_indicator[1];
} else {
indicator = indicator + choice + '|' + choice + indicator;
}
}
}
} else {
return indicator;
}
}
}
public void addData(String key, String value) {
this.data.put(key, value);
}
public void addAllData(Map<String, String> allData) {
this.data.putAll(allData);
}
public int getCode() {
return code;
}
public Data getData() {
return new Data(getDataAsString());
}
public Map<String, String> getDataMap() {
return data;
}
public String getDataAsString() {
return createData();
}
}
public static boolean isDataString(String string) {
try {
string = string.strip();
if (string.startsWith("{") && string.endsWith("}") && string.contains(":")) {
String separator = string.substring(1).split(":")[0];
int lenBeforeCode = 1 + separator.length() + 1;
Integer.parseInt(string.substring(lenBeforeCode, lenBeforeCode + DataCodes.DATACODESLENGHT));
return true;
} else {
return false;
}
} catch (Exception e) {
return false;
}
}
}

View File

@ -0,0 +1,156 @@
package org.blueshard.olymp.data;
public class DataCodes {
public static final int DATACODESLENGHT = 5;
public static class Client {
public static final int UNEXPECTEDERROR = 56400;
public static final int UNEXPECTEDEXIT = 95078;
public static final int CLOSE = 69826;
public static final int FIRSTCONNECT = 19938;
public static final int PUBLICKEY = 19294;
public static final int UPDATEYES = 80515;
public static final int UPDATENO = 38510;
public static final int LOGIN = 39208;
public static final int REGISTERCODE = 18981;
public static final int REGISTER = 84219;
public static final int GETFILESDATA = 28926;
public static final int GETFILE = 95868;
public static final int SENDFILE = 53639;
}
public static class Server {
public static final int UNEXPECTEDERROR = 29875;
public static final int UNEXPECTEDEXIT = 85048;
public static final int NOTLOGGEDIN = 77015;
public static final int CLOSE = 42812;
public static final int READY = 86670;
public static final int FIRSTCONNECT = 76896;
public static final int PUBLICKEY = 19294;
public static final int OPTIONALUPDATE = 12925;
public static final int REQUIREDUPDATE = 97103;
public static final int LOGINFAIL = 11868;
public static final int LOGINSUCCESS = 54151;
public static final int REGISTERCODE_EXIST = 31166;
public static final int REGISTERCODE_NOT_EXIST = 47648;
public static final int REGISTERFAIL = 52300;
public static final int REGISTERFAIL_USER_EXIST= 77444;
public static final int REGISTERSUCCESS = 34367;
public static final int RECEIVEFILEFAIL = 45747;
public static final int RECEIVEFILESUCCESS = 75368;
public static final int SENDFILESDATA = 78946;
public static final int SENDFILEFAIL = 90173;
public static final int SENDFILESSUCCESS = 37272;
}
public static class Params {
public static class CheckSum {
public static final String MD5 = "md5";
}
public static class ClientAgent {
public static final String CLIENTAGENT = "clientAgent";
public static final String VALIDAGENT = "validAgent";
public static final String THEOSUI = "theosUI";
}
public static class File {
public static final String STARTDIRECOTRY = "startDirectory";
public static final String FILEPATH = "filepath";
}
public static class Key {
public static final String PUBLICKEY = "key";
}
public static class LogLevel {
public static final String LOGLEVEL = "logLevel";
public static final String ALL = "0";
public static final String WARNING = "1";
public static final String NOTHING = "2";
}
public static class LogReg {
public static final String USERNAME = "username";
public static final String PASSWORD = "password";
public static final String SALT = "salt";
public static final String EMAIL = "email";
}
public static class RegisterCode {
public static final String REGISTERCODE = "registerCode";
}
public static class Update {
public static final String UPDATE = "update";
public static final String NEWVERSION = "newVersion";
public static final String CHANGES = "changes";
}
public static class UserLevel {
public static final String USERLEVEL = "userLevel";
public static final String PUBLIC = "0";
public static final String PROTECTED = "1";
public static final String PRIVATE = "2";
}
public static class State {
public static final String STATE = "state";
public static final String ACTIVE = "active";
public static final String DISABLED = "disabled";
}
public static class Version {
public static final String VERSION = "version";
}
}
}

View File

@ -0,0 +1,48 @@
package org.blueshard.olymp.e2ee;
import org.blueshard.olymp.exception.UnexpectedException;
import org.blueshard.olymp.utils.ExceptionUtils;
import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
public class AESCipher {
private static final int keySize = 256;
public static byte[] generateKey() throws UnexpectedException {
try {
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
keyGenerator.init(keySize);
SecretKey secretKey = keyGenerator.generateKey();
return secretKey.getEncoded();
} catch (NoSuchAlgorithmException e) {
throw new UnexpectedException(ExceptionUtils.extractExceptionMessage(e));
}
}
public static byte[] encrypt(byte[] input, byte[] key) throws UnexpectedException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
try {
SecretKey secretKey = new SecretKeySpec(key, 0, key.length, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
return cipher.doFinal(input);
} catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
throw new UnexpectedException(e);
}
}
public static byte[] decrypt(byte[] input, byte[] key) throws UnexpectedException, BadPaddingException, IllegalBlockSizeException, InvalidKeyException {
try {
SecretKey secretKey = new SecretKeySpec(key, 0, key.length, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, secretKey);
return cipher.doFinal(input);
} catch (NoSuchPaddingException | NoSuchAlgorithmException e) {
throw new UnexpectedException(e);
}
}
}

View File

@ -0,0 +1,36 @@
package org.blueshard.olymp.e2ee;
import org.blueshard.olymp.exception.UnexpectedException;
import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.spec.InvalidKeySpecException;
import java.util.Base64;
public class E2EEConverter {
private final static String separator = "@";
public static String decrypt(String input, byte[] privateKey) throws UnexpectedException, BadPaddingException, InvalidKeySpecException, InvalidKeyException, NoSuchPaddingException, IllegalBlockSizeException {
String[] inputAsArray = input.split(separator);
String key = inputAsArray[0];
String realInput = inputAsArray[1];
byte[] AESKey = RSACipher.decrypt(Base64.getDecoder().decode(key), privateKey);
return new String(AESCipher.decrypt(Base64.getDecoder().decode(realInput), AESKey));
}
public static String encrypt(String input, byte[] publicKey) throws UnexpectedException, BadPaddingException, InvalidKeyException, IllegalBlockSizeException, InvalidKeySpecException {
byte[] AESKey = AESCipher.generateKey();
String encryptedKey = Base64.getEncoder().encodeToString(RSACipher.encrypt(AESKey, publicKey));
String encryptedInput = Base64.getEncoder().encodeToString(AESCipher.encrypt(input.getBytes(StandardCharsets.UTF_8), AESKey));
return encryptedKey + separator + encryptedInput;
}
}

View File

@ -0,0 +1,57 @@
package org.blueshard.olymp.e2ee;
import org.blueshard.olymp.exception.UnexpectedException;
import org.blueshard.olymp.utils.ExceptionUtils;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.security.*;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
public class RSACipher {
private static final int keySize = 2048;
public static KeyPair generateKeyPair() throws UnexpectedException {
try {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(keySize);
return keyPairGenerator.generateKeyPair();
} catch (NoSuchAlgorithmException e) {
throw new UnexpectedException(ExceptionUtils.extractExceptionMessage(e));
}
}
public static byte[] encrypt(byte[] key, byte[] publicKey) throws UnexpectedException, InvalidKeyException, InvalidKeySpecException, BadPaddingException {
try {
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKey);
RSAPublicKey publicRSAKey = (RSAPublicKey) keyFactory.generatePublic(keySpec);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, publicRSAKey);
return cipher.doFinal(key);
} catch (NoSuchAlgorithmException | IllegalBlockSizeException | NoSuchPaddingException e) {
throw new UnexpectedException(ExceptionUtils.extractExceptionMessage(e));
}
}
public static byte[] decrypt(byte[] key, byte[] privateKey) throws UnexpectedException, NoSuchPaddingException, InvalidKeySpecException, InvalidKeyException, BadPaddingException {
try {
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey privatePKCS8Key = keyFactory.generatePrivate(new PKCS8EncodedKeySpec(privateKey));
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, privatePKCS8Key);
return cipher.doFinal(key);
} catch (NoSuchAlgorithmException | IllegalBlockSizeException e) {
throw new UnexpectedException(ExceptionUtils.extractExceptionMessage(e));
}
}
}

View File

@ -0,0 +1,24 @@
package org.blueshard.olymp.exception;
import java.util.HashSet;
import java.util.Set;
public class ErrorCodes {
public final static int couldnt_create_userfiles_folder = 293;
public final static int couldnt_delete_userfiles_folder = 219;
public final static int couldnt_delete_custom_user_directory = 383;
public final static int couldnt_delete_custom_user_file = 942;
public static final int couldnt_read_versions_conf = 317;
public final static int couldnt_create_user_information = 249;
public final static int couldnt_get_user_information = 890;
public final static int couldnt_delete_user_information = 345;
public final static int couldnt_create_register_code = 457;
public final static int couldnt_get_register_code = 350;
public final static int couldnt_delete_register_code = 569;
}

View File

@ -0,0 +1,30 @@
package org.blueshard.olymp.exception;
public class FatalIOException extends Exception {
private final int errno;
private final Throwable throwable;
public FatalIOException(int errno, String message) {
super("Errno: " + errno + " - " + message);
this.errno = errno;
this.throwable = null;
}
public FatalIOException(int errno, String message, Throwable t) {
super("Errno: " + errno + " - " + message);
this.errno = errno;
this.throwable = t;
}
public int getErrno() {
return errno;
}
public Throwable getCauseThrowable() {
return throwable;
}
}

View File

@ -0,0 +1,15 @@
package org.blueshard.olymp.exception;
public class IllegalCodeException extends Exception {
private final int givenCode;
private final int requiredCode;
public IllegalCodeException(int givenCode, int requiredCode){
super("Wrong data code is given '" + givenCode + "', expected '" + requiredCode + "'");
this.givenCode = givenCode;
this.requiredCode = requiredCode;
}
}

View File

@ -0,0 +1,9 @@
package org.blueshard.olymp.exception;
public class IllegalPasswordException extends Exception {
public IllegalPasswordException(String errorMessage){
super(errorMessage);
}
}

View File

@ -0,0 +1,9 @@
package org.blueshard.olymp.exception;
public class RegisterCodeNotExistException extends Exception {
public RegisterCodeNotExistException(String registerCode) {
super("The register code '" + registerCode + "' do not exist");
}
}

View File

@ -0,0 +1,23 @@
package org.blueshard.olymp.exception;
public class UnexpectedException extends Exception {
public UnexpectedException() {
super("An unexpected error occurred");
}
public UnexpectedException(Throwable t) {
super("An unexpected error occurred (" + t.getMessage() + ")");
this.setStackTrace(t.getStackTrace());
}
public UnexpectedException(String message) {
super(message);
}
public UnexpectedException(String message, Throwable t) {
super(message);
this.setStackTrace(t.getStackTrace());
}
}

View File

@ -0,0 +1,9 @@
package org.blueshard.olymp.exception;
public class UserAlreadyExistException extends UserException {
public UserAlreadyExistException(String username, String message) {
super(username, message);
}
}

View File

@ -0,0 +1,13 @@
package org.blueshard.olymp.exception;
public class UserException extends Exception {
final String UUID;
public UserException(String UUID, String message) {
super(message);
this.UUID = UUID;
}
}

View File

@ -0,0 +1,9 @@
package org.blueshard.olymp.exception;
public class UserNotExistException extends UserException {
public UserNotExistException(String username, String message){
super(username, message);
}
}

View File

@ -0,0 +1,8 @@
package org.blueshard.olymp.exception;
public class UserNotLoggedInException extends UserException {
public UserNotLoggedInException(String username, String message) {
super(username, message);
}
}

View File

@ -0,0 +1,209 @@
package org.blueshard.olymp.files;
import java.io.*;
import java.util.Map;
import java.util.TreeMap;
public class ConfReader {
public static class SingleConfReader {
private File confFile;
private TreeMap<String, String> entries = new TreeMap<>();
public SingleConfReader(File confFile) throws IOException {
initialize(confFile);
}
public SingleConfReader(String confFile) throws IOException {
initialize(new File(confFile));
}
private void initialize(File confFile) throws IOException {
this.confFile = confFile;
BufferedReader bufferedReader = new BufferedReader(new FileReader(confFile));
String line;
while ((line = bufferedReader.readLine()) != null) {
line = line.strip();
if (line.isBlank() || line.isEmpty()) {
entries.put("#", null);
} else if (line.contains("#")) {
entries.put("#", line.substring(1));
} else {
String[] keyValue = line.split("=", 1);
entries.put(keyValue[0].strip(), keyValue[1].strip());
}
}
bufferedReader.close();
}
public boolean containsKey(String sectionName, String key) {
return entries.containsKey(key);
}
public boolean containsValue(String sectionName, String value) {
return entries.containsKey(value);
}
public TreeMap<String, String> getAll() {
return entries;
}
public TreeMap<String, String> getAll(boolean onlyText) {
if (onlyText) {
TreeMap<String, String> returnEntries = entries;
returnEntries.entrySet().removeIf(stringStringEntry -> stringStringEntry.getKey().equals("#"));
return returnEntries;
} else {
return entries;
}
}
public String getKey(String value) {
for (Map.Entry<String, String> entry: entries.entrySet()) {
if (entry.getValue().equals(value)) {
return entry.getKey();
}
}
return null;
}
public String getValue(String key) {
return entries.get(key);
}
public void remove(String key) {
entries.remove(key);
}
public void replace(String key, String newValue) {
entries.replace(key, newValue);
}
}
public static class MultipleConfReader {
private File confFile;
private TreeMap<String, TreeMap<String, String>> entries = new TreeMap<>();
public MultipleConfReader(File confFile) throws IOException {
initialize(confFile);
}
public MultipleConfReader(String confFile) throws IOException {
initialize(new File(confFile));
}
private void initialize(File confFile) throws IOException {
this.confFile = confFile;
BufferedReader bufferedReader = new BufferedReader(new FileReader(confFile));
String currentSection = null;
TreeMap<String, String> currentEntries = new TreeMap<>();
String line;
while ((line = bufferedReader.readLine()) != null) {
line = line.strip();
if (line.isBlank() || line.isEmpty()) {
currentEntries.put("#", null);
} else if (line.contains("#")) {
currentEntries.put("#", line.substring(1));
} else if (line.startsWith("[") && line.endsWith("]")) {
if (currentSection != null) {
entries.put(currentSection, currentEntries);
}
currentSection = line.substring(1, line.length() - 1);
} else {
String[] keyValue = line.split("=", 1);
if (keyValue.length == 1) {
currentEntries.put(keyValue[0].strip(), "");
} else {
currentEntries.put(keyValue[0].strip(), keyValue[1].strip());
}
}
}
bufferedReader.close();
}
public boolean containsKey(String sectionName, String key) {
return entries.get(sectionName).containsKey(key);
}
public boolean containsValue(String sectionName, String value) {
return entries.get(sectionName).containsKey(value);
}
public boolean containsSection(String sectionName) {
return entries.containsKey(sectionName);
}
public TreeMap<String, TreeMap<String, String>> getAll() {
return entries;
}
public TreeMap<String, TreeMap<String, String>> getAll(boolean onlyText) {
if (onlyText) {
TreeMap<String, TreeMap<String, String>> returnEntries = entries;
for (Map.Entry<String, TreeMap<String, String>> entry : entries.entrySet()) {
entry.getValue().entrySet().removeIf(stringStringEntry -> stringStringEntry.getKey().equals("#"));
}
return returnEntries;
} else {
return entries;
}
}
public TreeMap<String, String> getAll(String sectionName) {
TreeMap<String, String> returnEntries = entries.get(sectionName);
returnEntries.entrySet().removeIf(stringStringEntry -> stringStringEntry.getKey().equals("#"));
return returnEntries;
}
public TreeMap<String, String> getAll(String sectionName, boolean onlyText) {
if (onlyText) {
TreeMap<String, String> returnEntries = entries.get(sectionName);
returnEntries.entrySet().removeIf(stringStringEntry -> stringStringEntry.getKey().equals("#"));
return returnEntries;
} else {
return entries.get(sectionName);
}
}
public String getKey(String sectionName, String value) {
for (Map.Entry<String, String> entry: entries.get(sectionName).entrySet()) {
if (entry.getValue().equals(value)) {
return entry.getKey();
}
}
return null;
}
public String getValue(String sectionName, String key) {
return entries.get(sectionName).get(key);
}
public void remove(String sectionName, String key) {
entries.remove(sectionName).remove(key);
}
public void removeSection(String sectionName) {
entries.remove(sectionName);
}
public void replace(String sectionName, String key, String newValue) {
entries.get(sectionName).replace(key, newValue);
}
}
}

View File

@ -0,0 +1,267 @@
package org.blueshard.olymp.files;
import java.io.*;
import java.util.*;
public class ConfWriter {
public static class SingleConfWriter {
private TreeMap<String, String> entries = new TreeMap<>();
public void write(String filename) throws IOException {
write(new File(filename));
}
public void write(File file) throws IOException {
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(file));
String key;
String value;
for (Map.Entry<String, String> entry: entries.entrySet()) {
key = entry.getKey();
value = entry.getValue();
if (key.equals("#")) {
if (value == null) {
bufferedWriter.newLine();
} else {
bufferedWriter.write(key + value);
}
} else {
bufferedWriter.write(key + " = " + value);
}
bufferedWriter.newLine();
}
bufferedWriter.flush();
bufferedWriter.close();
}
public void add(String key, String value) {
if (key == null) {
return;
} else if (key.contains("#")) {
throw new IllegalArgumentException("Found '#' in " + key);
} else if (value.contains("#")) {
throw new IllegalArgumentException("Found '#' in " + value);
} else {
entries.put(key, value);
}
}
public void addAll(TreeMap<String, String> newEntries) {
TreeMap<String, String> tempEntries = new TreeMap<>();
newEntries.forEach((key, value) -> {
if (key == null) {
return;
} else if (key.contains("#")) {
throw new IllegalArgumentException("Found '#' in " + key);
} else if (value.contains("#")) {
throw new IllegalArgumentException("Found '#' in " + value);
} else {
tempEntries.put(key, value);
}
});
entries.putAll(tempEntries);
}
public void addBlankLine() {
TreeMap<String, String> newEntries = entries;
newEntries.put("#", null);
entries = newEntries;
}
public void addComment(String comment) {
TreeMap<String, String> newEntries = entries;
newEntries.put("#", comment);
entries = newEntries;
}
public TreeMap<String, String> getAll() {
return entries;
}
public void getAndAdd(String string) throws IOException {
getAndAdd(new File(string));
}
public void getAndAdd(File file) throws IOException {
entries.putAll(new ConfReader.SingleConfReader(file).getAll());
}
public String getKey(String value) {
for (Map.Entry<String, String> entry: entries.entrySet()) {
if (entry.getValue().equals(value)) {
return entry.getKey();
}
}
return null;
}
public String getValue(String key) {
return entries.get(key);
}
public void remove(String key) {
entries.remove(key);
}
public void replace(String key, String newValue) {
entries.replace(key, newValue);
}
}
public static class MultipleConfWriter {
private TreeMap<String, TreeMap<String, String>> entries = new TreeMap<>();
public void createNewSection(String sectionName) {
entries.put(sectionName, new TreeMap<>());
}
public void write(String filename) throws IOException {
write(new File(filename));
}
public void write(File file) throws IOException {
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(file));
String sectionKey;
String sectionValue;
for (Map.Entry<String, TreeMap<String, String>> entry: entries.entrySet()) {
String sectionName = entry.getKey();
bufferedWriter.write("[" + sectionName + "]");
bufferedWriter.newLine();
bufferedWriter.newLine();
for (Map.Entry<String, String> sectionEntry: entries.get(sectionName).entrySet()) {
sectionKey = sectionEntry.getKey();
sectionValue = sectionEntry.getValue();
if (sectionKey.equals("#")) {
if (sectionValue == null) {
bufferedWriter.newLine();
} else {
bufferedWriter.write(sectionKey + sectionValue);
}
} else {
bufferedWriter.write(sectionKey + " = " + sectionValue);
}
bufferedWriter.newLine();
}
}
bufferedWriter.flush();
bufferedWriter.close();
}
public void add(String sectionName, String key, String value) {
if (sectionName == null || key == null || !entries.containsKey(sectionName)) {
return;
} else if (key.contains("#")) {
throw new IllegalArgumentException("Found '#' in " + key);
} else if (value.contains("#")) {
throw new IllegalArgumentException("Found '#' in " + value);
} else {
TreeMap<String, String> newEntries = entries.get(sectionName);
newEntries.put(key, value);
entries.replace(sectionName, new TreeMap<>(newEntries));
}
}
public void addAll(String sectionName, TreeMap<String, String> newEntries) {
TreeMap<String, String> tempEntries = new TreeMap<>();
if (sectionName == null || !newEntries.containsKey(sectionName)) {
return;
} else {
newEntries.forEach((key, value) -> {
if (key == null) {
return;
} else if (key.contains("#")) {
throw new IllegalArgumentException("Found '#' in " + key);
} else if (value.contains("#")) {
throw new IllegalArgumentException("Found '#' in " + value);
} else {
tempEntries.put(key, value);
}
});
}
TreeMap<String, String> newSectionEntries = entries.get(sectionName);
newSectionEntries.putAll(tempEntries);
entries.replace(sectionName, new TreeMap<>(newSectionEntries));
}
public void addBlankLine(String sectionName) {
TreeMap<String, String> newEntries = entries.get(sectionName);
newEntries.put("#", null);
entries.put(sectionName, newEntries);
}
public void addComment(String sectionName, String comment) {
TreeMap<String, String> newEntries = entries.get(sectionName);
newEntries.put("#", comment);
entries.put(sectionName, newEntries);
}
public void addSingleConfWriter(String sectionName, ConfWriter.SingleConfWriter singleConfWriter) {
entries.put(sectionName, singleConfWriter.entries);
}
public TreeMap<String, TreeMap<String, String>> getAll() {
return entries;
}
public void getAndAdd(String string) throws IOException {
getAndAdd(new File(string));
}
public void getAndAdd(File file) throws IOException {
entries.putAll(new ConfReader.MultipleConfReader(file).getAll());
}
public String getKey(String sectionName, String value) {
for (Map.Entry<String, String> entry: entries.get(sectionName).entrySet()) {
if (entry.getValue().equals(value)) {
return entry.getKey();
}
}
return null;
}
public String getValue(String sectionName, String key) {
return entries.get(sectionName).get(key);
}
public void remove(String sectionName, String key) {
entries.remove(sectionName).remove(key);
}
public void removeSection(String sectionName) {
entries.remove(sectionName);
}
public void replace(String sectionName, String key, String newValue) {
entries.get(sectionName).replace(key, newValue);
}
}
}

View File

@ -0,0 +1,39 @@
package org.blueshard.olymp.files;
public class ServerFiles {
public static class etc {
public static final String dir = "/srv/etc/";
public static final String register_codes = dir + "register_codes";
public static final String versions = dir + "versions.conf";
public static class update {
public static final String dir = "/srv/etc/update/";
public static final String TheosUI_jar = dir + "update.jar";
}
}
public static class logs {
public static final String dir = "/srv/logs/";
public static final String main_log = dir + "main.log";
}
public static class user_files {
public static final String dir = "/srv/user_files/";
public final String user_files_dir;
public user_files(String UUID) {
user_files_dir = dir + UUID + "/";
}
}
}

View File

@ -0,0 +1,76 @@
package org.blueshard.olymp.fileserver;
import org.apache.log4j.Logger;
import org.blueshard.olymp.e2ee.E2EEConverter;
import org.blueshard.olymp.exception.UnexpectedException;
import org.blueshard.olymp.server.ClientFactory;
import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.SSLServerSocketFactory;
import javax.net.ssl.SSLSocket;
import java.io.*;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.util.Base64;
public class FileReceiver {
ClientFactory.Client client;
File destFile;
byte[] privateKey;
Logger logger;
public FileReceiver(ClientFactory.Client client, File destFile, byte[] privateKey, Logger logger) {
this.client = client;
this.destFile = destFile;
this.privateKey = privateKey;
this.logger = logger;
}
public String main() throws IOException, UnexpectedException, IllegalBlockSizeException, InvalidKeyException, InvalidKeySpecException, BadPaddingException, NoSuchPaddingException {
try {
SSLServerSocket FTPSocket = (SSLServerSocket) SSLServerSocketFactory.getDefault().createServerSocket(20);
logger.info("Start File Receiver for client " + client.getId());
logger.info("Receiver infos: " + FTPSocket.toString());
SSLSocket sslSocket = (SSLSocket) FTPSocket.accept();
logger.info("Client connected");
InputStream inputStream = sslSocket.getInputStream();
FileOutputStream fileOutputStream = new FileOutputStream(destFile);
StringBuilder hexString = new StringBuilder();
MessageDigest md5 = MessageDigest.getInstance("MD5");
byte[] buffer = new byte[1024];
int length;
while ((length = inputStream.read(buffer)) > 0) {
fileOutputStream.write(Base64.getDecoder().decode(E2EEConverter.decrypt(Base64.getEncoder().encodeToString(buffer), privateKey)), 0, length);
md5.update(buffer, 0, length);
}
logger.info("Received file from client and saved it");
byte[] digest = md5.digest();
for (byte b : digest) {
if ((0xff & b) < 0x10) {
hexString.append("0").append(Integer.toHexString((0xFF & b)));
} else {
hexString.append(Integer.toHexString(0xFF & b));
}
}
sslSocket.close();
logger.info("Closed File Receiver");
logger.info("File MD5 check sum is " + hexString.toString());
return hexString.toString();
} catch (NoSuchAlgorithmException e) {
throw new UnexpectedException(e);
}
}
}

View File

@ -0,0 +1,74 @@
package org.blueshard.olymp.fileserver;
import org.apache.log4j.Logger;
import org.blueshard.olymp.e2ee.E2EEConverter;
import org.blueshard.olymp.exception.UnexpectedException;
import org.blueshard.olymp.server.ClientFactory;
import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.SSLServerSocketFactory;
import javax.net.ssl.SSLSocket;
import java.io.*;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.util.Base64;
public class FileSender {
ClientFactory.Client client;
File sourceFile;
byte[] publicKey;
Logger logger;
public FileSender(ClientFactory.Client client, File sourceFile, byte[] publicKey, Logger logger) {
this.client = client;
this.sourceFile = sourceFile;
this.publicKey = publicKey;
this.logger = logger;
}
public String main() throws IOException, UnexpectedException, BadPaddingException, IllegalBlockSizeException, InvalidKeySpecException, InvalidKeyException {
try {
SSLServerSocket FTPSocket = (SSLServerSocket) SSLServerSocketFactory.getDefault().createServerSocket(20);
logger.info("Started file sender");
logger.info("Sender infos: " + FTPSocket.toString());
SSLSocket sslSocket = (SSLSocket) FTPSocket.accept();
logger.info("Client connected");
FileInputStream fileInputStream = new FileInputStream(sourceFile);
OutputStream outputStream = sslSocket.getOutputStream();
StringBuilder hexString = new StringBuilder();
MessageDigest md5 = MessageDigest.getInstance("MD5");
byte[] buffer = new byte[1024];
int length;
while ((length = fileInputStream.read(buffer)) > 0) {
outputStream.write(Base64.getDecoder().decode(E2EEConverter.encrypt(Base64.getEncoder().encodeToString(buffer), publicKey)), 0, length);
md5.update(buffer, 0, length);
}
logger.info("Send file to client and saved it");
byte[] digest = md5.digest();
for (byte b : digest) {
if ((0xff & b) < 0x10) {
hexString.append("0").append(Integer.toHexString((0xFF & b)));
} else {
hexString.append(Integer.toHexString(0xFF & b));
}
}
sslSocket.close();
logger.info("Closed File Sender");
return hexString.toString();
} catch (NoSuchAlgorithmException e) {
throw new UnexpectedException(e);
}
}
}

View File

@ -0,0 +1,102 @@
package org.blueshard.olymp.logging;
import org.apache.log4j.*;
import org.apache.log4j.spi.LoggingEvent;
import org.apache.log4j.spi.ThrowableInformation;
import org.blueshard.olymp.files.ServerFiles;
import org.blueshard.olymp.server.ClientFactory;
import org.blueshard.olymp.utils.ConsoleColors;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Locale;
public class ClientLogger {
private final Logger logger;
public ClientLogger(ClientFactory.Client client, Level logLevel) throws IOException {
logger = Logger.getLogger(String.valueOf(client.getId()));
logger.setLevel(logLevel);
ConsoleAppender consoleAppender = new ConsoleAppender(new Layout() {
@Override
public String format(LoggingEvent loggingEvent) {
DateFormat date = new SimpleDateFormat("yyyy:MM:dd HH:mm:ss", Locale.GERMANY);
Level level = loggingEvent.getLevel();
StringBuilder extraData = new StringBuilder();
String color;
String id = String.valueOf(client.getId());
ThrowableInformation throwableInformation = loggingEvent.getThrowableInformation();
switch (loggingEvent.getLevel().toInt()) {
case Level.WARN_INT:
color = ConsoleColors.RED_BRIGHT;
break;
case Level.ERROR_INT:
color = ConsoleColors.RED_BOLD + ConsoleColors.RED_UNDERLINED;
break;
case Level.FATAL_INT:
color = ConsoleColors.BLACK;
break;
default:
color = "";
break;
}
if (throwableInformation != null) {
extraData.append(ConsoleColors.RED);
Arrays.asList(throwableInformation.getThrowable().getStackTrace()).forEach(stackTraceElement -> extraData.append(stackTraceElement).append("\n"));
}
return color + "[" + date.format(loggingEvent.getTimeStamp()) + " - ID: " + id + "] " + level + ": " + loggingEvent.getMessage() + "\n" + extraData.toString() + ConsoleColors.RESET;
}
@Override
public boolean ignoresThrowable() {
return false;
}
@Override
public void activateOptions() {
}
});
RollingFileAppender rollingFileAppender = new RollingFileAppender(new Layout() {
@Override
public String format(LoggingEvent loggingEvent) {
DateFormat date = new SimpleDateFormat("yyyy:MM:dd HH:mm:ss", Locale.GERMANY);
Level level = loggingEvent.getLevel();
StringBuilder extraData = new StringBuilder();
String id = String.valueOf(client.getId());
ThrowableInformation throwableInformation = loggingEvent.getThrowableInformation();
if (throwableInformation != null) {
Arrays.asList(throwableInformation.getThrowable().getStackTrace()).forEach(stackTraceElement -> extraData.append(stackTraceElement).append("\n"));
}
return "[" + date.format(loggingEvent.getTimeStamp()) + " - ID: " + id + "] " + level + ": " + loggingEvent.getMessage() + "\n" + extraData.toString();
}
@Override
public boolean ignoresThrowable() {
return false;
}
@Override
public void activateOptions() {
}
}, ServerFiles.logs.main_log, true);
rollingFileAppender.setMaxBackupIndex(10);
rollingFileAppender.setMaxFileSize("10MB");
logger.addAppender(consoleAppender);
logger.addAppender(rollingFileAppender);
}
public Logger getLogger() {
return logger;
}
}

View File

@ -0,0 +1,14 @@
package org.blueshard.olymp.logging;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
public class EmptyLogger {
public Logger getLogger() {
Logger logger = Logger.getLogger(EmptyLogger.class.getName());
logger.setLevel(Level.OFF);
return logger;
}
}

View File

@ -0,0 +1,15 @@
package org.blueshard.olymp.logging;
import org.blueshard.olymp.user.User;
public class LogDeleter {
private final User user;
private final String logLifeTime;
public LogDeleter(User user, String logLifeTime) {
this.user = user;
this.logLifeTime = logLifeTime;
}
}

View File

@ -0,0 +1,92 @@
package org.blueshard.olymp.logging;
import org.apache.log4j.*;
import org.apache.log4j.spi.LoggingEvent;
import org.apache.log4j.spi.ThrowableInformation;
import org.blueshard.olymp.files.ServerFiles;
import org.blueshard.olymp.utils.ConsoleColors;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
public class ServerLogger {
private final Logger logger = LogManager.getLogger(ServerLogger.class);
public Logger main() throws IOException {
logger.setLevel(Level.ALL);
RollingFileAppender rollingFileAppender = new RollingFileAppender(new Layout() {
@Override
public String format(LoggingEvent loggingEvent) {
SimpleDateFormat date = new SimpleDateFormat("HH:mm:ss");
StringBuilder extraData = new StringBuilder();
ThrowableInformation throwableInformation = loggingEvent.getThrowableInformation();
if (throwableInformation != null) {
Arrays.asList(throwableInformation.getThrowable().getStackTrace()).forEach(stackTraceElement -> extraData.append(stackTraceElement).append("\n"));
}
return "[" + date.format(loggingEvent.getTimeStamp()) + " - Server] " + loggingEvent.getLevel() + ": " + loggingEvent.getMessage() + "\n" + extraData.toString();
}
@Override
public boolean ignoresThrowable() {
return false;
}
@Override
public void activateOptions() {
}
}, ServerFiles.logs.main_log, true);
rollingFileAppender.setMaxBackupIndex(10);
rollingFileAppender.setMaxFileSize("10MB");
ConsoleAppender consoleAppender = new ConsoleAppender(new Layout() {
@Override
public String format(LoggingEvent loggingEvent) {
SimpleDateFormat date = new SimpleDateFormat("HH:mm:ss");
StringBuilder extraData = new StringBuilder();
String color;
ThrowableInformation throwableInformation = loggingEvent.getThrowableInformation();
switch (loggingEvent.getLevel().toInt()) {
case Level.WARN_INT:
color = ConsoleColors.RED_BRIGHT;
break;
case Level.ERROR_INT:
color = ConsoleColors.RED_BOLD + ConsoleColors.RED_UNDERLINED;
break;
case Level.FATAL_INT:
color = ConsoleColors.BLACK;
break;
default:
color = "";
break;
}
if (throwableInformation != null) {
extraData.append(ConsoleColors.RED);
Arrays.asList(throwableInformation.getThrowable().getStackTrace()).forEach(stackTraceElement -> extraData.append(stackTraceElement).append("\n"));
}
return color + "[" + date.format(loggingEvent.getTimeStamp()) + " - Server] " + loggingEvent.getLevel() + ": " + loggingEvent.getMessage() + "\n" + extraData.toString() + ConsoleColors.RESET;
}
@Override
public boolean ignoresThrowable() {
return false;
}
@Override
public void activateOptions() {
}
});
logger.addAppender(rollingFileAppender);
logger.addAppender(consoleAppender);
return logger;
}
}

View File

@ -0,0 +1,95 @@
package org.blueshard.olymp.register_code;
import org.blueshard.olymp.Main;
import org.blueshard.olymp.exception.ErrorCodes;
import org.blueshard.olymp.exception.FatalIOException;
import org.blueshard.olymp.sql.SQL;
import java.sql.*;
import java.util.HashSet;
import java.util.concurrent.ThreadLocalRandom;
public class RegisterCode {
public static String generateNewRegisterCode() throws FatalIOException {
String[] letters = new String[]{"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z",
"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z",
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"};
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < 18; i++) {
stringBuilder.append(letters[ThreadLocalRandom.current().nextInt(0, letters.length)]);
}
try {
Connection connection = Main.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("INSERT INTO REGISTER_CODES VALUES(?)");
preparedStatement.setString(1, stringBuilder.toString());
preparedStatement.executeUpdate();
SQL.checkpoint();
} catch (SQLException e) {
throw new FatalIOException(ErrorCodes.couldnt_create_register_code, "Couldn't add new register code", e);
}
return stringBuilder.toString();
}
public static HashSet<String> getAllRegisterCodes() throws FatalIOException {
HashSet<String> registerCodes = new HashSet<>();
try {
Statement statement = Main.getConnection().createStatement();
ResultSet resultSet = statement.executeQuery("SELECT CODE FROM REGISTER_CODE");
int columnCount;
while (resultSet.next()) {
registerCodes.add(resultSet.getString(1));
}
} catch (SQLException e) {
throw new FatalIOException(ErrorCodes.couldnt_get_register_code, "Failed to read register codes", e);
}
return registerCodes;
}
public static boolean isRegisterCode(String registerCode) throws FatalIOException {
try {
Statement statement = Main.getConnection().createStatement();
ResultSet resultSet = statement.executeQuery("SELECT CODE FROM REGISTER_CODE");
while (resultSet.next()) {
if (resultSet.getString(1).equals(registerCode)) {
resultSet.close();
return true;
}
}
resultSet.close();
} catch (SQLException e) {
throw new FatalIOException(ErrorCodes.couldnt_get_register_code, "Failed to read register codes", e);
}
return false;
}
public static void removeRegisterCode(String registerCode) throws FatalIOException {
try {
PreparedStatement preparedStatement = Main.getConnection().prepareStatement("DELETE FROM REGISTER_CODES WHERE CODE = ?");
preparedStatement.setString(1, registerCode);
preparedStatement.executeUpdate();
SQL.checkpoint();
} catch (SQLException e) {
throw new FatalIOException(ErrorCodes.couldnt_delete_register_code, "Failed to delete register code " + registerCode, e);
}
}
}

View File

@ -0,0 +1,67 @@
package org.blueshard.olymp.security;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import java.util.Base64;
public class Password {
public static PasswordInfos createPassword(String password, byte[] salt) throws InvalidKeySpecException {
SecureRandom secureRandom = new SecureRandom();
secureRandom.nextBytes(salt);
KeySpec keySpec = new PBEKeySpec(password.toCharArray(), salt, 65536, 256);
SecretKeyFactory factory = null;
try {
factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
} catch (NoSuchAlgorithmException ignore) {
}
byte[] hashedPassword;
try {
hashedPassword = factory.generateSecret(keySpec).getEncoded();
} catch (InvalidKeySpecException ignore) {
}
hashedPassword = factory.generateSecret(keySpec).getEncoded();
return new PasswordInfos(hashedPassword, salt);
}
public static class PasswordInfos {
private final byte[] password;
private final byte[] salt;
public PasswordInfos(byte[] password, byte[] salt) {
this.password = password;
this.salt = salt;
}
public byte[] getPasswordAsBytes() {
return password;
}
public String getPasswordAsString() {
Base64.Encoder encoder = Base64.getEncoder();
return encoder.encodeToString(password);
}
public byte[] getSaltAsBytes() {
return salt;
}
public String getSaltAsString() {
Base64.Encoder encoder = Base64.getEncoder();
return encoder.encodeToString(salt);
}
}
}

View File

@ -0,0 +1,133 @@
package org.blueshard.olymp.server;
import org.apache.log4j.Logger;
import org.blueshard.olymp.Main;
import org.blueshard.olymp.data.DataCodes;
import org.blueshard.olymp.data.Data;
import org.blueshard.olymp.e2ee.RSACipher;
import org.blueshard.olymp.exception.*;
import org.blueshard.olymp.files.ServerFiles;
import org.blueshard.olymp.register_code.RegisterCode;
import org.blueshard.olymp.sql.SQL;
import org.blueshard.olymp.sql.SQLPosition;
import org.blueshard.olymp.user.User;
import org.blueshard.olymp.version.TheosUIVersion;
import java.io.*;
import java.net.URI;
import java.net.URISyntaxException;
import java.security.KeyPair;
import java.security.PrivateKey;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Arrays;
public class Action {
private Data data;
private final ClientSender clientSender;
public Action(Data data, ClientSender clientSender) {
this.data = data;
this.clientSender = clientSender;
}
public void refreshData(Data data) {
this.data = data;
}
public void close() {
clientSender.close();
}
public void firstConnectionResult(boolean validAgent, boolean update) {
clientSender.firstConnectResult(validAgent, update);
}
public void isRegisterCode() throws FatalIOException {
if (RegisterCode.isRegisterCode(data.getFromData(DataCodes.Params.RegisterCode.REGISTERCODE))) {
clientSender.registerCodeExist();
} else {
clientSender.registerCodeNotExist();
}
}
public static PrivateKey publicKey(OutputStream outputStream, Logger logger) throws UnexpectedException {
KeyPair keyPair = RSACipher.generateKeyPair();
ClientSender.publicKey(keyPair.getPublic(), new DataOutputStream(outputStream), logger);
return keyPair.getPrivate();
}
public static void ready(OutputStream outputStream, Logger logger) {
ClientSender.ready(new DataOutputStream(outputStream), logger);
}
public User login() throws UserNotExistException, IllegalCodeException, IllegalPasswordException, FatalIOException {
try {
PreparedStatement preparedStatement = Main.getConnection().prepareStatement("SELECT UUID FROM USERS WHERE USERNAME = ?");
preparedStatement.setString(1, data.getFromData(DataCodes.Params.LogReg.USERNAME));
ResultSet resultSet = preparedStatement.executeQuery();
if (resultSet.next()) {
User user = new User(resultSet.getString(1));
if (data.getCode() != DataCodes.Client.LOGIN) {
throw new IllegalCodeException(data.getCode(), DataCodes.Client.LOGIN);
} else if (!data.getFromData(DataCodes.Params.LogReg.PASSWORD).equals(user.getPasswordInfos().getPasswordAsString())) {
throw new IllegalPasswordException("Wrong password is given");
}
clientSender.loginSuccess();
resultSet.close();
return user;
} else {
resultSet.close();
throw new UserNotExistException(data.getFromData(DataCodes.Params.LogReg.USERNAME), "The user doesn't exist");
}
} catch (SQLException e) {
throw new FatalIOException(ErrorCodes.couldnt_get_user_information, "Couldn't get UUID for user with name " + data.getFromData(DataCodes.Params.LogReg.USERNAME), e);
}
}
public User register() throws FatalIOException, UserAlreadyExistException, RegisterCodeNotExistException {
User user = User.createNewUser(data.getFromData(DataCodes.Params.RegisterCode.REGISTERCODE),
data.getFromData(DataCodes.Params.LogReg.USERNAME), data.getFromData(DataCodes.Params.LogReg.PASSWORD),
data.getFromData(DataCodes.Params.LogReg.SALT), data.getFromData(DataCodes.Params.LogReg.EMAIL));
clientSender.registerSuccess();
return user;
}
public void receiveFile(User user, byte[] privateKey) {
clientSender.receiveFile(new ServerFiles.user_files(user.getUUID()) + data.getFromData(DataCodes.Params.File.FILEPATH), privateKey);
}
public void requestArtificeUIOptionalUpdate(TheosUIVersion version) {
clientSender.requestArtificeUIOptionalUpdate(version, version.getChanges());
}
public void requestArtificeUIRequiredUpdate(TheosUIVersion version) {
clientSender.requestArtificeUIRequiredUpdate(version, version.getChanges());
}
public void sendFile(String file, byte[] publicKey) {
clientSender.sendFile(new File(file), publicKey);
}
public void sendUpdateFile(byte[] publicKey) {
clientSender.sendFile(new File(ServerFiles.etc.update.TheosUI_jar), publicKey);
}
public void sendUserFilesData(String UUID, String startDirectory) {
clientSender.filesData(UUID, new File(new ServerFiles.user_files(UUID).user_files_dir + startDirectory));
}
}

View File

@ -0,0 +1,86 @@
package org.blueshard.olymp.server;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.util.Arrays;
import java.util.TreeMap;
import java.util.concurrent.ThreadLocalRandom;
public class ClientFactory {
private TreeMap<Integer, Client> ids = new TreeMap<>();
public Client createNewClient(Socket socket, String clientAgent) {
int id;
do {
id = ThreadLocalRandom.current().nextInt(1, 999);
} while (ids.containsKey(id));
return new Client(id, socket, clientAgent);
}
public class Client {
private final int id;
private final Socket socket;
private String clientAgent;
public Client(int id, Socket socket, String clientAgent) {
ClientFactory.this.ids.clear();
this.id = id;
this.socket = socket;
this.clientAgent = clientAgent;
}
public void close() throws IOException {
try {
socket.close();
ids.remove(id);
} catch (IOException e) {
e.printStackTrace();
throw new IOException("Couldn't close connection");
}
}
public int getId() {
return id;
}
public String getClientAgent() {
return clientAgent;
}
public InetAddress getInetAddress() {
return socket.getInetAddress();
}
public InputStream getInputStream() throws IOException {
return socket.getInputStream();
}
public String getIPAddress() {
return getInetAddress().getHostAddress();
}
public OutputStream getOutputStream() throws IOException {
return socket.getOutputStream();
}
public int getPort() {
return socket.getPort();
}
public void setClientAgent(String clientAgent) throws IllegalAccessException {
if (this.clientAgent != null) {
throw new IllegalAccessException("Client agent is already set");
} else {
this.clientAgent = clientAgent;
}
}
}
}

View File

@ -0,0 +1,86 @@
package org.blueshard.olymp.server;
import org.apache.log4j.Logger;
import org.blueshard.olymp.data.DataCodes;
import org.blueshard.olymp.data.Data;
import org.blueshard.olymp.e2ee.E2EEConverter;
import org.blueshard.olymp.exception.UnexpectedException;
import org.blueshard.olymp.user.User;
import java.io.*;
import java.security.GeneralSecurityException;
public class ClientReceiver {
private final User user;
private final ClientFactory.Client client;
private final byte[] clientPublicKey;
private final byte[] privateKey;
private final Logger logger;
private final DataInputStream clientInput;
private final ClientSender clientSender;
ClientReceiver(User user, ClientFactory.Client client, ClientSender clientSender, byte[] clientPublicKey, byte[] privateKey, Logger logger) throws IOException {
this.user = user;
this.client = client;
this.clientPublicKey = clientPublicKey;
this.privateKey = privateKey;
this.logger = logger;
try {
this.clientInput = new DataInputStream(this.client.getInputStream());
this.clientSender = clientSender;
} catch (IOException e) {
throw new IOException(ResultCodes.UNEXPECTEDEXIT + ";" + e.getMessage());
}
}
public int main() {
Data inputData;
Action action = new Action(null, clientSender);
while (true) {
try {
inputData = new Data(E2EEConverter.decrypt(clientInput.readUTF(), privateKey));
} catch (IOException | GeneralSecurityException e) {
return ResultCodes.UNEXPECTEDEXIT;
} catch (UnexpectedException e) {
clientSender.unexpectedError();
return ResultCodes.UNEXPECTEDEXIT;
}
action.refreshData(inputData);
switch (inputData.getCode()) {
case DataCodes.Client.UNEXPECTEDEXIT:
return ResultCodes.UNEXPECTEDEXIT;
case DataCodes.Client.CLOSE:
return ResultCodes.EXIT;
case DataCodes.Client.GETFILESDATA:
String startDirectory = inputData.getFromData(DataCodes.Params.File.STARTDIRECOTRY);
if (startDirectory == null) {
startDirectory = "/";
}
action.sendUserFilesData(user.getUUID(), startDirectory);
break;
case DataCodes.Client.GETFILE:
action.sendFile(user.getUserfileDirectory() + inputData.getFromData(DataCodes.Params.File.FILEPATH), privateKey);
break;
case DataCodes.Client.SENDFILE:
action.receiveFile(user, clientPublicKey);
break;
}
}
}
public static class ResultCodes {
public static final int EXIT = 25;
public static final int UNEXPECTEDEXIT = 84;
}
}

View File

@ -0,0 +1,350 @@
package org.blueshard.olymp.server;
import org.apache.log4j.Logger;
import org.blueshard.olymp.data.Data;
import org.blueshard.olymp.data.DataCodes;
import org.blueshard.olymp.e2ee.E2EEConverter;
import org.blueshard.olymp.exception.UnexpectedException;
import org.blueshard.olymp.fileserver.FileReceiver;
import org.blueshard.olymp.fileserver.FileSender;
import org.blueshard.olymp.files.ServerFiles;
import org.blueshard.olymp.utils.SizeUnit;
import org.blueshard.olymp.version.TheosUIVersion;
import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.io.DataOutputStream;
import java.io.File;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.PublicKey;
import java.security.spec.InvalidKeySpecException;
import java.util.Base64;
import java.util.concurrent.Executors;
public class ClientSender {
private final ClientFactory.Client client;
private final byte[] clientPublicKey;
private final Logger logger;
private final DataOutputStream dataOutputStream;
public ClientSender(ClientFactory.Client client, byte[] clientPublicKey, Logger logger) throws IOException, IllegalBlockSizeException, UnexpectedException, InvalidKeySpecException, InvalidKeyException, BadPaddingException {
this.client = client;
this.clientPublicKey = clientPublicKey;
this.logger = logger;
this.dataOutputStream = new DataOutputStream(this.client.getOutputStream());
if (clientPublicKey.length != 0) {
E2EEConverter.encrypt("Test", clientPublicKey); // just test if the client key works
}
}
public void send(Data data) throws IOException {
if (clientPublicKey.length == 0) {
dataOutputStream.writeUTF(data.getDataAsString() + "\n");
} else {
try {
dataOutputStream.writeUTF(E2EEConverter.encrypt(data.getDataAsString() + "\n", clientPublicKey));
} catch (UnexpectedException e) {
logger.error("An unexpected error occurred", e);
unexpectedError();
} catch (InvalidKeyException | IllegalBlockSizeException | BadPaddingException | InvalidKeySpecException ignore) {
}
}
dataOutputStream.flush();
}
public void send(Data.Builder data) throws IOException {
send(data.getData());
}
private String loggerInfo(String data) {
return "Send " + data + " data";
}
private String loggerWarning(String data) {
return "Failed to send " + data + " data";
}
public void close() {
try {
send(new Data.Builder(DataCodes.Server.CLOSE));
logger.info(loggerInfo("close"));
} catch (IOException e) {
logger.warn(loggerWarning("close"), e);
}
}
public void unexpectedError() {
try {
send(new Data.Builder(DataCodes.Server.UNEXPECTEDERROR));
logger.info(loggerInfo("unexpected error"));
} catch (IOException e) {
logger.warn(loggerWarning("unexpected error"));
}
}
public void unexpectedExit() {
try {
send(new Data.Builder(DataCodes.Server.UNEXPECTEDEXIT));
logger.info(loggerInfo("unexpected exit"));
} catch (IOException e) {
logger.warn(loggerWarning("unexpected exit"));
}
}
public static void publicKey(PublicKey publicKey, DataOutputStream dataOutputStream, Logger logger) {
try {
Data.Builder data = new Data.Builder(DataCodes.Server.PUBLICKEY);
data.addData(DataCodes.Params.Key.PUBLICKEY, Base64.getEncoder().encodeToString(publicKey.getEncoded()));
dataOutputStream.writeUTF(data.getDataAsString() + "\n");
dataOutputStream.flush();
logger.info("Send public key data");
} catch (IOException e) {
logger.warn("Failed to send public key data");
}
}
public static void ready(DataOutputStream dataOutputStream, Logger logger) {
try {
dataOutputStream.writeUTF(new Data.Builder(DataCodes.Server.READY).getDataAsString() + "\n");
dataOutputStream.flush();
logger.info("Send ready data");
} catch (IOException e) {
logger.warn("Failed to send ready data", e);
}
}
public void userNotLoggedIn() {
try {
send(new Data.Builder(DataCodes.Server.NOTLOGGEDIN));
logger.info(loggerInfo("user not logged in"));
} catch (IOException e) {
logger.warn(loggerWarning("user not logged in"));
}
}
//----- update -----//
public void firstConnectResult(boolean validAgent, boolean update) {
Data.Builder data = new Data.Builder(DataCodes.Server.FIRSTCONNECT);
data.addData(DataCodes.Params.ClientAgent.VALIDAGENT, String.valueOf(validAgent));
data.addData(DataCodes.Params.Update.UPDATE, String.valueOf(update));
try {
send(data);
logger.info(loggerInfo("first connect result"));
} catch (IOException e) {
logger.warn(loggerWarning("first connect result"), e);
}
}
public void requestArtificeUIOptionalUpdate(TheosUIVersion version, String changes) {
Data.Builder data = new Data.Builder(DataCodes.Server.OPTIONALUPDATE);
data.addData(DataCodes.Params.Update.NEWVERSION, version.toString());
data.addData(DataCodes.Params.Update.CHANGES, changes);
try {
send(data);
logger.info(loggerInfo("request ArtificeUI optional update"));
} catch (IOException e) {
logger.warn(loggerWarning("request ArtificeUI optional update"));
}
}
public void requestArtificeUIRequiredUpdate(TheosUIVersion version, String changes) {
Data.Builder data = new Data.Builder(DataCodes.Server.REQUIREDUPDATE);
data.addData(DataCodes.Params.Update.NEWVERSION, version.toString());
data.addData(DataCodes.Params.Update.CHANGES, changes);
try {
send(data);
logger.info(loggerInfo("request ArtificeUI required update"));
} catch (IOException e) {
logger.warn(loggerWarning("request ArtificeUI required update"));
}
}
//----- login / register -----//
public void loginFailed() {
try {
send(new Data.Builder(DataCodes.Server.LOGINFAIL));
logger.info(loggerInfo("login fail"));
} catch (IOException e) {
logger.warn(loggerWarning("login fail"));
}
}
public void loginSuccess() {
try {
send(new Data.Builder(DataCodes.Server.LOGINSUCCESS));
logger.info(loggerInfo("login success"));
} catch (IOException e) {
logger.warn(loggerWarning("login success"));
}
}
public void registerCodeExist() {
try {
send(new Data.Builder(DataCodes.Server.REGISTERCODE_EXIST));
logger.info(loggerInfo("register code exist"));
} catch (IOException e) {
logger.warn(loggerWarning("register code exist"));
}
}
public void registerCodeNotExist() {
try {
send(new Data.Builder(DataCodes.Server.REGISTERCODE_NOT_EXIST));
logger.info(loggerInfo("register code not exist"));
} catch (IOException e) {
logger.warn(loggerWarning("register code not exist"));
}
}
public void registerFailed() {
try {
send(new Data.Builder(DataCodes.Server.REGISTERFAIL));
logger.info(loggerInfo("register fail"));
} catch (IOException e) {
logger.warn(loggerWarning("register fail"));
}
}
public void registerFailed_UserExist() {
try {
send(new Data.Builder(DataCodes.Server.REGISTERFAIL_USER_EXIST));
logger.info(loggerInfo("register fail, user exist"));
} catch (IOException e) {
logger.warn(loggerWarning("register fail, user exist"));
}
}
public void registerSuccess() {
try {
send(new Data.Builder(DataCodes.Server.REGISTERSUCCESS));
System.out.println(new Data.Builder(DataCodes.Server.REGISTERSUCCESS).getDataAsString());
logger.info(loggerInfo("register success"));
} catch (IOException e) {
logger.warn(loggerWarning("register success"));
}
}
//----- filesData ----//
public void filesData(String UUID, File startDirectory) {
Data.Builder data = new Data.Builder(DataCodes.Server.SENDFILESDATA);
String file;
File[] files = startDirectory.listFiles();
int userDirectoryLength = new ServerFiles.user_files(UUID).user_files_dir.length();
for (int i = 0; i < files.length; i++) {
file = startDirectory.getAbsolutePath() + "/" + files[i].getName();
if (files[i].isDirectory()) {
data.addData("d" + i, file.substring(userDirectoryLength));
} else {
data.addData("f" + SizeUnit.BYTES(files[i].length()).toMegabyte() + "MB", file.substring(userDirectoryLength));
}
}
try {
send(data);
logger.info("Send files data");
} catch (IOException e) {
logger.warn("Failed to send user files data");
}
}
public void receiveFile(String file, byte[] privateKey) {
FileReceiver fileReceiver = new FileReceiver(client, new File(file), privateKey, logger);
Executors.newSingleThreadExecutor().execute(() -> {
try {
try {
String md5CheckSum = fileReceiver.main();
} catch (UnexpectedException e) {
logger.warn("An unexpected io exception occurred", e);
} catch (IllegalBlockSizeException | InvalidKeyException | InvalidKeySpecException | BadPaddingException | NoSuchPaddingException e) {
logger.warn("An unexpected exception occurred");
}
logger.info("Received file " + file);
receiveFileSuccess();
} catch (IOException e) {
logger.warn("Failed to receive file " + file);
e.printStackTrace();
}
});
}
public void receiveFileFailed() {
try {
send(new Data.Builder(DataCodes.Server.RECEIVEFILEFAIL));
logger.info(loggerInfo("receive file fail"));
} catch (IOException e) {
logger.warn(loggerWarning("receive file fail"));
}
}
public void receiveFileSuccess() {
try {
send(new Data.Builder(DataCodes.Server.RECEIVEFILESUCCESS));
logger.info(loggerInfo("receive file success"));
} catch (IOException e) {
logger.warn(loggerWarning("receive file success"));
}
}
public void sendFile(File file, byte[] publicKey) {
FileSender fileSender = new FileSender(client, file, publicKey, logger);
Executors.newSingleThreadExecutor().execute(() -> {
try {
String md5CheckSum = null;
try {
md5CheckSum = fileSender.main();
} catch (UnexpectedException e) {
logger.warn("An unexpected io exception occurred", e);
} catch (BadPaddingException | IllegalBlockSizeException | InvalidKeySpecException | InvalidKeyException e) {
logger.warn("An unexpected exception occurred");
}
logger.info("Send file " + file);
sendFileSuccess(md5CheckSum);
} catch (IOException e) {
logger.warn("Failed to send file " + file.getAbsolutePath());
e.printStackTrace();
sendFileFailed();
}
});
}
public void sendFileFailed() {
try {
send(new Data.Builder(DataCodes.Server.SENDFILEFAIL));
logger.info(loggerInfo("send file data"));
} catch (IOException e) {
logger.warn(loggerWarning("send file fail"));
}
}
public void sendFileSuccess(String checkSum) {
try {
Data.Builder data = new Data.Builder(DataCodes.Server.SENDFILESSUCCESS);
data.addData(DataCodes.Params.CheckSum.MD5, checkSum);
send(data);
logger.info(loggerInfo("send file success"));
} catch (IOException e) {
logger.warn(loggerWarning("send file success"));
}
}
}

View File

@ -0,0 +1,345 @@
package org.blueshard.olymp.server;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.blueshard.olymp.Main;
import org.blueshard.olymp.data.Data;
import org.blueshard.olymp.data.DataCodes;
import org.blueshard.olymp.e2ee.E2EEConverter;
import org.blueshard.olymp.exception.*;
import org.blueshard.olymp.logging.ClientLogger;
import org.blueshard.olymp.register_code.RegisterCode;
import org.blueshard.olymp.user.User;
import org.blueshard.olymp.utils.ExceptionUtils;
import org.blueshard.olymp.version.TheosUIVersion;
import javax.net.ServerSocketFactory;
import java.io.*;
import java.lang.reflect.Field;
import java.net.ServerSocket;
import java.net.SocketException;
import java.security.GeneralSecurityException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.Base64;
import java.util.HashSet;
import java.util.concurrent.Executors;
public class MainServer {
private final int port;
private final Logger logger;
private ServerSocket serverSocket = null;
private ClientFactory clientFactory = new ClientFactory();
public MainServer(int port, Logger logger) {
this.port = port;
this.logger = logger;
}
public void start() {
try {
serverSocket = ServerSocketFactory.getDefault().createServerSocket(port);
} catch (IOException e) {
logger.fatal("Couldn't create server");
e.printStackTrace();
return;
}
logger.info("Start server");
logger.info("Server infos: " + serverSocket.toString());
while (true){
ClientFactory.Client client;
try {
client = clientFactory.createNewClient(serverSocket.accept(), null);
} catch (IOException e) {
logger.error("Couldn't connect to new client");
e.printStackTrace();
return;
}
logger.info("New Client connected - ID: " + client.getId());
try {
Executors.newSingleThreadExecutor().execute(() -> {
try {
boolean notLoggedIn = true;
Data inputData;
Logger clientLogger = null;
User user = null;
byte[] clientPublicKey;
if (client.getInetAddress().getHostAddress().equals("127.0.0.1")) {
logger.info("Localhost connected");
DataInputStream dataInputStream = new DataInputStream(client.getInputStream());
DataOutputStream dataOutputStream = new DataOutputStream(client.getOutputStream());
String connectionType = dataInputStream.readUTF().strip().toLowerCase();
switch (connectionType) {
case "sql":
logger.info("Localhost acts in SQL mode");
Connection connection = Main.getConnection();
StringBuilder resultData = new StringBuilder();
ResultSetMetaData resultSetMetaData;
String input;
while (true) {
try {
input = dataInputStream.readUTF().replaceAll("\\s{2,}", " ").strip();
if (input.toLowerCase().equals("exit")) {
logger.info("Localhost exit sql mode");
break;
} else if (input.toLowerCase().startsWith("add register code")) {
String times = input.toLowerCase().substring("add register code".length() - 1);
if (times.isBlank()) {
String registerCode = RegisterCode.generateNewRegisterCode();
logger.info("Localhost generated a new register code ('" + registerCode + "')");
dataOutputStream.writeUTF(registerCode);
} else {
StringBuilder stringBuilder = new StringBuilder();
int intTimes;
try {
intTimes = Integer.parseInt(times);
} catch (NumberFormatException e) {
logger.warn("'" + times + "' is not a valid number", e);
dataOutputStream.writeUTF(ExceptionUtils.extractExceptionMessage(e));
continue;
}
for (int i = 1; i < intTimes + 1; i++) {
stringBuilder.append(RegisterCode.generateNewRegisterCode()).append("\n");
}
logger.info("Localhost generated a new register codes ('" + stringBuilder.toString() + "')");
dataOutputStream.writeUTF(stringBuilder.toString());
}
} else if (input.toLowerCase().startsWith("all register codes")) {
HashSet<String> allRegisterCodes = RegisterCode.getAllRegisterCodes();
logger.info("Localhost got all register codes");
dataOutputStream.writeUTF(Arrays.toString(allRegisterCodes.toArray(new String[allRegisterCodes.size()])));
} else if (input.toLowerCase().startsWith("is register code")) {
String registerCode = input.toLowerCase().substring("is register code".length() - 1);
boolean isRegisterCode = RegisterCode.isRegisterCode(registerCode);
logger.info("Localhost checked register code '" + registerCode + "' for it's validity (" + isRegisterCode + ")");
dataOutputStream.writeUTF(String.valueOf(isRegisterCode));
} else if (input.toLowerCase().startsWith("remove register code")) {
String registerCode = input.toLowerCase().substring("remove register code".length() - 1);
RegisterCode.removeRegisterCode(registerCode);
logger.info("Localhost removed register code '" + registerCode + "'");
} else {
logger.info("Localhost send following SQL query: '" + input + "'");
try {
ResultSet resultSet = connection.createStatement().executeQuery(input);
logger.info("SQL query from localhost executed successfully");
while (resultSet.next()) {
resultSetMetaData = resultSet.getMetaData();
for (int i = 1; i < resultSetMetaData.getColumnCount() + 1; i++) {
resultData.append(resultSetMetaData.getColumnName(i)).append(resultSet.getString(i)).append("\n");
}
}
dataOutputStream.writeUTF(resultData.toString());
logger.info("Sent SQL query result set");
} catch (SQLException e) {
logger.warn("SQL query from localhost caused an error", e);
dataOutputStream.writeUTF(e.getSQLState());
}
resultData.delete(0, resultData.length());
}
} catch (FatalIOException e) {
logger.fatal("Fatal IO Exception occurred (" + ExceptionUtils.errorNumberToString(e.getErrno()) + ")", e);
dataOutputStream.writeUTF("Fatal IO Exception occurred (" + ExceptionUtils.errorNumberToString(e.getErrno()) + ")\n" + ExceptionUtils.extractExceptionMessage(e));
}
}
break;
}
client.close();
logger.info("Localhost disconnected");
return;
}
while (true) {
String clientData = new DataInputStream(client.getInputStream()).readUTF();
if (Data.isDataString(clientData)) {
if (new Data(clientData).getCode() == DataCodes.Client.PUBLICKEY) {
clientPublicKey = Base64.getDecoder().decode(new Data(clientData).getFromData(DataCodes.Params.Key.PUBLICKEY));
logger.info("Received client public key");
break;
} else {
logger.info("Client send invalid data");
}
} else {
logger.info("Client send invalid data");
}
}
byte[] privateKey = Action.publicKey(client.getOutputStream(), logger).getEncoded();
ClientSender clientSender;
try {
clientSender = new ClientSender(client, clientPublicKey, logger);
} catch (GeneralSecurityException ignore) {
return;
}
Action action = new Action(null, clientSender);
String agent = null;
String update = null;
TheosUIVersion version = null;
try {
Data data = new Data(E2EEConverter.decrypt(new DataInputStream(client.getInputStream()).readUTF(), privateKey));
String clientAgent = data.getFromData(DataCodes.Params.ClientAgent.CLIENTAGENT);
if (clientAgent.equals(DataCodes.Params.ClientAgent.THEOSUI)) {
client.setClientAgent(clientAgent);
agent = DataCodes.Params.ClientAgent.THEOSUI;
version = new TheosUIVersion(data.getFromData(DataCodes.Params.Version.VERSION));
if (version.hasRequiredUpdate()) {
logger.info("Client has a deprecated TheosUI version");
update = "r";
} else if (version.hasOptionalUpdate()) {
logger.info("Client has a deprecated TheosUI version");
update = "o";
}
} else {
logger.error("Client use an invalid client agent, connection get closed");
}
} catch (GeneralSecurityException | IllegalAccessException ignore) {
}
action.firstConnectionResult(agent != null, update != null);
if (agent == null) {
clientSender.close();
client.close();
return;
}
if (update != null && agent.equals(DataCodes.Params.ClientAgent.THEOSUI)) {
if (update.equals("r")) {
action.requestArtificeUIRequiredUpdate(version);
} else if (update.equals("o")) {
action.requestArtificeUIOptionalUpdate(version);
}
}
while (notLoggedIn) {
try {
inputData = new Data(E2EEConverter.decrypt(new DataInputStream(client.getInputStream()).readUTF(), privateKey));
} catch (IOException | GeneralSecurityException e) {
clientSender.unexpectedError();
return;
}
action.refreshData(inputData);
switch (inputData.getCode()) {
case DataCodes.Client.CLOSE:
case DataCodes.Client.UNEXPECTEDEXIT:
return;
case DataCodes.Client.REGISTERCODE:
action.isRegisterCode();
break;
case DataCodes.Client.LOGIN:
try {
user = action.login();
if (String.valueOf(user.getLogLevel()).equals(DataCodes.Params.LogLevel.ALL)) {
clientLogger = new ClientLogger(client, Level.ALL).getLogger();
} else if (String.valueOf(user.getLogLevel()).equals(DataCodes.Params.LogLevel.WARNING)) {
clientLogger = new ClientLogger(client, Level.WARN).getLogger();
} else {
clientLogger = new ClientLogger(client, Level.OFF).getLogger();
}
logger.info("New Client details - IP: " + client.getIPAddress() + "\n" +
"Port: " + client.getPort());
logger.info("Logged in successfully");
notLoggedIn = false;
} catch (IOException | UserNotExistException | IllegalPasswordException e) {
clientSender.loginFailed();
logger.warn("Login failed", e);
} catch (IllegalCodeException e) {
clientSender.unexpectedError();
logger.warn("An unexpected error occurred", e);
}
break;
case DataCodes.Client.REGISTER:
try {
user = action.register();
clientLogger = new ClientLogger(client, Level.OFF).getLogger();
logger.info("Registered in successfully");
notLoggedIn = false;
} catch (IOException e) {
clientSender.registerFailed();
logger.warn("Register failed", e);
} catch (UserAlreadyExistException e) {
clientSender.registerFailed_UserExist();
logger.warn("Couldn't register, user already exist", e);
} catch (RegisterCodeNotExistException e) {
clientSender.registerCodeNotExist();
logger.warn("Couldn't register, given register code do not exist");
}
break;
default:
clientSender.userNotLoggedIn();
logger.warn("User isn't logged in");
break;
}
}
int resultCode = new ClientReceiver(user, client, clientSender, clientPublicKey, privateKey, clientLogger).main();
if (resultCode == ClientReceiver.ResultCodes.EXIT) {
client.close();
logger.info("Closed connection to client");
} else if (resultCode == ClientReceiver.ResultCodes.UNEXPECTEDEXIT) {
client.close();
logger.warn("Unexpected closed the connection to client");
}
} catch (SocketException e) {
logger.error("Socket Exception for client " + client.getId() + " occurred", e);
} catch (IOException e) {
logger.error("IO Exception for client " + client.getId() +" occurred", e);
} catch (FatalIOException e) {
String name;
int errno;
ErrorCodes errorCodes = new ErrorCodes();
Field[] fields = ErrorCodes.class.getFields();
for (Field field : fields) {
try {
name = field.getName();
errno = (int) field.get(errorCodes);
if (errno == e.getErrno()) {
logger.fatal("Fatal IOException occurred while login or register - Errno: " + e.getErrno() + " (" + name + ")", e);
return;
}
} catch (IllegalAccessException illegalAccessException) {
illegalAccessException.printStackTrace();
}
}
logger.error("Fatal IOException occurred while login or register - Errno: " + e.getErrno(), e);
} catch (UnexpectedException e) {
e.printStackTrace();
}
});
} catch (Exception e) {
StringWriter stringWriter = new StringWriter();
e.printStackTrace(new PrintWriter(stringWriter));
logger.error("An unexpected error occurred: " + stringWriter, e);
}
}
}
public void close() throws IOException {
serverSocket.close();
logger.info("Closed server");
}
}

View File

@ -0,0 +1,39 @@
package org.blueshard.olymp.sql;
import org.blueshard.olymp.Main;
import java.sql.*;
public class SQL {
private Connection connection = null;
public SQL () {
try {
Class.forName("org.hsqldb.jdbcDriver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
return;
}
try {
connection = DriverManager.getConnection("jdbc:hsqldb:file:/srv/hsqldb/olympdb/olympdb", "OLYMP", "&C=@zFR7kLQvGy%e");
} catch (SQLException e) {
e.printStackTrace();
return;
}
}
public void close() throws SQLException {
connection.close();
}
public Connection getConnection() {
return connection;
}
public static void checkpoint() throws SQLException {
Main.getConnection().createStatement().execute("CHECKPOINT");
}
}

View File

@ -0,0 +1,22 @@
package org.blueshard.olymp.sql;
public class SQLPosition {
public static class USERS {
public static final int UUID = 1;
public static final int USERNAME = 2;
public static final int PASSWORD = 3;
public static final int SALT = 4;
public static final int MAIL = 5;
public static final int ACTIVE = 6;
public static final int USERLEVEL = 7;
public static final int LOGLEVEL = 8;
public static final int MAX_FILES = 9;
public static final int FILES = 10;
public static final int MAX_FILES_SIZE = 11;
public static final int FILES_SIZE = 12;
}
}

View File

@ -0,0 +1,146 @@
package org.blueshard.olymp.user;
import org.blueshard.olymp.Main;
import org.blueshard.olymp.exception.*;
import org.blueshard.olymp.files.ServerFiles;
import org.blueshard.olymp.register_code.RegisterCode;
import org.blueshard.olymp.security.Password;
import org.blueshard.olymp.sql.SQL;
import org.blueshard.olymp.sql.SQLPosition;
import org.blueshard.olymp.utils.*;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.sql.*;
import java.util.*;
public class User extends UserInfos {
private Password.PasswordInfos passwordInfos;
public User(String UUID) throws UserNotExistException, FatalIOException {
super(UUID);
if (!isUser(UUID)){
throw new UserNotExistException(UUID, "The user " + UUID + " doesn't exists");
}
try {
PreparedStatement preparedStatement = Main.getConnection().prepareStatement("SELECT PASSWORD, SALT FROM USERS WHERE (UUID = ?)");
preparedStatement.setString(1, UUID);
ResultSet resultSet = preparedStatement.executeQuery();
if (resultSet.next()) {
passwordInfos = new Password.PasswordInfos(Base64.getDecoder().decode(resultSet.getString(1)), Base64.getDecoder().decode(resultSet.getString(2)));
}
} catch (SQLException e) {
e.printStackTrace();
throw new FatalIOException(ErrorCodes.couldnt_get_user_information, "Couldn't get user information for user " + UUID, e);
}
}
public boolean equalsPassword(String clearPassword) throws InvalidKeySpecException {
return Password.createPassword(clearPassword, passwordInfos.getSaltAsBytes()).getPasswordAsString().equals(passwordInfos.getPasswordAsString());
}
public static User createNewUser(String registerCode, String username, String password, String salt, String mailAddress) throws FatalIOException, UserAlreadyExistException, RegisterCodeNotExistException {
if (isUser(username)) {
throw new UserAlreadyExistException(username, "The user " + username + " already exists");
}
if (!RegisterCode.isRegisterCode(registerCode)) {
throw new RegisterCodeNotExistException(registerCode);
}
String uuid = UUID.randomUUID().toString();
File userDirectory = new File(new ServerFiles.user_files(uuid).user_files_dir);
if (!userDirectory.mkdir()) {
throw new FatalIOException(ErrorCodes.couldnt_create_userfiles_folder, "Couldn't create " + new ServerFiles.user_files(uuid).user_files_dir);
}
//--------------------------------------------------------------------------------------//
try {
PreparedStatement preparedStatement = Main.getConnection().prepareStatement("INSERT INTO USERS (UUID, USERNAME, PASSWORD, SALT, EMAIL) VALUES (?, ?, ?, ?, ?)");
preparedStatement.setString(1, uuid);
preparedStatement.setString(2, username);
preparedStatement.setString(3, password);
preparedStatement.setString(4, salt);
preparedStatement.setString(5, mailAddress);
preparedStatement.executeUpdate();
SQL.checkpoint();
} catch (SQLException e) {
throw new FatalIOException(ErrorCodes.couldnt_create_user_information, "Failed to add new user", e);
}
RegisterCode.removeRegisterCode(registerCode);
try {
return new User(username);
} catch (UserNotExistException e) {
//shouldn't get thrown
return null;
}
}
public static void deleteUser(String UUID) throws FatalIOException, IOException {
try {
PreparedStatement preparedStatement = Main.getConnection().prepareStatement("DELETE FROM USERS WHERE UUID = ?");
preparedStatement.setString(1, UUID);
preparedStatement.executeUpdate();
SQL.checkpoint();
} catch (SQLException e) {
throw new FatalIOException(ErrorCodes.couldnt_delete_user_information, "Couldn't delete user information for user " + UUID, e);
}
File file;
ArrayList<File> customUserFiles = FileUtils.getAllFilesInDirectory(new ServerFiles.user_files(UUID).user_files_dir);
ListIterator<File> customUserFileListIterator = customUserFiles.listIterator(customUserFiles.size());
while(customUserFileListIterator.hasPrevious()) {
file = customUserFileListIterator.previous();
if (!file.delete()) {
if (file.isDirectory()) {
throw new FatalIOException(ErrorCodes.couldnt_delete_custom_user_directory, "Couldn't delete custom user folder " + file.getAbsolutePath());
} else {
throw new FatalIOException(ErrorCodes.couldnt_delete_custom_user_file, "Couldn't delete custom user file " + file.getAbsolutePath());
}
}
}
}
public static boolean isUser(String UUID) throws FatalIOException {
try {
Statement statement = Main.getConnection().createStatement();
ResultSet resultSet = statement.executeQuery("SELECT UUID FROM USERS");
while (resultSet.next()) {
if (resultSet.getString(1).equals(UUID)) {
return true;
}
}
resultSet.close();
return false;
} catch (SQLException e) {
throw new FatalIOException(ErrorCodes.couldnt_get_user_information, "Couldn't get all usernames", e);
}
}
}

View File

@ -0,0 +1,112 @@
package org.blueshard.olymp.user;
import org.blueshard.olymp.Main;
import org.blueshard.olymp.exception.ErrorCodes;
import org.blueshard.olymp.exception.FatalIOException;
import org.blueshard.olymp.files.ConfReader;
import org.blueshard.olymp.files.ConfWriter;
import org.blueshard.olymp.files.ServerFiles;
import org.blueshard.olymp.security.Password;
import org.blueshard.olymp.sql.SQL;
import org.blueshard.olymp.sql.SQLPosition;
import java.io.*;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Base64;
import java.util.TreeMap;
public class UserInfos {
private final String UUID;
private String username;
private Password.PasswordInfos passwordInfos;
private String mail;
private boolean active;
private int userLevel;
private int logLevel;
private long maxFiles;
private long files;
private double maxFilesSize;
private double filesSize;
public UserInfos(String UUID) throws FatalIOException {
try {
PreparedStatement preparedStatement = Main.getConnection().prepareStatement("SELECT * FROM USERS WHERE (UUID = ?)");
preparedStatement.setString(1, UUID);
ResultSet resultSet = preparedStatement.executeQuery();
if (resultSet.next()) {
this.UUID = UUID;
this.username = resultSet.getString(SQLPosition.USERS.USERNAME);
this.passwordInfos = new Password.PasswordInfos(Base64.getDecoder().decode(resultSet.getString(SQLPosition.USERS.PASSWORD)),
Base64.getDecoder().decode(resultSet.getString(SQLPosition.USERS.SALT)));
this.mail = resultSet.getString(SQLPosition.USERS.MAIL);
this.active = resultSet.getBoolean(SQLPosition.USERS.ACTIVE);
this.userLevel = resultSet.getInt(SQLPosition.USERS.USERLEVEL);
this.logLevel = resultSet.getInt(SQLPosition.USERS.LOGLEVEL);
this.maxFiles = resultSet.getLong(SQLPosition.USERS.MAX_FILES);
this.files = resultSet.getLong(SQLPosition.USERS.FILES);
this.maxFilesSize = resultSet.getDouble(SQLPosition.USERS.MAX_FILES_SIZE);
this.filesSize = resultSet.getDouble(SQLPosition.USERS.FILES_SIZE);
} else {
throw new FatalIOException(ErrorCodes.couldnt_get_user_information, "Couldn't get user information for user " + UUID);
}
} catch (SQLException e) {
e.printStackTrace();
throw new FatalIOException(ErrorCodes.couldnt_get_user_information, "Couldn't get user information for user " + UUID, e);
}
}
public String getUUID() {
return UUID;
}
public String getUsername() {
return username;
}
public Password.PasswordInfos getPasswordInfos() {
return passwordInfos;
}
public String getMail() {
return mail;
}
public boolean getActive() {
return active;
}
public int getUserLevel() {
return userLevel;
}
public int getLogLevel() {
return logLevel;
}
public long getMaxFiles() {
return maxFiles;
}
public long getFiles() {
return files;
}
public double getMaxFilesSize() {
return maxFilesSize;
}
public double getFilesSize() {
return filesSize;
}
public String getUserfileDirectory() {
return new ServerFiles.user_files(getUUID()).user_files_dir;
}
}

View File

@ -0,0 +1 @@
#empty

View File

@ -0,0 +1,76 @@
package org.blueshard.olymp.utils;
public class ConsoleColors {
// Reset
public static final String RESET = "\033[0m"; // Text Reset
// Regular Colors
public static final String BLACK = "\033[0;30m"; // BLACK
public static final String RED = "\033[0;31m"; // RED
public static final String GREEN = "\033[0;32m"; // GREEN
public static final String YELLOW = "\033[0;33m"; // YELLOW
public static final String BLUE = "\033[0;34m"; // BLUE
public static final String PURPLE = "\033[0;35m"; // PURPLE
public static final String CYAN = "\033[0;36m"; // CYAN
public static final String WHITE = "\033[0;37m"; // WHITE
// Bold
public static final String BLACK_BOLD = "\033[1;30m"; // BLACK
public static final String RED_BOLD = "\033[1;31m"; // RED
public static final String GREEN_BOLD = "\033[1;32m"; // GREEN
public static final String YELLOW_BOLD = "\033[1;33m"; // YELLOW
public static final String BLUE_BOLD = "\033[1;34m"; // BLUE
public static final String PURPLE_BOLD = "\033[1;35m"; // PURPLE
public static final String CYAN_BOLD = "\033[1;36m"; // CYAN
public static final String WHITE_BOLD = "\033[1;37m"; // WHITE
// Underline
public static final String BLACK_UNDERLINED = "\033[4;30m"; // BLACK
public static final String RED_UNDERLINED = "\033[4;31m"; // RED
public static final String GREEN_UNDERLINED = "\033[4;32m"; // GREEN
public static final String YELLOW_UNDERLINED = "\033[4;33m"; // YELLOW
public static final String BLUE_UNDERLINED = "\033[4;34m"; // BLUE
public static final String PURPLE_UNDERLINED = "\033[4;35m"; // PURPLE
public static final String CYAN_UNDERLINED = "\033[4;36m"; // CYAN
public static final String WHITE_UNDERLINED = "\033[4;37m"; // WHITE
// Background
public static final String BLACK_BACKGROUND = "\033[40m"; // BLACK
public static final String RED_BACKGROUND = "\033[41m"; // RED
public static final String GREEN_BACKGROUND = "\033[42m"; // GREEN
public static final String YELLOW_BACKGROUND = "\033[43m"; // YELLOW
public static final String BLUE_BACKGROUND = "\033[44m"; // BLUE
public static final String PURPLE_BACKGROUND = "\033[45m"; // PURPLE
public static final String CYAN_BACKGROUND = "\033[46m"; // CYAN
public static final String WHITE_BACKGROUND = "\033[47m"; // WHITE
// High Intensity
public static final String BLACK_BRIGHT = "\033[0;90m"; // BLACK
public static final String RED_BRIGHT = "\033[0;91m"; // RED
public static final String GREEN_BRIGHT = "\033[0;92m"; // GREEN
public static final String YELLOW_BRIGHT = "\033[0;93m"; // YELLOW
public static final String BLUE_BRIGHT = "\033[0;94m"; // BLUE
public static final String PURPLE_BRIGHT = "\033[0;95m"; // PURPLE
public static final String CYAN_BRIGHT = "\033[0;96m"; // CYAN
public static final String WHITE_BRIGHT = "\033[0;97m"; // WHITE
// Bold High Intensity
public static final String BLACK_BOLD_BRIGHT = "\033[1;90m"; // BLACK
public static final String RED_BOLD_BRIGHT = "\033[1;91m"; // RED
public static final String GREEN_BOLD_BRIGHT = "\033[1;92m"; // GREEN
public static final String YELLOW_BOLD_BRIGHT = "\033[1;93m";// YELLOW
public static final String BLUE_BOLD_BRIGHT = "\033[1;94m"; // BLUE
public static final String PURPLE_BOLD_BRIGHT = "\033[1;95m";// PURPLE
public static final String CYAN_BOLD_BRIGHT = "\033[1;96m"; // CYAN
public static final String WHITE_BOLD_BRIGHT = "\033[1;97m"; // WHITE
// High Intensity backgrounds
public static final String BLACK_BACKGROUND_BRIGHT = "\033[0;100m";// BLACK
public static final String RED_BACKGROUND_BRIGHT = "\033[0;101m";// RED
public static final String GREEN_BACKGROUND_BRIGHT = "\033[0;102m";// GREEN
public static final String YELLOW_BACKGROUND_BRIGHT = "\033[0;103m";// YELLOW
public static final String BLUE_BACKGROUND_BRIGHT = "\033[0;104m";// BLUE
public static final String PURPLE_BACKGROUND_BRIGHT = "\033[0;105m"; // PURPLE
public static final String CYAN_BACKGROUND_BRIGHT = "\033[0;106m"; // CYAN
public static final String WHITE_BACKGROUND_BRIGHT = "\033[0;107m"; // WHITE
}

View File

@ -0,0 +1,38 @@
package org.blueshard.olymp.utils;
import org.blueshard.olymp.exception.ErrorCodes;
import java.lang.reflect.Field;
import java.util.Arrays;
public class ExceptionUtils {
public static String errorNumberToString(int errorNumber) {
String name;
int errno;
ErrorCodes errorCodes = new ErrorCodes();
Field[] fields = ErrorCodes.class.getFields();
for (Field field : fields) {
try {
name = field.getName();
errno = (int) field.get(errorCodes);
if (errno == errorNumber) {
return name;
}
} catch (IllegalAccessException illegalAccessException) {
illegalAccessException.printStackTrace();
}
}
return null;
}
public static String extractExceptionMessage(Throwable throwable) {
StringBuilder stringBuilder = new StringBuilder();
Arrays.asList(throwable.getStackTrace()).forEach(stackTraceElement -> stringBuilder.append(stackTraceElement).append("\n"));
return stringBuilder.toString();
}
}

View File

@ -0,0 +1,70 @@
package org.blueshard.olymp.utils;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Arrays;
public class FileUtils {
public static ArrayList<File> getAllFilesInDirectory(String path) throws IOException {
ArrayList<File> files = new ArrayList<>();
Files.walk(Paths.get(path)).map(Path::toFile).forEach(files::add);
return files;
}
public static File[] sortFilesInDirectory(File path) {
File[] files = path.listFiles();
Arrays.sort(files, (object1, object2) -> object1.getName().compareToIgnoreCase(object2.getName()));
return files;
}
public class CreateHashSum {
String file;
CreateHashSum(String file) {
this.file = file;
}
public String MD5() throws IOException {
try {
StringBuilder hexString = new StringBuilder();
MessageDigest md5 = MessageDigest.getInstance("MD5");
InputStream inputStream = Files.newInputStream(Paths.get(file));
byte[] buffer = new byte[1024];
int length;
while ((length = inputStream.read(buffer)) > 0) {
md5.update(buffer, 0 , length);
}
byte[] digest = md5.digest();
for (byte b : digest) {
if ((0xff & b) < 0x10) {
hexString.append("0").append(Integer.toHexString((0xFF & b)));
} else {
hexString.append(Integer.toHexString(0xFF & b));
}
}
return hexString.toString();
} catch (NoSuchAlgorithmException ignore) {
return null;
}
}
}
}

View File

@ -0,0 +1,196 @@
package org.blueshard.olymp.utils;
public class SizeUnit {
private int unit;
private double size;
private final static int BYTE = 1;
private final static int KILOBYTE = 3;
private final static int MEGABYTE = 5;
private final static int GIGABYTE = 7;
private final static int TERRABYTE = 9;
private final static int PETABYTE = 11;
private final static int EXABYTE = 13;
SizeUnit(int unit, double size){
this.unit = unit;
this.size = size;
}
public static SizeUnit BYTES(double bytes){
return new SizeUnit(BYTE, bytes);
}
public static SizeUnit KILOBYTE(double kilobytes) {
return new SizeUnit(KILOBYTE, kilobytes);
}
public static SizeUnit MEGABYTE(double megabytes) {
return new SizeUnit(MEGABYTE, megabytes);
}
public static SizeUnit GIGABYTE(double gigabytes) {
return new SizeUnit(GIGABYTE, gigabytes);
}
public static SizeUnit TERRABYTE(double terrabytes) {
return new SizeUnit(TERRABYTE, terrabytes);
}
public static SizeUnit PETABYTE(double petabytes) {
return new SizeUnit(PETABYTE, petabytes);
}
public static SizeUnit EXABYTE(double exabytes) {
return new SizeUnit(EXABYTE, exabytes);
}
public Double toByte(){
switch (unit) {
case BYTE:
return size;
case KILOBYTE:
return size * 1000;
case MEGABYTE:
return size * 1000000;
case GIGABYTE:
return size * 1000000000;
case TERRABYTE:
return size * 1000000000000L;
case PETABYTE:
return size * 1000000000000000L;
case EXABYTE:
return size * 1000000000000000000L;
default:
return 0D;
}
}
public Double toKilobyte(){
switch (unit) {
case BYTE:
return size / 1000;
case KILOBYTE:
return size;
case MEGABYTE:
return size * 1000;
case GIGABYTE:
return size * 1000000;
case TERRABYTE:
return size * 1000000000;
case PETABYTE:
return size * 1000000000000L;
case EXABYTE:
return size * 1000000000000000L;
default:
return 0D;
}
}
public Double toMegabyte(){
switch (unit) {
case BYTE:
return size / 1000000;
case KILOBYTE:
return size / 1000;
case MEGABYTE:
return size;
case GIGABYTE:
return size * 1000;
case TERRABYTE:
return size * 1000000;
case PETABYTE:
return size * 1000000000;
case EXABYTE:
return size * 1000000000000L;
default:
return 0D;
}
}
public Double toGigabyte(){
switch (unit) {
case BYTE:
return size / 1000000000L;
case KILOBYTE:
return size / 1000000;
case MEGABYTE:
return size / 1000;
case GIGABYTE:
return size;
case TERRABYTE:
return size * 1000;
case PETABYTE:
return size * 1000000;
case EXABYTE:
return size * 1000000000;
default:
return 0D;
}
}
public Double toTerrabyte(){
switch (unit) {
case BYTE:
return size / 1000000000000L;
case KILOBYTE:
return size / 1000000000;
case MEGABYTE:
return size / 1000000;
case GIGABYTE:
return size / 1000;
case TERRABYTE:
return size;
case PETABYTE:
return size * 1000;
case EXABYTE:
return size * 1000000;
default:
return 0D;
}
}
public Double toPetabyte(){
switch (unit) {
case BYTE:
return size / 1000000000000000L;
case KILOBYTE:
return size / 1000000000000L;
case MEGABYTE:
return size / 1000000000;
case GIGABYTE:
return size / 1000000;
case TERRABYTE:
return size / 1000;
case PETABYTE:
return size;
case EXABYTE:
return size * 1000;
default:
return 0D;
}
}
public Double toExabyte(){
switch (unit) {
case BYTE:
return size / 1000000000000000000L;
case KILOBYTE:
return size / 1000000000000000L;
case MEGABYTE:
return size / 1000000000000L;
case GIGABYTE:
return size / 1000000000;
case TERRABYTE:
return size / 1000000;
case PETABYTE:
return size / 1000;
case EXABYTE:
return size;
default:
return 0D;
}
}
}

View File

@ -0,0 +1,17 @@
package org.blueshard.olymp.utils;
import java.util.Map;
public class StringUtils {
public static String format(String string, Map<String, String> formatMap){
for(Map.Entry<String, String> entry: formatMap.entrySet()) {
string = string.replace("{" + entry.getKey() + "}", entry.getValue());
}
return string;
}
}

View File

@ -0,0 +1,40 @@
package org.blueshard.olymp.version;
public class ServerVersion extends Version {
public ServerVersion(String version) {
super(version);
}
@Override
public int toInt() {
switch (toString()) {
case "0.1.0":
return 1;
default:
return 0;
}
}
public boolean higherThan(String version) {
return higherThan(new ServerVersion(version));
}
@Override
public boolean higherThan(Version version) {
return toInt() > version.toInt();
}
public boolean lowerThan(String version) {
return lowerThan(new ServerVersion(version));
}
@Override
public boolean lowerThan(Version version) {
return toInt() < version.toInt();
}
public static ServerVersion currentVersion() {
return new ServerVersion("0.1.0");
}
}

View File

@ -0,0 +1,133 @@
package org.blueshard.olymp.version;
import org.blueshard.olymp.exception.ErrorCodes;
import org.blueshard.olymp.exception.FatalIOException;
import org.blueshard.olymp.files.ConfReader;
import org.blueshard.olymp.files.ServerFiles;
import java.io.IOException;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
public class TheosUIVersion extends Version {
TreeMap<String, String> versions;
Set<String> versionsKeySet;
public TheosUIVersion(String version) throws FatalIOException {
super(version);
try {
versions = new ConfReader.MultipleConfReader(ServerFiles.etc.versions).getAll("TheosUI", true);
} catch (IOException e) {
throw new FatalIOException(ErrorCodes.couldnt_read_versions_conf, "Failed to read versions.conf", e);
}
versionsKeySet = versions.keySet();
}
@Override
public int toInt() {
String[] allVersions = versionsKeySet.toArray(new String[versionsKeySet.size()]);
for (int i = 0; i < allVersions.length; i++) {
if (allVersions[i].equals(toString())) {
return i + 1;
}
}
return 0;
}
private int toInt(String version) {
String[] allVersions = versionsKeySet.toArray(new String[versionsKeySet.size()]);
for (int i = 0; i < allVersions.length; i++) {
if (allVersions[i].equals(version)) {
return i + 1;
}
}
return 0;
}
public boolean higherThan(String version) {
return toInt() > toInt(version);
}
@Override
public boolean higherThan(Version version) {
return toInt() > toInt(version.toString());
}
public boolean lowerThan(String version) {
return toInt() < toInt(version);
}
@Override
public boolean lowerThan(Version version) {
return toInt() < toInt(version.toString());
}
public String getChanges() {
return versions.get(toString()).split(":")[1];
}
public boolean hasOptionalUpdate() throws FatalIOException {
if (toInt() != currentVersion().toInt()) {
Map<String, String> reverseVersions = versions.descendingMap();
for (Map.Entry<String, String> stringStringEntry : reverseVersions.entrySet()) {
String key = stringStringEntry.getKey();
String value = stringStringEntry.getValue().split(":")[0];
if (!key.equals(toString())) {
if (value.equals("optional")) {
return true;
}
} else {
return false;
}
}
}
return false;
}
public boolean hasRequiredUpdate() throws FatalIOException {
if (toInt() != currentVersion().toInt()) {
Map<String, String> reverseVersions = versions.descendingMap();
for (Map.Entry<String, String> stringStringEntry : reverseVersions.entrySet()) {
String key = stringStringEntry.getKey();
String value = stringStringEntry.getValue().split(":")[0];
if (!key.equals(toString())) {
if (value.equals("required")) {
return true;
}
} else {
return false;
}
}
}
return false;
}
public static TheosUIVersion currentVersion() throws FatalIOException {
try {
return new TheosUIVersion(new ConfReader.MultipleConfReader(ServerFiles.etc.versions).getAll("TheosUI", true).lastKey());
} catch (IOException e) {
throw new FatalIOException(ErrorCodes.couldnt_read_versions_conf, "Failed to read versions.conf", e);
}
}
public static TheosUIVersion toArtificeUIVersion(int versionAsInt) throws IOException, FatalIOException {
Set<String> versionsKeySet = new ConfReader.MultipleConfReader(ServerFiles.etc.versions).getAll("TheosUI", true).keySet();
String[] allVersions = versionsKeySet.toArray(new String[versionsKeySet.size()]);
for (int i = allVersions.length; i > 0; i--) {
if (i == versionAsInt) {
return new TheosUIVersion(allVersions[i]);
}
}
return null;
}
}

View File

@ -0,0 +1,21 @@
package org.blueshard.olymp.version;
public abstract class Version {
private final String version;
public Version(String version) {
this.version = version;
}
@Override
public String toString() {
return version;
}
public abstract int toInt();
public abstract boolean higherThan(Version version);
public abstract boolean lowerThan(Version version);
}

View File

@ -0,0 +1,16 @@
package org.blueshard.sekaijuclt;
import org.apache.log4j.Level;
import org.blueshard.sekaijuclt.client.MainClient;
import org.blueshard.sekaijuclt.logging.MainLogger;
import java.io.IOException;
public class Main {
public static void main(String[] args) throws IOException {
MainClient client = new MainClient(8269, "192.168.2.104", new MainLogger(Level.ALL).getLogger());
client.start("/srv/ssl/sslTrustStore.jks", "@VR&_*p%9!L+kC3FZ4QX");
}
}

View File

@ -0,0 +1 @@
#empty

View File

@ -0,0 +1,52 @@
package org.blueshard.sekaijuclt.client;
import org.blueshard.sekaijuclt.data.Data;
import org.blueshard.sekaijuclt.data.DataCodes;
import org.blueshard.sekaijuclt.exception.IllegalCodeException;
import org.blueshard.sekaijuclt.security.Password;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
public class Action {
private final DataInputStream dataInputStream;
private final ServerSender serverSender;
public Action(InputStream inputStream, ServerSender serverSender) {
this.dataInputStream = new DataInputStream(inputStream);
this.serverSender = serverSender;
}
public int login(String username, String clearPassword) throws IOException {
Password.PasswordInfos passwordInfos = Password.createPassword(clearPassword, new byte[64]);
serverSender.login(username, passwordInfos);
return new Data(dataInputStream.readUTF()).getCode();
}
public int register(String username, String clearPassword, String email) throws IOException {
Password.PasswordInfos passwordInfos = Password.createPassword(clearPassword, new byte[64]);
serverSender.register(username, passwordInfos, email);
return new Data(dataInputStream.readUTF()).getCode();
}
public String[][] getFilesData(String directory) throws IOException, IllegalCodeException {
serverSender.getFilesData();
Data data = new Data(dataInputStream.readUTF());
String[][] files = new String[2][data.getData().hashCode()];
if (data.getCode() != DataCodes.Server.SENDFILESDATA) {
throw new IllegalCodeException(data.getCode(), DataCodes.Server.SENDFILESDATA);
}
data.getData().forEach((index, file) -> {
if (index.startsWith("d")) {
files[0][Integer.parseInt(index.substring(1))] = file;
} else {
files[1][Integer.parseInt(index.substring(1))] = file;
}
});
return files;
}
}

View File

@ -0,0 +1,110 @@
package org.blueshard.sekaijuclt.client;
import org.apache.log4j.Logger;
import org.blueshard.sekaijuclt.data.DataCodes;
import org.blueshard.sekaijuclt.exception.IllegalCodeException;
import org.blueshard.sekaijuserv.data.Data;
import org.blueshard.sekaijuserv.exception.UnexpectedException;
import org.blueshard.sekaijuserv.server.ClientSender;
import org.blueshard.sekaijuserv.user.UserParams;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import java.io.*;
import java.security.GeneralSecurityException;
import java.util.Base64;
public class MainClient {
private final int serverPort;
private final String serverIP;
private final Logger logger;
public MainClient(int serverPort, String serverIP, Logger logger) {
this.serverPort = serverPort;
this.serverIP = serverIP;
this.logger = logger;
}
public void start(String trustStoreFile, String trustStorePassword) throws IOException {
System.setProperty("javax.net.ssl.trustStore", trustStoreFile);
System.setProperty("javax.net.ssl.trustStorePassword", trustStorePassword);
SSLSocket server = (SSLSocket) SSLSocketFactory.getDefault().createSocket("192.168", 8269);
byte[] privateKey;
try {
privateKey = new org.blueshard.sekaijuserv.server.Action(null, new ClientSender(server, new byte[0], logger)).publicKey().getEncoded();
} catch (GeneralSecurityException | UnexpectedException ignore) {
return;
}
byte[] serverPublicKey = Base64.getDecoder().decode(new Data(new DataInputStream(server.getInputStream()).readUTF()).getFromData(UserParams.Key.PUBLICKEY));
ServerSender serverSender;
try {
serverSender = new ServerSender(server.getOutputStream(), serverPublicKey, logger);
} catch (GeneralSecurityException | UnexpectedException ignore) {
return;
}
Action action = new Action(null, serverSender);
logger.info("Started client");
Console console = System.console();
while (true) {
String logReg = console.readLine("To connect type 'login' to login, or 'register' to register: ").strip().toLowerCase();
if (logReg.equals("login")) {
String username = console.readLine("Username: ").strip();
String password = String.valueOf(console.readPassword("Password: ")).strip();
int resultCode = action.login(username, password);
if (resultCode == DataCodes.Server.LOGINFAIL) {
logger.warn("Login failed");
} else if (resultCode == DataCodes.Server.LOGINSUCCESS) {
logger.info("Logged in successfully");
break;
} else if (resultCode == DataCodes.Server.UNEXPECTEDERROR) {
logger.warn("An unexpected error occurred");
} else if (resultCode == DataCodes.Server.UNEXPECTEDEXIT) {
logger.fatal("Server exited unexpected");
return;
}
} else if (logReg.equals("register")) {
String password;
String passwordAgain;
String username = console.readLine("Username: ");
do {
password = String.valueOf(console.readPassword("Password: "));
passwordAgain = String.valueOf(console.readPassword("Re-type your Password: "));
} while (!password.equals(passwordAgain));
String email = console.readLine("Email: ");
int resultCode = action.register(username, password, email);
if (resultCode == DataCodes.Server.REGISTERFAIL) {
logger.warn("Register failed");
} else if (resultCode == DataCodes.Server.REGISTERFAIL_USER_EXIST) {
logger.warn("The user already exists");
} else if (resultCode == DataCodes.Server.REGISTERSUCCESS) {
logger.info("Registered successfully");
break;
} else if (resultCode == DataCodes.Server.UNEXPECTEDERROR) {
logger.warn("An unexpected error occurred");
} else if (resultCode == DataCodes.Server.UNEXPECTEDEXIT) {
logger.fatal("Server exited unexpected");
return;
}
}
}
ServerSendRecv sendRecv = new ServerSendRecv(server, logger);
try {
sendRecv.main();
} catch (IllegalCodeException e) {
serverSender.unexpectedExit();
}
}
}

View File

@ -0,0 +1,143 @@
package org.blueshard.sekaijuclt.client;
import org.apache.log4j.Logger;
import org.blueshard.sekaijuclt.exception.IllegalCodeException;
import javax.net.ssl.SSLSocket;
import java.io.Console;
import java.io.DataInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
public class ServerSendRecv {
private final Logger logger;
private final Action action;
private final DataInputStream serverInput;
private final ServerSender serverSender;
public ServerSendRecv(SSLSocket socket, ServerSender serverSender, byte[] privateKey, Logger logger) throws IOException {
this.logger = logger;
try {
this.serverInput = new DataInputStream(socket.getInputStream());
this.serverSender = serverSender;
} catch (IOException e) {
throw new IOException(ResultCode.UNEXPECTEDEXIT + ";" + e.getMessage());
}
this.action = new Action(socket.getInputStream(), this.serverSender);
}
public int main() throws IOException, IllegalCodeException {
Console console = System.console();
String input;
System.out.println("Type ... to ...: " +
" exit Close connection to server" +
" file-mode Enter file mode");
while (true) {
input = console.readLine("Action: ").strip().toLowerCase();
if (input.equals("exit")) {
serverSender.exit();
return ResultCode.EXIT;
} else if (input.equals("file-mode")) {
while (true) {
SendRecvFiles files = new SendRecvFiles(action);
input = console.readLine(files.getCurrentDirectory() + ": ").strip().toLowerCase();
if (input.startsWith("cd")) {
files.cdDirectory(input.substring(2).strip());
} else if (input.equals("ls")) {
StringBuilder stringBuilder = new StringBuilder();
files.listFilesAsList().forEach(s -> stringBuilder.append(s).append(" "));
System.out.println(stringBuilder.toString());
} else if (input.equals("exit")) {
return ResultCode.EXIT;
}
}
}
}
}
public static class SendRecvFiles {
private final Action action;
private ArrayList<String> currentDirectory = new ArrayList<>();
private HashMap<String, Object> files = new HashMap<>();
public SendRecvFiles(Action action) throws IOException, IllegalCodeException {
this.action = action;
addToFiles(action.getFilesData(""));
}
private void addToFiles(String[][] data) {
for (int i = 0; i < data[0].length; i++) {
files.put(data[0][i], new HashMap<>());
}
for (int i = 0; i < data[1].length; i++) {
files.put(data[1][i], null);
}
}
private ArrayList<String> toSortedArrayList(String[] files) {
Arrays.sort(files, String::compareToIgnoreCase);
return new ArrayList<>(Arrays.asList(files));
}
public void cdDirectory(String directory) throws IOException, IllegalCodeException {
directory = directory.strip();
if (directory.equals("..")) {
if (currentDirectory.isEmpty()) {
return;
} else {
currentDirectory.remove(currentDirectory.size() - 1);
}
} else {
if (listFiles().get(directory) != null) {
HashMap<String, Object> files = (HashMap<String, Object>) listFiles().get(directory);
if (files.isEmpty()) {
addToFiles(action.getFilesData(getCurrentDirectory() + "/"));
}
currentDirectory.add(directory);
}
}
}
public ArrayList<String> listFilesAsList() {
HashMap<String, Object> currentFiles = new HashMap<>();
for (String s: currentDirectory) {
currentFiles = (HashMap<String, Object>) files.get(s);
}
return toSortedArrayList((String[]) currentFiles.keySet().toArray());
}
public HashMap<String, Object> listFiles() {
HashMap<String, Object> currentFiles = new HashMap<>();
for (String s: currentDirectory) {
currentFiles = (HashMap<String, Object>) files.get(s);
}
return currentFiles;
}
public String getCurrentDirectory() {
StringBuilder stringBuilder = new StringBuilder();
currentDirectory.forEach(stringBuilder::append);
return stringBuilder.toString();
}
}
public static class ResultCode {
public static final int EXIT = 25;
public static final int UNEXPECTEDEXIT = 84;
}
}

View File

@ -0,0 +1,145 @@
package org.blueshard.sekaijuclt.client;
import org.apache.log4j.Logger;
import org.blueshard.sekaijuclt.data.Data;
import org.blueshard.sekaijuclt.data.DataCodes;
import org.blueshard.sekaijuclt.security.Password;
import org.blueshard.sekaijuclt.user.UserParams;
import org.blueshard.sekaijuserv.e2ee.E2EEConverter;
import org.blueshard.sekaijuserv.exception.UnexpectedException;
import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.security.InvalidKeyException;
import java.security.spec.InvalidKeySpecException;
public class ServerSender {
private final DataOutputStream dataOutputStream;
private final byte[] serverPublicKey;
private final Logger logger;
public ServerSender(OutputStream outputStream, byte[] serverPublicKey, Logger logger) throws IllegalBlockSizeException, UnexpectedException, InvalidKeySpecException, InvalidKeyException, BadPaddingException {
this.dataOutputStream = new DataOutputStream(outputStream);
this.serverPublicKey = serverPublicKey;
this.logger = logger;
if (serverPublicKey.length != 0) {
E2EEConverter.encrypt("Test", serverPublicKey); // just test if the server key works
}
}
private void send(Data data) throws IOException {
if (serverPublicKey.length == 0) {
dataOutputStream.writeUTF(data.getDataAsString() + "\n");
} else {
try {
dataOutputStream.writeUTF(E2EEConverter.encrypt(data.getDataAsString() + "\n", serverPublicKey));
} catch (UnexpectedException e) {
logger.error("An unexpected error occurred", e);
unexpectedError();
} catch (InvalidKeyException | IllegalBlockSizeException | BadPaddingException | InvalidKeySpecException ignore) {
}
}
dataOutputStream.flush();
}
private void send(Data.Builder data) throws IOException {
send(data.getData());
}
private String loggerInfo(String data) {
return "Send " + data + " data";
}
private String loggerWarning(String data) {
return "Failed to send " + data + " data";
}
public void exit() {
try {
send(new Data.Builder(DataCodes.Client.EXIT));
logger.info(loggerInfo("exit"));
} catch (IOException e) {
logger.warn(loggerWarning("exit"));
}
}
public void unexpectedError() {
try {
send(new Data.Builder(DataCodes.Client.UNEXPECTEDERROR));
logger.info(loggerInfo("unexpected error"));
} catch (IOException e) {
logger.warn(loggerWarning("unexpected error"), e);
}
}
public void unexpectedExit() {
try {
send(new Data.Builder(DataCodes.Client.UNEXPECTEDEXIT));
logger.info(loggerInfo("unexpected exit"));
} catch (IOException e) {
logger.warn(loggerWarning("unexpected exit"), e);
}
}
public void publicKey(String publicKey) {
try {
Data.Builder data = new Data.Builder(DataCodes.Client.PUBLICKEY);
data.addData(org.blueshard.sekaijuserv.user.UserParams.Key.PUBLICKEY, publicKey);
send(data);
logger.info(loggerInfo("public key"));
} catch (IOException e) {
logger.warn(loggerWarning("public key"));
}
}
//----- login / register -----//
public void login(String username, Password.PasswordInfos passwordInfos) {
Data.Builder data = new Data.Builder(DataCodes.Client.LOGIN);
data.addData(UserParams.USERNAME, username);
data.addData(UserParams.PASSWORD, passwordInfos.getPasswordAsString());
data.addData(UserParams.SALT, passwordInfos.getSaltAsString());
try {
send(data);
logger.info(loggerInfo("login"));
} catch (IOException e) {
logger.warn(loggerWarning("login"), e);
}
}
public void register(String username, Password.PasswordInfos passwordInfos, String email) {
Data.Builder data = new Data.Builder(DataCodes.Client.REGISTER);
data.addData(UserParams.USERNAME, username);
data.addData(UserParams.PASSWORD, passwordInfos.getPasswordAsString());
data.addData(UserParams.SALT, passwordInfos.getSaltAsString());
data.addData(UserParams.EMAIL, email);
try {
send(data);
logger.info(loggerInfo("register"));
} catch (IOException e) {
logger.warn(loggerWarning("register"), e);
}
}
//----- files -----//
public void getFilesData() {
Data.Builder data = new Data.Builder(DataCodes.Client.GETFILESDATA);
try {
send(data);
logger.info(loggerInfo("get files data"));
} catch (IOException e) {
logger.warn(loggerWarning("get files data"), e);
}
}
}

View File

@ -0,0 +1,161 @@
package org.blueshard.sekaijuclt.data;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
public class Data {
private String dataAsString;
private Map<String, String> data = new HashMap<>();
public Data(String data) {
this.dataAsString = data;
String key = "";
String dataString = dataAsString;
String separator = getSeparator();
try {
if (separator.length() == 1) {
dataString = dataString.substring(dataString.indexOf(",")).strip();
} else {
dataString = dataString.substring(dataString.indexOf(",") + 1).strip();
}
} catch (StringIndexOutOfBoundsException e) {
dataString = "";
}
for (String string: dataString.split(separator)) {
string = string.strip();
if (string.equals(":") || string.equals(",") || string.equals("{") || string.equals("}")) {
continue;
} else if (key.isEmpty()) {
key = string;
} else {
this.data.put(key, string);
key = "";
}
}
}
public int getCode() {
int lenBeforeCode = 1 + getSeparator().length() + 1;
return Integer.parseInt(dataAsString.substring(lenBeforeCode, lenBeforeCode + DataCodes.DATACODESLENGHT));
}
public Map<String, String> getData() {
return data;
}
public String getDataAsString() {
return dataAsString;
}
public String getFromData(String key) {
return data.get(key);
}
private String getSeparator() {
return dataAsString.substring(1).split(":")[0];
}
public static class Builder {
private Map<String, String> data = new HashMap<>();
private int code;
public Builder(int code) {
this.code = code;
}
public String createData() {
String separator = createSeparator();
StringBuilder dataAsString = new StringBuilder("{" + separator + ":" + code);
data.forEach((key, value) -> dataAsString.append(",")
.append(separator)
.append(key)
.append(separator)
.append(":")
.append(separator)
.append(value)
.append(separator));
dataAsString.append("}");
return dataAsString.toString();
}
public String createSeparator() {
char choice;
StringBuilder stringBuilder = new StringBuilder();
String indicator = "'";
char[] choices = {'\'', '"', '^'};
data.forEach((key, value) -> stringBuilder.append(key).append(value));
String string = stringBuilder.toString();
while (true) {
if (string.contains(indicator)) {
switch (indicator) {
case "'" -> indicator = "\"";
case "\"" -> indicator = "^";
default -> {
choice = choices[new Random().nextInt(choices.length) - 1];
if (indicator.contains("|")) {
String[] splitted_indicator = indicator.split("\\|");
indicator = splitted_indicator[0] + choice + '|' + choice + splitted_indicator[1];
} else {
indicator = indicator + choice + '|' + choice + indicator;
}
}
}
} else {
return indicator;
}
}
}
public void addData(String key, String value) {
this.data.put(key, value);
}
public void addAllData(Map<String, String> allData) {
this.data.putAll(allData);
}
public int getCode() {
return code;
}
public Data getData() {
return new Data(getDataAsString());
}
public Map<String, String> getDataMap() {
return data;
}
public String getDataAsString() {
return createData();
}
}
public static boolean isDataString(String string) {
try {
string = string.strip();
if (string.startsWith("{") && string.endsWith("}") && string.contains(":")) {
String separator = string.substring(1).split(":")[0];
int lenBeforeCode = 1 + separator.length() + 1;
Integer.parseInt(string.substring(lenBeforeCode, lenBeforeCode + DataCodes.DATACODESLENGHT));
return true;
} else {
return false;
}
} catch (Exception e) {
return false;
}
}
}

View File

@ -0,0 +1,50 @@
package org.blueshard.sekaijuclt.data;
public class DataCodes {
public static final int DATACODESLENGHT = 5;
public static class Client {
public static final int UNEXPECTEDERROR = 56400;
public static final int UNEXPECTEDEXIT = 95078;
public static final int EXIT = 69826;
public static final int PUBLICKEY = 19294;
public static final int LOGIN = 39208;
public static final int REGISTER = 84219;
public static final int GETFILESDATA = 28926;
public static final int GETFILE = 95868;
public static final int SENDFILE = 53639;
}
public static class Server {
public static final int UNEXPECTEDERROR = 29875;
public static final int UNEXPECTEDEXIT = 85048;
public static final int NOTLOGGEDIN = 77015;
public static final int EXIT = 42812;
public static final int PUBLICKEY = 19294;
public static final int LOGINFAIL = 11868;
public static final int LOGINSUCCESS = 54151;
public static final int REGISTERFAIL = 52300;
public static final int REGISTERFAIL_USER_EXIST= 77444;
public static final int REGISTERSUCCESS = 34367;
public static final int RECEIVEFILEFAIL = 45747;
public static final int RECEIVEFILESUCCESS = 75368;
public static final int SENDFILESDATA = 78946;
public static final int SENDFILEFAIL = 90173;
public static final int SENDFILESSUCCESS = 37272;
}
}

View File

@ -0,0 +1,48 @@
package org.blueshard.sekaijuclt.e2ee;
import org.blueshard.sekaijuserv.exception.UnexpectedException;
import org.blueshard.sekaijuserv.utils.ExceptionUtils;
import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
public class AESCipher {
private static final int keySize = 256;
public static byte[] generateKey() throws UnexpectedException {
try {
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
keyGenerator.init(keySize);
SecretKey secretKey = keyGenerator.generateKey();
return secretKey.getEncoded();
} catch (NoSuchAlgorithmException e) {
throw new UnexpectedException(ExceptionUtils.extractExceptionMessage(e));
}
}
public static byte[] encrypt(byte[] input, byte[] key) throws UnexpectedException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
try {
SecretKey secretKey = new SecretKeySpec(key, 0, key.length, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
return cipher.doFinal(input);
} catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
throw new UnexpectedException(e);
}
}
public static byte[] decrypt(byte[] input, byte[] key) throws UnexpectedException, BadPaddingException, IllegalBlockSizeException, InvalidKeyException {
try {
SecretKey secretKey = new SecretKeySpec(key, 0, key.length, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, secretKey);
return cipher.doFinal(input);
} catch (NoSuchPaddingException | NoSuchAlgorithmException e) {
throw new UnexpectedException(e);
}
}
}

View File

@ -0,0 +1,36 @@
package org.blueshard.sekaijuclt.e2ee;
import org.blueshard.sekaijuserv.exception.UnexpectedException;
import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.spec.InvalidKeySpecException;
import java.util.Base64;
public class E2EEConverter {
private final static String separator = "@";
public static String decrypt(String input, byte[] privateKey) throws UnexpectedException, BadPaddingException, InvalidKeySpecException, InvalidKeyException, NoSuchPaddingException, IllegalBlockSizeException {
String[] inputAsArray = input.split(separator);
String key = inputAsArray[0];
String realInput = inputAsArray[1];
byte[] AESKey = RSACipher.decrypt(Base64.getDecoder().decode(key), privateKey);
return new String(AESCipher.decrypt(Base64.getDecoder().decode(realInput), AESKey));
}
public static String encrypt(String input, byte[] publicKey) throws UnexpectedException, BadPaddingException, InvalidKeyException, IllegalBlockSizeException, InvalidKeySpecException {
byte[] AESKey = AESCipher.generateKey();
String encryptedKey = Base64.getEncoder().encodeToString(RSACipher.encrypt(AESKey, publicKey));
String encryptedInput = Base64.getEncoder().encodeToString(AESCipher.encrypt(input.getBytes(StandardCharsets.UTF_8), AESKey));
return encryptedKey + separator + encryptedInput;
}
}

View File

@ -0,0 +1,57 @@
package org.blueshard.sekaijuclt.e2ee;
import org.blueshard.sekaijuserv.exception.UnexpectedException;
import org.blueshard.sekaijuserv.utils.ExceptionUtils;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.security.*;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
public class RSACipher {
private static final int keySize = 2048;
public static KeyPair generateKeyPair() throws UnexpectedException {
try {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(keySize);
return keyPairGenerator.generateKeyPair();
} catch (NoSuchAlgorithmException e) {
throw new UnexpectedException(ExceptionUtils.extractExceptionMessage(e));
}
}
public static byte[] encrypt(byte[] key, byte[] publicKey) throws UnexpectedException, InvalidKeyException, InvalidKeySpecException, BadPaddingException {
try {
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKey);
RSAPublicKey publicRSAKey = (RSAPublicKey) keyFactory.generatePublic(keySpec);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, publicRSAKey);
return cipher.doFinal(key);
} catch (NoSuchAlgorithmException | IllegalBlockSizeException | NoSuchPaddingException e) {
throw new UnexpectedException(ExceptionUtils.extractExceptionMessage(e));
}
}
public static byte[] decrypt(byte[] key, byte[] privateKey) throws UnexpectedException, NoSuchPaddingException, InvalidKeySpecException, InvalidKeyException, BadPaddingException {
try {
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey privatePKCS8Key = keyFactory.generatePrivate(new PKCS8EncodedKeySpec(privateKey));
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, privatePKCS8Key);
return cipher.doFinal(key);
} catch (NoSuchAlgorithmException | IllegalBlockSizeException e) {
throw new UnexpectedException(ExceptionUtils.extractExceptionMessage(e));
}
}
}

View File

@ -0,0 +1,37 @@
package org.blueshard.sekaijuclt.exception;
import java.util.HashSet;
import java.util.Set;
public class ErrorCodes {
public final static int couldnt_read_users_conf = 545;
public final static int couldnt_write_users_conf = 376;
public final static int couldnt_create_user_folder = 639;
public final static int couldnt_delete_user_folder = 152;
public final static int couldnt_create_user_userfiles_folder = 293;
public final static int couldnt_delete_user_userfiles_folder = 219;
public final static int couldnt_create_user_user_conf = 934;
public final static int couldnt_read_user_user_conf = 177;
public final static int couldnt_write_user_user_conf = 990;
public final static int couldnt_delete_user_user_conf = 680;
public final static int couldnt_create_user_user_files_conf = 353;
public final static int couldnt_read_user_user_files_conf = 155;
public final static int couldnt_write_user_user_files_conf = 476;
public final static int couldnt_delete_user_user_files_conf = 559;
public final static int couldnt_delete_custom_user_directory = 383;
public final static int couldnt_delete_custom_user_file = 942;
public final static HashSet<Integer> allFatalUserLoginRegisterErrors = new HashSet<>(Set.of(couldnt_read_users_conf, couldnt_write_users_conf,
couldnt_create_user_folder, couldnt_delete_user_folder,
couldnt_create_user_userfiles_folder, couldnt_delete_user_userfiles_folder,
couldnt_create_user_user_conf, couldnt_read_user_user_conf, couldnt_write_user_user_conf, couldnt_delete_user_user_conf,
couldnt_create_user_user_files_conf, couldnt_read_user_user_files_conf, couldnt_write_user_user_files_conf, couldnt_delete_user_user_files_conf,
couldnt_delete_custom_user_directory, couldnt_delete_custom_user_file));
}

View File

@ -0,0 +1,17 @@
package org.blueshard.sekaijuclt.exception;
public class FatalIOException extends Exception {
private final int errno;
public FatalIOException(int errno, String message) {
super("Errno: " + errno + " - " + message);
this.errno = errno;
}
public int getErrno() {
return errno;
}
}

View File

@ -0,0 +1,15 @@
package org.blueshard.sekaijuclt.exception;
public class IllegalCodeException extends Exception {
private final int givenCode;
private final int requiredCode;
public IllegalCodeException(int givenCode, int requiredCode){
super("Wrong data code is given '" + givenCode + "', expected '" + requiredCode + "'");
this.givenCode = givenCode;
this.requiredCode = requiredCode;
}
}

View File

@ -0,0 +1,9 @@
package org.blueshard.sekaijuclt.exception;
public class IllegalPasswordException extends Exception {
public IllegalPasswordException(String errorMessage){
super(errorMessage);
}
}

View File

@ -0,0 +1,23 @@
package org.blueshard.sekaijuclt.exception;
public class UnexpectedException extends Exception {
public UnexpectedException() {
super("An unexpected error occurred");
}
public UnexpectedException(Throwable t) {
super("An unexpected error occurred (" + t.getMessage() + ")");
this.setStackTrace(t.getStackTrace());
}
public UnexpectedException(String message) {
super(message);
}
public UnexpectedException(String message, Throwable t) {
super(message);
this.setStackTrace(t.getStackTrace());
}
}

View File

@ -0,0 +1,9 @@
package org.blueshard.sekaijuclt.exception;
public class UserAlreadyExistException extends UserException {
public UserAlreadyExistException(String username, String message) {
super(username, message);
}
}

View File

@ -0,0 +1,13 @@
package org.blueshard.sekaijuclt.exception;
public class UserException extends Exception {
final String username;
public UserException(String username, String message) {
super(message);
this.username = username;
}
}

View File

@ -0,0 +1,9 @@
package org.blueshard.sekaijuclt.exception;
public class UserNotExistException extends UserException {
public UserNotExistException(String username, String message){
super(username, message);
}
}

View File

@ -0,0 +1,8 @@
package org.blueshard.sekaijuclt.exception;
public class UserNotLoggedInException extends UserException {
public UserNotLoggedInException(String username, String message) {
super(username, message);
}
}

View File

@ -0,0 +1 @@
#empty

View File

@ -0,0 +1,65 @@
package org.blueshard.sekaijuclt.security;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import java.util.Base64;
public class Password {
public static PasswordInfos createPassword(String password, byte[] salt) {
SecureRandom secureRandom = new SecureRandom();
secureRandom.nextBytes(salt);
KeySpec keySpec = new PBEKeySpec(password.toCharArray(), salt, 65536, 256);
SecretKeyFactory factory = null;
try {
factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
} catch (NoSuchAlgorithmException ignore) {
}
byte[] hashedPassword = new byte[0];
try {
hashedPassword = factory.generateSecret(keySpec).getEncoded();
} catch (InvalidKeySpecException ignore) {
}
return new PasswordInfos(hashedPassword, salt);
}
public static class PasswordInfos {
private final byte[] password;
private final byte[] salt;
public PasswordInfos(byte[] password, byte[] salt) {
this.password = password;
this.salt = salt;
}
public byte[] getPasswordAsBytes() {
return password;
}
public String getPasswordAsString() {
Base64.Encoder encoder = Base64.getEncoder();
return encoder.encodeToString(password);
}
public byte[] getSaltAsBytes() {
return salt;
}
public String getSaltAsString() {
Base64.Encoder encoder = Base64.getEncoder();
return encoder.encodeToString(salt);
}
}
}

View File

@ -0,0 +1,58 @@
package org.blueshard.sekaijuclt.user;
public class UserParams {
public final static String USERNAME = "username";
public final static String PASSWORD = "password";
public final static String SALT = "salt";
public final static String EMAIL = "email";
public static class File {
public final static String STARTDIRECOTRY = "startDirectory";
public final static String FILEPATH = "filepath";
}
public static class CheckSum {
public final static String MD5 = "md5";
}
public static class Key {
public final static String PUBLICKEY = "key";
}
public static class LogLevel {
public final static String LOGLEVEL = "logLevel";
public final static String ALL = "0";
public final static String WARNING = "1";
public final static String NOTHING = "2";
}
public static class UserLevel {
public final static String USERLEVEL = "userLevel";
public final static String PUBLIC = "0";
public final static String PROTECTED = "1";
public final static String PRIVATE = "2";
}
public static class State {
public final static String STATE = "state";
public final static String ACTIVE = "active";
public final static String DISABLED = "disabled";
}
}

View File

@ -0,0 +1,76 @@
package org.blueshard.sekaijuclt.utils;
public class ConsoleColors {
// Reset
public static final String RESET = "\033[0m"; // Text Reset
// Regular Colors
public static final String BLACK = "\033[0;30m"; // BLACK
public static final String RED = "\033[0;31m"; // RED
public static final String GREEN = "\033[0;32m"; // GREEN
public static final String YELLOW = "\033[0;33m"; // YELLOW
public static final String BLUE = "\033[0;34m"; // BLUE
public static final String PURPLE = "\033[0;35m"; // PURPLE
public static final String CYAN = "\033[0;36m"; // CYAN
public static final String WHITE = "\033[0;37m"; // WHITE
// Bold
public static final String BLACK_BOLD = "\033[1;30m"; // BLACK
public static final String RED_BOLD = "\033[1;31m"; // RED
public static final String GREEN_BOLD = "\033[1;32m"; // GREEN
public static final String YELLOW_BOLD = "\033[1;33m"; // YELLOW
public static final String BLUE_BOLD = "\033[1;34m"; // BLUE
public static final String PURPLE_BOLD = "\033[1;35m"; // PURPLE
public static final String CYAN_BOLD = "\033[1;36m"; // CYAN
public static final String WHITE_BOLD = "\033[1;37m"; // WHITE
// Underline
public static final String BLACK_UNDERLINED = "\033[4;30m"; // BLACK
public static final String RED_UNDERLINED = "\033[4;31m"; // RED
public static final String GREEN_UNDERLINED = "\033[4;32m"; // GREEN
public static final String YELLOW_UNDERLINED = "\033[4;33m"; // YELLOW
public static final String BLUE_UNDERLINED = "\033[4;34m"; // BLUE
public static final String PURPLE_UNDERLINED = "\033[4;35m"; // PURPLE
public static final String CYAN_UNDERLINED = "\033[4;36m"; // CYAN
public static final String WHITE_UNDERLINED = "\033[4;37m"; // WHITE
// Background
public static final String BLACK_BACKGROUND = "\033[40m"; // BLACK
public static final String RED_BACKGROUND = "\033[41m"; // RED
public static final String GREEN_BACKGROUND = "\033[42m"; // GREEN
public static final String YELLOW_BACKGROUND = "\033[43m"; // YELLOW
public static final String BLUE_BACKGROUND = "\033[44m"; // BLUE
public static final String PURPLE_BACKGROUND = "\033[45m"; // PURPLE
public static final String CYAN_BACKGROUND = "\033[46m"; // CYAN
public static final String WHITE_BACKGROUND = "\033[47m"; // WHITE
// High Intensity
public static final String BLACK_BRIGHT = "\033[0;90m"; // BLACK
public static final String RED_BRIGHT = "\033[0;91m"; // RED
public static final String GREEN_BRIGHT = "\033[0;92m"; // GREEN
public static final String YELLOW_BRIGHT = "\033[0;93m"; // YELLOW
public static final String BLUE_BRIGHT = "\033[0;94m"; // BLUE
public static final String PURPLE_BRIGHT = "\033[0;95m"; // PURPLE
public static final String CYAN_BRIGHT = "\033[0;96m"; // CYAN
public static final String WHITE_BRIGHT = "\033[0;97m"; // WHITE
// Bold High Intensity
public static final String BLACK_BOLD_BRIGHT = "\033[1;90m"; // BLACK
public static final String RED_BOLD_BRIGHT = "\033[1;91m"; // RED
public static final String GREEN_BOLD_BRIGHT = "\033[1;92m"; // GREEN
public static final String YELLOW_BOLD_BRIGHT = "\033[1;93m";// YELLOW
public static final String BLUE_BOLD_BRIGHT = "\033[1;94m"; // BLUE
public static final String PURPLE_BOLD_BRIGHT = "\033[1;95m";// PURPLE
public static final String CYAN_BOLD_BRIGHT = "\033[1;96m"; // CYAN
public static final String WHITE_BOLD_BRIGHT = "\033[1;97m"; // WHITE
// High Intensity backgrounds
public static final String BLACK_BACKGROUND_BRIGHT = "\033[0;100m";// BLACK
public static final String RED_BACKGROUND_BRIGHT = "\033[0;101m";// RED
public static final String GREEN_BACKGROUND_BRIGHT = "\033[0;102m";// GREEN
public static final String YELLOW_BACKGROUND_BRIGHT = "\033[0;103m";// YELLOW
public static final String BLUE_BACKGROUND_BRIGHT = "\033[0;104m";// BLUE
public static final String PURPLE_BACKGROUND_BRIGHT = "\033[0;105m"; // PURPLE
public static final String CYAN_BACKGROUND_BRIGHT = "\033[0;106m"; // CYAN
public static final String WHITE_BACKGROUND_BRIGHT = "\033[0;107m"; // WHITE
}

View File

@ -0,0 +1,71 @@
package org.blueshard.sekaijuclt.utils;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.DigestInputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Arrays;
public class FileUtils {
public static ArrayList<File> getAllFilesInDirectory(String path) throws IOException {
ArrayList<File> files = new ArrayList<>();
Files.walk(Paths.get(path)).map(Path::toFile).forEach(files::add);
return files;
}
public static File[] sortFilesInDirectory(File path) {
File[] files = path.listFiles();
Arrays.sort(files, (object1, object2) -> object1.getName().compareToIgnoreCase(object2.getName()));
return files;
}
public class CreateHashSum {
String file;
CreateHashSum(String file) {
this.file = file;
}
public String MD5() throws IOException {
try {
StringBuilder hexString = new StringBuilder();
MessageDigest md5 = MessageDigest.getInstance("MD5");
InputStream inputStream = Files.newInputStream(Paths.get(file));
byte[] buffer = new byte[1024];
int length;
while ((length = inputStream.read(buffer)) > 0) {
md5.update(buffer, 0 , length);
}
byte[] digest = md5.digest();
for (byte b : digest) {
if ((0xff & b) < 0x10) {
hexString.append("0").append(Integer.toHexString((0xFF & b)));
} else {
hexString.append(Integer.toHexString(0xFF & b));
}
}
return hexString.toString();
} catch (NoSuchAlgorithmException ignore) {
return null;
}
}
}
}

View File

@ -0,0 +1,140 @@
package org.blueshard.sekaijuclt.utils;
public class SizeUnit {
private int unit;
private double size;
private final static int BYTE = 1;
private final static int KILOBYTE = 3;
private final static int MEGABYTE = 5;
private final static int GIGABYTE = 7;
private final static int TERRABYTE = 9;
private final static int PETABYTE = 11;
private final static int EXABYTE = 13;
SizeUnit(int unit, double size){
this.unit = unit;
this.size = size;
}
public static SizeUnit BYTES(double bytes){
return new SizeUnit(BYTE, bytes);
}
public static SizeUnit KILOBYTE(double kilobytes) {
return new SizeUnit(KILOBYTE, kilobytes);
}
public static SizeUnit MEGABYTE(double megabytes) {
return new SizeUnit(MEGABYTE, megabytes);
}
public static SizeUnit GIGABYTE(double gigabytes) {
return new SizeUnit(GIGABYTE, gigabytes);
}
public static SizeUnit TERRABYTE(double terrabytes) {
return new SizeUnit(TERRABYTE, terrabytes);
}
public static SizeUnit PETABYTE(double petabytes) {
return new SizeUnit(PETABYTE, petabytes);
}
public static SizeUnit EXABYTE(double exabytes) {
return new SizeUnit(EXABYTE, exabytes);
}
public Double toByte(){
return switch (unit) {
case BYTE -> size;
case KILOBYTE -> size * 1000;
case MEGABYTE -> size * 1000000;
case GIGABYTE -> size * 1000000000;
case TERRABYTE -> size * 1000000000000L;
case PETABYTE -> size * 1000000000000000L;
case EXABYTE -> size * 1000000000000000000L;
default -> 0D;
};
}
public Double toKilobyte(){
return switch (unit) {
case BYTE -> size / 1000;
case KILOBYTE -> size;
case MEGABYTE -> size * 1000;
case GIGABYTE -> size * 1000000;
case TERRABYTE -> size * 1000000000;
case PETABYTE -> size * 1000000000000L;
case EXABYTE -> size * 1000000000000000L;
default -> 0D;
};
}
public Double toMegabyte(){
return switch (unit) {
case BYTE -> size / 1000000;
case KILOBYTE -> size / 1000;
case MEGABYTE -> size;
case GIGABYTE -> size * 1000;
case TERRABYTE -> size * 1000000;
case PETABYTE -> size * 1000000000;
case EXABYTE -> size * 1000000000000L;
default -> 0D;
};
}
public Double toGigabyte(){
return switch (unit) {
case BYTE -> size / 1000000000L;
case KILOBYTE -> size / 1000000;
case MEGABYTE -> size / 1000;
case GIGABYTE -> size;
case TERRABYTE -> size * 1000;
case PETABYTE -> size * 1000000;
case EXABYTE -> size * 1000000000;
default -> 0D;
};
}
public Double toTerrabyte(){
return switch (unit) {
case BYTE -> size / 1000000000000L;
case KILOBYTE -> size / 1000000000;
case MEGABYTE -> size / 1000000;
case GIGABYTE -> size / 1000;
case TERRABYTE -> size;
case PETABYTE -> size * 1000;
case EXABYTE -> size * 1000000;
default -> 0D;
};
}
public Double toPetabyte(){
return switch (unit) {
case BYTE -> size / 1000000000000000L;
case KILOBYTE -> size / 1000000000000L;
case MEGABYTE -> size / 1000000000;
case GIGABYTE -> size / 1000000;
case TERRABYTE -> size / 1000;
case PETABYTE -> size;
case EXABYTE -> size * 1000;
default -> 0D;
};
}
public Double toExabyte(){
return switch (unit) {
case BYTE -> size / 1000000000000000000L;
case KILOBYTE -> size / 1000000000000000L;
case MEGABYTE -> size / 1000000000000L;
case GIGABYTE -> size / 1000000000;
case TERRABYTE -> size / 1000000;
case PETABYTE -> size / 1000;
case EXABYTE -> size;
default -> 0D;
};
}
}

View File

@ -0,0 +1,17 @@
package org.blueshard.sekaijuclt.utils;
import java.util.Map;
public class StringUtils {
public static String format(String string, Map<String, String> formatMap){
for(Map.Entry<String, String> entry: formatMap.entrySet()) {
string = string.replace("{" + entry.getKey() + "}", entry.getValue());
}
return string;
}
}

7
srv/etc/versions.conf Normal file
View File

@ -0,0 +1,7 @@
[TheosUI]
0.1.0 = required:
[olymp]
0.1.0 =

View File

@ -0,0 +1 @@
#empty

View File

@ -0,0 +1 @@
#empty

1
srv/hsqldb/empty Normal file
View File

@ -0,0 +1 @@
#empty

1
srv/logs/main.log Normal file
View File

@ -0,0 +1 @@
#empty

1
srv/public_files/empty Normal file
View File

@ -0,0 +1 @@
#empty

6
srv/ssl/java ssl.txt Normal file
View File

@ -0,0 +1,6 @@
Keystore password: @VR&_*p%9!L+kC3FZ4QX
keytool -keygen -keyalg RSA -keysize 2048 -validity 365 -alias sslkey -keystore sslKeyStore.jks
keytool -export -alias sslkey -keystore sslKeyStore.jks -file sslKey.cert
keytool -import -file sslKey.cert -alias sslkey -keystore sslTrustStore.jts
365 28.03.2020

BIN
srv/ssl/sslKey.cert Normal file

Binary file not shown.

BIN
srv/ssl/sslKeyStore.jks Normal file

Binary file not shown.

BIN
srv/ssl/sslTrustStore.jks Normal file

Binary file not shown.

View File

@ -0,0 +1 @@
#empty

3
start.sh Normal file
View File

@ -0,0 +1,3 @@
#!/bin/bash
java -Dfile.encoding=UTF-8 -classpath "out/production/olymp:lib/*:lib/batik/*:lib/hsqldb/*" org.blueshard.olymp.Main

BIN
theosui/lib/TFX.jar Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More