From 7339eed0e69a58fb0824e6537653614810548b3c Mon Sep 17 00:00:00 2001 From: Subhash Arabhi Date: Thu, 12 Dec 2024 11:24:47 +0530 Subject: [PATCH] Draft patches 8036, 8038 --- build.xml | 2 + patches/8036-draft.diff | 235 ++++++++++++++++++++++++++++++++++++++++ patches/8038-draft.diff | 128 ++++++++++++++++++++++ 3 files changed, 365 insertions(+) create mode 100644 patches/8036-draft.diff create mode 100644 patches/8038-draft.diff diff --git a/build.xml b/build.xml index 3f803233..1363869c 100644 --- a/build.xml +++ b/build.xml @@ -60,6 +60,8 @@ patches/7921.diff patches/7923.diff patches/7926.diff + patches/8036-draft.diff + patches/8038-draft.diff patches/mvn-sh.diff patches/generate-dependencies.diff patches/rename-debugger.diff diff --git a/patches/8036-draft.diff b/patches/8036-draft.diff new file mode 100644 index 00000000..7e6ff673 --- /dev/null +++ b/patches/8036-draft.diff @@ -0,0 +1,235 @@ +diff --git a/platform/core.network/src/org/netbeans/core/network/proxy/pac/impl/NbPacScriptEvaluator.java b/platform/core.network/src/org/netbeans/core/network/proxy/pac/impl/NbPacScriptEvaluator.java +index 76bb6080c73c..a708698bd008 100644 +--- a/platform/core.network/src/org/netbeans/core/network/proxy/pac/impl/NbPacScriptEvaluator.java ++++ b/platform/core.network/src/org/netbeans/core/network/proxy/pac/impl/NbPacScriptEvaluator.java +@@ -26,6 +26,7 @@ + import java.util.LinkedList; + import java.util.List; + import java.util.StringTokenizer; ++import java.util.concurrent.atomic.AtomicReference; + import java.util.logging.Level; + import java.util.logging.Logger; + import java.util.regex.Matcher; +@@ -46,6 +47,9 @@ + import org.netbeans.core.network.proxy.pac.PacUtils; + import org.openide.util.Lookup; + import org.openide.util.NbBundle; ++import org.openide.util.RequestProcessor; ++import org.openide.util.RequestProcessor.Task; ++import org.netbeans.core.ProxySettings; + + /** + * NetBeans implementation of a PAC script evaluator. This implementation +@@ -196,6 +200,8 @@ public class NbPacScriptEvaluator implements PacScriptEvaluator { + private static final String PAC_SOCKS5_FFEXT = "SOCKS5"; // Mozilla Firefox extension. Not part of original Netscape spec. + private static final String PAC_HTTP_FFEXT = "HTTP"; // Mozilla Firefox extension. Not part of original Netscape spec. + private static final String PAC_HTTPS_FFEXT = "HTTPS"; // Mozilla Firefox extension. Not part of original Netscape spec. ++ private static class RPSingleton { private static final RequestProcessor instance = new RequestProcessor(NbPacScriptEvaluator.class.getName(), Runtime.getRuntime().availableProcessors(), true, false); } ++ private static RequestProcessor getRequestProcessor() { return RPSingleton.instance; } + private final String pacScriptSource; + + +@@ -213,7 +219,8 @@ public NbPacScriptEvaluator(String pacSourceCocde) throws PacParsingException { + @Override + public List findProxyForURL(URI uri) throws PacValidationException { + +- List jsResultAnalyzed; ++ AtomicReference> resultHolder = new AtomicReference<>(null); ++ List jsResultAnalyzed = null; + + // First try the cache + if (resultCache != null) { +@@ -222,38 +229,36 @@ public List findProxyForURL(URI uri) throws PacValidationException { + return jsResultAnalyzed; + } + } +- try { +- Object jsResult; +- synchronized (scriptEngine) { +- jsResult = scriptEngine.findProxyForURL(PacUtils.toStrippedURLStr(uri), uri.getHost()); +- } +- jsResultAnalyzed = analyzeResult(uri, jsResult); +- if (canUseURLCaching && (resultCache != null)) { +- resultCache.put(uri, jsResultAnalyzed); // save the result in the cache +- } +- return jsResultAnalyzed; +- } catch (NoSuchMethodException ex) { +- // If this exception occur at this time it is really, really unexpected. +- // We already gave the function a test spin in the constructor. +- Exceptions.printStackTrace(ex); +- return Collections.singletonList(Proxy.NO_PROXY); +- } catch (ScriptException ex) { +- LOGGER.log(Level.WARNING, "Error when executing PAC script function " + scriptEngine.getJsMainFunction().getJsFunctionName() + " : ", ex); +- return Collections.singletonList(Proxy.NO_PROXY); +- } catch (Exception ex) { // for runtime exceptions +- if (ex.getCause() != null) { +- if (ex.getCause() instanceof ClassNotFoundException) { +- // Is someone trying to break out of the sandbox ? +- LOGGER.log(Level.WARNING, "The downloaded PAC script is attempting to access Java class ''{0}'' which may be a sign of maliciousness. You should investigate this with your network administrator.", ex.getCause().getMessage()); +- return Collections.singletonList(Proxy.NO_PROXY); ++ ++ int timeout = ProxySettings.getPacScriptTimeout(); ++ ++ if (timeout <= 0){ ++ jsResultAnalyzed = executeProxyScript(uri); ++ } else { ++ Task task = getRequestProcessor().post(() -> { ++ resultHolder.set(executeProxyScript(uri)); ++ }); ++ ++ try{ ++ if(!task.waitFinished(timeout)){ ++ LOGGER.log(Level.WARNING, "Timeout when executing PAC script function: {0}", scriptEngine.getJsMainFunction().getJsFunctionName()); ++ } ++ } catch (InterruptedException ex) { ++ LOGGER.log(Level.WARNING, "PAC script execution interrupted: {0}", ex); ++ } finally { ++ if (!task.isFinished()) { ++ // interruptThread is set true for the RequestProcessor so cancel will interrupt without any setting ++ task.cancel(); + } + } +- // other unforseen errors +- LOGGER.log(Level.WARNING, "Error when executing PAC script function " + scriptEngine.getJsMainFunction().getJsFunctionName() + " : ", ex); +- return Collections.singletonList(Proxy.NO_PROXY); ++ jsResultAnalyzed = resultHolder.get(); ++ } ++ if (canUseURLCaching && (resultCache != null) && (jsResultAnalyzed != null)) { ++ resultCache.put(uri, jsResultAnalyzed); // save the result in the cache + } ++ return jsResultAnalyzed != null ? jsResultAnalyzed : Collections.singletonList(Proxy.NO_PROXY); + } +- ++ + @Override + public boolean usesCaching() { + return (canUseURLCaching && (resultCache != null)); +@@ -275,6 +280,32 @@ public String getPacScriptSource() { + return this.pacScriptSource; + } + ++ private List executeProxyScript(URI uri) { ++ try{ ++ Object jsResult; ++ synchronized (scriptEngine) { ++ jsResult = scriptEngine.findProxyForURL(PacUtils.toStrippedURLStr(uri), uri.getHost()); ++ } ++ return analyzeResult(uri, jsResult); ++ ++ } catch (NoSuchMethodException ex) { ++ // If this exception occur at this time it is really, really unexpected. ++ // We already gave the function a test spin in the constructor. ++ Exceptions.printStackTrace(ex); ++ } catch (ScriptException ex) { ++ LOGGER.log(Level.WARNING, "Error when executing PAC script function " + scriptEngine.getJsMainFunction().getJsFunctionName() + " : ", ex); ++ } catch (Exception ex) { // for runtime exceptions ++ if (ex.getCause() != null) { ++ if (ex.getCause() instanceof ClassNotFoundException) { ++ // Is someone trying to break out of the sandbox ? ++ LOGGER.log(Level.WARNING, "The downloaded PAC script is attempting to access Java class ''{0}'' which may be a sign of maliciousness. You should investigate this with your network administrator.", ex.getCause().getMessage()); ++ } ++ } ++ // other unforseen errors ++ LOGGER.log(Level.WARNING, "Error when executing PAC script function " + scriptEngine.getJsMainFunction().getJsFunctionName() + " : ", ex); ++ } ++ return null; ++ } + + + private PacScriptEngine getScriptEngine(String pacSource) throws PacParsingException { +diff --git a/platform/core.network/test/unit/data/pacFiles2/pac-test-timeout.js b/platform/core.network/test/unit/data/pacFiles2/pac-test-timeout.js +new file mode 100644 +index 000000000000..9e31d3cb76b1 +--- /dev/null ++++ b/platform/core.network/test/unit/data/pacFiles2/pac-test-timeout.js +@@ -0,0 +1,30 @@ ++/* ++ * Licensed 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 ++ * ++ * http://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. ++ */ ++ ++ ++ ++ ++// ++// A PAC script which takes long time to execute and wastes cpu resources ++// ++ ++function FindProxyForURL(url, host) ++{ ++ alert("pac-test-timeout.js"); ++ const repeatedA = "A".repeat(999); ++ while(true){ ++ console.log(repeatedA); ++ } ++ return "DIRECT"; ++} +\ No newline at end of file +diff --git a/platform/core.network/test/unit/src/org/netbeans/core/network/proxy/pac/PacEngineTest.java b/platform/core.network/test/unit/src/org/netbeans/core/network/proxy/pac/PacEngineTest.java +index 178c9b162feb..90812bfa4612 100644 +--- a/platform/core.network/test/unit/src/org/netbeans/core/network/proxy/pac/PacEngineTest.java ++++ b/platform/core.network/test/unit/src/org/netbeans/core/network/proxy/pac/PacEngineTest.java +@@ -27,9 +27,12 @@ + import org.junit.Before; + import org.junit.BeforeClass; + import org.junit.Test; ++import org.netbeans.core.ProxySettings; ++import static org.netbeans.core.ProxySettings.PAC_SCRIPT_TIMEOUT; + import org.netbeans.core.network.proxy.pac.impl.NbPacScriptEvaluatorFactory; + import org.netbeans.junit.NbModuleSuite; + import org.netbeans.junit.NbTestCase; ++import org.openide.util.NbPreferences; + + /** + * +@@ -73,6 +76,9 @@ public static final junit.framework.Test suite() { + @Test + public void testEngine() throws PacParsingException, IOException, URISyntaxException, PacValidationException { + System.out.println("toSemiColonListStr"); ++ ++ NbPreferences.forModule(ProxySettings.class) ++ .putInt(PAC_SCRIPT_TIMEOUT, 2000); + + PacScriptEvaluatorFactory factory = new NbPacScriptEvaluatorFactory(); + +@@ -81,6 +87,7 @@ public void testEngine() throws PacParsingException, IOException, URISyntaxExcep + testPacFile("pac-test3.js", factory, 1, false); + testPacFileMalicious("pac-test-sandbox-breakout.js", factory); + testPacFileMalicious("pac-test-getclass.js", factory); ++ testPacFileMalicious("pac-test-timeout.js", factory); + + testPacFile2("pac-test4.js", factory); + } +diff --git a/platform/o.n.core/src/org/netbeans/core/ProxySettings.java b/platform/o.n.core/src/org/netbeans/core/ProxySettings.java +index 2d29427cd3c2..19e48d9bad82 100644 +--- a/platform/o.n.core/src/org/netbeans/core/ProxySettings.java ++++ b/platform/o.n.core/src/org/netbeans/core/ProxySettings.java +@@ -49,6 +49,8 @@ public class ProxySettings { + public static final String USE_PROXY_ALL_PROTOCOLS = "useProxyAllProtocols"; // NOI18N + public static final String DIRECT = "DIRECT"; // NOI18N + public static final String PAC = "PAC"; // NOI18N ++ public static final String PAC_SCRIPT_TIMEOUT = "pacScriptTimeout"; // NOI18N ++ public static final int DEFAULT_TIMEOUT = 60000; + + public static final String SYSTEM_PROXY_HTTP_HOST = "systemProxyHttpHost"; // NOI18N + public static final String SYSTEM_PROXY_HTTP_PORT = "systemProxyHttpPort"; // NOI18N +@@ -141,6 +143,10 @@ public static int getProxyType () { + return type; + } + ++ public static int getPacScriptTimeout() { ++ return NbPreferences.forModule(ProxySettings.class) ++ .getInt(PAC_SCRIPT_TIMEOUT, DEFAULT_TIMEOUT); ++ } + + public static String getSystemHttpHost() { + return getPreferences().get(SYSTEM_PROXY_HTTP_HOST, ""); diff --git a/patches/8038-draft.diff b/patches/8038-draft.diff new file mode 100644 index 00000000..8071a27c --- /dev/null +++ b/patches/8038-draft.diff @@ -0,0 +1,128 @@ +diff --git a/extide/gradle/src/org/netbeans/modules/gradle/ProjectTrust.java b/extide/gradle/src/org/netbeans/modules/gradle/ProjectTrust.java +index 216291f86fd4..cb9d51baa54c 100644 +--- a/extide/gradle/src/org/netbeans/modules/gradle/ProjectTrust.java ++++ b/extide/gradle/src/org/netbeans/modules/gradle/ProjectTrust.java +@@ -48,6 +48,7 @@ + public class ProjectTrust { + private static final Logger LOG = Logger.getLogger(ProjectTrust.class.getName()); + ++ private static final int KEY_LENGTH = 64; + private static final String KEY_SALT = "secret"; //NOI18N + private static final String NODE_PROJECT = "projects"; //NOI18N + private static final String NODE_TRUST = "trust"; //NOI18N +@@ -68,7 +69,7 @@ public class ProjectTrust { + ProjectTrust(Preferences prefs) { + byte[] buf = prefs.getByteArray(KEY_SALT, null); + if (buf == null) { +- buf = new byte[16]; ++ buf = new byte[KEY_LENGTH]; + new SecureRandom().nextBytes(buf); + prefs.putByteArray(KEY_SALT, buf); + } +diff --git a/platform/o.n.bootstrap/src/org/netbeans/CLIHandler.java b/platform/o.n.bootstrap/src/org/netbeans/CLIHandler.java +index 3140aba8eafa..11327beed908 100644 +--- a/platform/o.n.bootstrap/src/org/netbeans/CLIHandler.java ++++ b/platform/o.n.bootstrap/src/org/netbeans/CLIHandler.java +@@ -63,7 +63,7 @@ + */ + public abstract class CLIHandler extends Object { + /** lenght of the key used for connecting */ +- private static final int KEY_LENGTH = 10; ++ private static final int KEY_LENGTH = 64; + private static final byte[] VERSION = { + 'N', 'B', 'C', 'L', 'I', 0, 0, 0, 0, 1 + }; +@@ -579,7 +579,19 @@ static Status initialize( + enterState(10, block); + + final byte[] arr = new byte[KEY_LENGTH]; +- new SecureRandom().nextBytes(arr); ++ SecureRandom secureRandom = new SecureRandom(); ++ boolean isPrefix; ++ // making sure arr doesn't have VERSION as prefix, rare occurance ++ do{ ++ secureRandom.nextBytes(arr); ++ isPrefix = true; ++ for(int j = 0; j < VERSION.length; j++) { ++ if (arr[j] != VERSION[j]) { ++ isPrefix = false; ++ break; ++ } ++ } ++ } while(isPrefix); + + + final RandomAccessFile os = raf; +@@ -741,7 +753,7 @@ public void run() { + } else { + os.write(key); + } +- assert VERSION.length == key.length; ++ assert VERSION.length <= key.length; + os.flush(); + + enterState(30, block); +@@ -1144,7 +1156,7 @@ private void handleConnect(Socket s) throws IOException { + + enterState(70, block); + +- is.readFully(check); ++ is.readFully(check, 0, VERSION.length); + + final DataOutputStream os = new DataOutputStream(s.getOutputStream()); + +@@ -1162,6 +1174,9 @@ private void handleConnect(Socket s) throws IOException { + is.readFully(check); + } else { + requestedVersion = 0; ++ if(check.length > VERSION.length){ ++ is.readFully(check, VERSION.length, check.length); ++ } + } + + enterState(90, block); +diff --git a/platform/o.n.bootstrap/test/unit/src/org/netbeans/CLIHandlerTest.java b/platform/o.n.bootstrap/test/unit/src/org/netbeans/CLIHandlerTest.java +index 91df241d2429..bc7c0925ba26 100644 +--- a/platform/o.n.bootstrap/test/unit/src/org/netbeans/CLIHandlerTest.java ++++ b/platform/o.n.bootstrap/test/unit/src/org/netbeans/CLIHandlerTest.java +@@ -274,14 +274,14 @@ public void testFileExistsButTheServerCannotBeContactedAndWeDoNotWantToCleanTheF + File f = runner.resultFile(); + byte[] arr = new byte[(int)f.length()]; + int len = arr.length; +- assertTrue("We know that the size of the file should be int + key_length + 4 for ip address: ", len >=14 && len <= 18); ++ assertTrue("We know that the size of the file should be int + key_length + 4 for ip address: ", len >=68 && len <= 72); + FileInputStream is = new FileInputStream(f); + assertEquals("Fully read", arr.length, is.read(arr)); + is.close(); + +- byte[] altarr = new byte[18]; +- for (int i = 0; i < 18; i++) { +- altarr[i] = i<14? arr[i]: 1; ++ byte[] altarr = new byte[72]; ++ for (int i = 0; i < 72; i++) { ++ altarr[i] = i<68? arr[i]: 1; + } + + // change the IP at the end of the file +diff --git a/platform/o.n.bootstrap/test/unit/src/org/netbeans/CLIHowHardIsToGuessKeyTest.java b/platform/o.n.bootstrap/test/unit/src/org/netbeans/CLIHowHardIsToGuessKeyTest.java +index 00ad770223ec..365561dc9388 100644 +--- a/platform/o.n.bootstrap/test/unit/src/org/netbeans/CLIHowHardIsToGuessKeyTest.java ++++ b/platform/o.n.bootstrap/test/unit/src/org/netbeans/CLIHowHardIsToGuessKeyTest.java +@@ -107,14 +107,14 @@ public void run() { + LOG.info("lock file exists" + lock); + for (int i = 0; i < 500; i++) { + LOG.info(i + ": testing its size: " + lock.length()); +- if (lock.length() >= 14) { ++ if (lock.length() >= 68) { + break; + } + Thread.sleep(500); + } +- assertTrue("Lock must contain the key now: " + lock.length(), lock.length() >= 14);//fail("Ok"); ++ assertTrue("Lock must contain the key now: " + lock.length(), lock.length() >= 68);//fail("Ok"); + +- final byte[] arr = new byte[10]; // CLIHandler.KEY_LENGTH ++ final byte[] arr = new byte[64]; // CLIHandler.KEY_LENGTH + DataInputStream is = new DataInputStream(new FileInputStream(lock)); + final int port = is.readInt(); + int read = is.read(arr);