diff --git a/.gitignore b/.gitignore index 6605be4..5abc9b8 100644 --- a/.gitignore +++ b/.gitignore @@ -100,3 +100,6 @@ build/ # Gradle .gradle/ + +.idea/.name +.idea/compiler.xml diff --git a/.idea/misc.xml b/.idea/misc.xml index bc8d0a3..38167d7 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,7 +1,7 @@ - + \ No newline at end of file diff --git a/src/main/groovy/com/chrisney/enigma/EnigmaPlugin.groovy b/src/main/groovy/com/chrisney/enigma/EnigmaPlugin.groovy index cb77fd4..7763df5 100644 --- a/src/main/groovy/com/chrisney/enigma/EnigmaPlugin.groovy +++ b/src/main/groovy/com/chrisney/enigma/EnigmaPlugin.groovy @@ -42,6 +42,17 @@ class EnigmaPlugin implements Plugin { enabled = extension.enabled rootProject = project.rootDir.absolutePath pathSrc = project.rootDir.absolutePath + extension.srcJava + + pathSrcs = [] + project.rootProject.getAllprojects().forEach { proj -> + if(proj.rootDir.absolutePath != proj.projectDir.absolutePath) { + pathSrcs += proj.projectDir.absolutePath + "/src/main/java/" + } + else { + println("Ignoring root: " + proj.projectDir.absolutePath) + } + } + debug = extension.debug } @@ -49,6 +60,17 @@ class EnigmaPlugin implements Plugin { enabled = extension.enabled rootProject = project.rootDir.absolutePath pathSrc = project.rootDir.absolutePath + extension.srcJava + + pathSrcs = [] + project.rootProject.getAllprojects().forEach { proj -> + if(proj.rootDir.absolutePath != proj.projectDir.absolutePath) { + pathSrcs += proj.projectDir.absolutePath + "/src/main/java/" + } + else { + println("Ignoring root: " + proj.projectDir.absolutePath) + } + } + debug = extension.debug } @@ -56,6 +78,17 @@ class EnigmaPlugin implements Plugin { enabled = extension.enabled rootProject = project.rootDir.absolutePath pathSrc = project.rootDir.absolutePath + extension.srcJava + + pathSrcs = [] + project.rootProject.getAllprojects().forEach { proj -> + if(proj.rootDir.absolutePath != proj.projectDir.absolutePath) { + pathSrcs += proj.projectDir.absolutePath + "/src/main/java/" + } + else { + println("Ignoring root: " + proj.projectDir.absolutePath) + } + } + hash = extension.hash customFunction = extension.customFunction debug = extension.debug @@ -65,6 +98,17 @@ class EnigmaPlugin implements Plugin { enabled = extension.enabled rootProject = project.rootDir.absolutePath pathSrc = project.rootDir.absolutePath + extension.srcJava + + pathSrcs = [] + project.rootProject.getAllprojects().forEach { proj -> + if(proj.rootDir.absolutePath != proj.projectDir.absolutePath) { + pathSrcs += proj.projectDir.absolutePath + "/src/main/java/" + } + else { + println("Ignoring root: " + proj.projectDir.absolutePath) + } + } + hash = extension.hash ignoredClasses = extension.ignoredClasses classes = extension.classes @@ -78,6 +122,17 @@ class EnigmaPlugin implements Plugin { enabled = extension.enabled rootProject = project.rootDir.absolutePath pathSrc = project.rootDir.absolutePath + extension.srcJava + + pathSrcs = [] + project.rootProject.getAllprojects().forEach { proj -> + if(proj.rootDir.absolutePath != proj.projectDir.absolutePath) { + pathSrcs += proj.projectDir.absolutePath + "/src/main/java/" + } + else { + println("Ignoring root: " + proj.projectDir.absolutePath) + } + } + debug = extension.debug } diff --git a/src/main/java/com/chrisney/enigma/parser/JavaCode.java b/src/main/java/com/chrisney/enigma/parser/JavaCode.java index d99663c..aae1f8a 100644 --- a/src/main/java/com/chrisney/enigma/parser/JavaCode.java +++ b/src/main/java/com/chrisney/enigma/parser/JavaCode.java @@ -385,6 +385,9 @@ public void injectFakeKeys() { int sizeValue = Utils.getRandomNumberInRange(10, 30); String randomValue = TextUtils.getRandomString(sizeValue, TextUtils.KEY_CHARACTERS); + System.out.println("Injecting fake param: " + fakeParamName); + System.out.println("Injecting fake randomValue: " + randomValue); + injectFakeKeys(fakeParamName, randomValue); } @@ -398,8 +401,13 @@ public void injectFakeKeys(String fakeParamName, String randomValue) { ArrayList classBlocks = getBlocksByType(CodeBlock.BlockType.Class); ArrayList functions = getFunctions(); + System.out.println("classBlocks size: " + classBlocks.size()); + System.out.println("functions size: " + functions.size()); + if (Utils.arrayNotEmpty(classBlocks) && Utils.arrayNotEmpty(functions)) { + System.out.println("Utils.arrayNotEmpty(classBlocks) && Utils.arrayNotEmpty(functions) PASSED"); + // Generate fake code: String fakeAttribute = getFakeAttribute(fakeParamName, randomValue); CodeBlock fakeCode = getFakeCode(fakeParamName); diff --git a/src/main/java/com/chrisney/enigma/tasks/AbstractTask.java b/src/main/java/com/chrisney/enigma/tasks/AbstractTask.java index cc311cd..c508767 100644 --- a/src/main/java/com/chrisney/enigma/tasks/AbstractTask.java +++ b/src/main/java/com/chrisney/enigma/tasks/AbstractTask.java @@ -4,10 +4,12 @@ import org.apache.commons.io.FileUtils; import org.gradle.api.DefaultTask; import org.gradle.api.tasks.Internal; +import org.gradle.internal.Pair; import java.io.File; import java.io.IOException; import java.util.Collection; +import java.util.Collections; import java.util.HashSet; import java.util.Set; @@ -29,6 +31,7 @@ public class AbstractTask extends DefaultTask { public boolean debug = false; public String rootProject; public String pathSrc; + public String[] pathSrcs; public AbstractTask() { this.setGroup("enigma"); @@ -39,8 +42,32 @@ public AbstractTask() { * @return Collection of all JAVA files (*.java) */ @Internal - protected Collection getAllJavaFiles() { - return Utils.listFileTree(new File(pathSrc), ".java"); + protected Collection> getAllJavaFiles() { + System.out.println("Enigma pathSrcs:["); + for(String src : pathSrcs) { + System.out.println("\tEnigma src: " + src); + } + System.out.println("Enigma ]"); + + Collection> ret = new java.util.ArrayList<>(Collections.emptyList()); + if(pathSrcs.length <= 0) { + Collection files = Utils.listFileTree(new File(pathSrc), ".java"); + for(File file : files) { + ret.add(Pair.of(0, file)); + } + return ret; + } + else { + int index = 0; + for(String src : pathSrcs) { + Collection files = Utils.listFileTree(new File(src), ".java"); + for(File file : files) { + ret.add(Pair.of(index, file)); + } + index++; + } + return ret; + } } /** @@ -50,7 +77,16 @@ protected Collection getAllJavaFiles() { */ @Internal protected Collection getAllXmlFiles() { - return Utils.listFileTree(new File(pathSrc), ".xml"); + if(pathSrcs.length <= 0) { + Utils.listFileTree(new File(pathSrc), ".xml"); + } + + Collection ret = new java.util.ArrayList<>(Collections.emptyList()); + + for(String src : pathSrcs) { + ret.addAll(Utils.listFileTree(new File(src), ".xml")); + } + return ret; } /** diff --git a/src/main/java/com/chrisney/enigma/tasks/BackupTask.java b/src/main/java/com/chrisney/enigma/tasks/BackupTask.java index c5d33d2..865e607 100644 --- a/src/main/java/com/chrisney/enigma/tasks/BackupTask.java +++ b/src/main/java/com/chrisney/enigma/tasks/BackupTask.java @@ -2,6 +2,7 @@ import org.apache.commons.io.FileUtils; import org.gradle.api.tasks.TaskAction; +import org.gradle.internal.Pair; import javax.inject.Inject; import java.io.File; @@ -24,8 +25,9 @@ public void backup() throws IOException { if (!checkSCM()) return; this.removeBackupDir(); this.createBackupDir(); - for (File javaFile : this.getAllJavaFiles()) { - this.backupFile(javaFile); + for (Pair pair : this.getAllJavaFiles()) { + assert pair.right != null; + this.backupFile(pair.right); } } diff --git a/src/main/java/com/chrisney/enigma/tasks/EnigmaTask.java b/src/main/java/com/chrisney/enigma/tasks/EnigmaTask.java index 4907c5b..3226fe0 100644 --- a/src/main/java/com/chrisney/enigma/tasks/EnigmaTask.java +++ b/src/main/java/com/chrisney/enigma/tasks/EnigmaTask.java @@ -7,6 +7,7 @@ import org.gradle.api.DefaultTask; import org.gradle.api.tasks.TaskAction; import org.apache.commons.io.FileUtils; +import org.gradle.internal.Pair; import javax.inject.Inject; import java.io.File; @@ -47,16 +48,19 @@ public void encrypt() throws Exception { return; } - for (File javaFile : this.getAllJavaFiles()) { + for (Pair pair : this.getAllJavaFiles()) { + File javaFile = pair.right; + assert javaFile != null; if (!isSelected(javaFile) || isIgnored(javaFile)) { System.out.println("\uD83D\uDEAB️ " + javaFile.getName() + " ignored"); } else { - encryptJavaFile(javaFile); + encryptJavaFile(pair); } } } private boolean isSelected(File javaFile) { + System.out.println("Enigma: Checking isSelected: " + javaFile.getAbsolutePath()); if (this.classes != null) { for (String ignored : this.classes) { String path = ignored.replace(".", File.separator) @@ -71,6 +75,7 @@ private boolean isSelected(File javaFile) { } private boolean isIgnored(File javaFile) { + System.out.println("Enigma: Checking isIgnored: " + javaFile.getAbsolutePath()); if (this.ignoredClasses != null) { for (String ignored : this.ignoredClasses) { String path = ignored.replace(".", File.separator) @@ -83,7 +88,13 @@ private boolean isIgnored(File javaFile) { return false; } - private void encryptJavaFile(File srcFile) throws Exception { + private void encryptJavaFile(Pair pair) throws Exception { + assert pair != null; + assert pair.right != null; + assert pair.left != null; + + File srcFile = pair.right; + int srcIteration = pair.left; if (isEnigmaFile(srcFile)) return; if (isEnigmatized(srcFile)) { @@ -96,10 +107,16 @@ private void encryptJavaFile(File srcFile) throws Exception { JavaParser p = new JavaParser(); JavaCode code = p.parse(contents); - code.addImport(InjectCodeTask.PACKAGE_NAME + "." + InjectCodeTask.CLASS_NAME); + // Change the statement per the 'iteration' of the src + String importPackageStatement = InjectCodeTask.PACKAGE_NAME + "_" + srcIteration + "." + InjectCodeTask.CLASS_NAME; + + code.addImport(importPackageStatement); code.encryptStrings(hash, InjectCodeTask.FUNCTION_NAME); - if (injectFakeKeys) code.injectFakeKeys(); + if (injectFakeKeys) { + System.out.println("INJECTING FAKE KEYS"); + code.injectFakeKeys(); + } String contentSecured = code.toCode(); FileUtils.writeStringToFile(srcFile, contentSecured, "UTF-8"); diff --git a/src/main/java/com/chrisney/enigma/tasks/InjectCodeTask.java b/src/main/java/com/chrisney/enigma/tasks/InjectCodeTask.java index cbe65c3..6781dff 100644 --- a/src/main/java/com/chrisney/enigma/tasks/InjectCodeTask.java +++ b/src/main/java/com/chrisney/enigma/tasks/InjectCodeTask.java @@ -14,14 +14,36 @@ */ public class InjectCodeTask extends AbstractTask { + class AddFileRunnable implements Runnable { + private final String src; + private final int iteration; + + AddFileRunnable(int iteration, String src) { + this.iteration = iteration; + this.src = src; + } + + @Override + public void run() { + try { + addFile(this.iteration, this.src); + } catch (IOException e) { + throw new RuntimeException("Failed to AddFile, src: " + src, e); + } + } + } + public static final String PACKAGE_NAME = "com.chrisney.enigma"; public static final String CLASS_NAME = "EnigmaUtils"; public static final String FUNCTION_NAME = InjectCodeTask.CLASS_NAME + ".enigmatization"; public static final String IMPORT_NAME = "import " + InjectCodeTask.PACKAGE_NAME + "." + InjectCodeTask.CLASS_NAME + ";"; - public static final String SOURCE_CODE = "package " + PACKAGE_NAME + ";\n" + - "\n" + - "import javax.crypto.Cipher;\n" + + public static final String SOURCE_CODE_PACKAGE_STATEMENT = "package " + PACKAGE_NAME; + public static final String getSourceCodePackageStatement(int iteration) { + return SOURCE_CODE_PACKAGE_STATEMENT + "_" + iteration + ";\n\n"; + } + + public static final String SOURCE_CODE = "import javax.crypto.Cipher;\n" + "import javax.crypto.SecretKey;\n" + "import javax.crypto.spec.SecretKeySpec;\n" + "import javax.crypto.spec.IvParameterSpec;\n" + @@ -65,6 +87,16 @@ public InjectCodeTask() { super(); } + private void addFile(int iteration, String src) throws IOException { + File packageName = new File(src + File.separator + PACKAGE_NAME.replace(".", File.separator) + "_" + iteration); + if (!packageName.exists()) packageName.mkdir(); + + File codeFile = new File(packageName.getAbsolutePath() + File.separator + CLASS_NAME + ".java"); + String data = encodeHash(getSourceCodePackageStatement(iteration) + SOURCE_CODE); + System.out.println("addFile, adding with package statement: " + getSourceCodePackageStatement(iteration)); + FileUtils.writeStringToFile(codeFile, data, "UTF-8"); + } + @TaskAction public void addCode() throws IOException { if (!enabled) return; @@ -76,12 +108,17 @@ public void addCode() throws IOException { System.out.println("⚠️ Missing Hash value to inject Enigma code"); return; } - File packageName = new File(pathSrc + File.separator + PACKAGE_NAME.replace(".", File.separator)); - if (!packageName.exists()) packageName.mkdir(); - File codeFile = new File(packageName.getAbsolutePath() + File.separator + CLASS_NAME + ".java"); - String data = encodeHash(SOURCE_CODE); - FileUtils.writeStringToFile(codeFile, data, "UTF-8"); + if(pathSrcs.length <= 0) { + new AddFileRunnable(0, pathSrc).run(); + } + else { + int index = 0; + for(String src : pathSrcs) { + new AddFileRunnable(index, src).run(); + index++; + } + } System.out.println("✏️ Add Enigma code"); } diff --git a/src/main/java/com/chrisney/enigma/tasks/RestoreTask.java b/src/main/java/com/chrisney/enigma/tasks/RestoreTask.java index 885cf34..17d68c8 100644 --- a/src/main/java/com/chrisney/enigma/tasks/RestoreTask.java +++ b/src/main/java/com/chrisney/enigma/tasks/RestoreTask.java @@ -2,6 +2,7 @@ import org.apache.commons.io.FileUtils; import org.gradle.api.tasks.TaskAction; +import org.gradle.internal.Pair; import javax.inject.Inject; import java.io.File; @@ -13,6 +14,23 @@ */ public class RestoreTask extends AbstractTask { + class RemoveCodeRunnable implements Runnable { + private final String src; + + RemoveCodeRunnable(String src) { + this.src = src; + } + + @Override + public void run() { + try { + removeCode(this.src); + } catch (IOException e) { + throw new RuntimeException("Failed to RemoveCode, src: " + src, e); + } + } + } + @Inject public RestoreTask() { super(); @@ -24,7 +42,9 @@ public void restore() throws IOException { if (!checkSCM()) return; if (backupDirExists()) { - for (File javaFile : this.getAllJavaFiles()) { + for (Pair pair : this.getAllJavaFiles()) { + File javaFile = pair.right; + assert javaFile != null; this.restoreFile(javaFile); } } else { @@ -33,12 +53,23 @@ public void restore() throws IOException { removeEnigmaCode(); } - private void removeEnigmaCode() throws IOException { - File codePackage = new File(pathSrc + File.separator + InjectCodeTask.PACKAGE_NAME.replace(".", File.separator)); + private void removeCode(String src) throws IOException { + File codePackage = new File(src + File.separator + InjectCodeTask.PACKAGE_NAME.replace(".", File.separator)); FileUtils.deleteDirectory(codePackage); System.out.println("\uD83E\uDDF9 Remove Enigma code: " + codePackage.getAbsolutePath()); } + private void removeEnigmaCode() { + if(pathSrcs.length <= 0) { + new RemoveCodeRunnable(pathSrc).run(); + } + else { + for(String src : pathSrcs) { + new RemoveCodeRunnable(src).run(); + } + } + } + private void restoreFile(File file) throws IOException { String srcFile = file.getAbsolutePath().replace(rootProject, ""); diff --git a/src/main/java/com/chrisney/enigma/utils/Utils.java b/src/main/java/com/chrisney/enigma/utils/Utils.java index 8b7f551..82570ba 100644 --- a/src/main/java/com/chrisney/enigma/utils/Utils.java +++ b/src/main/java/com/chrisney/enigma/utils/Utils.java @@ -1,13 +1,15 @@ package com.chrisney.enigma.utils; -import com.chrisney.enigma.parser.JavaCode; +import static org.gradle.internal.impldep.com.google.common.io.Resources.getResource; import java.io.File; import java.net.URISyntaxException; import java.net.URL; -import java.util.*; - -import static org.gradle.internal.impldep.com.google.common.io.Resources.getResource; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.Random; +import java.util.Set; /** * Various helper functions