LicenseManager.java 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. package com.aip.gateway.api;
  2. import lombok.Data;
  3. import lombok.extern.slf4j.Slf4j;
  4. import org.w3c.dom.Document;
  5. import org.w3c.dom.Element;
  6. import org.w3c.dom.Node;
  7. import org.w3c.dom.NodeList;
  8. import org.xml.sax.SAXException;
  9. import javax.xml.parsers.DocumentBuilder;
  10. import javax.xml.parsers.DocumentBuilderFactory;
  11. import javax.xml.parsers.ParserConfigurationException;
  12. import java.io.File;
  13. import java.io.IOException;
  14. import java.nio.charset.StandardCharsets;
  15. import java.security.MessageDigest;
  16. import java.security.NoSuchAlgorithmException;
  17. import java.text.ParseException;
  18. import java.text.SimpleDateFormat;
  19. import java.util.Calendar;
  20. import java.util.Date;
  21. @Slf4j
  22. public class LicenseManager {
  23. @Data
  24. private static class License {
  25. private boolean isValid;
  26. private int errorCode;
  27. private String product;
  28. private String serialId;
  29. private String issueDay;
  30. private Date startDate;
  31. private String licensee;
  32. private String edition;
  33. private String type;
  34. private int accounts;
  35. private String identifiedHost;
  36. private String signature;
  37. private int demoDuration;
  38. private boolean isDemo;
  39. public License() {
  40. this.isValid = false;
  41. this.errorCode = 0;
  42. this.product = "";
  43. this.serialId = "";
  44. this.issueDay = "";
  45. this.licensee = "";
  46. this.edition = "";
  47. this.type = "";
  48. this.accounts = 0;
  49. this.identifiedHost = "";
  50. this.signature = "";
  51. this.demoDuration = 0;
  52. this.isDemo = false;
  53. }
  54. }
  55. private static String getComputerName() {
  56. String hostName = System.getenv("COMPUTERNAME");
  57. if (hostName == null || hostName.isEmpty()) {
  58. hostName = "localhost";
  59. }
  60. return hostName;
  61. }
  62. private static NodeList getXmlNodeList(String filePath, String nodeTag) {
  63. try {
  64. DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
  65. DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
  66. File xmlFile = new File(filePath);
  67. Document document = documentBuilder.parse(xmlFile);
  68. document.getDocumentElement().normalize();
  69. return document.getElementsByTagName(nodeTag);
  70. } catch (ParserConfigurationException e) {
  71. log.error("getXmlNodeList(ParserConfigurationException): {}, {}: {}", filePath, nodeTag, e.toString());
  72. } catch (SAXException e) {
  73. log.error("getXmlNodeList(SAXException): {}, {}: {}", filePath, nodeTag, e.toString());
  74. } catch (IOException e) {
  75. log.error("getXmlNodeList(IOException): {}, {}: {}", filePath, nodeTag, e.toString());
  76. } catch (Exception e) {
  77. log.error("getXmlNodeList(Exception): {}, {}: {}", filePath, nodeTag, e.toString());
  78. }
  79. return null;
  80. }
  81. private static String getElementTagValue(Element element, String tagName) {
  82. NodeList list = element.getElementsByTagName(tagName);
  83. if (list == null) {
  84. return null;
  85. }
  86. Node node = list.item(0);
  87. if (node == null) {
  88. return null;
  89. }
  90. return node.getTextContent().trim();
  91. }
  92. private static License errorLicenseItem(License license, int errorCode) {
  93. license.setErrorCode(errorCode);
  94. if (errorCode > 20) {
  95. log.error("License item data validation error: {}", errorCode);
  96. }
  97. else {
  98. log.error("License item data not found: {}", errorCode);
  99. }
  100. return license;
  101. }
  102. private static boolean errorLicenseItemValue(String orgValue, String curValue, int errorCode) {
  103. log.error("License value error: {}, {}", curValue, errorCode);
  104. return false;
  105. }
  106. private static Date getDay(String dayString) {
  107. try {
  108. SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
  109. Date date = dateFormat.parse(dayString);
  110. return date;
  111. } catch (ParseException e) {
  112. return null;
  113. }
  114. }
  115. private static boolean isValidIntegerString(String inputString) {
  116. try {
  117. Integer.parseInt(inputString);
  118. return true;
  119. } catch (NumberFormatException e) {
  120. return false;
  121. }
  122. }
  123. private static License loadLicenseFile() {
  124. License license = new License();
  125. String filePath = System.getProperty("user.dir") + File.separator + "conf" + File.separator + "license.xml";
  126. //log.info("Loading license: {}", filePath);
  127. NodeList nodeList = getXmlNodeList(filePath, "license");
  128. if (nodeList == null) {
  129. return license;
  130. }
  131. for (int ii = 0; ii < nodeList.getLength(); ii++) {
  132. Node node = nodeList.item(ii);
  133. if (node.getNodeType() != 1)
  134. continue;
  135. Element element = (Element) node;
  136. // log.info(" product: {}", getElementTagValue(element, "product"));
  137. // log.info(" serialId: {}", getElementTagValue(element, "serialId"));
  138. // log.info(" issueDay: {}", getElementTagValue(element, "issueDay"));
  139. // log.info(" edition: {}", getElementTagValue(element, "edition"));
  140. // log.info(" type: {}", getElementTagValue(element, "type"));
  141. // log.info(" accounts: {}", getElementTagValue(element, "accounts"));
  142. // log.info("identifiedHost: {}", getElementTagValue(element, "identifiedHost"));
  143. // log.info(" signature: {}", getElementTagValue(element, "signature"));
  144. // log.info(" demoDuration: {}", getElementTagValue(element, "demoDuration"));
  145. String product = getElementTagValue(element, "product");
  146. if (product == null) {
  147. return errorLicenseItem(license, 1);
  148. }
  149. license.setProduct(product);
  150. String serialId = getElementTagValue(element, "serialId");
  151. if (serialId == null) {
  152. return errorLicenseItem(license, 2);
  153. }
  154. license.setSerialId(serialId);
  155. String issueDay = getElementTagValue(element, "issueDay");
  156. if (issueDay == null) {
  157. return errorLicenseItem(license, 3);
  158. }
  159. Date day = getDay(issueDay);
  160. if (day == null) {
  161. return errorLicenseItem(license, 33);
  162. }
  163. license.setIssueDay(issueDay);
  164. license.setStartDate(day);
  165. String edition = getElementTagValue(element, "edition");
  166. if (edition == null) {
  167. return errorLicenseItem(license, 4);
  168. }
  169. if (!"standard".equalsIgnoreCase(edition) && !"enterprise".equalsIgnoreCase(edition)) {
  170. return errorLicenseItem(license, 34);
  171. }
  172. license.setEdition(edition);
  173. String type = getElementTagValue(element, "type");
  174. if (type == null) {
  175. return errorLicenseItem(license, 5);
  176. }
  177. if (!"demo".equalsIgnoreCase(type) && !"product".equalsIgnoreCase(type)) {
  178. return errorLicenseItem(license, 35);
  179. }
  180. license.setType(type);
  181. if ("demo".equalsIgnoreCase(type)) {
  182. license.setDemo(true);
  183. }
  184. String accounts = getElementTagValue(element, "accounts");
  185. if (accounts == null) {
  186. return errorLicenseItem(license, 6);
  187. }
  188. if (!isValidIntegerString(accounts)) {
  189. return errorLicenseItem(license, 36);
  190. }
  191. license.setAccounts(Integer.parseInt(accounts));
  192. String identifiedHost = getElementTagValue(element, "identifiedHost");
  193. if (identifiedHost == null) {
  194. return errorLicenseItem(license, 7);
  195. }
  196. license.setIdentifiedHost(identifiedHost);
  197. String signature = getElementTagValue(element, "signature");
  198. if (signature == null) {
  199. return errorLicenseItem(license, 8);
  200. }
  201. license.setSignature(signature);
  202. if (license.isDemo()) {
  203. String demoDuration = getElementTagValue(element, "demoDuration");
  204. if (demoDuration == null) {
  205. return errorLicenseItem(license, 9);
  206. }
  207. if (!isValidIntegerString(demoDuration)) {
  208. return errorLicenseItem(license, 39);
  209. }
  210. license.setDemoDuration(Integer.parseInt(demoDuration));
  211. }
  212. }
  213. license.setValid(true);
  214. return license;
  215. }
  216. public static String getSha256Encrypt(String str) {
  217. String SHA = "";
  218. try {
  219. MessageDigest msgDigest = MessageDigest.getInstance("SHA-256");
  220. //msgDigest.update(str.getBytes());
  221. msgDigest.update(str.getBytes(StandardCharsets.UTF_8));
  222. byte byteData[] = msgDigest.digest();
  223. StringBuffer builder = new StringBuffer();
  224. for (byte b : byteData) {
  225. builder.append(String.format("%02x", b));
  226. }
  227. SHA = builder.toString();
  228. } catch (NoSuchAlgorithmException e) {
  229. SHA = "";
  230. }
  231. return SHA;
  232. }
  233. public static boolean validateLicense() {
  234. log.info("Application License validateLicense: Start.");
  235. License license = loadLicenseFile();
  236. if (!license.isValid()) {
  237. return false;
  238. }
  239. if (license.isDemo()) {
  240. // 데모 모드 일 경우 유효기간 체크
  241. Calendar calendar = Calendar.getInstance();
  242. calendar.setTime(license.getStartDate());
  243. calendar.add(Calendar.DAY_OF_MONTH, license.getDemoDuration());
  244. Date resultDate = calendar.getTime();
  245. Date currentDate = new Date();
  246. if (!currentDate.before(resultDate)) {
  247. log.error("License Issue Day expired.");
  248. return false;
  249. }
  250. }
  251. String identifiedHost = getComputerName();
  252. if (!identifiedHost.equalsIgnoreCase(license.getIdentifiedHost())) {
  253. // 컴퓨터 이름 체크
  254. return errorLicenseItemValue(identifiedHost, license.getIdentifiedHost(), 1);
  255. }
  256. String encKey = license.getProduct().toUpperCase() + "hanteinfo12#$!" +
  257. license.getSerialId().toLowerCase() +
  258. license.getIssueDay() +
  259. license.getEdition().toUpperCase() +
  260. license.getType().toLowerCase() +
  261. String.valueOf(license.getAccounts() + 10000) +
  262. license.getIdentifiedHost().toLowerCase();
  263. String signature = getSha256Encrypt(encKey);
  264. if (!signature.equalsIgnoreCase(license.getSignature())) {
  265. // 컴퓨터 이름 체크
  266. return errorLicenseItemValue(signature, license.getSignature(), 2);
  267. }
  268. System.setProperty("AIP_GATEWAY_ACCOUNT", String.valueOf(license.getAccounts()));
  269. log.info("Application License validateLicense: ..End.[OK]");
  270. return true;
  271. }
  272. }