├── .gitignore
├── Dockerfile
├── src
└── main
│ └── java
│ └── com
│ └── vvvtimes
│ ├── util
│ ├── Base64.java
│ ├── Hex.java
│ └── rsasign.java
│ ├── JrebelUtil
│ ├── ByteUtil.java
│ ├── JrebelSign.java
│ └── LicenseServer2ToJRebelPrivateKey.java
│ └── server
│ └── MainServer.java
├── README.md
└── pom.xml
/.gitignore:
--------------------------------------------------------------------------------
1 | /.idea/*
2 | /target/*
3 | *.iml
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM java:8-jre-alpine
2 |
3 | ENV PORT 8081
4 |
5 | ADD target/JrebelBrainsLicenseServerforJava-1.0-SNAPSHOT-jar-with-dependencies.jar /JrebelBrains.jar
6 | CMD java -jar /JrebelBrains.jar -p $PORT
7 |
8 |
--------------------------------------------------------------------------------
/src/main/java/com/vvvtimes/util/Base64.java:
--------------------------------------------------------------------------------
1 | package com.vvvtimes.util;
2 |
3 |
4 | public class Base64 {
5 | /**
6 | * 编码
7 | *
8 | * @param bstr
9 | * @return String
10 | */
11 | public static String encode(byte[] bstr) {
12 | return org.apache.commons.codec.binary.Base64.encodeBase64String(bstr);
13 | }
14 |
15 | /**
16 | * 解码
17 | *
18 | * @param str
19 | * @return string
20 | */
21 | public static byte[] decode(String str) {
22 | return org.apache.commons.codec.binary.Base64.decodeBase64(str);
23 | }
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/src/main/java/com/vvvtimes/JrebelUtil/ByteUtil.java:
--------------------------------------------------------------------------------
1 | package com.vvvtimes.JrebelUtil;
2 | import org.apache.commons.codec.binary.Base64;
3 |
4 | import java.nio.charset.Charset;
5 | import java.util.Random;
6 |
7 | public class ByteUtil {
8 | private static final Random a;
9 |
10 | public static String a(final byte[] binaryData) {
11 | if (binaryData == null) {
12 | return null;
13 | }
14 | return new String(Base64.encodeBase64(binaryData), Charset.forName("UTF-8"));
15 | }
16 |
17 | public static byte[] a(final String s) {
18 | if (s == null) {
19 | return null;
20 | }
21 | return Base64.decodeBase64(s.getBytes(Charset.forName("UTF-8")));
22 | }
23 |
24 | public static byte[] a(final int n) {
25 | final byte[] array = new byte[n];
26 | ByteUtil.a.nextBytes(array);
27 | return array;
28 | }
29 |
30 | static {
31 | a = new Random();
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Jrebel & Jet Brains License Server for Java
2 |
3 | A license server for Jrebel & JetBrains products, it also support JRebel for Android and XRebel.
4 |
5 | ***
6 | Thank ilanyu
7 |
8 | NOTE: This is provided for educational purposes only. Please support genuine.
9 | ***
10 | ## Setup
11 | Run:
12 | ```
13 | cd /path/to/project
14 | mvn compile
15 | mvn exec:java -Dexec.mainClass="com.vvvtimes.server.MainServer" -Dexec.args="-p 8081"
16 | ```
17 | Packing a runnable jar:
18 | ```
19 | mvn package
20 | ```
21 | then
22 | ```
23 | java -jar JrebelBrainsLicenseServerforJava-1.0-SNAPSHOT-jar-with-dependencies.jar -p 8081
24 | ```
25 | default port is 8081.
26 | ## Docker
27 | Build image
28 | ```
29 | mvn package
30 | docker build -t jrebel-ls .
31 | ```
32 |
33 | start container
34 | ```
35 | docker run -d --name jrebel-ls --restart always -e PORT=9001 -p 9001:9001 jrebel-ls
36 | ```
37 | default port is 8081,you can modify it
38 | ## Support
39 |
40 | Jrebel
41 |
42 | JRebel for Android
43 |
44 | XRebel
45 |
46 | JetBrains Products
47 |
48 | ## Feedback
49 |
50 | + issue: https://gitee.com/gsls200808/JrebelLicenseServerforJava/issues
51 | + QQ Group: 527290836
--------------------------------------------------------------------------------
/src/main/java/com/vvvtimes/JrebelUtil/JrebelSign.java:
--------------------------------------------------------------------------------
1 | package com.vvvtimes.JrebelUtil;
2 |
3 | import org.apache.commons.lang3.StringUtils;
4 |
5 | public class JrebelSign {
6 | private String signature;
7 |
8 | public void toLeaseCreateJson(String clientRandomness, String guid, boolean offline, String validFrom, String validUntil) {
9 | //String serverRandomness = ByteUtil.a(ByteUtil.a(8));
10 | String serverRandomness = "H2ulzLlh7E0="; //服务端随机数,如果要自己生成,务必将其写到json的serverRandomness中
11 | String installationGuidString = guid;
12 | //String value = String.valueOf("false");
13 | String s2= "";
14 | if(offline){
15 | s2 = StringUtils.join((Object[]) new String[]{clientRandomness, serverRandomness, installationGuidString , String.valueOf(offline), validFrom, validUntil}, ';');
16 | }else{
17 | s2 = StringUtils.join((Object[]) new String[]{clientRandomness, serverRandomness, installationGuidString , String.valueOf(offline)}, ';');
18 | }
19 | System.out.println(s2);
20 | final byte[] a2 =LicenseServer2ToJRebelPrivateKey.a(s2.getBytes());
21 | this.signature = ByteUtil.a(a2);
22 | }
23 |
24 | public String getSignature() {
25 | return signature;
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/src/main/java/com/vvvtimes/util/Hex.java:
--------------------------------------------------------------------------------
1 | package com.vvvtimes.util;
2 |
3 | public class Hex {
4 | public static String bytesToHexString(byte[] src){
5 | StringBuilder stringBuilder = new StringBuilder("");
6 | if (src == null || src.length <= 0) {
7 | return null;
8 | }
9 | for (int i = 0; i < src.length; i++) {
10 | int v = src[i] & 0xFF;
11 | String hv = Integer.toHexString(v);
12 | if (hv.length() < 2) {
13 | stringBuilder.append(0);
14 | }
15 | stringBuilder.append(hv);
16 | }
17 | return stringBuilder.toString();
18 | }
19 | /**
20 | * Convert hex string to byte[]
21 | * @param hexString the hex string
22 | * @return byte[]
23 | */
24 | public static byte[] hexStringToBytes(String hexString) {
25 | if (hexString == null || hexString.equals("")) {
26 | return null;
27 | }
28 | hexString = hexString.toUpperCase();
29 | int length = hexString.length() / 2;
30 | char[] hexChars = hexString.toCharArray();
31 | byte[] d = new byte[length];
32 | for (int i = 0; i < length; i++) {
33 | int pos = i * 2;
34 | d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
35 | }
36 | return d;
37 | }
38 | private static byte charToByte(char c) {
39 | return (byte) "0123456789ABCDEF".indexOf(c);
40 | }
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | com.vvvtimes.com
8 | JrebelBrainsLicenseServerforJava
9 | 1.0-SNAPSHOT
10 |
11 |
12 | UTF-8
13 |
14 |
15 |
16 |
17 |
18 | org.apache.maven.plugins
19 | maven-compiler-plugin
20 |
21 | 3.1
22 |
23 | 1.6
24 | 1.6
25 | utf8
26 |
27 |
28 |
29 |
30 |
31 | org.apache.maven.plugins
32 | maven-assembly-plugin
33 | 3.1.0
34 |
35 |
36 |
37 | com.vvvtimes.server.MainServer
38 |
39 |
40 |
41 | jar-with-dependencies
42 |
43 |
44 |
45 |
46 | make-assembly
47 | package
48 |
49 | single
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 | org.eclipse.jetty.aggregate
61 | jetty-all
62 | 8.1.2.v20120308
63 |
64 |
65 |
66 | javax.servlet
67 | javax.servlet-api
68 | 3.0.1
69 | provided
70 |
71 |
72 |
73 | org.bouncycastle
74 | bcprov-jdk15on
75 | 1.58
76 |
77 |
78 |
79 | commons-codec
80 | commons-codec
81 | 1.10
82 |
83 |
84 |
85 | net.sf.json-lib
86 | json-lib
87 | 2.4
88 | jdk15
89 |
90 |
91 |
92 | org.apache.commons
93 | commons-lang3
94 | 3.1
95 |
96 |
97 |
98 |
99 |
--------------------------------------------------------------------------------
/src/main/java/com/vvvtimes/JrebelUtil/LicenseServer2ToJRebelPrivateKey.java:
--------------------------------------------------------------------------------
1 | package com.vvvtimes.JrebelUtil;
2 |
3 | import org.bouncycastle.jce.provider.BouncyCastleProvider;
4 |
5 | import java.security.GeneralSecurityException;
6 | import java.security.KeyFactory;
7 | import java.security.PrivateKey;
8 | import java.security.Signature;
9 | import java.security.spec.PKCS8EncodedKeySpec;
10 |
11 | public class LicenseServer2ToJRebelPrivateKey {
12 | private static final String b = "MIICXAIBAAKBgQDQ93CP6SjEneDizCF1P/MaBGf582voNNFcu8oMhgdTZ/N6qa6O7XJDr1FSCyaDdKSsPCdxPK7Y4Usq/fOPas2kCgYcRS/iebrtPEFZ/7TLfk39HLuTEjzo0/CNvjVsgWeh9BYznFaxFDLx7fLKqCQ6w1OKScnsdqwjpaXwXqiulwIDAQABAoGATOQvvBSMVsTNQkbgrNcqKdGjPNrwQtJkk13aO/95ZJxkgCc9vwPqPrOdFbZappZeHa5IyScOI2nLEfe+DnC7V80K2dBtaIQjOeZQt5HoTRG4EHQaWoDh27BWuJoip5WMrOd+1qfkOtZoRjNcHl86LIAh/+3vxYyebkug4UHNGPkCQQD+N4ZUkhKNQW7mpxX6eecitmOdN7Yt0YH9UmxPiW1LyCEbLwduMR2tfyGfrbZALiGzlKJize38shGC1qYSMvZFAkEA0m6psWWiTUWtaOKMxkTkcUdigalZ9xFSEl6jXFB94AD+dlPS3J5gNzTEmbPLc14VIWJFkO+UOrpl77w5uF2dKwJAaMpslhnsicvKMkv31FtBut5iK6GWeEafhdPfD94/bnidpP362yJl8Gmya4cI1GXvwH3pfj8S9hJVA5EFvgTB3QJBAJP1O1uAGp46X7Nfl5vQ1M7RYnHIoXkWtJ417Kb78YWPLVwFlD2LHhuy/okT4fk8LZ9LeZ5u1cp1RTdLIUqAiAECQC46OwOm87L35yaVfpUIjqg/1gsNwNsj8HvtXdF/9d30JIM3GwdytCvNRLqP35Ciogb9AO8ke8L6zY83nxPbClM=";
13 | private static final byte[] c;
14 | private static final BouncyCastleProvider d;
15 |
16 | private static PrivateKey a() {
17 | final PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(LicenseServer2ToJRebelPrivateKey.c);
18 | try {
19 | return KeyFactory.getInstance("RSA", LicenseServer2ToJRebelPrivateKey.d).generatePrivate(pkcs8EncodedKeySpec);
20 | } catch (Exception ex) {
21 | ex.printStackTrace();
22 | return null;
23 | }
24 | }
25 |
26 | public static byte[] a(final byte[] array) {
27 | try {
28 | final Signature instance = Signature.getInstance("SHA1withRSA", LicenseServer2ToJRebelPrivateKey.d);
29 | instance.initSign(a());
30 | instance.update(array);
31 | return instance.sign();
32 | } catch (GeneralSecurityException ex) {
33 | throw new RuntimeException("License Server installation error 0000000F2", ex);
34 | }
35 | }
36 |
37 | static {
38 | c = ByteUtil.a("MIICXAIBAAKBgQDQ93CP6SjEneDizCF1P/MaBGf582voNNFcu8oMhgdTZ/N6qa6O7XJDr1FSCyaDdKSsPCdxPK7Y4Usq/fOPas2kCgYcRS/iebrtPEFZ/7TLfk39HLuTEjzo0/CNvjVsgWeh9BYznFaxFDLx7fLKqCQ6w1OKScnsdqwjpaXwXqiulwIDAQABAoGATOQvvBSMVsTNQkbgrNcqKdGjPNrwQtJkk13aO/95ZJxkgCc9vwPqPrOdFbZappZeHa5IyScOI2nLEfe+DnC7V80K2dBtaIQjOeZQt5HoTRG4EHQaWoDh27BWuJoip5WMrOd+1qfkOtZoRjNcHl86LIAh/+3vxYyebkug4UHNGPkCQQD+N4ZUkhKNQW7mpxX6eecitmOdN7Yt0YH9UmxPiW1LyCEbLwduMR2tfyGfrbZALiGzlKJize38shGC1qYSMvZFAkEA0m6psWWiTUWtaOKMxkTkcUdigalZ9xFSEl6jXFB94AD+dlPS3J5gNzTEmbPLc14VIWJFkO+UOrpl77w5uF2dKwJAaMpslhnsicvKMkv31FtBut5iK6GWeEafhdPfD94/bnidpP362yJl8Gmya4cI1GXvwH3pfj8S9hJVA5EFvgTB3QJBAJP1O1uAGp46X7Nfl5vQ1M7RYnHIoXkWtJ417Kb78YWPLVwFlD2LHhuy/okT4fk8LZ9LeZ5u1cp1RTdLIUqAiAECQC46OwOm87L35yaVfpUIjqg/1gsNwNsj8HvtXdF/9d30JIM3GwdytCvNRLqP35Ciogb9AO8ke8L6zY83nxPbClM=");
39 | d = new BouncyCastleProvider();
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/main/java/com/vvvtimes/util/rsasign.java:
--------------------------------------------------------------------------------
1 | package com.vvvtimes.util;
2 |
3 | import org.bouncycastle.asn1.ASN1InputStream;
4 | import org.bouncycastle.asn1.ASN1Primitive;
5 | import org.bouncycastle.asn1.pkcs.RSAPrivateKeyStructure;
6 |
7 | import java.security.KeyFactory;
8 | import java.security.PrivateKey;
9 | import java.security.spec.PKCS8EncodedKeySpec;
10 | import java.security.spec.RSAPrivateKeySpec;
11 |
12 |
13 | public class rsasign {
14 | static String header = "607875500OK15084842582741licensee=Administrator licenseType=0 ";
15 | static String content = "607875500OK15084842582741licensee=Administrator licenseType=0 ";
16 | String ASNKEY = "-----BEGIN RSA PRIVATE KEY-----\r\n"
17 | + "MIIBOgIBAAJBALecq3BwAI4YJZwhJ+snnDFj3lF3DMqNPorV6y5ZKXCiCMqj8OeOmxk4YZW9aaV9\r\n"
18 | + "ckl/zlAOI0mpB3pDT+Xlj2sCAwEAAQJAW6/aVD05qbsZHMvZuS2Aa5FpNNj0BDlf38hOtkhDzz/h\r\n"
19 | + "kYb+EBYLLvldhgsD0OvRNy8yhz7EjaUqLCB0juIN4QIhAOeCQp+NXxfBmfdG/S+XbRUAdv8iHBl+\r\n"
20 | + "F6O2wr5fA2jzAiEAywlDfGIl6acnakPrmJE0IL8qvuO3FtsHBrpkUuOnXakCIQCqdr+XvADI/UTh\r\n"
21 | + "TuQepuErFayJMBSAsNe3NFsw0cUxAQIgGA5n7ZPfdBi3BdM4VeJWb87WrLlkVxPqeDSbcGrCyMkC\r\n"
22 | + "IFSs5JyXvFTreWt7IQjDssrKDRIPmALdNjvfETwlNJyY\r\n"
23 | + "-----END RSA PRIVATE KEY-----";
24 | String PCKS8KEY = "-----BEGIN PRIVATE KEY-----\r\n"
25 | + "MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAt5yrcHAAjhglnCEn\r\n"
26 | + "6yecMWPeUXcMyo0+itXrLlkpcKIIyqPw546bGThhlb1ppX1ySX/OUA4jSakHekNP\r\n"
27 | + "5eWPawIDAQABAkBbr9pUPTmpuxkcy9m5LYBrkWk02PQEOV/fyE62SEPPP+GRhv4Q\r\n"
28 | + "Fgsu+V2GCwPQ69E3LzKHPsSNpSosIHSO4g3hAiEA54JCn41fF8GZ90b9L5dtFQB2\r\n"
29 | + "/yIcGX4Xo7bCvl8DaPMCIQDLCUN8YiXppydqQ+uYkTQgvyq+47cW2wcGumRS46dd\r\n"
30 | + "qQIhAKp2v5e8AMj9ROFO5B6m4SsVrIkwFICw17c0WzDRxTEBAiAYDmftk990GLcF\r\n"
31 | + "0zhV4lZvztasuWRXE+p4NJtwasLIyQIgVKzknJe8VOt5a3shCMOyysoNEg+YAt02\r\n"
32 | + "O98RPCU0nJg=\r\n" + "-----END PRIVATE KEY-----";
33 |
34 | static String key22 = "MIIBOgIBAAJBALecq3BwAI4YJZwhJ+snnDFj3lF3DMqNPorV6y5ZKXCiCMqj8OeOmxk4YZW9aaV9"
35 | + "ckl/zlAOI0mpB3pDT+Xlj2sCAwEAAQJAW6/aVD05qbsZHMvZuS2Aa5FpNNj0BDlf38hOtkhDzz/h"
36 | + "kYb+EBYLLvldhgsD0OvRNy8yhz7EjaUqLCB0juIN4QIhAOeCQp+NXxfBmfdG/S+XbRUAdv8iHBl+"
37 | + "F6O2wr5fA2jzAiEAywlDfGIl6acnakPrmJE0IL8qvuO3FtsHBrpkUuOnXakCIQCqdr+XvADI/UTh"
38 | + "TuQepuErFayJMBSAsNe3NFsw0cUxAQIgGA5n7ZPfdBi3BdM4VeJWb87WrLlkVxPqeDSbcGrCyMkC"
39 | + "IFSs5JyXvFTreWt7IQjDssrKDRIPmALdNjvfETwlNJyY";
40 |
41 | static String key33 = "MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAt5yrcHAAjhglnCEn"
42 | + "6yecMWPeUXcMyo0+itXrLlkpcKIIyqPw546bGThhlb1ppX1ySX/OUA4jSakHekNP"
43 | + "5eWPawIDAQABAkBbr9pUPTmpuxkcy9m5LYBrkWk02PQEOV/fyE62SEPPP+GRhv4Q"
44 | + "Fgsu+V2GCwPQ69E3LzKHPsSNpSosIHSO4g3hAiEA54JCn41fF8GZ90b9L5dtFQB2"
45 | + "/yIcGX4Xo7bCvl8DaPMCIQDLCUN8YiXppydqQ+uYkTQgvyq+47cW2wcGumRS46dd"
46 | + "qQIhAKp2v5e8AMj9ROFO5B6m4SsVrIkwFICw17c0WzDRxTEBAiAYDmftk990GLcF"
47 | + "0zhV4lZvztasuWRXE+p4NJtwasLIyQIgVKzknJe8VOt5a3shCMOyysoNEg+YAt02"
48 | + "O98RPCU0nJg=";
49 |
50 | public static String Sign(String content){
51 | return rsasign.Sign(content.getBytes(), key22);
52 | }
53 |
54 | public static String Sign2(String content){
55 | return rsasign.Sign2(content.getBytes(), key33);
56 | }
57 |
58 | //传入秘钥为ASN格式
59 | //私钥签名程序,privateKey是私钥base64编码字符串,即私钥文件数据中,中间的主体部分
60 | public static String Sign(byte[] content, String privateKey) {
61 | try {
62 | byte[] keybyte = Base64.decode(privateKey.toString());
63 | ASN1InputStream in = new ASN1InputStream(keybyte);
64 | ASN1Primitive obj = in.readObject();
65 | RSAPrivateKeyStructure pStruct = RSAPrivateKeyStructure.getInstance(obj);
66 | RSAPrivateKeySpec spec = new RSAPrivateKeySpec(pStruct.getModulus(), pStruct.getPrivateExponent());
67 | KeyFactory keyFactory = KeyFactory.getInstance("RSA");
68 | PrivateKey priKey = keyFactory.generatePrivate(spec);
69 | java.security.Signature signature = java.security.Signature.getInstance("MD5WithRSA");
70 | signature.initSign(priKey);
71 | signature.update(content);
72 | byte[] signed = signature.sign();
73 | return Hex.bytesToHexString(signed);
74 | }
75 | catch (Exception e) {
76 | e.printStackTrace();
77 | }
78 | return null;
79 | }
80 |
81 | //传入秘钥为PKCS#8私钥非加密格式
82 | //私钥签名程序,privateKey是私钥base64编码字符串,即私钥文件数据中,中间的主体部分
83 | public static String Sign2(byte[] content, String privateKey) {
84 | try {
85 | PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(Base64.decode(privateKey));
86 | KeyFactory keyf = KeyFactory.getInstance("RSA");
87 | PrivateKey priKey = keyf.generatePrivate(priPKCS8);
88 | java.security.Signature signature = java.security.Signature.getInstance("MD5WithRSA");
89 | signature.initSign(priKey);
90 | signature.update(content);
91 | byte[] signed = signature.sign();
92 | return Hex.bytesToHexString(signed);
93 | } catch (Exception e) {
94 | e.printStackTrace();
95 | }
96 | return null;
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/src/main/java/com/vvvtimes/server/MainServer.java:
--------------------------------------------------------------------------------
1 | package com.vvvtimes.server;
2 |
3 | import com.vvvtimes.JrebelUtil.JrebelSign;
4 | import com.vvvtimes.util.rsasign;
5 | import net.sf.json.JSONObject;
6 |
7 | import java.io.IOException;
8 | import java.text.SimpleDateFormat;
9 | import java.util.*;
10 |
11 | import javax.servlet.ServletException;
12 | import javax.servlet.http.HttpServletRequest;
13 | import javax.servlet.http.HttpServletResponse;
14 |
15 | import org.eclipse.jetty.server.Request;
16 | import org.eclipse.jetty.server.Server;
17 | import org.eclipse.jetty.server.handler.AbstractHandler;
18 |
19 | public class MainServer extends AbstractHandler {
20 |
21 | public static Map parseArguments(String[] args) {
22 | Map params = new HashMap();
23 |
24 | String option = null;
25 | for (final String arg : args) {
26 | if (arg.charAt(0) == '-') {
27 | if (arg.length() < 2) {
28 | throw new IllegalArgumentException("Error at argument " + arg);
29 | }
30 | option = arg.substring(1);
31 | } else {
32 | params.put(option, arg);
33 | }
34 | }
35 | return params;
36 | }
37 |
38 | public static void main(String[] args) throws Exception {
39 | Map arguments = parseArguments(args);
40 | String port = arguments.get("p");
41 |
42 | if (port == null || !port.matches("\\d+")) {
43 | port = "8081";
44 | }
45 |
46 | Server server = new Server(Integer.parseInt(port));
47 | server.setHandler(new MainServer());
48 | server.start();
49 |
50 | System.out.println("License Server started at http://localhost:" + port);
51 | System.out.println("JetBrains Activation address was: http://localhost:" + port + "/");
52 | System.out.println("JRebel 7.1 and earlier version Activation address was: http://localhost:" + port + "/{tokenname}, with any email.");
53 | System.out.println("JRebel 2018.1 and later version Activation address was: http://localhost:" + port + "/{guid}(eg:http://localhost:" + port + "/"+ UUID.randomUUID().toString()+"), with any email.");
54 |
55 | server.join();
56 | }
57 |
58 |
59 | public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)
60 | throws IOException, ServletException {
61 | System.out.println(target);
62 | if (target.equals("/")) {
63 | indexHandler(target, baseRequest, request, response);
64 | } else if (target.equals("/jrebel/leases")) {
65 | jrebelLeasesHandler(target, baseRequest, request, response);
66 | } else if (target.equals("/jrebel/leases/1")) {
67 | jrebelLeases1Handler(target, baseRequest, request, response);
68 | } else if (target.equals("/agent/leases")) {
69 | jrebelLeasesHandler(target, baseRequest, request, response);
70 | } else if (target.equals("/agent/leases/1")) {
71 | jrebelLeases1Handler(target, baseRequest, request, response);
72 | } else if (target.equals("/jrebel/validate-connection")) {
73 | jrebelValidateHandler(target, baseRequest, request, response);
74 | } else if (target.equals("/rpc/ping.action")) {
75 | pingHandler(target, baseRequest, request, response);
76 | } else if (target.equals("/rpc/obtainTicket.action")) {
77 | obtainTicketHandler(target, baseRequest, request, response);
78 | } else if (target.equals("/rpc/releaseTicket.action")) {
79 | releaseTicketHandler(target, baseRequest, request, response);
80 | } else {
81 | response.setStatus(HttpServletResponse.SC_FORBIDDEN);
82 | }
83 | }
84 |
85 | private void jrebelValidateHandler(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException {
86 | response.setContentType("application/json; charset=utf-8");
87 | response.setStatus(HttpServletResponse.SC_OK);
88 | baseRequest.setHandled(true);
89 | String jsonStr = "{\n" +
90 | " \"serverVersion\": \"3.2.4\",\n" +
91 | " \"serverProtocolVersion\": \"1.1\",\n" +
92 | " \"serverGuid\": \"a1b4aea8-b031-4302-b602-670a990272cb\",\n" +
93 | " \"groupType\": \"managed\",\n" +
94 | " \"statusCode\": \"SUCCESS\",\n" +
95 | " \"company\": \"Administrator\",\n" +
96 | " \"canGetLease\": true,\n" +
97 | " \"licenseType\": 1,\n" +
98 | " \"evaluationLicense\": false,\n" +
99 | " \"seatPoolType\": \"standalone\"\n" +
100 | "}\n";
101 | JSONObject jsonObject = JSONObject.fromObject(jsonStr);
102 | String body = jsonObject.toString();
103 | response.getWriter().print(body);
104 | }
105 |
106 | private void jrebelLeases1Handler(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException {
107 | response.setContentType("application/json; charset=utf-8");
108 | response.setStatus(HttpServletResponse.SC_OK);
109 | String username = request.getParameter("username");
110 | baseRequest.setHandled(true);
111 | String jsonStr = "{\n" +
112 | " \"serverVersion\": \"3.2.4\",\n" +
113 | " \"serverProtocolVersion\": \"1.1\",\n" +
114 | " \"serverGuid\": \"a1b4aea8-b031-4302-b602-670a990272cb\",\n" +
115 | " \"groupType\": \"managed\",\n" +
116 | " \"statusCode\": \"SUCCESS\",\n" +
117 | " \"msg\": null,\n" +
118 | " \"statusMessage\": null\n" +
119 | "}\n";
120 | JSONObject jsonObject = JSONObject.fromObject(jsonStr);
121 | if (username != null ) {
122 | jsonObject.put("company", username);
123 | }
124 | String body = jsonObject.toString();
125 | response.getWriter().print(body);
126 |
127 | }
128 |
129 | private void jrebelLeasesHandler(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException {
130 | response.setContentType("application/json; charset=utf-8");
131 | response.setStatus(HttpServletResponse.SC_OK);
132 | String clientRandomness = request.getParameter("randomness");
133 | String username = request.getParameter("username");
134 | String guid = request.getParameter("guid");
135 | System.out.println(((Request) request).getParameters());
136 | boolean offline = Boolean.parseBoolean(request.getParameter("offline"));
137 | String validFrom = "null";
138 | String validUntil = "null";
139 | if (offline) {
140 | String clientTime = request.getParameter("clientTime");
141 | String offlineDays = request.getParameter("offlineDays");
142 | //long clinetTimeUntil = Long.parseLong(clientTime) + Long.parseLong(offlineDays) * 24 * 60 * 60 * 1000;
143 | long clinetTimeUntil = Long.parseLong(clientTime) + 180L * 24 * 60 * 60 * 1000;
144 | validFrom = clientTime;
145 | validUntil = String.valueOf(clinetTimeUntil);
146 | }
147 | baseRequest.setHandled(true);
148 | String jsonStr = "{\n" +
149 | " \"serverVersion\": \"3.2.4\",\n" +
150 | " \"serverProtocolVersion\": \"1.1\",\n" +
151 | " \"serverGuid\": \"a1b4aea8-b031-4302-b602-670a990272cb\",\n" +
152 | " \"groupType\": \"managed\",\n" +
153 | " \"id\": 1,\n" +
154 | " \"licenseType\": 1,\n" +
155 | " \"evaluationLicense\": false,\n" +
156 | " \"signature\": \"OJE9wGg2xncSb+VgnYT+9HGCFaLOk28tneMFhCbpVMKoC/Iq4LuaDKPirBjG4o394/UjCDGgTBpIrzcXNPdVxVr8PnQzpy7ZSToGO8wv/KIWZT9/ba7bDbA8/RZ4B37YkCeXhjaixpmoyz/CIZMnei4q7oWR7DYUOlOcEWDQhiY=\",\n" +
157 | " \"serverRandomness\": \"H2ulzLlh7E0=\",\n" +
158 | " \"seatPoolType\": \"standalone\",\n" +
159 | " \"statusCode\": \"SUCCESS\",\n" +
160 | " \"offline\": " + String.valueOf(offline) + ",\n" +
161 | " \"validFrom\": " + validFrom + ",\n" +
162 | " \"validUntil\": " + validUntil + ",\n" +
163 | " \"company\": \"Administrator\",\n" +
164 | " \"orderId\": \"\",\n" +
165 | " \"zeroIds\": [\n" +
166 | " \n" +
167 | " ],\n" +
168 | " \"licenseValidFrom\": 1490544001000,\n" +
169 | " \"licenseValidUntil\": 1691839999000\n" +
170 | "}";
171 |
172 | JSONObject jsonObject = JSONObject.fromObject(jsonStr);
173 | if (clientRandomness == null || username == null || guid == null) {
174 | response.setStatus(HttpServletResponse.SC_FORBIDDEN);
175 | } else {
176 | JrebelSign jrebelSign = new JrebelSign();
177 | jrebelSign.toLeaseCreateJson(clientRandomness, guid, offline, validFrom, validUntil);
178 | String signature = jrebelSign.getSignature();
179 | jsonObject.put("signature", signature);
180 | jsonObject.put("company", username);
181 | String body = jsonObject.toString();
182 | response.getWriter().print(body);
183 | }
184 | }
185 |
186 | private void releaseTicketHandler(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException{
187 | response.setContentType("text/html; charset=utf-8");
188 | response.setStatus(HttpServletResponse.SC_OK);
189 | String salt = request.getParameter("salt");
190 | baseRequest.setHandled(true);
191 | if(salt==null){
192 | response.setStatus(HttpServletResponse.SC_FORBIDDEN);
193 | }else{
194 | String xmlContent = "OK" + salt + "";
195 | String xmlSignature = rsasign.Sign(xmlContent);
196 | String body = "\n" + xmlContent;
197 | response.getWriter().print(body);
198 | }
199 | }
200 |
201 | private void obtainTicketHandler ( String target , Request baseRequest , HttpServletRequest request ,
202 | HttpServletResponse response ) throws IOException
203 | {
204 | response.setContentType("text/html; charset=utf-8");
205 | response.setStatus(HttpServletResponse.SC_OK);
206 | SimpleDateFormat fm=new SimpleDateFormat("EEE,d MMM yyyy hh:mm:ss Z", Locale.ENGLISH);
207 | String date =fm.format(new Date())+" GMT";
208 | //response.setHeader("Date", date);
209 | //response.setHeader("Server", "fasthttp");
210 | String salt = request.getParameter("salt");
211 | String username = request.getParameter("userName");
212 | String prolongationPeriod = "607875500";
213 | baseRequest.setHandled(true);
214 | if(salt==null||username==null){
215 | response.setStatus(HttpServletResponse.SC_FORBIDDEN);
216 | }else{
217 | String xmlContent = "" + prolongationPeriod + "OK" + salt + "1licensee=" + username + "\tlicenseType=0\t";
218 | String xmlSignature = rsasign.Sign(xmlContent);
219 | String body = "\n" + xmlContent;
220 | response.getWriter().print(body);
221 | }
222 | }
223 |
224 | private void pingHandler ( String target , Request baseRequest , HttpServletRequest request , HttpServletResponse response ) throws IOException
225 | {
226 | response.setContentType("text/html; charset=utf-8");
227 | response.setStatus(HttpServletResponse.SC_OK);
228 | String salt = request.getParameter("salt");
229 | baseRequest.setHandled(true);
230 | if(salt==null){
231 | response.setStatus(HttpServletResponse.SC_FORBIDDEN);
232 | }else{
233 | String xmlContent = "OK" + salt + "";
234 | String xmlSignature = rsasign.Sign(xmlContent);
235 | String body = "\n" + xmlContent;
236 | response.getWriter().print(body);
237 | }
238 |
239 | }
240 |
241 | private void indexHandler(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException {
242 | response.setContentType("text/html; charset=utf-8");
243 | response.setStatus(HttpServletResponse.SC_OK);
244 | baseRequest.setHandled(true);
245 | response.getWriter().println("Hello,This is a Jrebel & JetBrains License Server!
");
246 |
247 | }
248 | }
--------------------------------------------------------------------------------