From d3c5997baab259c0036e2a417c269d0d5fbb3671 Mon Sep 17 00:00:00 2001 From: Daniel Scalzi Date: Wed, 28 Mar 2018 16:13:57 -0400 Subject: [PATCH] Initial work on Java detection/validation system. --- app/app.ejs | 2 +- app/assets/js/javaguard.js | 197 +++++++++++++++++++++++++++++++++++++ package-lock.json | 15 +-- package.json | 4 +- 4 files changed, 202 insertions(+), 16 deletions(-) create mode 100644 app/assets/js/javaguard.js diff --git a/app/app.ejs b/app/app.ejs index 1bb0ddb6..cf42b38f 100644 --- a/app/app.ejs +++ b/app/app.ejs @@ -18,7 +18,7 @@ <% include frame.ejs %>
- <% include welcome.ejs %> + <% include login.ejs %>
\ No newline at end of file diff --git a/app/assets/js/javaguard.js b/app/assets/js/javaguard.js new file mode 100644 index 00000000..69c8dfaa --- /dev/null +++ b/app/assets/js/javaguard.js @@ -0,0 +1,197 @@ +const cp = require('child_process') +const fs = require('fs') +const path = require('path') +const Registry = require('winreg') + +/** + * WIP -> get a valid x64 Java path on windows. + */ +async function _win32Validate(){ + + // Get possible paths from the registry. + const pathSet = await _scanRegistry() + + console.log(Array.from(pathSet)) // DEBUGGING + + // Validate JAVA_HOME + const jHome = _scanJavaHome() + if(jHome != null && jHome.indexOf('(x86)') === -1){ + pathSet.add(jHome) + } + + // Convert path set to an array for processing. + const pathArr = Array.from(pathSet) + + console.log(pathArr) // DEBUGGING + + // TODO - Determine best candidate (based on version, etc). + + + + let res = await _validateBinary(pathArr[0]) // DEBUGGING + console.log(res) // DEBUGGING + +} + +/** + * Validates that a Java binary is at least 64 bit. This makes use of the non-standard + * command line option -XshowSettings:properties. The output of this contains a property, + * sun.arch.data.model = ARCH, in which ARCH is either 32 or 64. This option is supported + * in Java 8 and 9. Since this is a non-standard option. This will resolve to true if + * the function's code throws errors. That would indicate that the option is changed or + * removed. + * + * @param {string} binaryPath Path to the root of the java binary we wish to validate. + * + * @returns {Promise.} Resolves to false only if the test is successful and the result + * is less than 64. + */ +function _validateBinary(binaryPath){ + + return new Promise((resolve, reject) => { + const fBp = path.join(binaryPath, 'bin', 'java.exe') + cp.exec('"' + fBp + '" -XshowSettings:properties', (err, stdout, stderr) => { + + try { + // Output is stored in stderr? + const res = stderr + const props = res.split('\n') + for(let i=0; i -1){ + let arch = props[i].split('=')[1].trim() + console.log(props[i].trim() + ' for ' + binaryPath) + resolve(parseInt(arch) >= 64) + } + } + + // sun.arch.data.model not found? + // Disregard this test. + resolve(true) + + } catch (err){ + + // Output format might have changed, validation cannot be completed. + // Disregard this test in that case. + resolve(true) + } + }) + }) + +} + +/** + * Checks for the presence of the environment variable JAVA_HOME. If it exits, we will check + * to see if the value points to a path which exists. If the path exits, the path is returned. + * + * @returns {string} The path defined by JAVA_HOME, if it exists. Otherwise null. + */ +function _scanJavaHome(){ + const jHome = process.env.JAVA_HOME + try { + let res = fs.existsSync(jHome) + return res ? jHome : null + } catch (err) { + // Malformed JAVA_HOME property. + return null + } +} + +/** + * Scans the registry for 64-bit Java entries. The paths of each entry are added to + * a set and returned. Currently, only Java 8 (1.8) is supported. + * + * @returns {Promise.>} A promise which resolves to a set of 64-bit Java root + * paths found in the registry. + */ +function _scanRegistry(){ + + return new Promise((resolve, reject) => { + // Keys for Java v9.0.0 and later: + // 'SOFTWARE\\JavaSoft\\JRE' + // 'SOFTWARE\\JavaSoft\\JDK' + // Forge does not yet support Java 9, therefore we do not. + + let cbTracker = 0 + let cbAcc = 0 + + // Keys for Java 1.8 and prior: + const regKeys = [ + '\\SOFTWARE\\JavaSoft\\Java Runtime Environment', + '\\SOFTWARE\\JavaSoft\\Java Development Kit' + ] + + const candidates = new Set() + + for(let i=0; i { + if(err){ + console.error(err) + if(i === regKeys.length-1){ + resolve(candidates) + } + } else { + cbTracker += javaVers.length + if(i === regKeys.length-1 && cbTracker === cbAcc){ + resolve(candidates) + } + for(let j=0; j { + const jHome = res.value + if(jHome.indexOf('(x86)') == -1){ + candidates.add(jHome) + cbAcc++ + } + if(cbAcc === cbTracker){ + resolve(candidates) + } + }) + } + } + } + }) + } + + }) + +} + +/** + * WIP -> get a valid x64 Java path on macOS. + */ +function _darwinValidate(){ + +} + +/** + * WIP -> get a valid x64 Java path on linux. + */ +function _linuxValidate(){ + +} + +// This will eventually return something. +async function validate(){ + const opSys = process.platform + if(opSys === 'win32'){ + await _win32Validate() + } else if(opSys === 'darwin'){ + _darwinValidate() + } else if(opSys === 'linux'){ + _linuxValidate() + } +} + +validate() + +module.exports = { + validate +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index bdca598b..2cf1bc6d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1253,14 +1253,6 @@ "pend": "1.2.0" } }, - "find-java-home": { - "version": "https://registry.npmjs.org/find-java-home/-/find-java-home-0.2.0.tgz", - "integrity": "sha1-XFALutMBiDKruYhvfQ8D9XFGzdw=", - "requires": { - "which": "https://registry.npmjs.org/which/-/which-1.0.9.tgz", - "winreg": "https://registry.npmjs.org/winreg/-/winreg-1.2.4.tgz" - } - }, "find-up": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", @@ -2856,10 +2848,6 @@ "extsprintf": "1.3.0" } }, - "which": { - "version": "https://registry.npmjs.org/which/-/which-1.0.9.tgz", - "integrity": "sha1-RgwdoPgQED0DIam2M6+eV15kSG8=" - }, "which-module": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", @@ -2909,7 +2897,8 @@ } }, "winreg": { - "version": "https://registry.npmjs.org/winreg/-/winreg-1.2.4.tgz", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/winreg/-/winreg-1.2.4.tgz", "integrity": "sha1-ugZWKbepJRMOFXeRCM9UCZDpjRs=" }, "wrap-ansi": { diff --git a/package.json b/package.json index e0349b33..ced96ad1 100644 --- a/package.json +++ b/package.json @@ -31,10 +31,10 @@ "discord-rpc": "^3.0.0-beta.8", "ejs": "^2.5.7", "ejs-electron": "^2.0.1", - "find-java-home": "^0.2.0", "jquery": "^3.3.1", "request-promise-native": "^1.0.5", - "uuid": "^3.2.1" + "uuid": "^3.2.1", + "winreg": "^1.2.4" }, "devDependencies": { "electron": "^1.8.4",