Skip to content

feat: new launcher using Apache Mina sshd library #570

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
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
8 changes: 8 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,14 @@ charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

[*.java]
indent_style = space
indent_size = 4
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

[Jenkinsfile*]
indent_style = space
indent_size = 2
Expand Down
2 changes: 1 addition & 1 deletion Jenkinsfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@ buildPlugin(
useContainerAgent: false, // TestContainers
configurations: [
[platform: 'linux', jdk: 21],
[platform: 'windows', jdk: 17],
[platform: 'windows', jdk: 21],
])
29 changes: 29 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -93,19 +93,48 @@
<version>4924.v6b_eb_a_79a_d9d0</version>
<type>pom</type>
<scope>import</scope>
<exclusions>
<exclusion>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>trilead-api</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</dependencyManagement>

<dependencies>
<dependency>
<groupId>io.jenkins.plugins</groupId>
<artifactId>eddsa-api</artifactId>
Copy link
Member

@olamy olamy Jun 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we remove this dependency and use this new feature from mina-sshd see apache/mina-sshd#639
The project https://github.com/str4d/ed25519-java is not maintained anymore and has some known security issues such str4d/ed25519-java#95

</dependency>
<dependency>
<groupId>io.jenkins.plugins.mina-sshd-api</groupId>
<artifactId>mina-sshd-api-common</artifactId>
</dependency>
<dependency>
<groupId>io.jenkins.plugins.mina-sshd-api</groupId>
<artifactId>mina-sshd-api-core</artifactId>
</dependency>
<dependency>
<groupId>io.jenkins.plugins.mina-sshd-api</groupId>
<artifactId>mina-sshd-api-scp</artifactId>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>credentials</artifactId>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>ssh-credentials</artifactId>
<exclusions>
<exclusion>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>trilead-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- TODO remove in future versions -->
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>trilead-api</artifactId>
Expand Down
164 changes: 164 additions & 0 deletions src/main/java/io/jenkins/plugins/sshbuildagents/ssh/Connection.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
/*
* The MIT License
*
* Copyright (c) 2016, Michael Clarke
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure why you use this copyright here?
It looks to be a new class written by you. Either you put yourself or nobody but not someone who was not part of writing this code.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

C&P from the old class, so I keep the same header

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will review it, as it is likely new content, even though I started by copying it from the old file.

*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package io.jenkins.plugins.sshbuildagents.ssh;

import com.cloudbees.plugins.credentials.common.StandardUsernameCredentials;
import java.io.IOException;
import java.io.OutputStream;
import org.apache.sshd.client.session.ClientSession;

/**
* Interface to manage an SSH connection.
*
* @author Ivan Fernandez Calvo
*/
public interface Connection extends AutoCloseable {
Copy link
Member

@olamy olamy Jun 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need such abstraction here? maybe for simplicity we could use directly a class using Apache Mina.
I can't imagine to what other libraries we could switch?
At least this should be marked as internal (in the package name?) or clearly documented in the Javadoc as internal. Otherwise we have to commit to support this as a long term API (is it the goal of this Jenkins plugin?)

/**
* Execute a command and return the error code returned when it finish.
*
* @param command Command to execute.
* @return The error code returned by the command.
* @throws IOException in case of error.
*/
int execCommand(String command) throws IOException;

/**
* Create a {@link #shellChannel()} to execute non-interactive commands.
*
* @return Return a {@link #shellChannel()}
* @throws IOException
*/
ShellChannel shellChannel() throws IOException;

/**
* @return Return the host configured to connect by SSH.
*/
String getHostname();

/**
* @return Return the port configured to connect by SSH.
*/
int getPort();

/** Close the connections and resources associated. */
void close();

/**
* Copy a file to the host by SCP. It does not create folders, so the folders of the path should
* exist.
*
* @param remoteFile Full path to the remote file.
* @param bytes Array of bytes with the data to write.
* @param overwrite True to overwrite exit files.
* @param checkSameContent True to check the md5 of the file before write it and do not update the
* lie if it is the same.
* @throws IOException
*/
void copyFile(String remoteFile, byte[] bytes, boolean overwrite, boolean checkSameContent) throws IOException;

/**
* Set server host key Algorithms.
*
* @param algorithms Array of Host Key Algorithms.
*/
void setServerHostKeyAlgorithms(String[] algorithms);

/**
* Set the TCP_NODELAY flag on connections.
*
* @param tcpNoDelay True to set TCP_NODELAY.
*/
void setTCPNoDelay(boolean tcpNoDelay);

/**
* Establishes an SSH connection with the configuration set in the class.
*
* @return Return a {@link ClientSession} to interact with the SSH connection.
* @throws IOException
*/
ClientSession connect() throws IOException;

/**
* Set Server host verifier.
*
* @param verifier The Server host verifier to use.
*/
void setServerHostKeyVerifier(ServerHostKeyVerifier verifier);

/**
* Set the connection timeout.
*
* @param timeout Timeout in milliseconds.
*/
void setTimeout(long timeout);

/**
* Set the credential to use to authenticate in the SSH service.
*
* @param credentials Credentials used to authenticate.
*/
void setCredentials(StandardUsernameCredentials credentials);

/**
* Set the time to wait between retries.
*
* @param time Time to wait in seconds.
*/
void setRetryWaitTime(int time);

/**
* Set the number of times we will retry the SSH connection.
*
* @param retries Number of retries.
*/
void setRetries(int retries);

/**
* Set the absolute path to the working directory.
*
* @param path absolute path to the working directory.
*/
void setWorkingDirectory(String path);

/**
* Set the standard error output.
*
* @param stderr Value of the new standard error output.
*/
void setStdErr(OutputStream stderr);

/**
* Set the standard output.
*
* @param stdout Value of the new standard output.
*/
void setStdOut(OutputStream stdout);

/**
* Check if the connection is open.
*
* @return True if the connection is open, false otherwise.
*/
boolean isOpen();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* The MIT License
*
* Copyright (c) 2016, Michael Clarke
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package io.jenkins.plugins.sshbuildagents.ssh;

import java.io.IOException;

/**
* Class to manage key algorithms for SSH connections.
*
* @author Ivan Fernandez Calvo
*/
public class KeyAlgorithm {
public String getKeyFormat() {
return "";
}

public void decodePublicKey(byte[] keyValue) throws IOException {}

Check warning on line 38 in src/main/java/io/jenkins/plugins/sshbuildagents/ssh/KeyAlgorithm.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Not covered lines

Lines 33-38 are not covered by tests
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* The MIT License
*
* Copyright (c) 2016, Michael Clarke
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package io.jenkins.plugins.sshbuildagents.ssh;

import java.util.List;

/**
* Interface to manage supported key algorithms for SSH connections.
*
* @author Ivan Fernandez Calvo
*/
public interface KeyAlgorithmManager {

List<KeyAlgorithm> getSupportedAlgorithms();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* The MIT License
*
* Copyright (c) 2016, Michael Clarke
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package io.jenkins.plugins.sshbuildagents.ssh;

import java.io.File;

/**
* Class to manage known hosts for SSH connections. It provides methods to verify host keys and
* manage known hosts files. TODO Implement a proper host key verification mechanism.

Check warning on line 30 in src/main/java/io/jenkins/plugins/sshbuildagents/ssh/KnownHosts.java

View check run for this annotation

ci.jenkins.io / Open Tasks Scanner

TODO

NORMAL: Implement a proper host key verification mechanism.
*
* @author Ivan Fernandez Calvo
*/
public class KnownHosts {
public static final int HOSTKEY_IS_OK = 0;
public static final int HOSTKEY_IS_NEW = 1;

public KnownHosts(File knownHostsFile) {}

public static String createHexFingerprint(String algorithm, byte[] key) {
return "";
}

public int verifyHostkey(String host, String algorithm, byte[] key) {
return 1;
}

public String[] getPreferredServerHostkeyAlgorithmOrder(String host) {
return new String[0];

Check warning on line 49 in src/main/java/io/jenkins/plugins/sshbuildagents/ssh/KnownHosts.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Not covered lines

Lines 38-49 are not covered by tests
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* The MIT License
*
* Copyright (c) 2016, Michael Clarke
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package io.jenkins.plugins.sshbuildagents.ssh;

/**
* Interface to verify the server host key during SSH connections. TODO Implement a proper host key

Check warning on line 27 in src/main/java/io/jenkins/plugins/sshbuildagents/ssh/ServerHostKeyVerifier.java

View check run for this annotation

ci.jenkins.io / Open Tasks Scanner

TODO

NORMAL: Implement a proper host key
* verification mechanism.
*
* @author Ivan Fernandez Calvo
*/
public interface ServerHostKeyVerifier {}
Loading
Loading