66
66
import java .util .List ;
67
67
import java .util .Map ;
68
68
import java .util .Set ;
69
+ import java .util .regex .Matcher ;
70
+ import java .util .regex .Pattern ;
69
71
70
72
import static org .opensearch .bootstrap .FilePermissionUtils .addDirectoryPath ;
71
73
import static org .opensearch .bootstrap .FilePermissionUtils .addSingleFilePath ;
121
123
*/
122
124
@ SuppressWarnings ("removal" )
123
125
final class Security {
126
+ private static final Pattern CODEBASE_JAR_WITH_CLASSIFIER = Pattern .compile ("^(.+)-\\ d+\\ .\\ d+[^-]*.*?[-]?([^-]+)?\\ .jar$" );
127
+
124
128
/** no instantiation */
125
129
private Security () {}
126
130
@@ -231,33 +235,45 @@ static Policy readPolicy(URL policyFile, Map<String, URL> codebases) {
231
235
try {
232
236
List <String > propertiesSet = new ArrayList <>();
233
237
try {
238
+ final Map <Map .Entry <String , URL >, String > jarsWithPossibleClassifiers = new HashMap <>();
234
239
// set codebase properties
235
240
for (Map .Entry <String , URL > codebase : codebases .entrySet ()) {
236
- String name = codebase .getKey ();
237
- URL url = codebase .getValue ();
241
+ final String name = codebase .getKey ();
242
+ final URL url = codebase .getValue ();
238
243
239
244
// We attempt to use a versionless identifier for each codebase. This assumes a specific version
240
245
// format in the jar filename. While we cannot ensure all jars in all plugins use this format, nonconformity
241
246
// only means policy grants would need to include the entire jar filename as they always have before.
247
+ final Matcher matcher = CODEBASE_JAR_WITH_CLASSIFIER .matcher (name );
248
+ if (matcher .matches () && matcher .group (2 ) != null ) {
249
+ // There is a JAR that, possibly, has a classifier or SNAPSHOT at the end, examples are:
250
+ // - netty-tcnative-boringssl-static-2.0.61.Final-linux-x86_64.jar
251
+ // - kafka-server-common-3.6.1-test.jar
252
+ // - lucene-core-9.11.0-snapshot-8a555eb.jar
253
+ // - zstd-jni-1.5.5-5.jar
254
+ jarsWithPossibleClassifiers .put (codebase , matcher .group (2 ));
255
+ } else {
256
+ String property = "codebase." + name ;
257
+ String aliasProperty = "codebase." + name .replaceFirst ("-\\ d+\\ .\\ d+.*\\ .jar" , "" );
258
+ addCodebaseToSystemProperties (propertiesSet , url , property , aliasProperty );
259
+ }
260
+ }
261
+
262
+ // set codebase properties for JARs that might present with classifiers
263
+ for (Map .Entry <Map .Entry <String , URL >, String > jarWithPossibleClassifier : jarsWithPossibleClassifiers .entrySet ()) {
264
+ final Map .Entry <String , URL > codebase = jarWithPossibleClassifier .getKey ();
265
+ final String name = codebase .getKey ();
266
+ final URL url = codebase .getValue ();
267
+
242
268
String property = "codebase." + name ;
243
269
String aliasProperty = "codebase." + name .replaceFirst ("-\\ d+\\ .\\ d+.*\\ .jar" , "" );
244
- if (aliasProperty .equals (property ) == false ) {
245
- propertiesSet .add (aliasProperty );
246
- String previous = System .setProperty (aliasProperty , url .toString ());
247
- if (previous != null ) {
248
- throw new IllegalStateException (
249
- "codebase property already set: " + aliasProperty + " -> " + previous + ", cannot set to " + url .toString ()
250
- );
251
- }
252
- }
253
- propertiesSet .add (property );
254
- String previous = System .setProperty (property , url .toString ());
255
- if (previous != null ) {
256
- throw new IllegalStateException (
257
- "codebase property already set: " + property + " -> " + previous + ", cannot set to " + url .toString ()
258
- );
270
+ if (System .getProperties ().containsKey (aliasProperty )) {
271
+ aliasProperty = aliasProperty + "@" + jarWithPossibleClassifier .getValue ();
259
272
}
273
+
274
+ addCodebaseToSystemProperties (propertiesSet , url , property , aliasProperty );
260
275
}
276
+
261
277
return Policy .getInstance ("JavaPolicy" , new URIParameter (policyFile .toURI ()));
262
278
} finally {
263
279
// clear codebase properties
@@ -270,6 +286,27 @@ static Policy readPolicy(URL policyFile, Map<String, URL> codebases) {
270
286
}
271
287
}
272
288
289
+ /** adds the codebase to properties and System properties */
290
+ @ SuppressForbidden (reason = "accesses System properties to configure codebases" )
291
+ private static void addCodebaseToSystemProperties (List <String > propertiesSet , final URL url , String property , String aliasProperty ) {
292
+ if (aliasProperty .equals (property ) == false ) {
293
+ propertiesSet .add (aliasProperty );
294
+ String previous = System .setProperty (aliasProperty , url .toString ());
295
+ if (previous != null ) {
296
+ throw new IllegalStateException (
297
+ "codebase property already set: " + aliasProperty + " -> " + previous + ", cannot set to " + url .toString ()
298
+ );
299
+ }
300
+ }
301
+ propertiesSet .add (property );
302
+ String previous = System .setProperty (property , url .toString ());
303
+ if (previous != null ) {
304
+ throw new IllegalStateException (
305
+ "codebase property already set: " + property + " -> " + previous + ", cannot set to " + url .toString ()
306
+ );
307
+ }
308
+ }
309
+
273
310
/** returns dynamic Permissions to configured paths and bind ports */
274
311
static Permissions createPermissions (Environment environment ) throws IOException {
275
312
Permissions policy = new Permissions ();
0 commit comments