Advertisement
Guest User

CatsGuard.java

a guest
Jul 26th, 2013
204
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.84 KB | None | 0 0
  1. package silentium.protection;
  2.  
  3. import java.nio.ByteBuffer;
  4. import java.sql.Connection;
  5. import java.sql.PreparedStatement;
  6. import java.sql.ResultSet;
  7. import java.sql.SQLException;
  8. import java.util.List;
  9. import java.util.Map;
  10.  
  11. import javolution.util.FastList;
  12. import javolution.util.FastMap;
  13.  
  14. import org.slf4j.Logger;
  15. import org.slf4j.LoggerFactory;
  16.  
  17. import silentium.commons.database.DatabaseFactory;
  18. import silentium.gameserver.Announcements;
  19. import silentium.gameserver.AuthServerThread;
  20. import silentium.gameserver.model.actor.instance.L2PcInstance;
  21. import silentium.gameserver.network.L2GameClient;
  22. import silentium.gameserver.network.L2GameClient.IExReader;
  23. import silentium.gameserver.network.serverpackets.GameGuardQuery;
  24. import silentium.gameserver.network.serverpackets.LeaveWorld;
  25.  
  26. public class CatsGuard
  27. {
  28. protected static final Logger _log = LoggerFactory.getLogger(CatsGuard.class.getName());
  29.  
  30. private class CatsGuardReader implements IExReader
  31. {
  32. private RC4 _crypt;
  33. private final L2GameClient _client;
  34. private int _prevcode = 0;
  35. private final byte[] buffer = new byte[4];
  36. private int _state;
  37. protected boolean _checkChar;
  38.  
  39. protected CatsGuardReader(L2GameClient cl)
  40. {
  41. _state = 0;
  42. _client = cl;
  43. }
  44.  
  45. public void setKey(int data[])
  46. {
  47. String key = "";
  48. for (int i = 0; i < 10; i++)
  49. {
  50. key += String.format("%X%X", data[1], ProtectionProperties.SERVER_KEY);
  51. }
  52. _crypt = new RC4(key, false);
  53. _state = 1;
  54. }
  55.  
  56. @Override
  57. public int read(ByteBuffer buf)
  58. {
  59. int opcode = 0;
  60. if (_state == 0)
  61. {
  62. opcode = buf.get() & 0xff;
  63. if (opcode != 0xca)
  64. {
  65. illegalAction(_client, "Invalid opcode on pre-auth state");
  66. return 0;
  67. }
  68. }
  69. else
  70. {
  71. if (buf.remaining() < 4)
  72. {
  73. illegalAction(_client, "Invalid block size on authed state");
  74. }
  75. else
  76. {
  77. buf.get(buffer);
  78. opcode = decryptPacket(buffer) & 0xff;
  79. }
  80. }
  81. return opcode;
  82. }
  83.  
  84. private int decryptPacket(byte[] packet)
  85. {
  86. packet = _crypt.rc4(packet);
  87. int crc = CRC16.calc(new byte[]
  88. {
  89. (byte) (_prevcode & 0xff),
  90. packet[1]
  91. });
  92. int read_crc = (((packet[3] & 0xff) << 8) & 0xff00) | (packet[2] & 0xff);
  93. if (crc != read_crc)
  94. {
  95. illegalAction(_client, "CRC error");
  96. return 0;
  97. }
  98. _prevcode = packet[1] & 0xff;
  99. return _prevcode;
  100. }
  101.  
  102. @Override
  103. public void checkChar(L2PcInstance cha)
  104. {
  105. if (!_checkChar || (cha == null))
  106. {
  107. return;
  108. }
  109. if (ProtectionProperties.ALLOW_GM_FROM_BANNED_HWID && cha.isGM())
  110. {
  111. return;
  112. }
  113. if (ProtectionProperties.LOG_OPTION.contains("BANNED"))
  114. {
  115. _log.info("CatsGuard: Client " + cha.getClient() + " try to log with banned hwid.");
  116. }
  117. cha.closeNetConnection(true);
  118. }
  119. }
  120.  
  121. private Map<String, Integer> _connections;
  122. private final List<String> _premium = new FastList<>();
  123. private List<String> _bannedhwid;
  124.  
  125. private CatsGuard()
  126. {
  127. ProtectionProperties.init();
  128.  
  129. if (ProtectionProperties.SERVER_KEY == 0)
  130. {
  131. return;
  132. }
  133.  
  134. _connections = new FastMap<>();
  135. _bannedhwid = new FastList<>();
  136.  
  137. try (Connection con = DatabaseFactory.getConnection();
  138. PreparedStatement stm = con.prepareStatement("select * from banned_hwid");
  139. ResultSet rs = stm.executeQuery())
  140. {
  141. while (rs.next())
  142. {
  143. _bannedhwid.add(rs.getString(1));
  144. }
  145. }
  146. catch (Exception e)
  147. {
  148. if (e.getClass().getSimpleName().equals("MySQLSyntaxErrorException"))
  149. {
  150. try (Connection con = DatabaseFactory.getConnection();
  151. PreparedStatement stmt = con.prepareStatement("create table `banned_hwid` (`hwid` varchar(64) not null primary key)");)
  152. {
  153. stmt.execute();
  154. }
  155. catch (Exception ex)
  156. {
  157. _log.warn("", ex);
  158. }
  159. }
  160. }
  161. _log.info("CatsGuard: Loaded " + _bannedhwid.size() + " banned hwid(s)");
  162. _log.info("CatsGuard: Ready");
  163. }
  164.  
  165. public boolean isEnabled()
  166. {
  167. return ProtectionProperties.ENABLED;
  168. }
  169.  
  170. public void ban(L2PcInstance player)
  171. {
  172. ban(player.getHWid());
  173. }
  174.  
  175. public void ban(String hwid)
  176. {
  177. if (!ProtectionProperties.ENABLED)
  178. {
  179. return;
  180. }
  181. synchronized (_bannedhwid)
  182. {
  183. if (_bannedhwid.contains(hwid))
  184. {
  185. return;
  186. }
  187. _bannedhwid.add(hwid);
  188. try
  189. {
  190. Connection con = DatabaseFactory.getConnection();
  191. PreparedStatement stm = con.prepareStatement("insert into banned_hwid values(?)");
  192. stm.setString(1, hwid);
  193. stm.execute();
  194. stm.close();
  195. con.close();
  196. }
  197. catch (SQLException e)
  198. {
  199. _log.warn("CatsGuard: Unable to store banned hwid");
  200. }
  201. }
  202. }
  203.  
  204. protected void illegalAction(L2GameClient cl, String reason)
  205. {
  206. if ((cl.getActiveChar() != null) && ProtectionProperties.ANNOUNCE_HACK)
  207. {
  208. Announcements.announceToAll("Player " + cl.getActiveChar().getName() + " used unlegal soft!");
  209. }
  210. if (ProtectionProperties.ON_HACK_ATTEMP.equals("hwidban") && (cl.getHWid() != null))
  211. {
  212. ban(cl.getHWid());
  213. }
  214. else if (ProtectionProperties.ON_HACK_ATTEMP.equals("jail") && (cl.getActiveChar() != null))
  215. {
  216. cl.getActiveChar().isInJail();
  217. }
  218. else if (ProtectionProperties.ON_HACK_ATTEMP.equals("ban") && (cl.getActiveChar() != null))
  219. {
  220. AuthServerThread.getInstance().sendAccessLevel(cl.getAccountName(), -100);
  221. }
  222. _log.info("CatsGuard: Client " + cl + " use illegal software and will " + ProtectionProperties.ON_HACK_ATTEMP + "ed. Reason: " + reason);
  223. cl.close(new LeaveWorld());
  224. }
  225.  
  226. public void initSession(L2GameClient cl)
  227. {
  228. if (!ProtectionProperties.ENABLED)
  229. {
  230. return;
  231. }
  232. cl.sendPacket(GameGuardQuery.STATIC_PACKET);
  233. cl._reader = new CatsGuardReader(cl);
  234. }
  235.  
  236. public void doneSession(L2GameClient cl)
  237. {
  238. if (!ProtectionProperties.ENABLED)
  239. {
  240. return;
  241. }
  242. if (cl.getHWid() != null)
  243. {
  244. _premium.remove(cl.getHWid());
  245. if (_connections.containsKey(cl.getHWid()))
  246. {
  247. int nwnd = _connections.get(cl.getHWid());
  248. if (nwnd == 0)
  249. {
  250. _connections.remove(cl.getHWid());
  251. }
  252. else
  253. {
  254. _connections.put(cl.getHWid(), --nwnd);
  255. }
  256. }
  257. }
  258. cl._reader = null;
  259. }
  260.  
  261. public void initSession(L2GameClient cl, int[] data)
  262. {
  263. if (!ProtectionProperties.ENABLED)
  264. {
  265. return;
  266. }
  267. if (data[0] != ProtectionProperties.SERVER_KEY)
  268. {
  269. if (ProtectionProperties.LOG_OPTION.contains("NOPROTECT"))
  270. {
  271. _log.info("CatsGuard: Client " + cl + " try to log with no CatsGuard");
  272. }
  273. cl.close(new LeaveWorld());
  274. return;
  275. }
  276. String hwid = String.format("%x", data[3]);
  277. if (cl._reader == null)
  278. {
  279. if (ProtectionProperties.LOG_OPTION.contains("HACK"))
  280. {
  281. _log.info("CatsGuard: Client " + cl + " has no pre-authed state");
  282. }
  283. cl.close(new LeaveWorld());
  284. return;
  285. }
  286. if (_bannedhwid.contains(hwid))
  287. {
  288. ((CatsGuardReader) cl._reader)._checkChar = true;
  289. }
  290. if (!_connections.containsKey(hwid))
  291. {
  292. _connections.put(hwid, 0);
  293. }
  294. int nwindow = _connections.get(hwid);
  295. int max = ProtectionProperties.MAX_SESSIONS;
  296. if (_premium.contains(hwid))
  297. {
  298. max = ProtectionProperties.MAX_PREMIUM_SESSIONS;
  299. }
  300. if ((max > 0) && (++nwindow > max))
  301. {
  302. if (ProtectionProperties.LOG_OPTION.contains("SESSIONS"))
  303. {
  304. _log.info("CatsGuard: To many sessions from hwid " + hwid);
  305. }
  306. cl.close(new LeaveWorld());
  307. return;
  308. }
  309. if (!_premium.contains(hwid))
  310. {
  311. _premium.add(hwid);
  312. }
  313. _connections.put(hwid, nwindow);
  314. cl.setHWID(hwid);
  315. ((CatsGuardReader) cl._reader).setKey(data);
  316. if (ProtectionProperties.LOG_SESSIONS)
  317. {
  318. _log.info("Client " + cl.getAccountName() + " connected with hwid " + cl.getHWid());
  319. }
  320. }
  321.  
  322. private static CatsGuard _instance;
  323.  
  324. public static CatsGuard getInstance()
  325. {
  326. if (_instance == null)
  327. {
  328. _instance = new CatsGuard();
  329. }
  330. return _instance;
  331. }
  332. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement