Skip to content

Commit fdeb09c

Browse files
committed
Merge branch 'main' into cve-fixes
2 parents 79a900f + 8a53cb2 commit fdeb09c

16 files changed

Lines changed: 435 additions & 166 deletions

File tree

.github/workflows/gradle.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@ jobs:
1414
- name: Get Fetch Tags
1515
run: git -c protocol.version=2 fetch --tags --progress --no-recurse-submodules origin
1616
if: "!contains(github.ref, 'refs/tags')"
17-
- name: Set up JDK 11
17+
- name: Set up JDK 17
1818
uses: actions/setup-java@v4
1919
with:
20-
java-version: '11'
20+
java-version: '17'
2121
distribution: 'zulu'
2222
- name: Grant execute permission for gradlew
2323
run: chmod +x gradlew

.github/workflows/release.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ on:
22
push:
33
# Sequence of patterns matched against refs/tags
44
tags:
5-
- 'v[0-9]+.[0-9]+.[0-9]+' # Push events to matching v*, i.e. v1.0, v20.15.10
5+
- '*.*.*' # Push events to matching semver tags (no v prefix)
66

77
name: Publish Release
88

@@ -15,10 +15,10 @@ jobs:
1515
uses: actions/checkout@v4
1616
with:
1717
fetch-depth: 0
18-
- name: Set up JDK 11
18+
- name: Set up JDK 17
1919
uses: actions/setup-java@v4
2020
with:
21-
java-version: '11'
21+
java-version: '17'
2222
distribution: 'zulu'
2323
- name: Build with Gradle
2424
run: ./gradlew build

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
build/
88
bin/
99
out/
10+
.temp/
1011

1112
# VS Code
1213
.vscode/

build.gradle

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,12 @@ ext.developers = [
1818
]
1919

2020
scmVersion {
21-
ignoreUncommittedChanges = true
21+
ignoreUncommittedChanges = false
2222
tag {
23-
prefix = 'v'
23+
prefix = '' // NO "v" prefix - see PLUGIN_TAGGING_ARCHITECTURE.md
2424
versionSeparator = ''
2525
}
26+
versionCreator 'simple' // Use simple version creator (just tag name)
2627
}
2728

