Install open ssl jar into Gerrit site for bouncycastle crypto provider

937d527ac0 upgraded bouncy castle to 1.49.

The old JAR artifact was renamed and split to number of files. For Gerrit
two libraries must be downloaded and be available under `$gerrit_site/lib`:

* bcprov-jdk15on-149.jar
* bcpkix-jdk15on-149.jar

Update download logic to support a basic concept of required dependencies,
ensuring BC provider is downloaded if the SSL library is installed by init.

Change-Id: I60092ebe136f78a5649fe8512737275f50195a34
This commit is contained in:
David Ostrovsky
2013-11-30 17:25:47 +01:00
committed by Shawn Pearce
parent 8ba03ff10b
commit c34d3607ba
7 changed files with 82 additions and 21 deletions

View File

@@ -72,9 +72,9 @@ class InitSshd implements InitStep {
sshd.set("listenAddress", SocketUtil.format(hostname, port)); sshd.set("listenAddress", SocketUtil.format(hostname, port));
if (site.ssh_rsa.exists() || site.ssh_dsa.exists()) { if (site.ssh_rsa.exists() || site.ssh_dsa.exists()) {
libraries.bouncyCastle.downloadRequired(); libraries.bouncyCastleSSL.downloadRequired();
} else if (!site.ssh_key.exists()) { } else if (!site.ssh_key.exists()) {
libraries.bouncyCastle.downloadOptional(); libraries.bouncyCastleSSL.downloadOptional();
} }
generateSshHostKeys(); generateSshHostKeys();

View File

@@ -37,7 +37,8 @@ class Libraries {
private final Provider<LibraryDownloader> downloadProvider; private final Provider<LibraryDownloader> downloadProvider;
/* final */LibraryDownloader bouncyCastle; /* final */LibraryDownloader bouncyCastleProvider;
/* final */LibraryDownloader bouncyCastleSSL;
/* final */LibraryDownloader mysqlDriver; /* final */LibraryDownloader mysqlDriver;
/* final */LibraryDownloader oracleDriver; /* final */LibraryDownloader oracleDriver;
@@ -58,29 +59,41 @@ class Libraries {
throw new RuntimeException(e.getMessage(), e); throw new RuntimeException(e.getMessage(), e);
} }
for (final Field f : Libraries.class.getDeclaredFields()) { for (Field f : Libraries.class.getDeclaredFields()) {
if ((f.getModifiers() & Modifier.STATIC) == 0
&& f.getType() == LibraryDownloader.class) {
try {
f.set(this, downloadProvider.get());
} catch (IllegalArgumentException | IllegalAccessException e) {
throw new IllegalStateException("Cannot initialize " + f.getName());
}
}
}
for (Field f : Libraries.class.getDeclaredFields()) {
if ((f.getModifiers() & Modifier.STATIC) == 0 if ((f.getModifiers() & Modifier.STATIC) == 0
&& f.getType() == LibraryDownloader.class) { && f.getType() == LibraryDownloader.class) {
try { try {
init(f, cfg); init(f, cfg);
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException | IllegalAccessException
throw new IllegalStateException("Cannot initialize " + f.getName()); | NoSuchFieldException | SecurityException e) {
} catch (IllegalAccessException e) { throw new IllegalStateException("Cannot configure " + f.getName());
throw new IllegalStateException("Cannot initialize " + f.getName());
} }
} }
} }
} }
private void init(final Field field, final Config cfg) private void init(Field field, Config cfg) throws IllegalArgumentException,
throws IllegalArgumentException, IllegalAccessException { IllegalAccessException, NoSuchFieldException, SecurityException {
final String n = field.getName(); String n = field.getName();
final LibraryDownloader dl = downloadProvider.get(); LibraryDownloader dl = (LibraryDownloader) field.get(this);
dl.setName(get(cfg, n, "name")); dl.setName(get(cfg, n, "name"));
dl.setJarUrl(get(cfg, n, "url")); dl.setJarUrl(get(cfg, n, "url"));
dl.setSHA1(get(cfg, n, "sha1")); dl.setSHA1(get(cfg, n, "sha1"));
dl.setRemove(get(cfg, n, "remove")); dl.setRemove(get(cfg, n, "remove"));
field.set(this, dl); for (String d : cfg.getStringList("library", n, "needs")) {
dl.addNeeds((LibraryDownloader) getClass().getDeclaredField(d).get(this));
}
} }
private static String get(Config cfg, String name, String key) { private static String get(Config cfg, String name, String key) {

View File

@@ -40,6 +40,8 @@ import java.net.URISyntaxException;
import java.net.URL; import java.net.URL;
import java.security.MessageDigest; import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;
/** Get optional or required 3rd party library files into $site_path/lib. */ /** Get optional or required 3rd party library files into $site_path/lib. */
class LibraryDownloader { class LibraryDownloader {
@@ -51,13 +53,17 @@ class LibraryDownloader {
private String jarUrl; private String jarUrl;
private String sha1; private String sha1;
private String remove; private String remove;
private List<LibraryDownloader> needs;
private LibraryDownloader neededBy;
private File dst; private File dst;
private boolean download; // download or copy private boolean download; // download or copy
private boolean exists;
@Inject @Inject
LibraryDownloader(ConsoleUI ui, SitePaths site) { LibraryDownloader(ConsoleUI ui, SitePaths site) {
this.ui = ui; this.ui = ui;
this.lib_dir = site.lib_dir; this.lib_dir = site.lib_dir;
this.needs = new ArrayList<>(2);
} }
void setName(final String name) { void setName(final String name) {
@@ -77,16 +83,27 @@ class LibraryDownloader {
this.remove = remove; this.remove = remove;
} }
void addNeeds(LibraryDownloader lib) {
needs.add(lib);
}
void downloadRequired() { void downloadRequired() {
this.required = true; setRequired(true);
download(); download();
} }
void downloadOptional() { void downloadOptional() {
this.required = false; required = false;
download(); download();
} }
private void setRequired(boolean r) {
required = r;
for (LibraryDownloader d : needs) {
d.setRequired(r);
}
}
private void download() { private void download() {
if (jarUrl == null || !jarUrl.contains("/")) { if (jarUrl == null || !jarUrl.contains("/")) {
throw new IllegalStateException("Invalid JarUrl for " + name); throw new IllegalStateException("Invalid JarUrl for " + name);
@@ -102,9 +119,18 @@ class LibraryDownloader {
} }
dst = new File(lib_dir, jarName); dst = new File(lib_dir, jarName);
if (!dst.exists() && shouldGet()) { if (dst.exists()) {
exists = true;
} else if (shouldGet()) {
doGet(); doGet();
} }
if (exists) {
for (LibraryDownloader d : needs) {
d.neededBy = this;
d.downloadRequired();
}
}
} }
private boolean shouldGet() { private boolean shouldGet() {
@@ -115,7 +141,11 @@ class LibraryDownloader {
final StringBuilder msg = new StringBuilder(); final StringBuilder msg = new StringBuilder();
msg.append("\n"); msg.append("\n");
msg.append("Gerrit Code Review is not shipped with %s\n"); msg.append("Gerrit Code Review is not shipped with %s\n");
if (required) { if (neededBy != null) {
msg.append(String.format(
"** This library is required by %s. **\n",
neededBy.name));
} else if (required) {
msg.append("** This library is required for your configuration. **\n"); msg.append("** This library is required for your configuration. **\n");
} else { } else {
msg.append(" If available, Gerrit can take advantage of features\n"); msg.append(" If available, Gerrit can take advantage of features\n");
@@ -171,6 +201,7 @@ class LibraryDownloader {
} }
if (dst.exists()) { if (dst.exists()) {
exists = true;
IoUtil.loadJARs(dst); IoUtil.loadJARs(dst);
} }
} }

View File

@@ -14,12 +14,20 @@
# Version should match lib/bouncycastle/BUCK # Version should match lib/bouncycastle/BUCK
[library "bouncyCastle"] [library "bouncyCastleProvider"]
name = Bouncy Castle Crypto v149 name = Bouncy Castle Crypto Provider v149
url = http://repo1.maven.org/maven2/org/bouncycastle/bcprov-jdk15on/1.49/bcprov-jdk15on-1.49.jar url = http://www.bouncycastle.org/download/bcprov-jdk15on-149.jar
sha1 = f5155f04330459104b79923274db5060c1057b99 sha1 = f5155f04330459104b79923274db5060c1057b99
remove = bcprov-.*[.]jar remove = bcprov-.*[.]jar
# Version should match lib/bouncycastle/BUCK
[library "bouncyCastleSSL"]
name = Bouncy Castle Crypto SSL v149
url = http://www.bouncycastle.org/download/bcpkix-jdk15on-149.jar
sha1 = 924cc7ad2f589630c97b918f044296ebf1bb6855
needs = bouncyCastleProvider
remove = bcpkix-.*[.]jar
[library "mysqlDriver"] [library "mysqlDriver"]
name = MySQL Connector/J 5.1.21 name = MySQL Connector/J 5.1.21
url = http://repo2.maven.org/maven2/mysql/mysql-connector-java/5.1.21/mysql-connector-java-5.1.21.jar url = http://repo2.maven.org/maven2/mysql/mysql-connector-java/5.1.21/mysql-connector-java-5.1.21.jar

View File

@@ -42,7 +42,7 @@ public class LibrariesTest {
} }
}); });
assertNotNull(lib.bouncyCastle); assertNotNull(lib.bouncyCastleProvider);
assertNotNull(lib.mysqlDriver); assertNotNull(lib.mysqlDriver);
verify(ui); verify(ui);

View File

@@ -68,6 +68,7 @@ java_library2(
compile_deps = [ compile_deps = [
'//lib/bouncycastle:bcprov', '//lib/bouncycastle:bcprov',
'//lib/bouncycastle:bcpg', '//lib/bouncycastle:bcpg',
'//lib/bouncycastle:bcpkix',
], ],
visibility = ['PUBLIC'], visibility = ['PUBLIC'],
) )

View File

@@ -18,3 +18,11 @@ maven_jar(
license = 'DO_NOT_DISTRIBUTE', #'bouncycastle' license = 'DO_NOT_DISTRIBUTE', #'bouncycastle'
deps = [':bcprov'], deps = [':bcprov'],
) )
maven_jar(
name = 'bcpkix',
id = 'org.bouncycastle:bcpkix-jdk15on:' + VERSION,
sha1 = '924cc7ad2f589630c97b918f044296ebf1bb6855',
license = 'DO_NOT_DISTRIBUTE', #'bouncycastle'
deps = [':bcprov'],
)