Skip to content

Commit a09e86f

Browse files
committed
[JENKINS-73305] Create .ssh directory with owner only permissions
When the JGit implementation needs to create a `.ssh` directory, create it with permissions only allowing access to the directory owner. That is the common pattern used by the OpenSSH project and by POSIX systems to reduce access to the sensitive information stored in the directory. Testing done Ran the CredentialsTest in a debugger with a configured 'auth-data` directory and confirmed that the modified lines are executed on my RHEL 8 development computer. Confirmed that the resulting directory permissions were read, write, and execute for only the owner, with no other permissions.
1 parent f988d25 commit a09e86f

File tree

2 files changed

+49
-11
lines changed

2 files changed

+49
-11
lines changed

src/main/java/org/jenkinsci/plugins/gitclient/JGitAPIImpl.java

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@
4242
import java.nio.file.Files;
4343
import java.nio.file.Path;
4444
import java.nio.file.Paths;
45+
import java.nio.file.attribute.FileAttribute;
46+
import java.nio.file.attribute.PosixFilePermission;
47+
import java.nio.file.attribute.PosixFilePermissions;
4548
import java.security.GeneralSecurityException;
4649
import java.util.ArrayList;
4750
import java.util.Arrays;
@@ -201,10 +204,22 @@ public class JGitAPIImpl extends LegacyCompatibleGitAPIImpl {
201204
public SshdSessionFactory buildSshdSessionFactory(@NonNull final HostKeyVerifierFactory hostKeyVerifierFactory) {
202205
if (Files.notExists(hostKeyVerifierFactory.getKnownHostsFile().toPath())) {
203206
try {
204-
Files.createDirectories(hostKeyVerifierFactory
205-
.getKnownHostsFile()
206-
.getParentFile()
207-
.toPath());
207+
if (isWindows()) {
208+
Files.createDirectories(hostKeyVerifierFactory
209+
.getKnownHostsFile()
210+
.getParentFile()
211+
.toPath());
212+
} else {
213+
Set<PosixFilePermission> ownerOnly = PosixFilePermissions.fromString("rwx------");
214+
FileAttribute<Set<PosixFilePermission>> fileAttribute =
215+
PosixFilePermissions.asFileAttribute(ownerOnly);
216+
Files.createDirectories(
217+
hostKeyVerifierFactory
218+
.getKnownHostsFile()
219+
.getParentFile()
220+
.toPath(),
221+
fileAttribute);
222+
}
208223
Files.createFile(hostKeyVerifierFactory.getKnownHostsFile().toPath());
209224
} catch (IOException e) {
210225
LOGGER.log(Level.SEVERE, "could not create known hosts file", e);
@@ -3231,4 +3246,9 @@ public void close() {
32313246
}
32323247
}
32333248
}
3249+
3250+
/** inline ${@link hudson.Functions#isWindows()} to prevent a transient remote classloader issue */
3251+
private static boolean isWindows() {
3252+
return File.pathSeparatorChar == ';';
3253+
}
32343254
}

src/main/java/org/jenkinsci/plugins/gitclient/verifier/KnownHostsFileVerifier.java

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@
66
import java.io.IOException;
77
import java.nio.file.Files;
88
import java.nio.file.Path;
9+
import java.nio.file.attribute.FileAttribute;
10+
import java.nio.file.attribute.PosixFilePermission;
11+
import java.nio.file.attribute.PosixFilePermissions;
12+
import java.util.Set;
913
import java.util.logging.Level;
1014
import java.util.logging.Logger;
1115
import org.eclipse.jgit.transport.sshd.ServerKeyDatabase;
@@ -29,19 +33,28 @@ public AbstractCliGitHostKeyVerifier forCliGit(TaskListener listener) {
2933
};
3034
}
3135

36+
private void createKnownHostsFile(Path knowHostPath) throws IOException {
37+
Path parent = knowHostPath.getParent();
38+
if (parent == null) {
39+
throw new IllegalArgumentException("knowHostPath parent cannot be null");
40+
}
41+
if (isWindows()) {
42+
Files.createDirectories(parent);
43+
} else {
44+
Set<PosixFilePermission> ownerOnly = PosixFilePermissions.fromString("rwx------");
45+
FileAttribute<Set<PosixFilePermission>> fileAttribute = PosixFilePermissions.asFileAttribute(ownerOnly);
46+
Files.createDirectories(parent, fileAttribute);
47+
}
48+
Files.createFile(knowHostPath);
49+
}
50+
3251
@Override
3352
public AbstractJGitHostKeyVerifier forJGit(TaskListener listener) {
3453
Path knowHostPath = getKnownHostsFile().toPath();
3554
if (Files.notExists(knowHostPath)) {
3655
try {
3756
logHint(listener);
38-
Path parent = knowHostPath.getParent();
39-
if (parent != null) {
40-
Files.createDirectories(parent);
41-
Files.createFile(knowHostPath);
42-
} else {
43-
throw new IllegalArgumentException("knowHostPath parent cannot be null");
44-
}
57+
createKnownHostsFile(knowHostPath);
4558
} catch (IOException e) {
4659
LOGGER.log(Level.WARNING, e, () -> "Could not load known hosts.");
4760
}
@@ -76,4 +89,9 @@ private void logHint(TaskListener listener) {
7689
"Known hosts file {0} not found, but verifying host keys with known hosts file",
7790
new Object[] {SshHostKeyVerificationStrategy.KNOWN_HOSTS_DEFAULT});
7891
}
92+
93+
/** inline ${@link hudson.Functions#isWindows()} to prevent a transient remote classloader issue */
94+
private static boolean isWindows() {
95+
return File.pathSeparatorChar == ';';
96+
}
7997
}

0 commit comments

Comments
 (0)