extend and fix pubkeys
This commit is contained in:
parent
5a394749bf
commit
902c795ecc
5 changed files with 184 additions and 64 deletions
|
@ -513,34 +513,54 @@ public class Client implements IThreadListener {
|
|||
})).channel(NioSocketChannel.class)).connect(address, serverPort).syncUninterruptibly();
|
||||
return networkmanager;
|
||||
}
|
||||
|
||||
public void displayConnecting(ServerInfo server) {
|
||||
this.displayGuiScreen(GuiLoading.makeWaitTask("Verbinde zu " + (server.getAddress() == null ? "localhost" : server.getAddress()) + ":" + server.getPort() + " ..."));
|
||||
}
|
||||
|
||||
public void connect(ServerInfo server) {
|
||||
this.displayGuiScreen(GuiLoading.makeWaitTask("Verbinde zu " + (server.getAddress() == null ? "localhost" : server.getAddress()) + ":" + server.getPort() + " ..."));
|
||||
public void connect(final ServerInfo server) {
|
||||
this.displayConnecting(server);
|
||||
Log.NETWORK.info("Verbinde zu " + (server.getAddress() == null ? "localhost" : server.getAddress()) + ":" + server.getPort());
|
||||
final NetConnection connection;
|
||||
try
|
||||
{
|
||||
connection = createNetworkManagerAndConnect(server.getAddress() == null ? InetAddress.getLoopbackAddress() : InetAddress.getByName(IDN.toASCII(server.getAddress())), server.getPort());
|
||||
connection.setNetHandler(new ClientLoginHandler(connection, this, server));
|
||||
connection.sendPacket(new HPacketHandshake(Util.PROTOCOL), new GenericFutureListener<Future<? super Void>>() {
|
||||
public void operationComplete(Future<? super Void> u) throws Exception {
|
||||
connection.setConnectionState(PacketRegistry.LOGIN);
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (UnknownHostException u)
|
||||
{
|
||||
Log.NETWORK.error(u, "Konnte nicht zu Server verbinden");
|
||||
this.disconnected("Unbekannter Hostname: " + (server.getAddress() == null ? "localhost" : server.getAddress()));
|
||||
return;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.NETWORK.error(e, "Konnte nicht zu Server verbinden");
|
||||
this.disconnected(e.toString());
|
||||
return;
|
||||
}
|
||||
this.connection = connection;
|
||||
new Thread(new Runnable() {
|
||||
public void run() {
|
||||
final NetConnection connection;
|
||||
try
|
||||
{
|
||||
connection = createNetworkManagerAndConnect(server.getAddress() == null ? InetAddress.getLoopbackAddress() : InetAddress.getByName(IDN.toASCII(server.getAddress())), server.getPort());
|
||||
connection.setNetHandler(new ClientLoginHandler(connection, Client.this, server));
|
||||
connection.sendPacket(new HPacketHandshake(Util.PROTOCOL), new GenericFutureListener<Future<? super Void>>() {
|
||||
public void operationComplete(Future<? super Void> u) throws Exception {
|
||||
connection.setConnectionState(PacketRegistry.LOGIN);
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (UnknownHostException u)
|
||||
{
|
||||
Log.NETWORK.error(u, "Konnte nicht zu Server verbinden");
|
||||
Client.this.schedule(new Runnable() {
|
||||
public void run() {
|
||||
Client.this.disconnected("Unbekannter Hostname: " + (server.getAddress() == null ? "localhost" : server.getAddress()));
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.NETWORK.error(e, "Konnte nicht zu Server verbinden");
|
||||
Client.this.schedule(new Runnable() {
|
||||
public void run() {
|
||||
Client.this.disconnected(e.toString());
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
Client.this.schedule(new Runnable() {
|
||||
public void run() {
|
||||
Client.this.connection = connection;
|
||||
}
|
||||
});
|
||||
}
|
||||
}, "Server connector").start();
|
||||
}
|
||||
|
||||
public void unloadWorld() {
|
||||
|
|
|
@ -34,13 +34,15 @@ public class GuiConnect extends GuiList<GuiConnect.ServerInfo> implements Button
|
|||
private String password;
|
||||
private String access;
|
||||
private KeyPair keypair;
|
||||
private String keyDigest;
|
||||
private PublicKey serverKey;
|
||||
private String serverDigest;
|
||||
private boolean enforceEncryption;
|
||||
private long lastConnected;
|
||||
|
||||
public ServerInfo(String address, int port, String user, String password, String access) {
|
||||
this.direct = true;
|
||||
this.name = "<Direktverbindung>";
|
||||
this.name = DIRECT_NAME;
|
||||
this.address = address;
|
||||
this.port = port;
|
||||
this.user = user;
|
||||
|
@ -61,6 +63,10 @@ public class GuiConnect extends GuiList<GuiConnect.ServerInfo> implements Button
|
|||
this.lastConnected = lastConnected;
|
||||
this.serverKey = serverKey;
|
||||
this.enforceEncryption = enforceEnc;
|
||||
if(this.keypair != null)
|
||||
this.keyDigest = EncryptUtil.getXorSha512Hash(this.keypair.getPublic().getEncoded());
|
||||
if(this.serverKey != null)
|
||||
this.serverDigest = EncryptUtil.getXorSha512Hash(this.serverKey.getEncoded());
|
||||
}
|
||||
|
||||
public boolean isDirect() {
|
||||
|
@ -117,6 +123,8 @@ public class GuiConnect extends GuiList<GuiConnect.ServerInfo> implements Button
|
|||
this.keypair = keypair;
|
||||
this.serverKey = serverKey;
|
||||
this.enforceEncryption = encryptReq;
|
||||
this.keyDigest = this.keypair != null ? EncryptUtil.getXorSha512Hash(this.keypair.getPublic().getEncoded()) : null;
|
||||
this.serverDigest = this.serverKey != null ? EncryptUtil.getXorSha512Hash(this.serverKey.getEncoded()) : null;
|
||||
}
|
||||
|
||||
public void setLastConnected() {
|
||||
|
@ -125,6 +133,7 @@ public class GuiConnect extends GuiList<GuiConnect.ServerInfo> implements Button
|
|||
|
||||
public void setServerKey(PublicKey key) {
|
||||
this.serverKey = key;
|
||||
this.serverDigest = this.serverKey != null ? EncryptUtil.getXorSha512Hash(this.serverKey.getEncoded()) : null;
|
||||
}
|
||||
|
||||
public int compareTo(ServerInfo comp) {
|
||||
|
@ -144,12 +153,22 @@ public class GuiConnect extends GuiList<GuiConnect.ServerInfo> implements Button
|
|||
|
||||
public void draw(int x, int y, int mouseXIn, int mouseYIn, boolean hover) {
|
||||
Drawing.drawText(this.name + TextColor.GRAY + " - " + TextColor.RESET + this.user, x + 2, y, 0xffffffff);
|
||||
Drawing.drawText(this.address + TextColor.GRAY + " Port " + TextColor.RESET + this.port, x + 2, y + 18, 0xff808080);
|
||||
if(this.keypair != null || !this.password.isEmpty())
|
||||
Drawing.drawTextRight(
|
||||
(this.keypair != null ? "Pubkey " + this.keyDigest : "") + (this.keypair != null && !this.password.isEmpty() ? " + " : "") + (!this.password.isEmpty() ? "Passwort" : ""),
|
||||
x + 660 - 4 - 2, y, 0xffffffff);
|
||||
Drawing.drawText(this.address + TextColor.GRAY + " Port " + TextColor.RESET + this.port + (this.enforceEncryption ? TextColor.GRAY + ", nur verschlüsselt" : ""),
|
||||
x + 2, y + 18, 0xff808080);
|
||||
if(!this.access.isEmpty())
|
||||
Drawing.drawTextRight((this.keypair != null || !this.password.isEmpty() ? "+ " : "") + "Server-Passwort", x + 660 - 4 - 2, y + 18, 0xff808080);
|
||||
Drawing.drawText("Zuletzt verbunden: " + (this.lastConnected == -1L ? "nie" : DATE_FORMAT.format(new Date(this.lastConnected))), x + 2, y + 18 + 16, 0xff808080);
|
||||
if(this.serverDigest != null)
|
||||
Drawing.drawTextRight("Server-ID: " + this.serverDigest, x + 660 - 4 - 2, y + 18 + 16, 0xff808080);
|
||||
}
|
||||
}
|
||||
|
||||
public static final GuiConnect INSTANCE = new GuiConnect();
|
||||
private static final String DIRECT_NAME = "<Direktverbindung>";
|
||||
private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("dd.MM.yyyy HH:mm:ss");
|
||||
private static final File SERVERS_FILE = new File("servers.cfg");
|
||||
|
||||
|
@ -185,7 +204,7 @@ public class GuiConnect extends GuiList<GuiConnect.ServerInfo> implements Button
|
|||
if(line == null || (line.startsWith("[") && line.endsWith("]"))) {
|
||||
if(!name.isEmpty() && !address.isEmpty() && !user.isEmpty() && user.length() < IPlayer.MAX_USER_LENGTH && IPlayer.isValidUser(user) &&
|
||||
password.length() < IPlayer.MAX_PASS_LENGTH && access.length() < IPlayer.MAX_PASS_LENGTH && address.length() < 128 && name.length() < 128 &&
|
||||
port >= 1024 && port <= 32767 && (password.length() >= 8 || password.isEmpty()) && (access.length() >= 8 || access.isEmpty())) {
|
||||
port >= 1024 && port <= 32767 && (password.length() >= 8 || password.isEmpty()) && (access.length() >= 8 || access.isEmpty()) && !this.isNameTaken(name)) {
|
||||
PrivateKey priv = key == null ? null : EncryptUtil.decodePrivateKey(key);
|
||||
PublicKey pub = pubkey == null ? null : EncryptUtil.decodePublicKey(pubkey);
|
||||
PublicKey serv = serverKey == null ? null : EncryptUtil.decodePublicKey(serverKey);
|
||||
|
@ -269,6 +288,14 @@ public class GuiConnect extends GuiList<GuiConnect.ServerInfo> implements Button
|
|||
this.gm.displayGuiScreen(this);
|
||||
}
|
||||
|
||||
public boolean isNameTaken(String name) {
|
||||
for(int z = 0; z < this.elements.size(); z++) {
|
||||
if(this.selectedElement != z && this.elements.get(z).getName().equals(name))
|
||||
return true;
|
||||
}
|
||||
return DIRECT_NAME.equals(name);
|
||||
}
|
||||
|
||||
public void editServer(ServerInfo server) {
|
||||
if(!server.isDirect())
|
||||
this.save();
|
||||
|
|
|
@ -37,11 +37,15 @@ public class GuiServer extends Gui implements FieldCallback {
|
|||
private Label userLabel;
|
||||
private Label passLabel;
|
||||
private Label accLabel;
|
||||
private Label keyLabel;
|
||||
private Label idLabel;
|
||||
private Toggle encToggle;
|
||||
private ActButton keyButton;
|
||||
private ActButton resetButton;
|
||||
private KeyPair keypair;
|
||||
private String keyDigest;
|
||||
private PublicKey serverKey;
|
||||
private String serverDigest;
|
||||
|
||||
public GuiServer(ServerInfo server) {
|
||||
this.server = server;
|
||||
|
@ -59,34 +63,40 @@ public class GuiServer extends Gui implements FieldCallback {
|
|||
private String lastAcc = "";
|
||||
|
||||
public void init(int width, int height) {
|
||||
if(this.server != null)
|
||||
if(this.server != null) {
|
||||
this.nameBox = this.add(new Field(0, -50, 400, 24, 128, this, this.server.getName()));
|
||||
this.keypair = this.server.getKeypair();
|
||||
this.keyDigest = this.keypair == null ? null : EncryptUtil.getXorSha512Hash(this.keypair.getPublic().getEncoded());
|
||||
}
|
||||
this.addrBox = this.add(new Field(0, 20, 400, 24, 128, this, this.server == null ? this.lastAddr : this.server.getAddress()));
|
||||
int port = this.server == null ? this.lastPort : this.server.getPort();
|
||||
this.portBox = this.add(new Field(404, 20, 76, 24, 5, this, port < 0 ? "" : "" + port));
|
||||
this.userBox = this.add(new Field(0, 70, 220, 24, IPlayer.MAX_USER_LENGTH, this, IPlayer.VALID_USER, this.server == null ? this.lastUser : this.server.getUser()));
|
||||
this.passBox = this.add(new Field(0, 120, 480, 24, IPlayer.MAX_PASS_LENGTH, this, this.server == null ? this.lastPass : this.server.getPassword()));
|
||||
this.accBox = this.add(new Field(0, 170, 480, 24, IPlayer.MAX_PASS_LENGTH, this, this.server == null ? this.lastAcc : this.server.getAccess()));
|
||||
this.add(new ActButton(0, this.server == null ? 220 : 370, 480, 24, new ButtonCallback() {
|
||||
this.passBox = this.add(new Field(0, this.server == null ? 120 : 170, 480, 24, IPlayer.MAX_PASS_LENGTH, this, this.server == null ? this.lastPass : this.server.getPassword()));
|
||||
this.accBox = this.add(new Field(0, this.server == null ? 170 : 220, 480, 24, IPlayer.MAX_PASS_LENGTH, this, this.server == null ? this.lastAcc : this.server.getAccess()));
|
||||
this.add(new ActButton(0, this.server == null ? 220 : 350, 480, 24, new ButtonCallback() {
|
||||
public void use(ActButton elem, PressType action) {
|
||||
GuiServer.this.connect();
|
||||
}
|
||||
}, this.server == null ? "Verbinden" : (this.server.getName().isEmpty() ? "Hinzufügen" : "Übernehmen")));
|
||||
this.add(new NavButton(0, this.server == null ? 250 : 400, 480, 24, this.server != null ? GuiConnect.INSTANCE : GuiMenu.INSTANCE, "Zurück"));
|
||||
this.add(new NavButton(0, this.server == null ? 250 : 380, 480, 24, this.server != null ? GuiConnect.INSTANCE : GuiMenu.INSTANCE, "Zurück"));
|
||||
if(this.server != null)
|
||||
this.nameLabel = this.add(new Label(0, -70, 410, 20, "Name", true));
|
||||
this.addrLabel = this.add(new Label(0, 0, 410, 20, "Adresse", true));
|
||||
this.nameLabel = this.add(new Label(0, -70, 410, 20, "Name in der Liste", true));
|
||||
this.addrLabel = this.add(new Label(0, 0, 410, 20, "Adresse / Hostname", true));
|
||||
this.portLabel = this.add(new Label(404, 0, 76, 20, "Port", true));
|
||||
this.rangeLabel = this.add(new Label(370, 44, 110, 20, "[1024..32767]", true));
|
||||
this.userLabel = this.add(new Label(0, 50, 220, 20, "Nutzer", true));
|
||||
this.passLabel = this.add(new Label(0, 100, 480, 20, "Passwort (mind. 8 Zeichen)", true));
|
||||
this.accLabel = this.add(new Label(0, 150, 480, 20, "Zugang (mind. 8 Zeichen)", true));
|
||||
this.userLabel = this.add(new Label(0, 50, 220, 20, "Benutzername", true));
|
||||
this.passLabel = this.add(new Label(0, this.server == null ? 100 : 150, 480, 20, (this.keypair == null ? "Anmelde" : "Ersatz") + "-Passwort (mind. 8 Zeichen)", true));
|
||||
this.accLabel = this.add(new Label(0, this.server == null ? 150 : 200, 480, 20, "Server-Passwort (mind. 8 Zeichen)", true));
|
||||
if(this.server != null) {
|
||||
this.keyButton = this.add(new ActButton(0, 220, 480, 24, new ButtonCallback() {
|
||||
this.keyButton = this.add(new ActButton(0, 120, 480, 24, new ButtonCallback() {
|
||||
public void use(ActButton elem, PressType action) {
|
||||
if(GuiServer.this.keypair == null) {
|
||||
GuiServer.this.keypair = EncryptUtil.generateKeyPair();
|
||||
GuiServer.this.keyDigest = EncryptUtil.getXorSha512Hash(GuiServer.this.keypair.getPublic().getEncoded());
|
||||
GuiServer.this.keyLabel.setText("Anmelde-Pubkey: RSA-2048 " + GuiServer.this.keyDigest);
|
||||
GuiServer.this.keyButton.setText("Schlüsselpaar entfernen");
|
||||
GuiServer.this.passLabel.setText("Ersatz-Passwort (mind. 8 Zeichen)");
|
||||
}
|
||||
else {
|
||||
final String name = GuiServer.this.nameBox.getText();
|
||||
|
@ -97,6 +107,8 @@ public class GuiServer extends Gui implements FieldCallback {
|
|||
final boolean reqEnc = GuiServer.this.encToggle.getValue();
|
||||
final KeyPair keys = GuiServer.this.keypair;
|
||||
final PublicKey key = GuiServer.this.serverKey;
|
||||
final String digest = GuiServer.this.keyDigest;
|
||||
final String sdigest = GuiServer.this.serverDigest;
|
||||
GuiServer.this.gm.displayGuiScreen(new GuiConfirm(new GuiConfirm.Callback() {
|
||||
public void confirm(boolean confirmed) {
|
||||
GuiServer.this.gm.displayGuiScreen(GuiServer.this);
|
||||
|
@ -107,30 +119,43 @@ public class GuiServer extends Gui implements FieldCallback {
|
|||
GuiServer.this.accBox.setText(acc);
|
||||
GuiServer.this.encToggle.setValue(reqEnc);
|
||||
GuiServer.this.serverKey = key;
|
||||
GuiServer.this.serverDigest = sdigest;
|
||||
GuiServer.this.idLabel.setText("Server-Pubkey: " + (key != null ? "RSA-2048 " + GuiServer.this.serverDigest : "nicht vorhanden"));
|
||||
GuiServer.this.resetButton.enabled = key != null;
|
||||
if(confirmed) {
|
||||
GuiServer.this.keypair = null;
|
||||
GuiServer.this.keyDigest = null;
|
||||
GuiServer.this.keyLabel.setText("Anmelde-Pubkey: nicht vorhanden");
|
||||
GuiServer.this.keyButton.setText("Neues Schlüsselpaar generieren");
|
||||
GuiServer.this.passLabel.setText("Anmelde-Passwort (mind. 8 Zeichen)");
|
||||
}
|
||||
else {
|
||||
GuiServer.this.keypair = keys;
|
||||
GuiServer.this.keyDigest = digest;
|
||||
GuiServer.this.keyLabel.setText("Anmelde-Pubkey: RSA-2048 " + GuiServer.this.keyDigest);
|
||||
GuiServer.this.keyButton.setText("Schlüsselpaar entfernen");
|
||||
GuiServer.this.passLabel.setText("Ersatz-Passwort (mind. 8 Zeichen)");
|
||||
}
|
||||
}
|
||||
}, "Schlüsselpaar wirklich entfernen?", "Wenn das Schlüsselpaar gelöscht wird, ist es nicht mehr möglich, sich damit auf dem Server zu identifizieren und sich anzumelden.\nDamit könnte der Zugriff auf den Server unmöglich werden.", "Schlüsselpaar löschen", "Abbrechen"));
|
||||
}
|
||||
}
|
||||
}, (this.keypair = this.server.getKeypair()) == null ? "Neues Schlüsselpaar generieren" : "Schlüsselpaar entfernen"));
|
||||
this.encToggle = this.add(new Toggle(0, 270, 480, 24, false, this.server.requiresEncryption(), null, "Nur Verschlüsselt verbinden"));
|
||||
GuiServer.this.serverKey = this.server.getServerKey();
|
||||
this.resetButton = this.add(new ActButton(0, 320, 480, 24, new ButtonCallback() {
|
||||
}, this.keypair == null ? "Neues Schlüsselpaar generieren" : "Schlüsselpaar entfernen"));
|
||||
this.keyLabel = this.add(new Label(0, 100, 480, 20, "Anmelde-Pubkey: " + (this.keypair != null ? "RSA-2048 " + this.keyDigest : "nicht vorhanden"), true));
|
||||
this.encToggle = this.add(new Toggle(0, 250, 480, 24, false, this.server.requiresEncryption(), null, "Nur Verschlüsselte Verbindung akzeptieren"));
|
||||
this.serverKey = this.server.getServerKey();
|
||||
this.serverDigest = this.serverKey == null ? null : EncryptUtil.getXorSha512Hash(this.serverKey.getEncoded());
|
||||
this.idLabel = this.add(new Label(0, 280, 480, 20, "Server-Pubkey: " + (this.serverKey != null ? "RSA-2048 " + this.serverDigest : "nicht vorhanden"), true));
|
||||
this.resetButton = this.add(new ActButton(0, 300, 480, 24, new ButtonCallback() {
|
||||
public void use(ActButton elem, PressType action) {
|
||||
if(GuiServer.this.serverKey != null) {
|
||||
GuiServer.this.serverKey = null;
|
||||
GuiServer.this.serverDigest = null;
|
||||
GuiServer.this.idLabel.setText("Server-Pubkey: nicht vorhanden");
|
||||
GuiServer.this.resetButton.enabled = false;
|
||||
}
|
||||
}
|
||||
}, "Server-Key zurücksetzen"));
|
||||
}, "Server-Identifizierung / Pubkey zurücksetzen"));
|
||||
this.resetButton.enabled = this.serverKey != null;
|
||||
}
|
||||
this.shift();
|
||||
|
@ -147,13 +172,17 @@ public class GuiServer extends Gui implements FieldCallback {
|
|||
if(this.server != null) {
|
||||
name = this.nameBox.getText();
|
||||
if(name.isEmpty()) {
|
||||
this.nameLabel.setText(TextColor.RED + "Name");
|
||||
this.nameLabel.setText(TextColor.RED + "Name in der Liste");
|
||||
return;
|
||||
}
|
||||
if(GuiConnect.INSTANCE.isNameTaken(name)) {
|
||||
this.nameLabel.setText("Name in der Liste - " + TextColor.RED + "Bereits vorhanden");
|
||||
return;
|
||||
}
|
||||
}
|
||||
String addr = this.addrBox.getText();
|
||||
if(addr.isEmpty()) {
|
||||
this.addrLabel.setText(TextColor.RED + "Adresse");
|
||||
this.addrLabel.setText(TextColor.RED + "Adresse / Hostname");
|
||||
return;
|
||||
}
|
||||
int port = -1;
|
||||
|
@ -176,17 +205,17 @@ public class GuiServer extends Gui implements FieldCallback {
|
|||
}
|
||||
String user = this.userBox.getText();
|
||||
if(user.isEmpty()) {
|
||||
this.userLabel.setText(TextColor.RED + "Nutzer");
|
||||
this.userLabel.setText(TextColor.RED + "Benutzername");
|
||||
return;
|
||||
}
|
||||
String pass = this.passBox.getText();
|
||||
if(pass.length() < 8) {
|
||||
this.passLabel.setText(pass.isEmpty() ? TextColor.RED + "Passwort (mind. 8 Zeichen)" : "Passwort (" + TextColor.RED + "mind. 8 Zeichen" + TextColor.RESET + ")");
|
||||
if(!pass.isEmpty() && pass.length() < 8) {
|
||||
this.passLabel.setText((this.keypair == null ? "Anmelde" : "Ersatz") + "-Passwort (" + TextColor.RED + "mind. 8 Zeichen" + TextColor.RESET + ")");
|
||||
return;
|
||||
}
|
||||
String acc = this.accBox.getText();
|
||||
if(acc.length() < 8) {
|
||||
this.accLabel.setText(acc.isEmpty() ? TextColor.RED + "Zugang (mind. 8 Zeichen)" : "Zugang (" + TextColor.RED + "mind. 8 Zeichen" + TextColor.RESET + ")");
|
||||
if(!acc.isEmpty() && acc.length() < 8) {
|
||||
this.accLabel.setText("Zugang (" + TextColor.RED + "mind. 8 Zeichen" + TextColor.RESET + ")");
|
||||
return;
|
||||
}
|
||||
if(this.server == null) {
|
||||
|
@ -211,19 +240,19 @@ public class GuiServer extends Gui implements FieldCallback {
|
|||
}
|
||||
else if(value == FieldAction.FOCUS) {
|
||||
if(elem == this.addrBox)
|
||||
this.addrLabel.setText("Adresse");
|
||||
this.addrLabel.setText("Adresse / Hostname");
|
||||
else if(elem == this.portBox) {
|
||||
this.portLabel.setText("Port");
|
||||
this.rangeLabel.setText("[1024..32767]");
|
||||
}
|
||||
else if(elem == this.userBox)
|
||||
this.userLabel.setText("Nutzer");
|
||||
this.userLabel.setText("Benutzername");
|
||||
else if(elem == this.passBox)
|
||||
this.passLabel.setText("Passwort (mind. 8 Zeichen)");
|
||||
this.passLabel.setText((this.keypair == null ? "Anmelde" : "Ersatz") + "-Passwort (mind. 8 Zeichen)");
|
||||
else if(elem == this.accBox)
|
||||
this.accLabel.setText("Zugang (mind. 8 Zeichen)");
|
||||
this.accLabel.setText("Server-Passwort (mind. 8 Zeichen)");
|
||||
else if(this.server != null && elem == this.nameBox)
|
||||
this.nameLabel.setText("Name");
|
||||
this.nameLabel.setText("Name in der Liste");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,6 @@ import client.Client;
|
|||
import client.gui.GuiConfirm;
|
||||
import client.gui.GuiConnect;
|
||||
import client.gui.GuiConnect.ServerInfo;
|
||||
import client.gui.GuiLoading;
|
||||
import common.net.util.concurrent.Future;
|
||||
import common.net.util.concurrent.GenericFutureListener;
|
||||
import common.network.IClientLoginHandler;
|
||||
|
@ -80,22 +79,21 @@ public class ClientLoginHandler extends NetHandler implements IClientLoginHandle
|
|||
if(confirmed) {
|
||||
ClientLoginHandler.this.server.setServerKey(pubkey);
|
||||
GuiConnect.INSTANCE.editServer(ClientLoginHandler.this.server);
|
||||
ClientLoginHandler.this.gm.displayGuiScreen(
|
||||
GuiLoading.makeWaitTask("Verbinde zu " + (ClientLoginHandler.this.server.getAddress() == null ? "localhost" :
|
||||
ClientLoginHandler.this.server.getAddress()) + ":" + ClientLoginHandler.this.server.getPort() + " ..."));
|
||||
ClientLoginHandler.this.gm.displayConnecting(ClientLoginHandler.this.server);
|
||||
ClientLoginHandler.this.startEncryption(secret, pubkey, token);
|
||||
}
|
||||
else {
|
||||
ClientLoginHandler.this.connection.closeChannel("Verbindung wurde abgebrochen");
|
||||
}
|
||||
}
|
||||
}, "Die Identität des Servers ist unbekannt", "Es wurde noch nie mit diesem Server verbunden.\nSoll die Verbindung wirklich fortgesetzt werden?\n\nDer öffentliche Schlüssel des Servers lautet:\n" + Base64.getEncoder().encodeToString(pubkey.getEncoded()), "Verbindung herstellen", "Abbrechen und trennen"));
|
||||
}, "Die Identität des Servers ist unbekannt", "Es wurde noch nie mit diesem Server verbunden.\nSoll die Verbindung wirklich fortgesetzt werden?\n\nDie Pubkey-ID des Servers lautet:\nRSA-2048 " + EncryptUtil.getXorSha512Hash(pubkey.getEncoded()) + "\n\nDer öffentliche Schlüssel des Servers lautet:\n" + Base64.getEncoder().encodeToString(pubkey.getEncoded()), "Verbindung herstellen", "Abbrechen und trennen"));
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
else if(!this.server.getServerKey().equals(pubkey)) {
|
||||
this.connection.closeChannel("Die Identität des Servers hat sich geändert\n\nDer Server hat einen anderen öffentlichen Schlüssel als vorher bekannt war, dies kann bedeuten dass der Inhaber jetzt einen anderen Schlüssel verwendet oder sich ein anderer Server als dieser ausgibt (man-in-the-middle attack).\n\nDer öffentliche Schlüssel des Servers lautet:\n" + Base64.getEncoder().encodeToString(pubkey.getEncoded()) + "\n\nDer vertrauenswürdige Schlüssel lautet:\n" + Base64.getEncoder().encodeToString(this.server.getServerKey().getEncoded()));
|
||||
this.connection.closeChannel("Die Identität des Servers hat sich geändert\n\nDer Server hat einen anderen öffentlichen Schlüssel als vorher bekannt war, dies kann bedeuten dass der Inhaber jetzt einen anderen Schlüssel verwendet oder sich ein anderer Server als dieser ausgibt (\"Man-in-the-middle-attack\").\n\nDie Pubkey-ID des Servers lautet:\nRSA-2048 " + EncryptUtil.getXorSha512Hash(pubkey.getEncoded()) + "\n\nDer öffentliche Schlüssel des Servers lautet:\n" + Base64.getEncoder().encodeToString(pubkey.getEncoded()) + "\n\nDie vertrauenswürdige Pubkey-ID lautet:\nRSA-2048 " + EncryptUtil.getXorSha512Hash(this.server.getServerKey().getEncoded()) + "\n\nDer vertrauenswürdige Schlüssel lautet:\n" + Base64.getEncoder().encodeToString(this.server.getServerKey().getEncoded()) +
|
||||
"\n\nFalls der Server trotzdem vertrauenswürdig wirkt, kann die Server-Identifizierung im den Einstellungen von '" + this.server.getName() + "' zurückgesetzt werden.");
|
||||
return;
|
||||
}
|
||||
this.startEncryption(secret, pubkey, token);
|
||||
|
@ -125,7 +123,7 @@ public class ClientLoginHandler extends NetHandler implements IClientLoginHandle
|
|||
this.state = LoginState.ENCRYPTED;
|
||||
}
|
||||
|
||||
public void handleConfig(RPacketServerConfig packet) {
|
||||
public void handleConfig(final RPacketServerConfig packet) {
|
||||
if(this.state == LoginState.HANDSHAKE) {
|
||||
this.connection.setConnectionState(PacketRegistry.LOGIN);
|
||||
if(this.server.requiresEncryption()) {
|
||||
|
@ -133,11 +131,37 @@ public class ClientLoginHandler extends NetHandler implements IClientLoginHandle
|
|||
+ this.server.getName() + "' als erforderlich eingestellt, stelle keine ungesicherte Verbindung her.");
|
||||
return;
|
||||
}
|
||||
if(this.server.getServerKey() != null) {
|
||||
this.state = LoginState.CONFIRMING;
|
||||
this.gm.schedule(new Runnable() {
|
||||
public void run() {
|
||||
ClientLoginHandler.this.gm.displayGuiScreen(new GuiConfirm(new GuiConfirm.Callback() {
|
||||
public void confirm(boolean confirmed) {
|
||||
if(confirmed) {
|
||||
ClientLoginHandler.this.server.setServerKey(null);
|
||||
GuiConnect.INSTANCE.editServer(ClientLoginHandler.this.server);
|
||||
ClientLoginHandler.this.gm.displayConnecting(ClientLoginHandler.this.server);
|
||||
ClientLoginHandler.this.state = LoginState.HANDSHAKE;
|
||||
ClientLoginHandler.this.handleConfig(packet);
|
||||
}
|
||||
else {
|
||||
ClientLoginHandler.this.connection.closeChannel("Verbindung wurde abgebrochen");
|
||||
}
|
||||
}
|
||||
}, "Der Server hat die Verschlüsselung deaktiviert", "Es wurde bereits verschlüsselt mit diesem Server kommuniziert.\n\nSoll die Verbindung wirklich fortgesetzt werden?\n\nDie Pubkey-Authentifizierung wird nicht verfügbar sein und die Server-ID wird ignoriert und zurückgesetzt.", "Unverschlüsselt verbinden", "Abbrechen und trennen"));
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if(this.state != LoginState.ENCRYPTED) {
|
||||
this.connection.closeChannel("Unerwartetes Konfigurations-Paket");
|
||||
return;
|
||||
}
|
||||
if(packet.hasAccessPassword() && this.server.getAccess().isEmpty()) {
|
||||
this.connection.closeChannel("Der Server verlangt ein Zugangs-Passwort zur Authentifizierung");
|
||||
return;
|
||||
}
|
||||
boolean auth = packet.isAuthenticating();
|
||||
boolean passwordAuth = packet.canUsePassword();
|
||||
boolean pubkeyAuth = packet.canUsePubkey() && this.state == LoginState.ENCRYPTED;
|
||||
|
|
|
@ -6,6 +6,7 @@ import java.security.Key;
|
|||
import java.security.KeyFactory;
|
||||
import java.security.KeyPair;
|
||||
import java.security.KeyPairGenerator;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.PublicKey;
|
||||
|
@ -117,4 +118,23 @@ public class EncryptUtil {
|
|||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static String getXorSha512Hash(byte[] data) {
|
||||
byte[] hash;
|
||||
try {
|
||||
MessageDigest digest = MessageDigest.getInstance("SHA-512");
|
||||
hash = digest.digest(data);
|
||||
}
|
||||
catch(NoSuchAlgorithmException e) {
|
||||
Log.SYSTEM.error(e, "Konnte Prüfwert nicht berechnen");
|
||||
return "<?>";
|
||||
}
|
||||
byte[] xor = new byte[8];
|
||||
for(int z = 0; z < hash.length / xor.length; z++) {
|
||||
for(int n = 0; n < xor.length; n++) {
|
||||
xor[n] ^= hash[z * xor.length + n];
|
||||
}
|
||||
}
|
||||
return Util.getHexString(xor);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue