SLING-8257 Provide a Node Descending JCR Property Digger
authorOliver Lietz <olli@apache.org>
Thu, 31 Jan 2019 10:31:24 +0000 (11:31 +0100)
committerOliver Lietz <olli@apache.org>
Thu, 31 Jan 2019 10:31:24 +0000 (11:31 +0100)
README.md
pom.xml
src/main/java/org/apache/sling/clam/jcr/NodeDescendingJcrPropertyDigger.java [new file with mode: 0644]
src/main/java/org/apache/sling/clam/jcr/internal/DefaultNodeDescendingJcrPropertyDigger.java [new file with mode: 0644]
src/main/java/org/apache/sling/clam/jcr/package-info.java [new file with mode: 0644]

index 642a345..7520c64 100644 (file)
--- a/README.md
+++ b/README.md
@@ -11,6 +11,8 @@ This module provides support for Clam in Sling.
 
 ## Finding data to scan for malware
 
+`NodeDescendingJcrPropertyDigger` starts descending from a given root path, digs properties based on type, path and length and creates scan jobs.
+
 `NodeObservingJcrPropertyDigger` observes Oak's NodeStore, digs properties based on type, path and length and creates scan jobs.
 
 **NOTE**: Ensure to exclude scan jobs in `/var/eventing` and scan results in `/var/clam/results` from scanning.
diff --git a/pom.xml b/pom.xml
index ea624da..6869803 100644 (file)
--- a/pom.xml
+++ b/pom.xml
@@ -29,7 +29,7 @@
   </parent>
 
   <artifactId>org.apache.sling.clam</artifactId>
-  <version>1.0.3-SNAPSHOT</version>
+  <version>1.1.0-SNAPSHOT</version>
 
   <name>Apache Sling Clam</name>
   <description>Support for scanning Sling's repository data with Clam service</description>
diff --git a/src/main/java/org/apache/sling/clam/jcr/NodeDescendingJcrPropertyDigger.java b/src/main/java/org/apache/sling/clam/jcr/NodeDescendingJcrPropertyDigger.java
new file mode 100644 (file)
index 0000000..f9174d9
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.clam.jcr;
+
+import java.util.Set;
+import java.util.regex.Pattern;
+
+import javax.jcr.Node;
+
+import org.jetbrains.annotations.NotNull;
+
+public interface NodeDescendingJcrPropertyDigger {
+
+    void dig(@NotNull final Node node, @NotNull final Pattern pattern, @NotNull final Set<Integer> propertyTypes, final long maxLength, final int maxDepth) throws Exception;
+
+}
diff --git a/src/main/java/org/apache/sling/clam/jcr/internal/DefaultNodeDescendingJcrPropertyDigger.java b/src/main/java/org/apache/sling/clam/jcr/internal/DefaultNodeDescendingJcrPropertyDigger.java
new file mode 100644 (file)
index 0000000..ec64fff
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.clam.jcr.internal;
+
+import java.util.Set;
+import java.util.regex.Pattern;
+
+import javax.jcr.Node;
+import javax.jcr.NodeIterator;
+import javax.jcr.Property;
+import javax.jcr.PropertyIterator;
+
+import org.apache.sling.clam.jcr.NodeDescendingJcrPropertyDigger;
+import org.apache.sling.event.jobs.JobManager;
+import org.jetbrains.annotations.NotNull;
+import org.osgi.framework.Constants;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Reference;
+import org.osgi.service.component.annotations.ReferencePolicy;
+import org.osgi.service.component.annotations.ReferencePolicyOption;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static org.apache.sling.clam.internal.ClamUtil.checkLength;
+import static org.apache.sling.clam.internal.ClamUtil.properties;
+import static org.apache.sling.clam.internal.ClamUtil.scanJobTopic;
+
+@Component(
+    service = NodeDescendingJcrPropertyDigger.class,
+    property = {
+        Constants.SERVICE_DESCRIPTION + "=Apache Sling Clam Default Node Descending JCR Property Digger",
+        Constants.SERVICE_VENDOR + "=The Apache Software Foundation"
+    }
+)
+public class DefaultNodeDescendingJcrPropertyDigger implements NodeDescendingJcrPropertyDigger {
+
+    @Reference(
+        policy = ReferencePolicy.DYNAMIC,
+        policyOption = ReferencePolicyOption.GREEDY
+    )
+    private volatile JobManager jobManager;
+
+    private final Logger logger = LoggerFactory.getLogger(DefaultNodeDescendingJcrPropertyDigger.class);
+
+    public DefaultNodeDescendingJcrPropertyDigger() {
+    }
+
+    public void dig(@NotNull final Node node, @NotNull final Pattern pattern, @NotNull final Set<Integer> propertyTypes, final long maxLength, final int maxDepth) throws Exception {
+        final int absoluteMaxDepth = maxDepth < 0 ? -1 : node.getDepth() + maxDepth;
+        _dig(node, pattern, propertyTypes, maxLength, absoluteMaxDepth);
+    }
+
+    private void _dig(@NotNull final Node node, @NotNull final Pattern pattern, @NotNull final Set<Integer> propertyTypes, final long maxLength, final int maxDepth) throws Exception {
+        final PropertyIterator properties = node.getProperties();
+        while (properties.hasNext()) {
+            final Property property = properties.nextProperty();
+            final int propertyType = property.getType();
+            final String path = property.getPath();
+            if (propertyTypes.contains(propertyType) && pattern.matcher(path).matches()) {
+                if (property.isMultiple()) { // multiple property values
+                    final long[] lengths = property.getLengths();
+                    for (int index = 0; index < lengths.length; index++) {
+                        final long length = lengths[index];
+                        if (checkLength(length, maxLength)) {
+                            jobManager.addJob(scanJobTopic(propertyType), properties(path, index, null));
+                        } else {
+                            logger.warn("Length of property '{}' [{}] greater than given max length ({}).", path, index, maxLength);
+                        }
+                    }
+                } else { // single property value
+                    if (checkLength(property.getLength(), maxLength)) {
+                        jobManager.addJob(scanJobTopic(propertyType), properties(path, null));
+                    } else {
+                        logger.warn("Length of property '{}' greater than given max length ({}).", path, maxLength);
+                    }
+                }
+            }
+        }
+        if (maxDepth == -1 || node.getDepth() < maxDepth) {
+            final NodeIterator nodes = node.getNodes();
+            while (nodes.hasNext()) {
+                _dig(nodes.nextNode(), pattern, propertyTypes, maxLength, maxDepth);
+            }
+        }
+    }
+
+}
diff --git a/src/main/java/org/apache/sling/clam/jcr/package-info.java b/src/main/java/org/apache/sling/clam/jcr/package-info.java
new file mode 100644 (file)
index 0000000..b8dcc8b
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+@Version("1.0.0")
+package org.apache.sling.clam.jcr;
+
+import org.osgi.annotation.versioning.Version;