mirror of
https://github.com/magefree/mage.git
synced 2025-12-24 04:22:01 -08:00
added optional SSL encryption
This commit is contained in:
parent
a168d53966
commit
b41cbe2703
11 changed files with 55 additions and 13 deletions
|
|
@ -699,7 +699,7 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
|
|||
|
||||
public boolean connect(Connection connection) {
|
||||
client = new Client(instance);
|
||||
boolean result = client.connect(connection.getUsername(), connection.getHost(), connection.getPort(), version);
|
||||
boolean result = client.connect(connection.getUsername(), connection.getHost(), connection.getPort(), true, version);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ public class MultiConnectTest {
|
|||
connection.setPort(17171);
|
||||
connection.setProxyType(Connection.ProxyType.NONE);
|
||||
|
||||
client.connect(username, "localhost", 17171, version);
|
||||
client.connect(username, "localhost", 17171, true, version);
|
||||
}
|
||||
|
||||
public MageVersion getVersion() {
|
||||
|
|
@ -75,6 +75,7 @@ public class MultiConnectTest {
|
|||
connected++;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disconnected(boolean errorCall) {
|
||||
logger.info("disconnected");
|
||||
}
|
||||
|
|
@ -158,8 +159,8 @@ public class MultiConnectTest {
|
|||
private void sleep(int ms) {
|
||||
try {
|
||||
Thread.sleep(ms);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} catch (InterruptedException e) {
|
||||
logger.error("Error", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,11 +10,14 @@ import io.netty.channel.socket.nio.NioSocketChannel;
|
|||
import io.netty.handler.codec.serialization.ClassResolvers;
|
||||
import io.netty.handler.codec.serialization.ObjectDecoder;
|
||||
import io.netty.handler.codec.serialization.ObjectEncoder;
|
||||
import io.netty.handler.ssl.SslContext;
|
||||
import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
|
||||
import io.netty.handler.timeout.IdleStateHandler;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import javax.net.ssl.SSLException;
|
||||
import mage.cards.decks.DeckCardLists;
|
||||
import mage.constants.ManaType;
|
||||
import mage.constants.PlayerAction;
|
||||
|
|
@ -59,9 +62,12 @@ public class Client {
|
|||
private final ClientRegisteredMessageHandler clientRegisteredMessageHandler;
|
||||
private final ServerMessageHandler serverMessageHandler;
|
||||
|
||||
private SslContext sslCtx;
|
||||
private Channel channel;
|
||||
private EventLoopGroup group;
|
||||
private String username;
|
||||
private String username;
|
||||
private String host;
|
||||
private int port;
|
||||
|
||||
public Client(MageClient client) {
|
||||
this.client = client;
|
||||
|
|
@ -73,12 +79,19 @@ public class Client {
|
|||
serverMessageHandler = new ServerMessageHandler();
|
||||
}
|
||||
|
||||
public boolean connect(String userName, String host, int port, MageVersion version) {
|
||||
public boolean connect(String userName, String host, int port, boolean ssl, MageVersion version) {
|
||||
|
||||
this.username = userName;
|
||||
this.host = host;
|
||||
this.port = port;
|
||||
|
||||
group = new NioEventLoopGroup();
|
||||
try {
|
||||
if (ssl) {
|
||||
sslCtx = SslContext.newClientContext(InsecureTrustManagerFactory.INSTANCE);
|
||||
} else {
|
||||
sslCtx = null;
|
||||
}
|
||||
Bootstrap b = new Bootstrap();
|
||||
b.group(group)
|
||||
.channel(NioSocketChannel.class)
|
||||
|
|
@ -90,7 +103,7 @@ public class Client {
|
|||
clientRegisteredMessageHandler.registerClient();
|
||||
client.connected(userName + "@" + host + ":" + port + " ");
|
||||
return true;
|
||||
} catch (InterruptedException ex) {
|
||||
} catch (SSLException | InterruptedException ex) {
|
||||
logger.fatal("Error connecting", ex);
|
||||
client.inform("Error connecting", MessageType.ERROR);
|
||||
group.shutdownGracefully();
|
||||
|
|
@ -103,6 +116,9 @@ public class Client {
|
|||
@Override
|
||||
public void initChannel(SocketChannel ch) throws Exception {
|
||||
|
||||
if (sslCtx != null) {
|
||||
ch.pipeline().addLast(sslCtx.newHandler(ch.alloc(), host, port));
|
||||
}
|
||||
ch.pipeline().addLast(new ObjectDecoder(ClassResolvers.cacheDisabled(null)));
|
||||
ch.pipeline().addLast(new ObjectEncoder());
|
||||
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@ import io.netty.handler.codec.serialization.ObjectDecoder;
|
|||
import io.netty.handler.codec.serialization.ObjectEncoder;
|
||||
import io.netty.handler.logging.LogLevel;
|
||||
import io.netty.handler.logging.LoggingHandler;
|
||||
import io.netty.handler.ssl.SslContext;
|
||||
import io.netty.handler.ssl.util.SelfSignedCertificate;
|
||||
import io.netty.handler.timeout.IdleStateHandler;
|
||||
import io.netty.util.concurrent.DefaultEventExecutorGroup;
|
||||
import io.netty.util.concurrent.EventExecutorGroup;
|
||||
|
|
@ -47,6 +49,8 @@ public class Server {
|
|||
private static final int IDLE_TIMEOUT = 60;
|
||||
|
||||
public static final ChannelGroup clients = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
|
||||
|
||||
private SslContext sslCtx;
|
||||
|
||||
private final HeartbeatHandler heartbeatHandler;
|
||||
private final PingMessageHandler pingMessageHandler = new PingMessageHandler();
|
||||
|
|
@ -69,7 +73,15 @@ public class Server {
|
|||
serverMessageHandler = new ServerMessageHandler(server);
|
||||
}
|
||||
|
||||
public void start(int port) {
|
||||
public void start(int port, boolean ssl) throws Exception {
|
||||
|
||||
if (ssl) {
|
||||
SelfSignedCertificate ssc = new SelfSignedCertificate();
|
||||
sslCtx = SslContext.newServerContext(ssc.certificate(), ssc.privateKey());
|
||||
} else {
|
||||
sslCtx = null;
|
||||
}
|
||||
|
||||
EventLoopGroup bossGroup = new NioEventLoopGroup();
|
||||
EventLoopGroup workerGroup = new NioEventLoopGroup();
|
||||
|
||||
|
|
@ -95,6 +107,9 @@ public class Server {
|
|||
@Override
|
||||
public void initChannel(SocketChannel ch) throws Exception {
|
||||
|
||||
if (sslCtx != null) {
|
||||
ch.pipeline().addLast(sslCtx.newHandler(ch.alloc()));
|
||||
}
|
||||
ch.pipeline().addLast(new ObjectDecoder(ClassResolvers.cacheDisabled(null)));
|
||||
ch.pipeline().addLast(new ObjectEncoder());
|
||||
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@
|
|||
userNamePattern="[^a-z0-9_]"
|
||||
maxAiOpponents="15"
|
||||
saveGameActivated="false"
|
||||
useSSL="true"
|
||||
/>
|
||||
<playerTypes>
|
||||
<playerType name="Human" jar="mage-player-human.jar" className="mage.player.human.HumanPlayer"/>
|
||||
|
|
|
|||
|
|
@ -212,7 +212,7 @@ public class Main implements MageServer {
|
|||
try {
|
||||
instance = new Main(adminPassword, testMode);
|
||||
server = new Server(instance);
|
||||
server.start(config.getPort());
|
||||
server.start(config.getPort(), config.isUseSSL());
|
||||
// Parameter: serializationtype => jboss
|
||||
// InvokerLocator serverLocator = new InvokerLocator(connection.getURI());
|
||||
// if (!isAlreadyRunning(serverLocator)) {
|
||||
|
|
@ -1320,7 +1320,7 @@ public class Main implements MageServer {
|
|||
return (MatchType) Class.forName(plugin.getTypeName(), true, classLoader).newInstance();
|
||||
} catch (ClassNotFoundException ex) {
|
||||
logger.warn("Game type not found:" + plugin.getJar() + " - check plugin folder", ex);
|
||||
} catch (Exception ex) {
|
||||
} catch (MalformedURLException | InstantiationException | IllegalAccessException ex) {
|
||||
logger.fatal("Error loading game type " + plugin.getJar(), ex);
|
||||
}
|
||||
return null;
|
||||
|
|
@ -1333,7 +1333,7 @@ public class Main implements MageServer {
|
|||
return (TournamentType) Class.forName(plugin.getTypeName(), true, classLoader).newInstance();
|
||||
} catch (ClassNotFoundException ex) {
|
||||
logger.warn("Tournament type not found:" + plugin.getName() + " / "+ plugin.getJar() + " - check plugin folder", ex);
|
||||
} catch (Exception ex) {
|
||||
} catch (MalformedURLException | InstantiationException | IllegalAccessException ex) {
|
||||
logger.fatal("Error loading game type " + plugin.getJar(), ex);
|
||||
}
|
||||
return null;
|
||||
|
|
|
|||
|
|
@ -61,6 +61,7 @@ public class Config {
|
|||
maxUserNameLength = Integer.parseInt(p.getProperty("maxUserNameLength"));
|
||||
userNamePattern = p.getProperty("userNamePattern");
|
||||
saveGameActivated = Boolean.parseBoolean(p.getProperty("saveGameActivated"));
|
||||
useSSL = Boolean.parseBoolean(p.getProperty("useSSL"));
|
||||
}
|
||||
|
||||
public static final String remoteServer;
|
||||
|
|
@ -76,5 +77,6 @@ public class Config {
|
|||
public static final int maxUserNameLength;
|
||||
public static final String userNamePattern;
|
||||
public static final boolean saveGameActivated;
|
||||
public static final boolean useSSL;
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
<xs:attribute name="userNamePattern" type="xs:string" use="required"/>
|
||||
<xs:attribute name="maxAiOpponents" type="xs:string" use="optional"/>
|
||||
<xs:attribute name="saveGameActivated" type="xs:boolean" use="optional"/>
|
||||
<xs:attribute name="useSSL" type="xs:boolean" use="optional"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
|
|
|
|||
|
|
@ -120,8 +120,12 @@ public class ConfigSettings {
|
|||
}
|
||||
|
||||
public Boolean isSaveGameActivated() {
|
||||
return config.getServer().isSaveGameActivated();
|
||||
}
|
||||
return config.getServer().isSaveGameActivated();
|
||||
}
|
||||
|
||||
public Boolean isUseSSL() {
|
||||
return config.getServer().isUseSSL();
|
||||
}
|
||||
|
||||
public List<Plugin> getPlayerTypes() {
|
||||
return config.getPlayerTypes().getPlayerType();
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
userNamePattern="[^a-z0-9_]"
|
||||
maxAiOpponents="15"
|
||||
saveGameActivated="false"
|
||||
useSSL="true"
|
||||
/>
|
||||
<playerTypes>
|
||||
<playerType name="Human" jar="Mage.Player.Human.jar" className="mage.player.human.HumanPlayer"/>
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
<xs:attribute name="userNamePattern" type="xs:string" use="required"/>
|
||||
<xs:attribute name="maxAiOpponents" type="xs:string" use="optional"/>
|
||||
<xs:attribute name="saveGameActivated" type="xs:boolean" use="optional"/>
|
||||
<xs:attribute name="useSSL" type="xs:boolean" use="optional"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue