Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 108 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ arch:
- ppc64le
dist: bionic
env:
- POSTGRESQL_VERSION: 13
JAVA_VERSION: 15
JVM_IMPL: hotspot
MVN_VERSION: 3.5.2
- POSTGRESQL_VERSION: 12
JAVA_VERSION: 14
JVM_IMPL: hotspot
Expand Down Expand Up @@ -151,8 +155,13 @@ script: |

boolean succeeding = false; // begin pessimistic

import static java.nio.file.Files.createTempFile
import static java.nio.file.Files.write
import java.nio.file.Path
import static java.nio.file.Paths.get
import java.sql.Connection
import java.sql.PreparedStatement
import java.sql.ResultSet
import org.postgresql.pljava.packaging.Node
import static org.postgresql.pljava.packaging.Node.q
import static org.postgresql.pljava.packaging.Node.stateMachine
Expand Down Expand Up @@ -251,6 +260,70 @@ script: |
(o,p,q) -> null == o
);

/*
* Exercise TrialPolicy some. Need another connection to change
* vmoptions. Uses some example functions, so insert here before the
* test of undeploying the examples.
*/
try ( Connection c2 = n1.connect() )
{
Path trialPolicy =
createTempFile(n1.data_dir().getParent(), "trial", "policy");

write(trialPolicy, List.of(
"grant {",
" permission",
" org.postgresql.pljava.policy.TrialPolicy$Permission;",
"};"
));

PreparedStatement setVmOpts = c2.prepareStatement(
"SELECT null::pg_catalog.void" +
" FROM pg_catalog.set_config('pljava.vmoptions', ?, false)"
);

setVmOpts.setString(1, vmopts +
" -Dorg.postgresql.pljava.policy.trial=" + trialPolicy.toUri());

succeeding &= stateMachine(
"change pljava.vmoptions",
null,

q(setVmOpts, setVmOpts::execute)
.flatMap(Node::semiFlattenDiagnostics)
.peek(Node::peek),

(o,p,q) -> isDiagnostic(o, Set.of("error")) ? 1 : -2,
(o,p,q) -> isVoidResultSet(o, 1, 1) ? 3 : false,
(o,p,q) -> null == o
);

PreparedStatement tryForbiddenRead = c2.prepareStatement(
"SELECT" +
" CASE WHEN javatest.java_getsystemproperty('java.home')" +
" OPERATOR(pg_catalog.=) ?" +
" THEN javatest.logmessage('INFO', 'trial policy test ok')" +
" ELSE javatest.logmessage('WARNING', 'trial policy test ng')" +
" END"
);

tryForbiddenRead.setString(1, System.getProperty("java.home"));

succeeding &= stateMachine(
"try to read a forbidden property",
null,

q(tryForbiddenRead, tryForbiddenRead::execute)
.flatMap(Node::semiFlattenDiagnostics)
.peek(Node::peek),

(o,p,q) -> isDiagnostic(o, Set.of("error", "warning")) ? 1 : -2,
(o,p,q) -> isVoidResultSet(o, 1, 1) ? 3 : false,
(o,p,q) -> null == o
);
// done with connection c2
}

/*
* Also confirm that the generated undeploy actions work.
*/
Expand All @@ -267,6 +340,41 @@ script: |
(o,p,q) -> null == o
);
}

/*
* Get another new connection and make sure the extension can be loaded
* in a non-superuser session.
*/
try ( Connection c = n1.connect() )
{
succeeding &= stateMachine(
"become non-superuser",
null,

q(c,
"CREATE ROLE alice;" +
"GRANT USAGE ON SCHEMA sqlj TO alice;" +
"SET SESSION AUTHORIZATION alice")
.flatMap(Node::semiFlattenDiagnostics)
.peek(Node::peek),

(o,p,q) -> isDiagnostic(o, Set.of("error")) ? 1 : -2,
(o,p,q) -> null == o
);

succeeding &= stateMachine(
"load as non-superuser",
null,

q(c, "SELECT null::pg_catalog.void FROM sqlj.get_classpath('public')")
.flatMap(Node::semiFlattenDiagnostics)
.peek(Node::peek),

(o,p,q) -> isDiagnostic(o, Set.of("error")) ? 1 : -2,
(o,p,q) -> isVoidResultSet(o, 1, 1) ? 3 : false,
(o,p,q) -> null == o
);
}
} catch ( Throwable t )
{
succeeding = false;
Expand Down
117 changes: 114 additions & 3 deletions appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,22 @@ environment:
JDK: 10
PG: 12
- SYS: MINGW
JDK: 14
JDK: 11
PG: 12
- SYS: MINGW
JDK: 12
PG: 12
- SYS: MINGW
JDK: 13
PG: 12
- SYS: MINGW
JDK: 12
JDK: 14
PG: 12
- SYS: MINGW
JDK: 11
JDK: 15
PG: 12
- SYS: MSVC
JDK: 15
PG: 12
- SYS: MSVC
JDK: 14
Expand Down Expand Up @@ -82,8 +88,13 @@ test_script:
@'
boolean succeeding = false; // begin pessimistic

import static java.nio.file.Files.createTempFile
import static java.nio.file.Files.write
import java.nio.file.Path
import static java.nio.file.Paths.get
import java.sql.Connection
import java.sql.PreparedStatement
import java.sql.ResultSet
import org.postgresql.pljava.packaging.Node
import static org.postgresql.pljava.packaging.Node.q
import static org.postgresql.pljava.packaging.Node.stateMachine
Expand Down Expand Up @@ -189,6 +200,70 @@ test_script:
(o,p,q) -> null == o
);

