Skip to content

Commit 27920fd

Browse files
committed
Merge remote-tracking branch 'upstream/main' into entitlements/missing-url-connection-4
2 parents d86a45c + dbac70e commit 27920fd

File tree

23 files changed

+418
-204
lines changed

23 files changed

+418
-204
lines changed

libs/cli/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ apply plugin: 'elasticsearch.publish'
1212
dependencies {
1313
api 'net.sf.jopt-simple:jopt-simple:5.0.2'
1414
api project(':libs:core')
15+
api project(':libs:logging')
1516

1617
testImplementation(project(":test:framework")) {
1718
exclude group: 'org.elasticsearch', module: 'cli'

libs/cli/src/main/java/module-info.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
module org.elasticsearch.cli {
1212
requires jopt.simple;
1313
requires org.elasticsearch.base;
14+
requires java.logging;
15+
requires org.elasticsearch.logging;
1416

1517
exports org.elasticsearch.cli;
1618
}

libs/cli/src/main/java/org/elasticsearch/cli/Command.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
import joptsimple.OptionSpec;
1616

1717
import org.elasticsearch.core.SuppressForbidden;
18+
import org.elasticsearch.logging.Level;
19+
import org.elasticsearch.logging.internal.spi.LoggerFactory;
1820

1921
import java.io.Closeable;
2022
import java.io.IOException;
@@ -84,12 +86,16 @@ protected void mainWithoutErrorHandling(String[] args, Terminal terminal, Proces
8486
return;
8587
}
8688

89+
LoggerFactory loggerFactory = LoggerFactory.provider();
8790
if (options.has(silentOption)) {
8891
terminal.setVerbosity(Terminal.Verbosity.SILENT);
92+
loggerFactory.setRootLevel(Level.OFF);
8993
} else if (options.has(verboseOption)) {
9094
terminal.setVerbosity(Terminal.Verbosity.VERBOSE);
95+
loggerFactory.setRootLevel(Level.DEBUG);
9196
} else {
9297
terminal.setVerbosity(Terminal.Verbosity.NORMAL);
98+
loggerFactory.setRootLevel(Level.INFO);
9399
}
94100

95101
execute(terminal, options, processInfo);

libs/entitlement/src/main/java/org/elasticsearch/entitlement/initialization/EntitlementInitialization.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,11 +64,11 @@
6464
import java.util.stream.Stream;
6565
import java.util.stream.StreamSupport;
6666

67+
import static org.elasticsearch.entitlement.runtime.policy.Platform.LINUX;
6768
import static org.elasticsearch.entitlement.runtime.policy.entitlements.FilesEntitlement.BaseDir.DATA;
6869
import static org.elasticsearch.entitlement.runtime.policy.entitlements.FilesEntitlement.BaseDir.SHARED_REPO;
6970
import static org.elasticsearch.entitlement.runtime.policy.entitlements.FilesEntitlement.Mode.READ;
7071
import static org.elasticsearch.entitlement.runtime.policy.entitlements.FilesEntitlement.Mode.READ_WRITE;
71-
import static org.elasticsearch.entitlement.runtime.policy.entitlements.FilesEntitlement.Platform.LINUX;
7272

7373
/**
7474
* Called by the agent during {@code agentmain} to configure the entitlement system,

libs/entitlement/src/main/java/org/elasticsearch/entitlement/runtime/policy/FileAccessTree.java

Lines changed: 1 addition & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,12 @@
2222
import java.nio.file.Paths;
2323
import java.util.ArrayList;
2424
import java.util.Arrays;
25-
import java.util.Comparator;
2625
import java.util.List;
2726
import java.util.Objects;
2827
import java.util.function.BiConsumer;
2928

3029
import static org.elasticsearch.core.PathUtils.getDefaultFileSystem;
30+
import static org.elasticsearch.entitlement.runtime.policy.FileUtils.PATH_ORDER;
3131

3232
public final class FileAccessTree {
3333

@@ -236,30 +236,4 @@ public boolean equals(Object o) {
236236
public int hashCode() {
237237
return Objects.hash(Arrays.hashCode(readPaths), Arrays.hashCode(writePaths));
238238
}
239-
240-
/**
241-
* For our lexicographic sort trick to work correctly, we must have path separators sort before
242-
* any other character so that files in a directory appear immediately after that directory.
243-
* For example, we require [/a, /a/b, /a.xml] rather than the natural order [/a, /a.xml, /a/b].
244-
*/
245-
private static final Comparator<String> PATH_ORDER = (s1, s2) -> {
246-
Path p1 = Path.of(s1);
247-
Path p2 = Path.of(s2);
248-
var i1 = p1.iterator();
249-
var i2 = p2.iterator();
250-
while (i1.hasNext() && i2.hasNext()) {
251-
int cmp = i1.next().compareTo(i2.next());
252-
if (cmp != 0) {
253-
return cmp;
254-
}
255-
}
256-
if (i1.hasNext()) {
257-
return 1;
258-
} else if (i2.hasNext()) {
259-
return -1;
260-
} else {
261-
assert p1.equals(p2);
262-
return 0;
263-
}
264-
};
265239
}
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the "Elastic License
4+
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
5+
* Public License v 1"; you may not use this file except in compliance with, at
6+
* your election, the "Elastic License 2.0", the "GNU Affero General Public
7+
* License v3.0 only", or the "Server Side Public License, v 1".
8+
*/
9+
10+
package org.elasticsearch.entitlement.runtime.policy;
11+
12+
import org.elasticsearch.core.SuppressForbidden;
13+
14+
import java.io.File;
15+
import java.util.Comparator;
16+
17+
import static java.lang.Character.isLetter;
18+
19+
public class FileUtils {
20+
21+
private FileUtils() {}
22+
23+
/**
24+
* For our lexicographic sort trick to work correctly, we must have path separators sort before
25+
* any other character so that files in a directory appear immediately after that directory.
26+
* For example, we require [/a, /a/b, /a.xml] rather than the natural order [/a, /a.xml, /a/b].
27+
*/
28+
static final Comparator<String> PATH_ORDER = (s1, s2) -> {
29+
int len1 = s1.length();
30+
int len2 = s2.length();
31+
int lim = Math.min(len1, len2);
32+
for (int k = 0; k < lim; k++) {
33+
char c1 = s1.charAt(k);
34+
char c2 = s2.charAt(k);
35+
if (c1 == c2) {
36+
continue;
37+
}
38+
boolean c1IsSeparator = isPathSeparator(c1);
39+
boolean c2IsSeparator = isPathSeparator(c2);
40+
if (c1IsSeparator == false || c2IsSeparator == false) {
41+
if (c1IsSeparator) {
42+
return -1;
43+
}
44+
if (c2IsSeparator) {
45+
return 1;
46+
}
47+
return c1 - c2;
48+
}
49+
}
50+
return len1 - len2;
51+
};
52+
53+
@SuppressForbidden(reason = "we need the separator as a char, not a string")
54+
private static boolean isPathSeparator(char c) {
55+
return c == File.separatorChar;
56+
}
57+
58+
/**
59+
* Tests if a path is absolute or relative, taking into consideration both Unix and Windows conventions.
60+
* Note that this leads to a conflict, resolved in favor of Unix rules: `/foo` can be either a Unix absolute path, or a Windows
61+
* relative path with "wrong" directory separator (using non-canonical / in Windows).
62+
* This method is intended to be used as validation for different file entitlements format: therefore it is preferable to reject a
63+
* relative path that is definitely absolute on Unix, rather than accept it as a possible relative path on Windows (if that is the case,
64+
* the developer can easily fix the path by using the correct platform separators).
65+
*/
66+
public static boolean isAbsolutePath(String path) {
67+
if (path.isEmpty()) {
68+
return false;
69+
}
70+
if (path.charAt(0) == '/') {
71+
// Unix/BSD absolute
72+
return true;
73+
}
74+
75+
return isWindowsAbsolutePath(path);
76+
}
77+
78+
/**
79+
* When testing for path separators in a platform-agnostic way, we may encounter both kinds of slashes, especially when
80+
* processing windows paths. The JDK parses paths the same way under Windows.
81+
*/
82+
static boolean isSlash(char c) {
83+
return (c == '\\') || (c == '/');
84+
}
85+
86+
private static boolean isWindowsAbsolutePath(String input) {
87+
// if a prefix is present, we expected (long) UNC or (long) absolute
88+
if (input.startsWith("\\\\?\\")) {
89+
return true;
90+
}
91+
92+
if (input.length() > 1) {
93+
char c0 = input.charAt(0);
94+
char c1 = input.charAt(1);
95+
if (isSlash(c0) && isSlash(c1)) {
96+
// Two slashes or more: UNC
97+
return true;
98+
}
99+
if (isLetter(c0) && c1 == ':') {
100+
// A drive: absolute
101+
return true;
102+
}
103+
}
104+
// Otherwise relative
105+
return false;
106+
}
107+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the "Elastic License
4+
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
5+
* Public License v 1"; you may not use this file except in compliance with, at
6+
* your election, the "Elastic License 2.0", the "GNU Affero General Public
7+
* License v3.0 only", or the "Server Side Public License, v 1".
8+
*/
9+
10+
package org.elasticsearch.entitlement.runtime.policy;
11+
12+
public enum Platform {
13+
LINUX,
14+
MACOS,
15+
WINDOWS;
16+
17+
private static final Platform current = findCurrent();
18+
19+
private static Platform findCurrent() {
20+
String os = System.getProperty("os.name");
21+
if (os.startsWith("Linux")) {
22+
return LINUX;
23+
} else if (os.startsWith("Mac OS")) {
24+
return MACOS;
25+
} else if (os.startsWith("Windows")) {
26+
return WINDOWS;
27+
} else {
28+
throw new AssertionError("Unsupported platform [" + os + "]");
29+
}
30+
}
31+
32+
public boolean isCurrent() {
33+
return this == current;
34+
}
35+
}

0 commit comments

Comments
 (0)