├── .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 | } --------------------------------------------------------------------------------