· 4 years ago · Feb 01, 2021, 04:46 AM
1/*
2 * This file is part of Lightning-Digital <lightning-digital.org>.
3 *
4 * Lightning-Digital is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * Lightning-Digital is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with Lightning-Digital. If not, see <http://www.gnu.org/licenses/>.
16 */
17package org.lightning.digital.server.network;
18
19import java.security.interfaces.RSAPrivateKey;
20
21import javax.crypto.SecretKey;
22import javax.crypto.spec.SecretKeySpec;
23
24import org.lightning.digital.sdk.netty.PacketsManager;
25import org.lightning.digital.sdk.netty.models.ClientState;
26import org.lightning.digital.sdk.netty.models.Connection;
27import org.lightning.digital.server.model.Account;
28import org.lightning.digital.server.model.SessionKey;
29import org.lightning.digital.server.network.crypt.CryptEngine;
30import org.lightning.digital.server.network.crypt.EncryptedRSAKeyPair;
31import org.lightning.digital.server.network.crypt.KeyGen;
32import org.lightning.digital.server.network.serverpacket.SM_INIT;
33
34import io.netty.buffer.ByteBuf;
35import io.netty.buffer.Unpooled;
36import io.netty.channel.ChannelHandlerContext;
37
38/**
39 * @author WeRn
40 *
41 */
42public class LoginConnection extends Connection {
43
44 private SessionKey sessionKey;
45 private Account account;
46 private int sessionId;
47 private EncryptedRSAKeyPair encryptedRSAKeyPair;
48 private CryptEngine cryptEngine;
49
50 public LoginConnection() {}
51
52 @Override
53 public void channelActive(ChannelHandlerContext ctx) throws Exception {
54 setContext(ctx);
55 this.sessionId = this.hashCode();
56 this.encryptedRSAKeyPair = KeyGen.getEncryptedRSAKeyPair();
57 final SecretKey blowfishKey = new SecretKeySpec(new byte[16], 0, 16, "AES");
58 (this.cryptEngine = new CryptEngine()).updateKey(blowfishKey.getEncoded());
59
60 log.info("IP: " + ctx.channel().remoteAddress() + " connected to server");
61 log.info("Connection attemp from: " + this.getIP());
62
63 setState(ClientState.CONNECTED);
64 sendPacket(new SM_INIT(this, getEncryptedModulus(), blowfishKey.getEncoded(), getSessionId()));
65 }
66
67 @Override
68 public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
69 log.debug("Received Object: " + msg);
70 log.debug("Received ChannelHandlerContext: " + ctx);
71
72 ByteBuf buf = decrypt((ByteBuf) msg);
73 byte opCode = buf.readByte();
74
75 log.debug("Received opCode: " + opCode);
76 log.debug("Received opCode in int: " + ((int) opCode));
77
78 ClientPacket clientPacket = getPacket(opCode, buf);
79 if (clientPacket != null && clientPacket.read()) {
80 clientPacket.run();
81 }
82 }
83
84 public void sendPacket(ServerPacket packet) {
85 ByteBuf cb = Unpooled.buffer();
86 packet.write(this, cb);
87 int leght = cb.readableBytes();
88 cb.setShortLE(0, (short) leght);
89 getContext().writeAndFlush(cb);
90 log.debug("Sent packet: " + packet);
91 }
92
93 private ByteBuf decrypt(ByteBuf buf) {
94 int size = buf.capacity();
95 byte[] decrypt_bytes = new byte[size];
96 buf.duplicate().readBytes(decrypt_bytes);
97 boolean ret = this.cryptEngine.decrypt(decrypt_bytes, 0, size);
98
99 if (!ret) {
100 log.warn("Wrong checksum from client: " + this);
101 }
102 ByteBuf read_cb = Unpooled.buffer(decrypt_bytes.length);
103 return read_cb.setBytes(0, decrypt_bytes).setIndex(0, decrypt_bytes.length);
104 }
105
106 public void encrypt(ByteBuf buf) {
107 int size = buf.readableBytes();
108 size = this.cryptEngine.encrypt(buf.array(), 2, size);
109 buf.setIndex(buf.readerIndex(), size + 2);
110 }
111
112 public ClientPacket getPacket(short opCode, ByteBuf data) {
113 ClientPacket prototype = null;
114 if (PacketsManager.getInstance().getClientPackets().containsKey(opCode)) {
115 prototype = (ClientPacket) PacketsManager.getInstance().getClientPacket(opCode).clonePacket();
116 prototype.setChannelBuffer(data);
117 prototype.setConnection(this);
118 packetInfo(prototype);
119 return prototype;
120 }
121 unknowPacker(getState(), opCode, data);
122 return null;
123 }
124
125 public final int getSessionId() {
126 return this.sessionId;
127 }
128
129 public final RSAPrivateKey getRSAPrivateKey() {
130 return (RSAPrivateKey) this.encryptedRSAKeyPair.getRSAKeyPair().getPrivate();
131 }
132
133 public final byte[] getEncryptedModulus() {
134 return this.encryptedRSAKeyPair.getEncryptedModulus();
135 }
136
137 public final SessionKey getSessionKey() {
138 return this.sessionKey;
139 }
140
141 public final void setSessionKey(final SessionKey sessionKey) {
142 this.sessionKey = sessionKey;
143 }
144
145 public final Account getAccount() {
146 return this.account;
147 }
148
149 public final void setAccount(final Account account) {
150 this.account = account;
151 }
152}
153