2829
allprojects {
@@ -34,6 +35,15 @@ defaultTasks 'clean','build'
3435

3536
repositories {
3637
mavenLocal()
38+
maven {
39+
name = 'Central Portal Snapshots'
40+
url = 'https://central.sonatype.com/repository/maven-snapshots/'
41+
42+
// Only search this repository for org.rundeck snapshots
43+
content {
44+
includeGroup('org.rundeck')
45+
}
46+
}
3747
mavenCentral()
3848
}
3949

@@ -55,7 +65,8 @@ dependencies {
5565
pluginLibs libs.expectitCore
5666

5767
implementation libs.commonsIo
58-
implementation libs.rundeckCore
68+
compileOnly libs.rundeckCore
69+
testImplementation libs.rundeckCore
5970
implementation libs.slf4jApi
6071

6172
// Add secure commons-lang3 to provide alternative to vulnerable commons-lang 2.6
@@ -101,6 +112,13 @@ jar {
101112

102113
test {
103114
useJUnitPlatform()
115+
116+
// Java 17+ module access for cglib/Spock mocking
117+
jvmArgs = [
118+
'--add-opens=java.base/java.lang=ALL-UNNAMED',
119+
'--add-opens=java.base/java.util=ALL-UNNAMED',
120+
'--add-opens=java.base/java.lang.reflect=ALL-UNNAMED'
121+
]
104122
}
105123

106124
//set jar task to depend on copyToLib
@@ -117,3 +135,20 @@ nexusPublishing {
117135
}
118136

119137
apply from: "${rootDir}/gradle/publishing.gradle"
138+
139+
// Add PackageCloud repository
140+
publishing {
141+
repositories {
142+
maven {
143+
name = "PackageCloudTest"
144+
url = uri("https://packagecloud.io/pagerduty/rundeckpro-test/maven2")
145+
authentication {
146+
header(HttpHeaderAuthentication)
147+
}
148+
credentials(HttpHeaderCredentials) {
149+
name = "Authorization"
150+
value = "Bearer " + (System.getenv("PKGCLD_WRITE_TOKEN") ?: project.findProperty("pkgcldWriteToken"))
151+
}
152+
}
153+
}
154+
}

gradle/java.gradle

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
java {
2-
sourceCompatibility = JavaVersion.VERSION_11
2+
sourceCompatibility = JavaVersion.VERSION_17
3+
targetCompatibility = JavaVersion.VERSION_17
34
withJavadocJar()
45
withSourcesJar()
56
}

gradle/libs.versions.toml

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
11
[versions]
2-
sshj = "0.39.0"
2+
sshj = "0.40.0"
33
asnOne = "0.6.0"
44
eddsa = "0.3.0"
5-
bouncycastle = "1.80"
5+
bouncycastle = "1.79"
66
expectit = "0.9.0"
77
commonsIo = "2.17.0"
8-
rundeckCore = "5.14.0-rc1-20250722"
8+
rundeckCore = "6.0.0-alpha1-20260407"
99
slf4j = "2.0.17"
1010
junit = "4.13.2"
11-
groovy = "3.0.22"
12-
spock = "2.0-groovy-3.0"
11+
groovy = "4.0.29"
12+
spock = "2.4-groovy-4.0"
1313
cglib = "3.3.0"
1414
objenesis = "1.4"
1515
axionRelease = "1.18.18"
1616
nexusPublish = "2.0.0"
1717
# Security overrides for transitive dependencies
18-
commonsLang3 = "3.18.0"
18+
commonsLang3 = "3.20.0"
1919

2020
[libraries]
2121
sshj = { group = "com.hierynomus", name = "sshj", version.ref = "sshj" }
@@ -28,7 +28,7 @@ commonsIo = { group = "commons-io", name = "commons-io", version.ref = "commonsI
2828
rundeckCore = { group = "org.rundeck", name = "rundeck-core", version.ref = "rundeckCore" }
2929
slf4jApi = { group = "org.slf4j", name = "slf4j-api", version.ref = "slf4j" }
3030
junit = { group = "junit", name = "junit", version.ref = "junit" }
31-
groovyAll = { group = "org.codehaus.groovy", name = "groovy-all", version.ref = "groovy" }
31+
groovyAll = { group = "org.apache.groovy", name = "groovy-all", version.ref = "groovy" }
3232
spockCore = { group = "org.spockframework", name = "spock-core", version.ref = "spock" }
3333
cglibNodep = { group = "cglib", name = "cglib-nodep", version.ref = "cglib" }
3434
objenesis = { group = "org.objenesis", name = "objenesis", version.ref = "objenesis" }
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
distributionBase=GRADLE_USER_HOME
22
distributionPath=wrapper/dists
3-
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.6-bin.zip
3+
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip
44
networkTimeout=10000
55
zipStoreBase=GRADLE_USER_HOME
66
zipStorePath=wrapper/dists

jitpack.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
jdk:
2-
- openjdk11
2+
- openjdk17

src/main/java/com/plugin/sshjplugin/SSHJNodeExecutorPlugin.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,8 @@ public NodeExecutorResult executeCommand(ExecutionContext context, String[] comm
277277
connectionInfo,
278278
listener);
279279
} catch (Exception e) {
280-
e.printStackTrace();
280+
listener.log(2, "[" + getClass().getSimpleName() + "] Failed to build SSH executor: " +
281+
e.getMessage() + " (" + e.getClass().getSimpleName() + ")");
281282
}
282283

283284

@@ -292,6 +293,9 @@ public NodeExecutorResult executeCommand(ExecutionContext context, String[] comm
292293
config.setKeepAliveProvider(KeepAliveProvider.KEEP_ALIVE);
293294
sshClient = new SSHClient(config);
294295
}
296+
if (sshexec == null) {
297+
throw new SSHJBuilder.BuilderException("Failed to initialize SSH executor");
298+
}
295299
sshexec.connect(sshClient);
296300
sshexec.execute(sshClient);
297301
success = true;
@@ -313,7 +317,9 @@ public NodeExecutorResult executeCommand(ExecutionContext context, String[] comm
313317
sshClient.disconnect();
314318
sshClient.close();
315319
} catch (Exception iex) {
316-
throw new SSHJBuilder.BuilderException(iex);
320+
// Log cleanup errors instead of throwing to avoid masking original exception
321+
listener.log(2, "[" + getClass().getSimpleName() + "] Error closing SSH client: " +
322+
iex.getMessage() + " (" + iex.getClass().getSimpleName() + ")");
317323
}
318324
}
319325

src/main/java/com/plugin/sshjplugin/model/SSHJAuthentication.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ void authenticate(final SSHClient ssh) throws IOException {
4242
try{
4343
passphrase = connectionParameters.getPrivateKeyPassphrase(passphrasePath);
4444
} catch (Exception e) {
45-
throw new SSHJBuilder.BuilderException("Failed to read SSH Passphrase stored at path: " + passphrasePath);
45+
throw new SSHJBuilder.BuilderException("Failed to read SSH Passphrase stored at path: " + passphrasePath, e);
4646
}
4747
}
4848
if(privateKeyFileSystemPath != null && privateKeyStoragePath == null){
@@ -59,7 +59,7 @@ void authenticate(final SSHClient ssh) throws IOException {
5959
try{
6060
privateKeyContent = connectionParameters.getPrivateKeyStorage(privateKeyStoragePath);
6161
} catch (Exception e) {
62-
throw new SSHJBuilder.BuilderException("Failed to read SSH Key Storage stored at path: " + privateKeyStoragePath);
62+
throw new SSHJBuilder.BuilderException("Failed to read SSH Key Storage stored at path: " + privateKeyStoragePath, e);
6363
}
6464
KeyFormat format = KeyProviderUtil.detectKeyFileFormat(privateKeyContent,true);
6565
keys = Factory.Named.Util.create(ssh.getTransport().getConfig().getFileKeyProviderFactories(), format.toString());
@@ -83,7 +83,7 @@ void authenticate(final SSHClient ssh) throws IOException {
8383
try{
8484
password = connectionParameters.getPassword(passwordPath);
8585
} catch (Exception e) {
86-
throw new SSHJBuilder.BuilderException("Failed to read SSH Password stored at path: " + passwordPath);
86+
throw new SSHJBuilder.BuilderException("Failed to read SSH Password stored at path: " + passwordPath, e);
8787
}
8888

8989
ssh.authPassword(username, password);

0 commit comments

Comments
 (0)