/*
* Exercise TrialPolicy some. Need another connection to change
* vmoptions. Uses some example functions, so insert here before the
* test of undeploying the examples.
*/
try ( Connection c2 = n1.connect() )
{
Path trialPolicy =
createTempFile(n1.data_dir().getParent(), "trial", "policy");

write(trialPolicy, List.of(
"grant {",
" permission",
" org.postgresql.pljava.policy.TrialPolicy$Permission;",
"};"
));

PreparedStatement setVmOpts = c2.prepareStatement(
"SELECT null::pg_catalog.void" +
" FROM pg_catalog.set_config('pljava.vmoptions', ?, false)"
);

setVmOpts.setString(1, vmopts +
" -Dorg.postgresql.pljava.policy.trial=" + trialPolicy.toUri());

succeeding &= stateMachine(
"change pljava.vmoptions",
null,

q(setVmOpts, setVmOpts::execute)
.flatMap(Node::semiFlattenDiagnostics)
.peek(Node::peek),

(o,p,q) -> isDiagnostic(o, Set.of("error")) ? 1 : -2,
(o,p,q) -> isVoidResultSet(o, 1, 1) ? 3 : false,
(o,p,q) -> null == o
);

PreparedStatement tryForbiddenRead = c2.prepareStatement(
"SELECT" +
" CASE WHEN javatest.java_getsystemproperty('java.home')" +
" OPERATOR(pg_catalog.=) ?" +
" THEN javatest.logmessage('INFO', 'trial policy test ok')" +
" ELSE javatest.logmessage('WARNING', 'trial policy test ng')" +
" END"
);

tryForbiddenRead.setString(1, System.getProperty("java.home"));

succeeding &= stateMachine(
"try to read a forbidden property",
null,

q(tryForbiddenRead, tryForbiddenRead::execute)
.flatMap(Node::semiFlattenDiagnostics)
.peek(Node::peek),

(o,p,q) -> isDiagnostic(o, Set.of("error", "warning")) ? 1 : -2,
(o,p,q) -> isVoidResultSet(o, 1, 1) ? 3 : false,
(o,p,q) -> null == o
);
// done with connection c2
}

/*
* Also confirm that the generated undeploy actions work.
*/
Expand All @@ -205,6 +280,42 @@ test_script:
(o,p,q) -> null == o
);
}

/*
* Get another new connection and make sure the extension can be loaded
* in a non-superuser session.
*/
try ( Connection c = n1.connect() )
{
succeeding &= stateMachine(
"become non-superuser",
null,

q(c,
"CREATE ROLE alice;" +
"GRANT USAGE ON SCHEMA sqlj TO alice;" +
"SET SESSION AUTHORIZATION alice")
.flatMap(Node::semiFlattenDiagnostics)
.peek(Node::peek),

(o,p,q) -> isDiagnostic(o, Set.of("error")) ? 1 : -2,
(o,p,q) -> null == o
);

succeeding &= stateMachine(
"load as non-superuser",
null,

q(c,
"SELECT null::pg_catalog.void FROM sqlj.get_classpath('public')")
.flatMap(Node::semiFlattenDiagnostics)
.peek(Node::peek),

(o,p,q) -> isDiagnostic(o, Set.of("error")) ? 1 : -2,
(o,p,q) -> isVoidResultSet(o, 1, 1) ? 3 : false,
(o,p,q) -> null == o
);
}
} catch ( Throwable t )
{
succeeding = false;
Expand Down
7 changes: 7 additions & 0 deletions pljava-packaging/src/main/resources/pljava.policy
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ grant {
//
permission java.util.PropertyPermission
"jdk.lang.ref.disableClearBeforeEnqueue", "read";

// Something similar happened in Java 14 (not yet fixed in 15).
//
permission java.util.PropertyPermission
"java.util.concurrent.ForkJoinPool.common.maximumSpares", "read";
};


Expand All @@ -58,6 +63,8 @@ grant codebase "${org.postgresql.pljava.codesource}" {
"charsetProvider";
permission java.lang.RuntimePermission
"createClassLoader";
permission java.lang.RuntimePermission
"getProtectionDomain";
permission java.net.NetPermission
"specifyStreamHandler";
permission java.util.logging.LoggingPermission
Expand Down
9 changes: 7 additions & 2 deletions pljava-so/src/main/c/Backend.c
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,7 @@ static bool seenVisualVMName;
static bool seenModuleMain;
static char const visualVMprefix[] = "-Dvisualvm.display.name=";
static char const moduleMainPrefix[] = "-Djdk.module.main=";
static char const policyUrlsGUC[] = "pljava.policy_urls";

/*
* In a background worker, _PG_init may be called very early, before much of
Expand Down Expand Up @@ -1648,7 +1649,7 @@ static void registerGUCOptions(void)
NULL); /* show hook */

STRING_GUC(
"pljava.policy_urls",
policyUrlsGUC,
"URLs to Java security policy file(s) for PL/Java's use",
"Quote each URL and separate with commas. Any URL may begin (inside "
"the quotes) with n= where n is the index of the Java "
Expand Down Expand Up @@ -1923,7 +1924,11 @@ JNICALL Java_org_postgresql_pljava_internal_Backend__1getConfigOption(JNIEnv* en
{
PG_TRY();
{
const char *value = PG_GETCONFIGOPTION(key);
const char *value;
if ( 0 == strcmp(policyUrlsGUC, key) )
value = policy_urls;
else
value = PG_GETCONFIGOPTION(key);
pfree(key);
if(value != 0)
result = String_createJavaStringFromNTS(value);
Expand Down
2 changes: 2 additions & 0 deletions pljava/src/main/java/module-info.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@

exports org.postgresql.pljava.elog to java.logging;

exports org.postgresql.pljava.policy to java.base; // has custom Permission

provides java.net.spi.URLStreamHandlerProvider
with org.postgresql.pljava.sqlj.Handler;

Expand Down
Loading