summaryrefslogtreecommitdiff
path: root/src/main/allow.java
blob: c52899eda526175b682f20d7813fba6a7cb8caf9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
//
// THIS CLASS IS INTENTIONALLY IN AN UNNAMED PACKAGE
// (see the class level javadoc of this class for more details)
//

import java.io.FileDescriptor;
import java.net.InetAddress;
import java.security.Permission;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * This class is only here to allow setting the {@code java.security.manager} system property
 * to a value of {@code allow}.
 * <p>
 * Certain versions of Java (like Java 8) do not recognize {@code allow}
 * as a valid textual value for the {@code java.security.manager}, but some higher versions of
 * Java do recognize this value. While launching Ant (from scripts for example), it isn't straightforward
 * to identify which runtime version of Java is used to launch Ant. That then causes additional and
 * complex scripting logic (that works across all supported OS platforms) to first identify the Java
 * runtime version being used and then deciding whether or not to set {@code allow} as a value for
 * that system property.
 * </p>
 * <p>
 * The system property value for this {@code java.security.manager} is considered some predefined
 * text or if it doesn't match that predefined text then is considered a fully qualified classname
 * of a class which extends the {@link SecurityManager} class. We use that knowledge to workaround
 * the problem we have with setting {@code allow} as the value for Java runtime which don't understand
 * that value. This {@code allow} class belongs to an unnamed package and is packaged within a jar
 * file {@code ant-launcher.jar} which Ant always adds to the classpath for launching Ant. That
 * way, this class is available in the classpath and any Java versions that don't recognize
 * {@code allow} as a predefined value will end up instantiating this class.
 * </p>
 * <p>
 * The implementation in this class doesn't really provide any {@code SecurityManager} expected
 * semantics. So this really isn't a {@code SecurityManager} implementation and shouldn't be used
 * as one. If/when this class gets instantiated and is set as a {@code SecurityManager}, it will
 * uninstall itself, on first use, by calling
 * {@link System#setSecurityManager(SecurityManager) System.setSecurityManager(null)}. First use is
 * defined as any call on a public method of this instance.
 * This class intentionally uninstalls itself on first use to preserve the semantics of {@code allow}
 * which merely implies that setting a security manager instance by the application code through the
 * use of {@link System#setSecurityManager(SecurityManager)} is allowed.
 * </p>
 *
 * @deprecated This isn't for public consumption and is an internal detail of Ant
 */
// This class has been copied over from the Apache NetBeans project
@Deprecated
public class allow extends SecurityManager {

    private final AtomicBoolean uninstalling = new AtomicBoolean();

    private void uninstall() {
        if (uninstalling.compareAndSet(false, true)) {
            // we set the security manager to null only when we ascertain that this class
            // instance is the current installed security manager. We do this to avoid any race
            // conditions where some other thread/caller had concurrently called
            // System.setSecurityManager and we end up "null"ing that set instance.
            // We rely on the (internal) detail that System.setSecurityManager is synchronized
            // on the System.class
            synchronized (System.class) {
                final SecurityManager currentSecManager = System.getSecurityManager();
                if (currentSecManager != this) {
                    return;
                }
                System.setSecurityManager(null);
            }
        }
    }

    @Override
    public void checkAccept(String host, int port) {
        uninstall();
    }

    @Override
    public void checkAccess(Thread t) {
        uninstall();
    }

    @Override
    public void checkAccess(ThreadGroup g) {
        uninstall();
    }

    //@Override
    public void checkAwtEventQueueAccess() {
        uninstall();
    }

    @Override
    public void checkConnect(String host, int port) {
        uninstall();
    }

    @Override
    public void checkConnect(String host, int port, Object context) {
        uninstall();
    }

    @Override
    public void checkCreateClassLoader() {
        uninstall();
    }

    @Override
    public void checkDelete(String file) {
        uninstall();
    }

    @Override
    public void checkExec(String cmd) {
        uninstall();
    }

    @Override
    public void checkExit(int status) {
        uninstall();
    }

    @Override
    public void checkLink(String lib) {
        uninstall();
    }

    @Override
    public void checkListen(int port) {
        uninstall();
    }

    //@Override
    public void checkMemberAccess(Class<?> clazz, int which) {
        uninstall();
    }

    @Override
    public void checkMulticast(InetAddress maddr) {
        uninstall();
    }

    @Override
    public void checkMulticast(InetAddress maddr, byte ttl) {
        uninstall();
    }

    @Override
    public void checkPackageAccess(String pkg) {
        uninstall();
    }

    @Override
    public void checkPackageDefinition(String pkg) {
        uninstall();
    }

    @Override
    public void checkPermission(Permission perm) {
        uninstall();
    }

    @Override
    public void checkPermission(Permission perm, Object context) {
        uninstall();
    }

    @Override
    public void checkPrintJobAccess() {
        uninstall();
    }

    @Override
    public void checkPropertiesAccess() {
        uninstall();
    }

    @Override
    public void checkPropertyAccess(String key) {
        uninstall();
    }

    @Override
    public void checkRead(FileDescriptor fd) {
        uninstall();
    }

    @Override
    public void checkRead(String file) {
        uninstall();
    }

    @Override
    public void checkRead(String file, Object context) {
        uninstall();
    }

    @Override
    public void checkSecurityAccess(String target) {
        uninstall();
    }

    @Override
    public void checkSetFactory() {
        uninstall();
    }

    //@Override
    public void checkSystemClipboardAccess() {
        uninstall();
    }

    //@Override
    public boolean checkTopLevelWindow(Object window) {
        uninstall();
        // we return false because we don't know what thread would be calling this permission
        // check method
        return false;
    }

    @Override
    public void checkWrite(FileDescriptor fd) {
        uninstall();
    }

    @Override
    public void checkWrite(String file) {
        uninstall();
    }
}