Permalink
Browse files

Resolves #28

Business args must be separated with '--'
Added warning if updating w/o signature validation
  • Loading branch information...
mordechaim committed Nov 8, 2018
1 parent 4849d27 commit 3d68cdff563271a0b4ffd0788a0c5ed18c79ce77
@@ -15,6 +15,7 @@
*/
package org.update4j;
import java.util.Collections;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -33,8 +34,6 @@
*
*/
public class Bootstrap {
/**
* The version of the current build of the framework.
@@ -83,26 +82,45 @@
*/
public static void main(String[] args) throws Throwable {
String override = null;
Pattern pattern = Pattern.compile("--delegate(?:\\s*=)?\\s*(" + StringUtils.CLASS_REGEX + ")");
for (String s : args) {
Matcher matcher = pattern.matcher(s);
List<String> argsList = List.of(args);
List<String> bootArgs;
int separatorIdx = argsList.indexOf("--");
if (separatorIdx < 0) {
bootArgs = argsList;
} else {
bootArgs = argsList.subList(0, separatorIdx);
}
for (int i = 0; i < bootArgs.size(); i++) {
String arg = bootArgs.get(i).trim();
Matcher matcher = pattern.matcher(arg);
if (matcher.matches()) {
override = matcher.group(1);
break;
} else if ("--delegate".equals(arg)) {
if (i == bootArgs.size() - 1) {
throw new IllegalArgumentException("Missing value for \"--delegate\"");
}
override = bootArgs.get(++i).trim();
break;
}
}
start(override, List.of(args));
start(override, argsList);
}
/**
* Starts the bootstrap by locating the highest versioned provider of
* {@link Delegate} (specified by {@link Service#version()}) currently present
* in the classpath or modulepath.
*
* @throws Throwable
* Any throwable thrown in the bootstrap.
* @throws Throwable Any throwable thrown in the bootstrap.
*/
public static void start() throws Throwable {
start((String) null);
@@ -118,8 +136,7 @@ public static void start() throws Throwable {
* highest versioned provider (specified by {@link Service#version()}) will be
* used instead.
*
* @throws Throwable
* Any throwable thrown in the bootstrap.
* @throws Throwable Any throwable thrown in the bootstrap.
*/
public static void start(String override) throws Throwable {
start(override, List.of());
@@ -128,8 +145,7 @@ public static void start(String override) throws Throwable {
/**
* Starts the bootstrap running the given {@link Delegate}.
*
* @throws Throwable
* Any throwable thrown in the bootstrap.
* @throws Throwable Any throwable thrown in the bootstrap.
*/
public static void start(Delegate delegate) throws Throwable {
start(delegate, List.of());
@@ -141,8 +157,7 @@ public static void start(Delegate delegate) throws Throwable {
* in the classpath or modulepath, with the given list as command-line
* arguments.
*
* @throws Throwable
* Any throwable thrown in the bootstrap.
* @throws Throwable Any throwable thrown in the bootstrap.
*/
public static void start(List<String> args) throws Throwable {
start((String) null, args);
@@ -158,8 +173,7 @@ public static void start(List<String> args) throws Throwable {
* highest versioned provider (specified by {@link Service#version()}) will be
* used instead.
*
* @throws Throwable
* Any throwable thrown in the bootstrap.
* @throws Throwable Any throwable thrown in the bootstrap.
*/
public static void start(String override, List<String> args) throws Throwable {
start(Service.loadService(Delegate.class, override), args);
@@ -169,8 +183,7 @@ public static void start(String override, List<String> args) throws Throwable {
* Starts the bootstrap running the given {@link Delegate}, with the given list
* as command-line arguments.
*
* @throws Throwable
* Any throwable thrown in the bootstrap.
* @throws Throwable Any throwable thrown in the bootstrap.
*/
public static void start(Delegate delegate, List<String> args) throws Throwable {
delegate.main(args);
@@ -913,6 +913,11 @@ public boolean updateTemp(Path tempDir, PublicKey key, Consumer<? super UpdateHa
private boolean updateImpl(Path tempDir, PublicKey key, UpdateHandler handler,
Consumer<? super UpdateHandler> handlerSetup) {
if(key == null) {
Warning.signature();
}
boolean updateTemp = tempDir != null;
boolean success;
@@ -1686,24 +1691,7 @@ public Configuration sync(Path overrideBasePath, PrivateKey signer) throws IOExc
* The public key to check against.
*/
public void verifyConfiguration(PublicKey key) {
if (getSignature() == null) {
throw new SecurityException("No signature in configuration root node.");
}
try {
Signature sign = Signature.getInstance("SHA256with" + key.getAlgorithm());
sign.initVerify(key);
sign.update(mapper.getChildrenXml().getBytes("UTF-8"));
if (!sign.verify(Base64.getDecoder().decode(getSignature()))) {
throw new SecurityException("Signature verification failed.");
}
} catch (InvalidKeyException | SignatureException e) {
throw new RuntimeException(e);
} catch (NoSuchAlgorithmException | UnsupportedEncodingException e) {
throw new AssertionError(e);
}
mapper.verifySignature(key);
}
/**
@@ -24,6 +24,7 @@
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.SignatureException;
import java.util.ArrayList;
@@ -161,11 +162,11 @@ public String toXml() {
return builder.toString();
}
public String getChildrenXml() {
private String getChildrenXml() {
// no children
if (baseUri == null && basePath == null && updateHandler == null && launcher == null && properties.isEmpty()
&& files.isEmpty()) {
&& files.isEmpty()) {
return "";
}
@@ -240,68 +241,87 @@ public String sign(PrivateKey key) {
}
}
// @Override
// public Node toNode(Document doc) {
// Element e = doc.createElement("configuration");
public void verifySignature(PublicKey key) {
if (signature == null) {
throw new SecurityException("No signature in configuration root node.");
}
try {
Signature sign = Signature.getInstance("SHA256with" + key.getAlgorithm());
sign.initVerify(key);
sign.update(getChildrenXml().getBytes("UTF-8"));
if (!sign.verify(Base64.getDecoder().decode(signature))) {
throw new SecurityException("Signature verification failed.");
}
} catch (InvalidKeyException | SignatureException | NoSuchAlgorithmException | UnsupportedEncodingException e) {
throw new SecurityException(e);
}
}
// @Override
// public Node toNode(Document doc) {
// Element e = doc.createElement("configuration");
//
// if (timestamp != null)
// e.setAttribute("timestamp", timestamp);
// if (timestamp != null)
// e.setAttribute("timestamp", timestamp);
//
// if (baseUri != null && basePath != null) {
// Element base = doc.createElement("base");
// if (baseUri != null && basePath != null) {
// Element base = doc.createElement("base");
//
// if (baseUri != null)
// base.setAttribute("uri", baseUri);
// if (basePath != null)
// base.setAttribute("path", basePath);
// if (baseUri != null)
// base.setAttribute("uri", baseUri);
// if (basePath != null)
// base.setAttribute("path", basePath);
//
// e.appendChild(base);
// }
// e.appendChild(base);
// }
//
// if (updateHandler != null && launcher != null) {
// Element provider = doc.createElement("provider");
// if (updateHandler != null && launcher != null) {
// Element provider = doc.createElement("provider");
//
// if (updateHandler != null)
// provider.setAttribute("updateHandler", updateHandler);
// if (launcher != null)
// provider.setAttribute("launcher", launcher);
// if (updateHandler != null)
// provider.setAttribute("updateHandler", updateHandler);
// if (launcher != null)
// provider.setAttribute("launcher", launcher);
//
// e.appendChild(provider);
// }
// e.appendChild(provider);
// }
//
// if (properties != null && properties.size() > 0) {
// if (properties != null && properties.size() > 0) {
//
// Element props = doc.createElement("properties");
// Element props = doc.createElement("properties");
//
// for (Property p : properties) {
// Element prop = doc.createElement("property");
// prop.setAttribute("key", p.getKey());
// prop.setAttribute("value", p.getValue());
// for (Property p : properties) {
// Element prop = doc.createElement("property");
// prop.setAttribute("key", p.getKey());
// prop.setAttribute("value", p.getValue());
//
// if (p.getOs() != null) {
// prop.setAttribute("os", p.getOs()
// .getShortName());
// }
// if (p.getOs() != null) {
// prop.setAttribute("os", p.getOs()
// .getShortName());
// }
//
// props.appendChild(prop);
// }
// props.appendChild(prop);
// }
//
// e.appendChild(props);
// }
// e.appendChild(props);
// }
//
// if (files != null && files.size() > 0) {
// if (files != null && files.size() > 0) {
//
// Element f = doc.createElement("files");
// Element f = doc.createElement("files");
//
// for (FileMapper fm : files) {
// f.appendChild(fm.toNode(doc));
// }
// for (FileMapper fm : files) {
// f.appendChild(fm.toNode(doc));
// }
//
// e.appendChild(f);
// }
// e.appendChild(f);
// }
//
// return e;
// }
// return e;
// }
public static ConfigMapper read(Reader reader) throws IOException {
try {
Oops, something went wrong.

0 comments on commit 3d68cdf

Please sign in to comment.