SecureLookupSupplier.java revision 1645:15d52fdd9168
1/*
2 * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package jdk.dynalink;
27
28import java.lang.invoke.MethodHandles;
29import java.lang.invoke.MethodHandles.Lookup;
30import java.util.Objects;
31
32/**
33 * Provides security-checked access to a {@code MethodHandles.Lookup} object.
34 * See {@link #getLookup()} for details.
35 */
36public class SecureLookupSupplier {
37    /**
38     * The name of a runtime permission required to successfully invoke the
39     * {@link #getLookup()} method.
40     */
41    public static final String GET_LOOKUP_PERMISSION_NAME = "dynalink.getLookup";
42
43    private static final RuntimePermission GET_LOOKUP_PERMISSION = new RuntimePermission(SecureLookupSupplier.GET_LOOKUP_PERMISSION_NAME);
44
45    private final MethodHandles.Lookup lookup;
46
47    /**
48     * Creates a new secure lookup supplier, securing the passed lookup.
49     * @param lookup the lookup to secure. Can not be null.
50     * @throws NullPointerException if null is passed.
51     */
52    public SecureLookupSupplier(final MethodHandles.Lookup lookup) {
53        this.lookup = Objects.requireNonNull(lookup, "lookup");
54    }
55
56    /**
57     * Returns the lookup secured by this {@code SecureLookupSupplier}.
58     * @return the lookup secured by this {@code SecureLookupSupplier}.
59     * @throws SecurityException if the secured lookup isn't the
60     * {@link MethodHandles#publicLookup()}, and a security manager is present,
61     * and a check for {@code RuntimePermission("dynalink.getLookup")} fails.
62     */
63    public final Lookup getLookup() {
64        final SecurityManager sm = System.getSecurityManager();
65        if (sm != null && lookup != MethodHandles.publicLookup()) {
66            sm.checkPermission(GET_LOOKUP_PERMISSION);
67        }
68        return lookup;
69    }
70
71    /**
72     * Returns the value of {@link #getLookup()} without a security check. Can
73     * be used by subclasses to access the lookup quickly.
74     * @return same as returned value of {@link #getLookup()}.
75     */
76    protected final Lookup getLookupPrivileged() {
77        return lookup;
78    }
79}
80