Skip to content

Commit

Permalink
Add support for passphraseEnvVar and passphraseCmdLine in DBConnectio…
Browse files Browse the repository at this point in the history
…n and IndexRebuild
  • Loading branch information
gquerret committed Jan 31, 2023
1 parent 16208a8 commit cfb2449
Show file tree
Hide file tree
Showing 41 changed files with 5,933 additions and 27 deletions.
23 changes: 23 additions & 0 deletions src/java/com/phenix/pct/PCT.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,13 @@
*/
package com.phenix.pct;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.nio.charset.Charset;
Expand All @@ -30,6 +32,7 @@
import java.util.List;
import java.util.Properties;
import java.util.Random;
import java.util.concurrent.TimeUnit;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

Expand Down Expand Up @@ -727,6 +730,26 @@ protected void deleteFile(File file) {
}
}

protected String getPassphraseFromCmdLine(String cmdLine) {
ProcessBuilder pb = new ProcessBuilder() //
.command(cmdLine.split(" ")) //
.directory(getProject().getBaseDir()) //
.redirectOutput(ProcessBuilder.Redirect.PIPE) //
.redirectError(ProcessBuilder.Redirect.INHERIT);
try {
Process process = pb.start();
process.waitFor(30, TimeUnit.SECONDS);
BufferedReader stdOut = new BufferedReader(
new InputStreamReader(process.getInputStream()));
return stdOut.readLine();
} catch (IOException caught) {
throw new BuildException(caught);
} catch (InterruptedException caught) {
Thread.currentThread().interrupt();
return "";
}
}

