[java-identity-provider] 03/04: IDP-2140 Move forward Windows Installer to V5
Rod Widdowson
rdw at steadingsoftware.com
Tue Jul 11 15:59:07 UTC 2023
This is an automated email from the git hooks/post-receive script.
rdw pushed a commit to branch main
in repository java-identity-provider.
View the commit online:
http://git.shibboleth.net/view/?p=java-identity-provider.git;a=commit;h=05ba2a360ec7203b6b964ad14ae94bff94fcb08e
commit 05ba2a360ec7203b6b964ad14ae94bff94fcb08e
Author: Rod Widdowson <rdw at steadingsoftware.com>
AuthorDate: Fri Jul 7 11:31:16 2023 +0100
IDP-2140 Move forward Windows Installer to V5
https://shibboleth.atlassian.net/browse/IDP-2140
Use a java program not Ant to configure jetty base.
---
.../idp/installer/impl/FinalizeJettyBase.java | 201 +++++++++++++++++++++
idp-installer/src/main/wix/ShibbolethIdP-main.wxs | 12 +-
idp-installer/src/main/wix/scripts/ant-jetty.xml | 117 ------------
.../src/main/wix/scripts/shib_write_configs.vbs | 59 ------
4 files changed, 207 insertions(+), 182 deletions(-)
diff --git a/idp-installer/src/main/java/net/shibboleth/idp/installer/impl/FinalizeJettyBase.java b/idp-installer/src/main/java/net/shibboleth/idp/installer/impl/FinalizeJettyBase.java
new file mode 100644
index 000000000..64ff64b03
--- /dev/null
+++ b/idp-installer/src/main/java/net/shibboleth/idp/installer/impl/FinalizeJettyBase.java
@@ -0,0 +1,201 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID 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 net.shibboleth.idp.installer.impl;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Properties;
+
+import javax.annotation.Nonnull;
+
+import net.shibboleth.idp.installer.InstallerSupport;
+import net.shibboleth.idp.installer.PropertiesWithComments;
+
+/**
+ * Small class to do the post install work on an embedded jetty-base.
+ * (primarily generated by the windows explorer but not tied to that).
+ */
+public class FinalizeJettyBase {
+
+ /** The IdP Installation dir. */
+ @Nonnull private final Path idpHome;
+
+ /** The jetty-base dir. */
+ @Nonnull private final Path jettyBase;
+
+
+ /** Constructor.
+ * @throws IOException */
+ private FinalizeJettyBase() throws IOException {
+ final String home = System.getProperty("idp.home");
+ if (home == null) {
+ System.err.println("idp.home not specified");
+ throw new IOException("idp.home not specified");
+ }
+ Path p = Path.of(home);
+ assert p!=null;
+ idpHome = p;
+ if (!Files.exists(idpHome) || !Files.isDirectory(idpHome)) {
+ final String msg = "'" + home + "' does not exist or is not a directory";
+ System.err.println(msg);
+ throw new IOException(msg);
+ }
+ p = idpHome.resolve("jetty-base");
+ assert p!=null;
+ jettyBase = p;
+ if (!Files.exists(jettyBase) || !Files.isDirectory(jettyBase)) {
+ final String msg = "'" + home + "/jetty-base' does not exist or is not a directory";
+ System.err.println(msg);
+ throw new IOException(msg);
+ }
+ p = jettyBase.resolve("start.d.dist");
+ if (!Files.exists(p) || !Files.isDirectory(p)) {
+ final String msg = "'" + home + "/jetty-base/start.d.dist' does not exist or is not a directory";
+ System.err.println(msg);
+ throw new IOException(msg);
+ }
+
+ }
+
+ /** Do the work associated with finalizing this install.
+ * @throws IOException if we encounter other issues
+ */
+ private void execute() throws IOException {
+ createDirectories();
+ final Path idpIni = jettyBase.resolve("start.d").resolve("idp.ini");
+ if (Files.exists(idpIni)) {
+ updateIdPini();
+ } else {
+ createP12IdPini();
+ }
+ final Path systemIniSrc = jettyBase.resolve("start.d.dist").resolve("idp-system.ini");
+ final Path dest = jettyBase.resolve("start.d").resolve("idp-system.ini");
+ assert systemIniSrc!=null && dest!=null;
+ copyFile(systemIniSrc, dest);
+ reprotect();
+ }
+
+ /** if they don't exists create
+ * @throws IOException if we failed to create a directory
+ */
+ private void createDirectories() throws IOException {
+ Files.createDirectories(jettyBase.resolve("start.d"));
+ Files.createDirectories(jettyBase.resolve("logs"));
+ Files.createDirectories(idpHome.resolve("static"));
+ }
+
+ /** Create the jetty.sslContext.keyStorePath as a copy
+ * from the idp.backchannel.keyStorePath file.
+ * The create start.d/idp.ini from the start.d.dist/idp.ini.windows
+ * but replacing the two password properties
+ * @throws IOException if we trip up.
+ */
+ private void createP12IdPini() throws IOException {
+ final Path credentials = idpHome.resolve("credentials");
+ final Path backChannelKeyStore = credentials.resolve("idp-backchannel.p12");
+ final Path sslKeyStore = credentials.resolve("idp-userfacing.p12");
+ assert backChannelKeyStore!=null && sslKeyStore!=null;
+
+ if (!Files.exists(backChannelKeyStore)) {
+ final String msg = backChannelKeyStore.toString() + " Does not exist";
+ System.err.println(msg);
+ throw new IOException(msg);
+ }
+ if (Files.exists(sslKeyStore)) {
+ final String msg = sslKeyStore.toString() + " Exists";
+ System.err.println(msg);
+ throw new IOException(msg);
+ }
+
+ copyFile(backChannelKeyStore, sslKeyStore);
+
+ final Properties passwords = new Properties();
+ try (final FileInputStream in = new FileInputStream(credentials.resolve("secrets.properties").toFile())) {
+ passwords.load(in);
+ }
+ final String p12Pass = passwords.getProperty("idp.backchannel.keyStorePassword");
+ final Properties replace = new Properties(2);
+ replace.setProperty("idp.backchannel.keyStorePassword", p12Pass);
+ replace.setProperty("jetty.sslContext.keyStorePassword", p12Pass);
+
+ final PropertiesWithComments idpIni = new PropertiesWithComments();
+ final File inputIni = jettyBase.resolve("start.d.dist").resolve("idp.ini.windows").toFile();
+ final File outputIni = jettyBase.resolve("start.d").resolve("idp.ini").toFile();
+ try (final FileInputStream in = new FileInputStream(inputIni); final FileOutputStream out = new FileOutputStream(outputIni)) {
+ idpIni.load(in);
+ idpIni.replaceProperties(replace);
+ idpIni.store(out);
+ }
+ }
+
+ /** Rewrite any property names needed.
+ * @throws IOException
+ */
+ private void updateIdPini() throws IOException {
+ final PropertiesWithComments props = new PropertiesWithComments();
+ final File idpIni = jettyBase.resolve("start.d").resolve("idp.ini").toFile();
+ final File replacementFile = jettyBase.resolve("start.d.dist").resolve("idp.ini.rewrite.property.names").toFile();
+ try (final FileInputStream in = new FileInputStream(idpIni); final FileInputStream replacementStream = new FileInputStream(replacementFile)) {
+ props.loadNameReplacement(replacementStream);
+ props.load(in);
+ }
+ try (final FileOutputStream out = new FileOutputStream(idpIni)) {
+ props.store(out);
+ }
+ }
+
+ /** Copy one file to another.
+ * @param fromFile from
+ * @param toFile to
+ * @throws IOException if it fails.
+ */
+ private void copyFile(@Nonnull final Path fromFile, @Nonnull final Path toFile) throws IOException {
+ try (final FileOutputStream out = new FileOutputStream(toFile.toFile())) {
+ Files.copy(fromFile, out);
+ }
+ }
+
+ /** lock down the jetty base directory. */
+ private void reprotect() {
+ final Path libDir = jettyBase.resolve("lib");
+ assert libDir!=null;
+ InstallerSupport.setReadOnlyDir(libDir, false);
+ InstallerSupport.setMode(libDir, "444", "*");
+ final Path etcDir = jettyBase.resolve("etc");
+ assert etcDir!=null;
+ InstallerSupport.setReadOnlyDir(etcDir, false);
+ InstallerSupport.setMode(etcDir, "444", "*");
+ final Path webapps = jettyBase.resolve("webapps");
+ assert webapps!=null;
+ InstallerSupport.setReadOnlyDir(webapps, false);
+ InstallerSupport.setMode(webapps, "444", "*");
+ }
+
+ /** Main entry.
+ * @param args As supplied
+ * @throws IOException if there is a problem with the jetty base.
+ */
+ public static void main(String[] args) throws IOException {
+ new FinalizeJettyBase().execute();
+ }
+
+}
diff --git a/idp-installer/src/main/wix/ShibbolethIdP-main.wxs b/idp-installer/src/main/wix/ShibbolethIdP-main.wxs
index 8bcb38ab2..d3320243f 100644
--- a/idp-installer/src/main/wix/ShibbolethIdP-main.wxs
+++ b/idp-installer/src/main/wix/ShibbolethIdP-main.wxs
@@ -162,9 +162,9 @@
<CustomAction Id="RunIdpInstall" Directory="ProgramFilesFolder" ExeCommand="[QtIdpInstall]" Execute="deferred" Impersonate="no" />
<CustomAction Id="QtIdpInstall" BinaryKey="WixCA" DllEntry="CAQuietExec" Execute="deferred" Impersonate="no" />
- <CustomAction Id="SetJettyAnt" Property="QtJettyAnt" Value=""[JAVA_EXECUTABLE]" -cp "[INSTALLDIR]\bin\lib\*;[INSTALLDIR]\dist\webapp\WEB-INF\lib\*" org.apache.tools.ant.Main -e -f "[INSTALLDIR]\bin\ant-jetty.xml" -Djetty.property.file=jetty.install.properties install" />
- <CustomAction Id="RunJettyAnt" Directory="INSTALLDIR" ExeCommand="[QtJettyAnt]" Execute="deferred" Impersonate="no" />
- <CustomAction Id="QtJettyAnt" BinaryKey="WixCA" DllEntry="CAQuietExec" Execute="deferred" Impersonate="no" />
+ <CustomAction Id="SetFinalizeJetty" Property="QtFinalizeJetty" Value=""[JAVA_EXECUTABLE]" -cp "[IDPDISTDIR]\bin\lib\*;[IDPDISTDIR]\dist\webapp\WEB-INF\lib\*" -Didp.home=[INSTALLDIR] net.shibboleth.idp.installer.impl.FinalizeJettyBase" />
+ <CustomAction Id="RunFinalizeJetty" Directory="INSTALLDIR" ExeCommand="[QtFinalizeJetty]" Execute="deferred" Impersonate="no" />
+ <CustomAction Id="QtFinalizeJetty" BinaryKey="WixCA" DllEntry="CAQuietExec" Execute="deferred" Impersonate="no" />
<CustomAction Id="SetJavaJvmMx" Property="JAVA_JVMMX" Value="#2048" />
@@ -257,9 +257,9 @@
<Custom Action="SetIdpInstall3" After="SetIdpInstall2">NOT Installed</Custom>
<Custom Action="RunIdpInstall" After="SetIdpInstall3">(NOT Installed) AND DEBUG_INSTALL</Custom>
<Custom Action="QtIdpInstall" After="SetIdpInstall3">(NOT Installed) AND (NOT DEBUG_INSTALL)</Custom>
- <Custom Action="SetJettyAnt" After="RunIdpInstall">(NOT Installed) AND INSTALL_JETTY</Custom>
- <Custom Action="RunJettyAnt" After="SetJettyAnt">(NOT Installed) AND INSTALL_JETTY AND DEBUG_INSTALL</Custom>
- <Custom Action="QtJettyAnt" After="SetJettyAnt">(NOT Installed) AND INSTALL_JETTY AND (NOT DEBUG_INSTALL)</Custom>
+ <Custom Action="SetFinalizeJetty" After="RunIdpInstall">(NOT Installed) AND INSTALL_JETTY</Custom>
+ <Custom Action="RunFinalizeJetty" After="SetFinalizeJetty">(NOT Installed) AND INSTALL_JETTY AND DEBUG_INSTALL</Custom>
+ <Custom Action="QtFinalizeJetty" After="SetFinalizeJetty">(NOT Installed) AND INSTALL_JETTY AND (NOT DEBUG_INSTALL)</Custom>
</InstallExecuteSequence>
diff --git a/idp-installer/src/main/wix/scripts/ant-jetty.xml b/idp-installer/src/main/wix/scripts/ant-jetty.xml
deleted file mode 100644
index 8a4b315b0..000000000
--- a/idp-installer/src/main/wix/scripts/ant-jetty.xml
+++ /dev/null
@@ -1,117 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project name="Shibboleth IdP V3 - Jetty Container" basedir=".." default="install">
-
- <!-- This file is for automatic configuration of Jetty, primarily from the MSI installer.
-
- Names and APIS *may* change in the future, please enter an RFI if you wish to use this
- in production outside the MSI installer.
-
- TARGETS:
-
- The only top level target is "install". This in turn calls subsidiary targets.
-
- PROPERTIES:
-
- The following properties are used. They have to be provided on the command line or
- via the property file.
-
- jetty.property.file: Name of a file to fill in all or some of the below. This file is deleted after processing.
- jetty.merge.properties: The name of a property file to merge with idp.ini. This file is deleted after processing.
- idp.host.name: The host name.
- idp.uri.subject.alt.name: If we are creating certificates.
- idp.target.dir: where to install to.
-
- idp.keystore.password: password to use on the PKCS12 file for a user-facing TLS credential,
- which will be created if one does not already exist either in JKS or PKCS12 form.
- This value must also have been written to the merge properties file as
- jetty.browser.keystore.password.
-
- jetty.no.tidy: Do not delete the two above files (debug only)
-
- -->
-
- <taskdef resource="net/shibboleth/idp/installer/ant.xml" />
-
- <target name="install" depends="init, properties, keystores, directories, copyinis, reprotect, tidy" />
-
- <target name="init">
- <tstamp />
- <hostinfo />
- </target>
-
- <target name="properties">
- <property file="${jetty.property.file}" />
- <available property="idp.ini.present" file="${idp.target.dir}/jetty-base/start.d/idp.ini" />
- <available property="idp.jks.present" file="${idp.target.dir}/credentials/idp.jks" />
- <available property="idp.userfacing.p12.present" file="${idp.target.dir}/credentials/idp-userfacing.p12" />
- <condition property="generate.userfacing.p12">
- <!-- Generate the pkcs12 keystore if neither the JKS nor the P12 exist -->
- <not>
- <or>
- <istrue value="${idp.jks.present}" />
- <istrue value="${idp.userfacing.p12.present}" />
- </or>
- </not>
- </condition>
- </target>
-
- <!-- Handle keystores -->
- <target name="keystores" depends="jks, gen-userfacing" />
-
- <target name="jks" if="idp.jks.present">
- <!-- Note that this password is the old default for QI. This will overwrite what we may have put in when the merge file was created. -->
- <echo file="${jetty.merge.properties}" append="yes">
- jetty.backchannel.keystore.type=JKS
- jetty.browser.keystore.type=JKS
- jetty.backchannel.keystore.password= SeCrEt
- jetty.browser.keystore.password= SeCrEt
- jetty.backchannel.keystore.path= ${idp.target.dir}/credentials/idp.jks
- jetty.browser.keystore.path= ${idp.target.dir}/credentials/idp.jks
- </echo>
- </target>
-
- <target name="gen-userfacing" if="generate.userfacing.p12">
- <selfsignedcert hostname="${idp.host.name}" keystoreFile="${idp.target.dir}/credentials/idp-userfacing.p12" keystorePassword="${idp.keystore.password}" uriSubjectAltNames="${idp.uri.subject.alt.name}" />
- </target>
-
- <target name="directories">
- <mkdir dir="jetty-base/start.d" />
- <mkdir dir="jetty-base/logs" />
- <mkdir dir="static" />
- </target>
-
- <target name="copyinis" depends="properties, directories, copyidpini, rewriteidpini">
- <copy file="${idp.target.dir}/jetty-base/start.d.dist/idp-system.ini" toFile="${idp.target.dir}/jetty-base/start.d/idp-system.ini" overwrite="true" force="true" />
- </target>
-
- <target name="copyidpini" depends="directories" unless="idp.ini.present">
- <mergeproperties inFile="${idp.target.dir}/jetty-base/start.d.dist/idp.ini.windows" outFile="${idp.target.dir}/jetty-base/start.d/idp.ini" mergeFile="${jetty.merge.properties}" />
- </target>
-
- <target name="rewriteidpini" depends="directories" if="idp.ini.present">
- <rewriteproperties inFile="${idp.target.dir}/jetty-base/start.d/idp.ini" outFile="${idp.target.dir}/jetty-base/start.d/idp.ini" propertyNameFile="${idp.target.dir}/jetty-base/start.d.dist/idp.ini.rewrite.property.names" />
- </target>
-
-
- <target name="reprotect">
- <chmod perm="600" dir="jetty-base/start.d" includes="**/*.key"/>
- <chmod perm="444" dir="jetty-base/etc" includes="**/*"/>
- <chmod perm="444" dir="jetty-base/lib" includes="**/*"/>
- <chmod perm="444" dir="jetty-base/webapps" includes="**/*"/>
- <attrib readonly="true">
- <fileset dir="jetty-base/etc" includes="**/*"/>
- </attrib>
- <attrib readonly="true">
- <fileset dir="jetty-base/lib" includes="**/*"/>
- </attrib>
- <attrib readonly="true">
- <fileset dir="jetty-base/webapps" includes="**/*"/>
- </attrib>
- </target>
-
- <target name="tidy" unless="jetty.no.tidy">
- <delete file="${jetty.merge.properties}" failonerror="false" />
- <delete file="${jetty.property.file}" failonerror="false" />
- </target>
-
-</project>
diff --git a/idp-installer/src/main/wix/scripts/shib_write_configs.vbs b/idp-installer/src/main/wix/scripts/shib_write_configs.vbs
index 040751468..41bd25a0b 100644
--- a/idp-installer/src/main/wix/scripts/shib_write_configs.vbs
+++ b/idp-installer/src/main/wix/scripts/shib_write_configs.vbs
@@ -48,10 +48,6 @@ LogFile.WriteLine "Domain " & Domain
LogFile.WriteLine "Scope " & IdPScope
LogFile.WriteLine "IntallJetty" & InstallJetty
-KeyStorePassword=left(CreateObject("Scriptlet.TypeLib").Guid, 38)
-SealerPassword=left(CreateObject("Scriptlet.TypeLib").Guid, 38)
-SsoStorePassword=left(CreateObject("Scriptlet.TypeLib").Guid, 38)
-
set AntFile=FileSystemObj.OpenTextFile(InstallDir & "\idp.install.properties" , 2, True)
if (Err.Number = 0 ) then
AntFile.WriteLine "#"
@@ -60,8 +56,6 @@ if (Err.Number = 0 ) then
AntFile.WriteLine "idp.noprompt=yes"
AntFile.WriteLine "idp.host.name=" & IdpHostName
AntFile.WriteLine "idp.uri.subject.alt.name=https://" & Domain & "/idp"
- AntFile.WriteLine "idp.keystore.password=" & KeyStorePassword
- AntFile.WriteLine "idp.sealer.password=" & SealerPassword
AntFile.WriteLine "idp.target.dir=" & InstallDirJava
AntFile.WriteLine "idp.merge.properties=" & InstallDirJava & "/idp.install.replace.properties"
if (IdPScope <> "") then
@@ -96,59 +90,6 @@ else
LogFile.Writeline "PropsFile failed " & Err & " - " & PropsFile
end if
-if (InstallJetty <> "") then
- set JettyAntFile=FileSystemObj.OpenTextFile(InstallDir & "\jetty.install.properties" , 2, True)
- if (Err.Number = 0 ) then
- JettyAntFile.WriteLine "#"
- JettyAntFile.WriteLine "# File with properties for ANT"
- JettyAntFile.WriteLine "#"
- JettyAntFile.WriteLine "jetty.merge.properties="& InstallDirJava & "/jetty.install.replace.properties"
- JettyAntFile.WriteLine "idp.host.name=" & IdpHostName
- JettyAntFile.WriteLine "idp.keystore.password=" & SsoStorePassword
- JettyAntFile.WriteLine "idp.uri.subject.alt.name=https://" & Domain & "/idp"
- JettyAntFile.WriteLine "idp.target.dir=" & InstallDirJava
- if (DebugInstall <> "") then
- JettyAntFile.WriteLine "jetty.no.tidy=true"
- else
- JettyAntFile.WriteLine "#jetty.no.tidy=true"
- end if
- JettyAntFile.Close
- else
- LogFile.Writeline "jettyAnt failed " & Err
- end if
-
- set JettyFile=FileSystemObj.OpenTextFile(InstallDir & "\jetty.install.replace.properties" , 2, True)
- if (Err.Number = 0 ) then
- JettyFile.WriteLine "#"
- JettyFile.WriteLine "# File to be merged into jetty's idp.ini file"
- JettyFile.WriteLine "#"
-
-'
-' Redundant - no longer in idp.ini.windows
-'
-' JettyFile.WriteLine "jetty.ssl.host=0.0.0.0"
-' JettyFile.WriteLine "jetty.ssl.port=443"
-' JettyFile.WriteLine "idp.war.path="../war/idp.war"
-' JettyFile.WriteLine "jetty.http.host=localhost"
-' JettyFile.WriteLine "jetty.http.port=80"
-
-'
-' Only these 6 properties are used and only the password need be changed.
-'
-' JettyFile.WriteLine "jetty.backchannel.keyStorePath=../credentials/idp-backchannel.p12"
-' JettyFile.WriteLine "jetty.sslContext.keyStorePath=../credentials/idp-userfacing.p12"
- JettyFile.WriteLine "idp.backchannel.keyStorePassword=" & KeyStorePassword
- JettyFile.WriteLine "jetty.sslContext.keyStorePassword=" & SsoStorePassword
-' JettyFile.WriteLine "idp.backchannel.keyStoreType=PKCS12"
-' JettyFile.WriteLine "jetty.sslContext.keyStoreType=PKCS12"
-
- JettyFile.Close
- else
- LogFile.Writeline "jetty failed " & Err
- end if
-else
- LogFile.WriteLine "NoJetty " & InstallJetty
-end if
if ConfigureAd = "true" then
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list