protected static void copyStreamFromJar(String streamName, File outFile) throws IOException {
try (InputStream in = PCT.class.getResourceAsStream(streamName);
OutputStream out = new FileOutputStream(outFile)) {
Expand Down
55 changes: 46 additions & 9 deletions src/java/com/phenix/pct/PCTConnection.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ public class PCTConnection extends DataType {
private File paramFile = null;
private Boolean singleUser = null;
private Boolean readOnly = null;
private String passphraseEnvVar = null;
private String passphraseCmdLine = null;
private Map<String, PCTAlias> aliases = new HashMap<>();
private List<PCTRunOption> options = null;

Expand Down Expand Up @@ -173,6 +175,20 @@ public void setReadOnly(boolean readOnly) {
this.readOnly = readOnly;
}

/**
* The passphrase will be read from this environment variable
*/
public void setPassphraseEnvVar(String passphrase) {
this.passphraseEnvVar = passphrase;
}

/**
* The passphrase will be read from the output of this command line
*/
public void setPassphraseCmdLine(String passphraseCmdLine) {
this.passphraseCmdLine = passphraseCmdLine;
}

/**
* If true, opens the database in single-user mode
*
Expand Down Expand Up @@ -213,6 +229,16 @@ protected PCTConnection getRef() {
return (PCTConnection) getCheckedRef();
}

public boolean hasCmdLinePassphrase() {
return (Boolean.TRUE.equals(singleUser) || Boolean.TRUE.equals(readOnly))
&& (passphraseCmdLine != null) && !passphraseCmdLine.trim().isEmpty();
}

public boolean hasEnvPassphrase() {
return (Boolean.TRUE.equals(singleUser) || Boolean.TRUE.equals(readOnly))
&& (passphraseEnvVar != null) && !passphraseEnvVar.trim().isEmpty();
}

/**
* Check if aliases defined
*
Expand Down Expand Up @@ -278,13 +304,10 @@ public List<String> getConnectParametersList() {
list.add(logicalName);
}

if (singleUser != null) {
if (singleUser) {
list.add("-1"); //$NON-NLS-1$
}
else {
list.remove("-1");
}
if (Boolean.TRUE.equals(singleUser)) {
list.add("-1"); //$NON-NLS-1$
} else {
list.remove("-1");
}

if (cacheFile != null) {
Expand Down Expand Up @@ -356,13 +379,20 @@ public String createConnectString() {

/**
* Return a string which could be used to connect a database from a background worker. Pipe
* separated list, first entry is connection string, followed by aliases. Aliases are
* separated list, first entry is connection string, second entry contains passphrase mode,
* third entry is the value of the passphrase mode, then followed by aliases. Aliases are
* comma-separated lists, first entry is alias name, second is 1 if NO-ERROR, 0 w/o no-error
*
* @return Connection string
*/
public String createBackgroundConnectString() {
StringBuilder sb = new StringBuilder(createConnectString());
StringBuilder sb = new StringBuilder(createConnectString()).append('|');
if (hasCmdLinePassphrase())
sb.append("cmdline|").append(passphraseCmdLine);
else if (hasEnvPassphrase())
sb.append("env|").append(passphraseEnvVar);
else
sb.append("|");
if (hasAliases()) {
for (PCTAlias alias : getAliases()) {
sb.append('|').append(alias.getName()).append(',')
Expand Down Expand Up @@ -419,4 +449,11 @@ else if (logicalName != null) {
}
}

public String getPassphraseEnvVar() {
return passphraseEnvVar;
}

public String getPassphraseCmdLine() {
return passphraseCmdLine;
}
}
9 changes: 9 additions & 0 deletions src/java/com/phenix/pct/PCTDynamicRun.java
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,15 @@ private void writeJsonConfigFile() throws IOException {
for (PCTConnection dbc : runAttributes.getAllDbConnections()) {
writer.beginObject();
writer.name("connect").value(dbc.createConnectString());
if (dbc.hasCmdLinePassphrase()) {
writer.name("passphrase").value("cmdline");
writer.name("cmd").value(dbc.getPassphraseCmdLine());
} else if (dbc.hasEnvPassphrase()) {
writer.name("passphrase").value("env");
writer.name("env").value(dbc.getPassphraseEnvVar());
} else {
writer.name("passphrase").value("none");
}
writer.name("aliases").beginArray();

Collection<PCTAlias> aliases = dbc.getAliases();
Expand Down
34 changes: 28 additions & 6 deletions src/java/com/phenix/pct/PCTIndexRebuild.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,15 @@
import org.apache.tools.ant.types.Environment;

/**
* Class for creating Progress databases
* IndexRebuild task
*
* @author <a href="mailto:[email protected]">Gilles QUERRET </a>
*/
public class PCTIndexRebuild extends PCT {
private File dbDir = null;
private String dbName = null;
private String passphraseEnvVar = null;
private String passphraseCmdLine = null;
private File outputLog = null;
private List<IndexNode> indexes = new ArrayList<>();
private String cpInternal = null;
Expand All @@ -55,6 +57,14 @@ public void setOutputLog(File outputLog) {
this.outputLog = outputLog;
}

public void setPassphraseEnvVar(String passphrase) {
this.passphraseEnvVar = passphrase;
}

public void setPassphraseCmdLine(String passphraseCmdLine) {
this.passphraseCmdLine = passphraseCmdLine;
}

/**
* Internal code page (-cpinternal attribute)
*/
Expand Down Expand Up @@ -89,6 +99,8 @@ public void execute() {
}
if (indexes.isEmpty())
throw new BuildException("Index list can't be empty");
if ((passphraseCmdLine != null) && (passphraseEnvVar != null))
throw new BuildException("Unable to define passphraseCmdLine and passphraseEnvVar");

// Update dbDir if not defined
if (dbDir == null) {
Expand Down Expand Up @@ -150,12 +162,22 @@ private ExecTask idxBuildCmdLine() {
exec.createArg().setValue("-cpinternal");
exec.createArg().setValue(cpInternal);
}
exec.setInputString(generateInputString());

Environment.Variable var = new Environment.Variable();
var.setKey("DLC"); //$NON-NLS-1$
var.setValue(getDlcHome().toString());
exec.addEnv(var);
if ((passphraseEnvVar != null) || (passphraseCmdLine != null)) {
exec.createArg().setValue("-Passphrase");
if (passphraseEnvVar != null) {
exec.setInputString(System.getenv(passphraseEnvVar) + System.lineSeparator() + generateInputString());
} else {
exec.setInputString(getPassphraseFromCmdLine(passphraseCmdLine) + System.lineSeparator() + generateInputString());
}
} else {
exec.setInputString(generateInputString());
}

Environment.Variable envVar = new Environment.Variable();
envVar.setKey("DLC"); //$NON-NLS-1$
envVar.setValue(getDlcHome().toString());
exec.addEnv(envVar);

return exec;
}
Expand Down
13 changes: 10 additions & 3 deletions src/java/com/phenix/pct/PCTRun.java
Original file line number Diff line number Diff line change
Expand Up @@ -641,9 +641,16 @@ private void createInitProcedure() {
// Defines database connections and aliases
int dbNum = 1;
for (PCTConnection dbc : runAttributes.getAllDbConnections()) {
String connect = dbc.createConnectString();
bw.write(MessageFormat.format(this.getProgressProcedures().getConnectString(),
connect));
if (dbc.hasCmdLinePassphrase()) {
bw.write(MessageFormat.format(this.getProgressProcedures().getConnectPassphraseCmdLineString(),
dbc.createConnectString(), dbc.getPassphraseCmdLine()));
} else if (dbc.hasEnvPassphrase()) {
bw.write(MessageFormat.format(this.getProgressProcedures().getConnectPassphraseEnvString(),
dbc.createConnectString(), dbc.getPassphraseEnvVar()));
} else {
bw.write(MessageFormat.format(this.getProgressProcedures().getConnectString(),
dbc.createConnectString()));
}

Collection<PCTAlias> aliases = dbc.getAliases();
if (aliases != null) {
Expand Down
2 changes: 2 additions & 0 deletions src/java/com/phenix/pct/ProgressProcedures.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ public abstract interface ProgressProcedures {
String getInitString();
String getCallbackString();
String getConnectString();
String getConnectPassphraseCmdLineString();
String getConnectPassphraseEnvString();
String getAliasString();
String getDBAliasString();
String getPropathString();
Expand Down
10 changes: 10 additions & 0 deletions src/java/com/phenix/pct/ProgressV10.java
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,16 @@ public String getConnectString() {
return getString("ProgressV10.1"); //$NON-NLS-1$
}

@Override
public String getConnectPassphraseCmdLineString() {
throw new UnsupportedOperationException("Not supported");
}

@Override
public String getConnectPassphraseEnvString() {
throw new UnsupportedOperationException("Not supported");
}

@Override
public String getAliasString() {
return getString("ProgressV10.2"); //$NON-NLS-1$
Expand Down
10 changes: 10 additions & 0 deletions src/java/com/phenix/pct/ProgressV11.java
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,16 @@ public String getConnectString() {
return getString("ProgressV11.1"); //$NON-NLS-1$
}

@Override
public String getConnectPassphraseCmdLineString() {
return getString("ProgressV11.17"); //$NON-NLS-1$
}

@Override
public String getConnectPassphraseEnvString() {
return getString("ProgressV11.18"); //$NON-NLS-1$
}

@Override
public String getAliasString() {
return getString("ProgressV11.2"); //$NON-NLS-1$
Expand Down
25 changes: 25 additions & 0 deletions src/java/com/phenix/pct/ProgressV11.properties
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ DEFINE VARIABLE zz AS INTEGER NO-UNDO INITIAL ?.\n\
DEFINE NEW SHARED VARIABLE pctVerbose AS LOGICAL NO-UNDO INITIAL {0}.\n\
DEFINE VARIABLE noErrorOnQuit AS LOGICAL NO-UNDO INITIAL {1}.\n\
DEFINE NEW SHARED VARIABLE mainCallback AS Progress.Lang.Object NO-UNDO.\n\
DEFINE VARIABLE osCmdOut AS CHARACTER NO-UNDO.\n\
DEFINE TEMP-TABLE ttParams NO-UNDO FIELD key AS CHARACTER FIELD val AS CHARACTER INDEX ttParams-PK IS UNIQUE key.\n\
FUNCTION getParameter RETURNS CHARACTER (k AS CHARACTER).\n\
FIND ttParams WHERE ttParams.key EQ k NO-LOCK NO-ERROR.\n\
Expand Down Expand Up @@ -69,3 +70,27 @@ DYNAMIC-INVOKE(mainCallback, "initialize").\n
ProgressV11.15=IF pctVerbose THEN MESSAGE SUBSTITUTE("Creating alias &1 for database &2", "{0}", "{1}").\n\
CREATE ALIAS "{0}" FOR DATABASE "{1}" {2}.\n
ProgressV11.16=SECURITY-POLICY:XCODE-SESSION-KEY = "{0}".\n
ProgressV11.17=MESSAGE "Executing passphrase command line: {1}".\n\
INPUT THROUGH VALUE("{1}").\n\
IMPORT UNFORMATTED osCmdOut.\n\
INPUT CLOSE.\n\
IF pctVerbose THEN MESSAGE "Trying to connect to : {0}".\n\
CONNECT VALUE(SUBSTITUTE(''{0} -KeyStorePassPhrase "&1"'', osCmdOut)) NO-ERROR.\n\
IF ERROR-STATUS:ERROR THEN DO:\n\
MESSAGE "Unable to connect to {0}".\n\
DO i = 1 TO ERROR-STATUS:NUM-MESSAGES:\n\
MESSAGE ERROR-STATUS:GET-MESSAGE(i).\n\
END.\n\
RUN returnValue(14).\n\
QUIT.\n\
END.\n
ProgressV11.18=IF pctVerbose THEN MESSAGE "Trying to connect to : {0} (with passphrase from {1} environment variable)".\n\
CONNECT VALUE(SUBSTITUTE(''{0} -KeyStorePassPhrase "&1"'', OS-GETENV("{1}"))) NO-ERROR.\n\
IF ERROR-STATUS:ERROR THEN DO:\n\
MESSAGE "Unable to connect to {0}".\n\
DO i = 1 TO ERROR-STATUS:NUM-MESSAGES:\n\
MESSAGE ERROR-STATUS:GET-MESSAGE(i).\n\
END.\n\
RUN returnValue(14).\n\
QUIT.\n\
END.\n
10 changes: 10 additions & 0 deletions src/java/com/phenix/pct/ProgressV12.java
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,16 @@ public String getConnectString() {
return getString("ProgressV12.1"); //$NON-NLS-1$
}

@Override
public String getConnectPassphraseCmdLineString() {
return getString("ProgressV12.17"); //$NON-NLS-1$
}

@Override
public String getConnectPassphraseEnvString() {
return getString("ProgressV12.18"); //$NON-NLS-1$
}

@Override
public String getAliasString() {
return getString("ProgressV12.2"); //$NON-NLS-1$
Expand Down
25 changes: 25 additions & 0 deletions src/java/com/phenix/pct/ProgressV12.properties
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ DEFINE VARIABLE zz AS INTEGER NO-UNDO INITIAL ?.\n\
DEFINE NEW SHARED VARIABLE pctVerbose AS LOGICAL NO-UNDO INITIAL {0}.\n\
DEFINE VARIABLE noErrorOnQuit AS LOGICAL NO-UNDO INITIAL {1}.\n\
DEFINE NEW SHARED VARIABLE mainCallback AS Progress.Lang.Object NO-UNDO.\n\
DEFINE VARIABLE osCmdOut AS CHARACTER NO-UNDO.\n\
DEFINE TEMP-TABLE ttParams NO-UNDO FIELD key AS CHARACTER FIELD val AS CHARACTER INDEX ttParams-PK IS UNIQUE key.\n\
FUNCTION getParameter RETURNS CHARACTER (k AS CHARACTER).\n\
FIND ttParams WHERE ttParams.key EQ k NO-LOCK NO-ERROR.\n\
Expand Down Expand Up @@ -67,3 +68,27 @@ DYNAMIC-INVOKE(mainCallback, "initialize").\n
ProgressV12.15=IF pctVerbose THEN MESSAGE SUBSTITUTE("Creating alias &1 for database &2", "{0}", "{1}").\n\
CREATE ALIAS "{0}" FOR DATABASE "{1}" {2}.\n
ProgressV12.16=SECURITY-POLICY:XCODE-SESSION-KEY = "{0}".\n
ProgressV12.17=MESSAGE "Executing passphrase command line: {1}".\n\
INPUT THROUGH VALUE("{1}").\n\
IMPORT UNFORMATTED osCmdOut.\n\
INPUT CLOSE.\n\
IF pctVerbose THEN MESSAGE "Trying to connect to : {0}".\n\
CONNECT VALUE(SUBSTITUTE(''{0} -KeyStorePassPhrase "&1"'', osCmdOut)) NO-ERROR.\n\
IF ERROR-STATUS:ERROR THEN DO:\n\
MESSAGE "Unable to connect to {0}".\n\
DO i = 1 TO ERROR-STATUS:NUM-MESSAGES:\n\
MESSAGE ERROR-STATUS:GET-MESSAGE(i).\n\
END.\n\
RUN returnValue(14).\n\
QUIT.\n\
END.\n
ProgressV12.18=IF pctVerbose THEN MESSAGE "Trying to connect to : {0} (with passphrase from {1} environment variable)".\n\
CONNECT VALUE(SUBSTITUTE(''{0} -KeyStorePassPhrase "&1"'', OS-GETENV("{1}"))) NO-ERROR.\n\
IF ERROR-STATUS:ERROR THEN DO:\n\
MESSAGE "Unable to connect to {0}".\n\
DO i = 1 TO ERROR-STATUS:NUM-MESSAGES:\n\
MESSAGE ERROR-STATUS:GET-MESSAGE(i).\n\
END.\n\
RUN returnValue(14).\n\
QUIT.\n\
END.\n
Loading

0 comments on commit cfb2449

Please sign in to comment.