- Timestamp:
- 2014-07-26T03:50:31+02:00 (11 years ago)
- Location:
- trunk
- Files:
-
- 1 deleted
- 13 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/Main.java
r7294 r7335 1514 1514 return Main.platform instanceof PlatformHookOsx; 1515 1515 } 1516 1517 /** 1518 * Determines if we are currently running on Windows. 1519 * @return {@code true} if we are currently running on Windows 1520 * @since 7335 1521 */ 1522 public static boolean isPlatformWindows() { 1523 return Main.platform instanceof PlatformHookWindows; 1524 } 1516 1525 } -
trunk/src/org/openstreetmap/josm/actions/FullscreenToggleAction.java
r7005 r7335 21 21 22 22 import org.openstreetmap.josm.Main; 23 import org.openstreetmap.josm.tools.PlatformHookWindows;24 23 import org.openstreetmap.josm.tools.Shortcut; 25 24 … … 77 76 } 78 77 } 79 78 80 79 boolean selected = isSelected(); 81 80 … … 95 94 // screen by default (it's a simulated mode, but should be ok) 96 95 String exclusive = Main.pref.get("draw.fullscreen.exclusive-mode", "auto"); 97 if ("true".equals(exclusive) || ("auto".equals(exclusive) && ! (Main.platform instanceofPlatformHookWindows))) {96 if ("true".equals(exclusive) || ("auto".equals(exclusive) && !Main.isPlatformWindows())) { 98 97 gd.setFullScreenWindow(selected ? frame : null); 99 98 } -
trunk/src/org/openstreetmap/josm/actions/RestartAction.java
r7005 r7335 18 18 import org.openstreetmap.josm.gui.HelpAwareOptionPane.ButtonSpec; 19 19 import org.openstreetmap.josm.tools.ImageProvider; 20 import org.openstreetmap.josm.tools.PlatformHookWindows;21 20 import org.openstreetmap.josm.tools.Shortcut; 22 21 … … 76 75 // java binary 77 76 final String java = System.getProperty("java.home") + File.separator + "bin" + File.separator + 78 (Main. platform instanceofPlatformHookWindows ? "java.exe" : "java");77 (Main.isPlatformWindows() ? "java.exe" : "java"); 79 78 if (!new File(java).isFile()) { 80 79 throw new IOException("Unable to find suitable java runtime at "+java); -
trunk/src/org/openstreetmap/josm/actions/ShowStatusReportAction.java
r7318 r7335 31 31 import org.openstreetmap.josm.tools.OpenBrowser; 32 32 import org.openstreetmap.josm.tools.PlatformHookUnixoid; 33 import org.openstreetmap.josm.tools.PlatformHookWindows;34 33 import org.openstreetmap.josm.tools.Shortcut; 35 34 import org.openstreetmap.josm.tools.Utils; … … 105 104 try { 106 105 final String envJavaHome = System.getenv("JAVA_HOME"); 107 final String envJavaHomeAlt = Main. platform instanceofPlatformHookWindows ? "%JAVA_HOME%" : "${JAVA_HOME}";106 final String envJavaHomeAlt = Main.isPlatformWindows() ? "%JAVA_HOME%" : "${JAVA_HOME}"; 108 107 final String propJavaHome = System.getProperty("java.home"); 109 108 final String propJavaHomeAlt = "<java.home>"; … … 160 159 try { 161 160 Map<String, Setting<?>> settings = Main.pref.getAllSettings(); 162 settings.remove("osm-server.username");163 settings.remove("osm-server.password");164 settings.remove("oauth.access-token.key");165 settings.remove("oauth.access-token.secret");166 161 Set<String> keys = new HashSet<>(settings.keySet()); 167 162 for (String key : keys) { 168 if (key.startsWith("marker.show")) { 163 // Remove sensitive information from status report 164 if (key.startsWith("marker.show") || key.contains("username") || key.contains("password") || key.contains("access-token")) { 169 165 settings.remove(key); 170 166 } -
trunk/src/org/openstreetmap/josm/data/validation/OsmValidator.java
r7315 r7335 145 145 146 146 /** 147 * Returns the plugin'sdirectoryof the plugin147 * Returns the validator directory. 148 148 * 149 * @return The directory of the plugin149 * @return The validator directory 150 150 */ 151 151 public static String getValidatorDir() { -
trunk/src/org/openstreetmap/josm/gui/MainApplication.java
r7187 r7335 13 13 import java.awt.event.WindowEvent; 14 14 import java.io.File; 15 import java.io.IOException; 15 16 import java.io.InputStream; 16 17 import java.net.Authenticator; … … 19 20 import java.security.AllPermission; 20 21 import java.security.CodeSource; 22 import java.security.KeyStoreException; 23 import java.security.NoSuchAlgorithmException; 21 24 import java.security.PermissionCollection; 22 25 import java.security.Permissions; 23 26 import java.security.Policy; 27 import java.security.cert.CertificateException; 24 28 import java.util.ArrayList; 25 29 import java.util.Collection; … … 59 63 import org.openstreetmap.josm.tools.ImageProvider; 60 64 import org.openstreetmap.josm.tools.OsmUrlToBounds; 65 import org.openstreetmap.josm.tools.PlatformHookWindows; 61 66 import org.openstreetmap.josm.tools.Utils; 62 67 … … 323 328 // Enable JOSM debug level 324 329 logLevel = 4; 325 // Enable debug in OAuth signpost326 Preferences.updateSystemProperty("debug", "true");327 330 Main.info(tr("Printing debugging messages to console")); 328 331 } … … 331 334 // Enable JOSM debug level 332 335 logLevel = 5; 336 // Enable debug in OAuth signpost via system preference, but only at trace level 337 Preferences.updateSystemProperty("debug", "true"); 333 338 Main.info(tr("Enabled detailed debug level (trace)")); 334 339 } … … 435 440 436 441 SwingUtilities.invokeLater(new GuiFinalizationWorker(args, proxySelector)); 442 443 if (Main.isPlatformWindows()) { 444 try { 445 // Check for insecure certificates to remove. 446 // This is Windows-dependant code but it can't go to preStartupHook (need i18n) neither startupHook (need to be called before remote control) 447 ((PlatformHookWindows)Main.platform).removeInsecureCertificates(); 448 } catch (NoSuchAlgorithmException | CertificateException | KeyStoreException | IOException e) { 449 error(e); 450 } 451 } 437 452 438 453 if (RemoteControl.PROP_REMOTECONTROL_ENABLED.get()) { -
trunk/src/org/openstreetmap/josm/gui/preferences/remotecontrol/RemoteControlPreference.java
r7005 r7335 28 28 import org.openstreetmap.josm.io.remotecontrol.PermissionPrefWithDefault; 29 29 import org.openstreetmap.josm.io.remotecontrol.RemoteControl; 30 import org.openstreetmap.josm.io.remotecontrol.RemoteControlHttpsServer; 30 31 import org.openstreetmap.josm.io.remotecontrol.handler.RequestHandler; 31 32 import org.openstreetmap.josm.tools.GBC; … … 59 60 private final Map<PermissionPrefWithDefault, JCheckBox> prefs = new LinkedHashMap<>(); 60 61 private JCheckBox enableRemoteControl; 62 private JCheckBox enableHttpsSupport; 61 63 private JCheckBox loadInNewLayer = new JCheckBox(tr("Download objects to new layer")); 62 64 private JCheckBox alwaysAskUserConfirm = new JCheckBox(tr("Confirm all Remote Control actions manually")); … … 89 91 remote.add(wrapper, GBC.eol().fill(GBC.HORIZONTAL).insets(5, 5, 5, 5)); 90 92 91 wrapper.add(new JLabel(tr("Permitted actions:")), GBC.eol()); 93 enableHttpsSupport = new JCheckBox(tr("Enable HTTPS support"), RemoteControl.PROP_REMOTECONTROL_HTTPS_ENABLED.get()); 94 wrapper.add(enableHttpsSupport, GBC.eol().fill(GBC.HORIZONTAL)); 95 wrapper.add(new JSeparator(), GBC.eop().fill(GBC.HORIZONTAL).insets(15, 5, 15, 5)); 96 97 wrapper.add(new JLabel(tr("Permitted actions:")), GBC.eol().insets(5, 0, 0, 0)); 92 98 for (JCheckBox p : prefs.values()) { 93 99 wrapper.add(p, GBC.eol().insets(15, 5, 0, 0).fill(GBC.HORIZONTAL)); … … 120 126 public boolean ok() { 121 127 boolean enabled = enableRemoteControl.isSelected(); 128 boolean httpsEnabled = enableHttpsSupport.isSelected(); 122 129 boolean changed = RemoteControl.PROP_REMOTECONTROL_ENABLED.put(enabled); 130 boolean httpsChanged = RemoteControl.PROP_REMOTECONTROL_HTTPS_ENABLED.put(httpsEnabled); 123 131 if (enabled) { 124 132 for (Entry<PermissionPrefWithDefault, JCheckBox> p : prefs.entrySet()) { … … 134 142 RemoteControl.stop(); 135 143 } 144 } else if (httpsChanged) { 145 if (httpsEnabled) { 146 RemoteControlHttpsServer.restartRemoteControlHttpsServer(); 147 } else { 148 RemoteControlHttpsServer.stopRemoteControlHttpsServer(); 149 } 136 150 } 137 151 return false; -
trunk/src/org/openstreetmap/josm/io/remotecontrol/RemoteControl.java
r6941 r7335 2 2 package org.openstreetmap.josm.io.remotecontrol; 3 3 4 import org.openstreetmap.josm.Main; 4 5 import org.openstreetmap.josm.data.preferences.BooleanProperty; 5 6 import org.openstreetmap.josm.io.remotecontrol.handler.RequestHandler; … … 11 12 * and increment the major version and set minor to 0 on incompatible changes. 12 13 */ 13 public class RemoteControl 14 { 14 public class RemoteControl { 15 15 16 /** 16 17 * If the remote control feature is enabled or disabled. If disabled, … … 18 19 */ 19 20 public static final BooleanProperty PROP_REMOTECONTROL_ENABLED = new BooleanProperty("remotecontrol.enabled", false); 21 22 /** 23 * If the remote control feature is enabled or disabled for HTTPS. If disabled, 24 * only HTTP access will be available. 25 * @since 7335 26 */ 27 public static final BooleanProperty PROP_REMOTECONTROL_HTTPS_ENABLED = new BooleanProperty("remotecontrol.https.enabled", false); 20 28 21 29 /** … … 54 62 RequestProcessor.addRequestHandlerClass(command, handlerClass); 55 63 } 64 65 /** 66 * Returns the remote control directory. 67 * @return The remote control directory 68 * @since 7335 69 */ 70 public static String getRemoteControlDir() { 71 return Main.pref.getPreferencesDir() + "remotecontrol/"; 72 } 56 73 } -
trunk/src/org/openstreetmap/josm/io/remotecontrol/RemoteControlHttpsServer.java
r7206 r7335 7 7 import java.io.IOException; 8 8 import java.io.InputStream; 9 import java.math.BigInteger; 9 10 import java.net.BindException; 10 11 import java.net.InetAddress; … … 12 13 import java.net.Socket; 13 14 import java.net.SocketException; 14 import java.security.Key; 15 import java.security.KeyManagementException; 15 import java.nio.file.Files; 16 import java.nio.file.Path; 17 import java.nio.file.Paths; 18 import java.nio.file.StandardOpenOption; 19 import java.security.GeneralSecurityException; 20 import java.security.KeyPair; 21 import java.security.KeyPairGenerator; 16 22 import java.security.KeyStore; 17 import java.security.KeyStoreException;18 23 import java.security.NoSuchAlgorithmException; 19 24 import java.security.PrivateKey; 20 import java.security. UnrecoverableEntryException;25 import java.security.SecureRandom; 21 26 import java.security.cert.Certificate; 22 import java.security.cert.Certificate Exception;27 import java.security.cert.X509Certificate; 23 28 import java.util.Arrays; 29 import java.util.Date; 24 30 import java.util.Enumeration; 31 import java.util.Vector; 25 32 26 33 import javax.net.ssl.KeyManagerFactory; … … 32 39 33 40 import org.openstreetmap.josm.Main; 41 import org.openstreetmap.josm.data.preferences.StringProperty; 42 43 import sun.security.util.ObjectIdentifier; 44 import sun.security.x509.AlgorithmId; 45 import sun.security.x509.BasicConstraintsExtension; 46 import sun.security.x509.CertificateAlgorithmId; 47 import sun.security.x509.CertificateExtensions; 48 import sun.security.x509.CertificateIssuerName; 49 import sun.security.x509.CertificateSerialNumber; 50 import sun.security.x509.CertificateSubjectName; 51 import sun.security.x509.CertificateValidity; 52 import sun.security.x509.CertificateVersion; 53 import sun.security.x509.CertificateX509Key; 54 import sun.security.x509.DNSName; 55 import sun.security.x509.ExtendedKeyUsageExtension; 56 import sun.security.x509.GeneralName; 57 import sun.security.x509.GeneralNameInterface; 58 import sun.security.x509.GeneralNames; 59 import sun.security.x509.IPAddressName; 60 import sun.security.x509.OIDName; 61 import sun.security.x509.SubjectAlternativeNameExtension; 62 import sun.security.x509.URIName; 63 import sun.security.x509.X500Name; 64 import sun.security.x509.X509CertImpl; 65 import sun.security.x509.X509CertInfo; 34 66 35 67 /** … … 47 79 private SSLContext sslContext; 48 80 49 private static final String KEYSTORE_PATH = "/data/josm.keystore"; 50 private static final String KEYSTORE_PASSWORD = "josm_ssl"; 81 private static final String KEYSTORE_FILENAME = "josm.keystore"; 82 83 /** 84 * Preference for keystore password (automatically generated by JOSM). 85 * @since 7335 86 */ 87 public StringProperty KEYSTORE_PASSWORD = new StringProperty("remotecontrol.https.keystore.password", ""); 88 89 /** 90 * Preference for certificate password (automatically generated by JOSM). 91 * @since 7335 92 */ 93 public StringProperty KEYENTRY_PASSWORD = new StringProperty("remotecontrol.https.keyentry.password", ""); 94 95 /** 96 * Creates a GeneralName object from known types. 97 * @param t one of 4 known types 98 * @param v value 99 * @return which one 100 * @throws IOException 101 */ 102 private static GeneralName createGeneralName(String t, String v) throws IOException { 103 GeneralNameInterface gn; 104 switch (t.toLowerCase()) { 105 case "uri": gn = new URIName(v); break; 106 case "dns": gn = new DNSName(v); break; 107 case "ip": gn = new IPAddressName(v); break; 108 default: gn = new OIDName(v); 109 } 110 return new GeneralName(gn); 111 } 112 113 /** 114 * Create a self-signed X.509 Certificate. 115 * @param dn the X.509 Distinguished Name, eg "CN=localhost, OU=JOSM, O=OpenStreetMap" 116 * @param pair the KeyPair 117 * @param days how many days from now the Certificate is valid for 118 * @param algorithm the signing algorithm, eg "SHA256withRSA" 119 * @param san SubjectAlternativeName extension (optional) 120 */ 121 private static X509Certificate generateCertificate(String dn, KeyPair pair, int days, String algorithm, String san) throws GeneralSecurityException, IOException { 122 PrivateKey privkey = pair.getPrivate(); 123 X509CertInfo info = new X509CertInfo(); 124 Date from = new Date(); 125 Date to = new Date(from.getTime() + days * 86400000l); 126 CertificateValidity interval = new CertificateValidity(from, to); 127 BigInteger sn = new BigInteger(64, new SecureRandom()); 128 X500Name owner = new X500Name(dn); 129 130 info.set(X509CertInfo.VALIDITY, interval); 131 info.set(X509CertInfo.SERIAL_NUMBER, new CertificateSerialNumber(sn)); 132 info.set(X509CertInfo.SUBJECT, new CertificateSubjectName(owner)); 133 info.set(X509CertInfo.ISSUER, new CertificateIssuerName(owner)); 134 info.set(X509CertInfo.KEY, new CertificateX509Key(pair.getPublic())); 135 info.set(X509CertInfo.VERSION, new CertificateVersion(CertificateVersion.V3)); 136 AlgorithmId algo = new AlgorithmId(AlgorithmId.md5WithRSAEncryption_oid); 137 info.set(X509CertInfo.ALGORITHM_ID, new CertificateAlgorithmId(algo)); 138 139 CertificateExtensions ext = new CertificateExtensions(); 140 // Critical: Not CA, max path len 0 141 ext.set(BasicConstraintsExtension.NAME, new BasicConstraintsExtension(true, false, 0)); 142 // Critical: only allow TLS ("serverAuth" = 1.3.6.1.5.5.7.3.1) 143 ext.set(ExtendedKeyUsageExtension.NAME, new ExtendedKeyUsageExtension(true, 144 new Vector<ObjectIdentifier>(Arrays.asList(new ObjectIdentifier("1.3.6.1.5.5.7.3.1"))))); 145 146 if (san != null) { 147 int colonpos; 148 String[] ps = san.split(","); 149 GeneralNames gnames = new GeneralNames(); 150 for(String item: ps) { 151 colonpos = item.indexOf(':'); 152 if (colonpos < 0) { 153 throw new IllegalArgumentException("Illegal item " + item + " in " + san); 154 } 155 String t = item.substring(0, colonpos); 156 String v = item.substring(colonpos+1); 157 gnames.add(createGeneralName(t, v)); 158 } 159 // Non critical 160 ext.set(SubjectAlternativeNameExtension.NAME, new SubjectAlternativeNameExtension(false, gnames)); 161 } 162 163 info.set(X509CertInfo.EXTENSIONS, ext); 164 165 // Sign the cert to identify the algorithm that's used. 166 X509CertImpl cert = new X509CertImpl(info); 167 cert.sign(privkey, algorithm); 168 169 // Update the algorithm, and resign. 170 algo = (AlgorithmId)cert.get(X509CertImpl.SIG_ALG); 171 info.set(CertificateAlgorithmId.NAME + "." + CertificateAlgorithmId.ALGORITHM, algo); 172 cert = new X509CertImpl(info); 173 cert.sign(privkey, algorithm); 174 return cert; 175 } 51 176 52 177 private void initialize() { 53 178 if (!initOK) { 54 179 try { 55 // Create new keystore 56 KeyStore ks = KeyStore.getInstance("JKS"); 57 char[] password = KEYSTORE_PASSWORD.toCharArray(); 58 59 // Load keystore generated with Java 7 keytool as follows: 60 // keytool -genkeypair -storepass josm_ssl -keypass josm_ssl -alias josm_localhost -dname "CN=localhost, OU=JOSM, O=OpenStreetMap" 61 // -ext san=ip:127.0.0.1 -keyalg RSA -validity 1825 62 try (InputStream in = RemoteControlHttpsServer.class.getResourceAsStream(KEYSTORE_PATH)) { 63 if (in == null) { 64 Main.error(tr("Unable to find JOSM keystore at {0}. Remote control will not be available on HTTPS.", KEYSTORE_PATH)); 65 } else { 66 ks.load(in, password); 67 68 if (Main.isDebugEnabled()) { 69 for (Enumeration<String> aliases = ks.aliases(); aliases.hasMoreElements();) { 70 Main.debug("Alias in keystore: "+aliases.nextElement()); 71 } 180 char[] storePassword = KEYSTORE_PASSWORD.get().toCharArray(); 181 char[] entryPassword = KEYENTRY_PASSWORD.get().toCharArray(); 182 183 Path dir = Paths.get(RemoteControl.getRemoteControlDir()); 184 Path path = dir.resolve(KEYSTORE_FILENAME); 185 Files.createDirectories(dir); 186 187 if (!Files.exists(path)) { 188 Main.debug("No keystore found, creating a new one"); 189 190 // Create new keystore like previous one generated with JDK keytool as follows: 191 // keytool -genkeypair -storepass josm_ssl -keypass josm_ssl -alias josm_localhost -dname "CN=localhost, OU=JOSM, O=OpenStreetMap" 192 // -ext san=ip:127.0.0.1 -keyalg RSA -validity 1825 193 194 KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA"); 195 generator.initialize(2048); 196 KeyPair pair = generator.generateKeyPair(); 197 198 X509Certificate cert = generateCertificate("CN=localhost, OU=JOSM, O=OpenStreetMap", pair, 1825, "SHA256withRSA", "ip:127.0.0.1"); 199 200 KeyStore ks = KeyStore.getInstance("JKS"); 201 ks.load(null, null); 202 203 // Generate new passwords. See https://stackoverflow.com/a/41156/2257172 204 SecureRandom random = new SecureRandom(); 205 KEYSTORE_PASSWORD.put(new BigInteger(130, random).toString(32)); 206 KEYENTRY_PASSWORD.put(new BigInteger(130, random).toString(32)); 207 208 storePassword = KEYSTORE_PASSWORD.get().toCharArray(); 209 entryPassword = KEYENTRY_PASSWORD.get().toCharArray(); 210 211 ks.setKeyEntry("josm_localhost", pair.getPrivate(), entryPassword, new Certificate[]{cert}); 212 ks.store(Files.newOutputStream(path, StandardOpenOption.CREATE), storePassword); 213 } 214 215 try (InputStream in = Files.newInputStream(path)) { 216 // Load keystore 217 KeyStore ks = KeyStore.getInstance("JKS"); 218 ks.load(in, storePassword); 219 220 if (Main.isDebugEnabled()) { 221 for (Enumeration<String> aliases = ks.aliases(); aliases.hasMoreElements();) { 222 Main.debug("Alias in keystore: "+aliases.nextElement()); 72 223 } 73 74 KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");75 kmf.init(ks, password);76 77 TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");78 tmf.init(ks);79 80 sslContext = SSLContext.getInstance("TLS");81 sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);82 83 if (Main.isDebugEnabled()) {84 Main.debug("SSL Context protocol: " + sslContext.getProtocol());85 Main.debug("SSL Context provider: " + sslContext.getProvider());86 }87 88 Enumeration<String> aliases = ks.aliases();89 if (aliases.hasMoreElements()) {90 String aliasKey = aliases.nextElement();91 Key key = ks.getKey(aliasKey, password);92 Certificate[] chain = ks.getCertificateChain(aliasKey);93 Main.platform.setupHttpsCertificate(new KeyStore.PrivateKeyEntry((PrivateKey) key, chain));94 }95 96 initOK = true;97 224 } 98 } 99 } catch (KeyStoreException | NoSuchAlgorithmException | CertificateException | 100 IOException | KeyManagementException | UnrecoverableEntryException e) { 225 226 KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); 227 kmf.init(ks, entryPassword); 228 229 TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); 230 tmf.init(ks); 231 232 sslContext = SSLContext.getInstance("TLS"); 233 sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); 234 235 if (Main.isTraceEnabled()) { 236 Main.trace("SSL Context protocol: " + sslContext.getProtocol()); 237 Main.trace("SSL Context provider: " + sslContext.getProvider()); 238 } 239 240 Enumeration<String> aliases = ks.aliases(); 241 if (aliases.hasMoreElements()) { 242 Main.platform.setupHttpsCertificate(new KeyStore.TrustedCertificateEntry(ks.getCertificate(aliases.nextElement()))); 243 } 244 245 initOK = true; 246 } 247 } catch (IOException | GeneralSecurityException e) { 101 248 Main.error(e); 102 249 } … … 112 259 stopRemoteControlHttpsServer(); 113 260 114 instance = new RemoteControlHttpsServer(port); 115 if (instance.initOK) { 116 instance.start(); 261 if (RemoteControl.PROP_REMOTECONTROL_HTTPS_ENABLED.get()) { 262 instance = new RemoteControlHttpsServer(port); 263 if (instance.initOK) { 264 instance.start(); 265 } 117 266 } 118 267 } catch (BindException ex) { … … 152 301 initialize(); 153 302 303 if (!initOK) { 304 Main.error(tr("Unable to initialize Remote Control HTTPS Server")); 305 return; 306 } 307 154 308 // Create SSL Server factory 155 309 SSLServerSocketFactory factory = sslContext.getServerSocketFactory(); 156 if (Main.is DebugEnabled()) {157 Main. debug("SSL factory - Supported Cipher suites: "+Arrays.toString(factory.getSupportedCipherSuites()));310 if (Main.isTraceEnabled()) { 311 Main.trace("SSL factory - Supported Cipher suites: "+Arrays.toString(factory.getSupportedCipherSuites())); 158 312 } 159 313 … … 165 319 InetAddress.getByName(Main.pref.get("remote.control.host", "localhost"))); 166 320 167 if (Main.is DebugEnabled() && server instanceof SSLServerSocket) {321 if (Main.isTraceEnabled() && server instanceof SSLServerSocket) { 168 322 SSLServerSocket sslServer = (SSLServerSocket) server; 169 Main. debug("SSL server - Enabled Cipher suites: "+Arrays.toString(sslServer.getEnabledCipherSuites()));170 Main. debug("SSL server - Enabled Protocols: "+Arrays.toString(sslServer.getEnabledProtocols()));171 Main. debug("SSL server - Enable Session Creation: "+sslServer.getEnableSessionCreation());172 Main. debug("SSL server - Need Client Auth: "+sslServer.getNeedClientAuth());173 Main. debug("SSL server - Want Client Auth: "+sslServer.getWantClientAuth());174 Main. debug("SSL server - Use Client Mode: "+sslServer.getUseClientMode());323 Main.trace("SSL server - Enabled Cipher suites: "+Arrays.toString(sslServer.getEnabledCipherSuites())); 324 Main.trace("SSL server - Enabled Protocols: "+Arrays.toString(sslServer.getEnabledProtocols())); 325 Main.trace("SSL server - Enable Session Creation: "+sslServer.getEnableSessionCreation()); 326 Main.trace("SSL server - Need Client Auth: "+sslServer.getNeedClientAuth()); 327 Main.trace("SSL server - Want Client Auth: "+sslServer.getWantClientAuth()); 328 Main.trace("SSL server - Use Client Mode: "+sslServer.getUseClientMode()); 175 329 } 176 330 } … … 187 341 @SuppressWarnings("resource") 188 342 Socket request = server.accept(); 189 if (Main.is DebugEnabled() && request instanceof SSLSocket) {343 if (Main.isTraceEnabled() && request instanceof SSLSocket) { 190 344 SSLSocket sslSocket = (SSLSocket) request; 191 Main. debug("SSL socket - Enabled Cipher suites: "+Arrays.toString(sslSocket.getEnabledCipherSuites()));192 Main. debug("SSL socket - Enabled Protocols: "+Arrays.toString(sslSocket.getEnabledProtocols()));193 Main. debug("SSL socket - Enable Session Creation: "+sslSocket.getEnableSessionCreation());194 Main. debug("SSL socket - Need Client Auth: "+sslSocket.getNeedClientAuth());195 Main. debug("SSL socket - Want Client Auth: "+sslSocket.getWantClientAuth());196 Main. debug("SSL socket - Use Client Mode: "+sslSocket.getUseClientMode());197 Main. debug("SSL socket - Session: "+sslSocket.getSession());345 Main.trace("SSL socket - Enabled Cipher suites: "+Arrays.toString(sslSocket.getEnabledCipherSuites())); 346 Main.trace("SSL socket - Enabled Protocols: "+Arrays.toString(sslSocket.getEnabledProtocols())); 347 Main.trace("SSL socket - Enable Session Creation: "+sslSocket.getEnableSessionCreation()); 348 Main.trace("SSL socket - Need Client Auth: "+sslSocket.getNeedClientAuth()); 349 Main.trace("SSL socket - Want Client Auth: "+sslSocket.getWantClientAuth()); 350 Main.trace("SSL socket - Use Client Mode: "+sslSocket.getUseClientMode()); 351 Main.trace("SSL socket - Session: "+sslSocket.getSession()); 198 352 } 199 353 RequestProcessor.processRequest(request); … … 214 368 */ 215 369 public void stopServer() throws IOException { 216 server.close(); 217 Main.info(marktr("RemoteControl::Server (https) stopped.")); 370 if (server != null) { 371 server.close(); 372 Main.info(marktr("RemoteControl::Server (https) stopped.")); 373 } 218 374 } 219 375 } -
trunk/src/org/openstreetmap/josm/tools/OpenBrowser.java
r7029 r7335 44 44 if (Desktop.isDesktopSupported()) { 45 45 try { 46 if (Main. platform instanceofPlatformHookWindows) {46 if (Main.isPlatformWindows()) { 47 47 // Desktop API works fine under Windows, so we don't try any fallback in case of I/O exceptions because it's not API's fault 48 48 Desktop.getDesktop().browse(uri); -
trunk/src/org/openstreetmap/josm/tools/PlatformHook.java
r7206 r7335 109 109 /** 110 110 * Setup system keystore to add JOSM HTTPS certificate (for remote control). 111 * @param privateKeyEntrythe JOSM certificate for localhostand associated private key111 * @param trustedCert the JOSM certificate for localhost 112 112 * @throws KeyStoreException in case of error 113 113 * @throws IOException in case of error … … 116 116 * @since 7206 117 117 */ 118 public void setupHttpsCertificate(KeyStore. PrivateKeyEntry privateKeyEntry)118 public void setupHttpsCertificate(KeyStore.TrustedCertificateEntry trustedCert) 119 119 throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException; 120 120 } -
trunk/src/org/openstreetmap/josm/tools/PlatformHookUnixoid.java
r7318 r7335 358 358 359 359 @Override 360 public void setupHttpsCertificate(KeyStore. PrivateKeyEntry privateKeyEntry)360 public void setupHttpsCertificate(KeyStore.TrustedCertificateEntry trustedCert) 361 361 throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException { 362 362 // TODO setup HTTPS certificate on Unix systems -
trunk/src/org/openstreetmap/josm/tools/PlatformHookWindows.java
r7206 r7335 30 30 import java.io.File; 31 31 import java.io.IOException; 32 import java.security.InvalidKeyException; 33 import java.security.KeyFactory; 32 34 import java.security.KeyStore; 33 35 import java.security.KeyStoreException; 34 36 import java.security.NoSuchAlgorithmException; 35 import java.security.cert.Certificate; 37 import java.security.NoSuchProviderException; 38 import java.security.PublicKey; 39 import java.security.SignatureException; 36 40 import java.security.cert.CertificateException; 41 import java.security.spec.InvalidKeySpecException; 42 import java.security.spec.X509EncodedKeySpec; 43 import java.util.ArrayList; 44 import java.util.Collection; 37 45 import java.util.Enumeration; 46 47 import javax.swing.JOptionPane; 38 48 39 49 import org.openstreetmap.josm.Main; … … 44 54 */ 45 55 public class PlatformHookWindows extends PlatformHookUnixoid implements PlatformHook { 56 57 private static final byte[] INSECURE_PUBLIC_KEY = new byte[] { 58 0x30, (byte) 0x82, 0x1, 0x22, 0x30, 0xd, 0x6, 0x9, 0x2a, (byte) 0x86, 0x48, (byte) 0x86, (byte) 0xf7, 0xd, 0x1, 0x1, 0x1, 0x5, 0x0, 0x3, (byte) 0x82, 0x1, 0xf, 0x0, 59 0x30, (byte) 0x82, 0x01, 0x0a, 0x02, (byte) 0x82, 0x01, 0x01, 0x00, (byte) 0x95, (byte) 0x95, (byte) 0x88, 60 (byte) 0x84, (byte) 0xc8, (byte) 0xd9, 0x6b, (byte) 0xc5, (byte) 0xda, 0x0b, 0x69, (byte) 0xbf, (byte) 0xfc, 0x7e, (byte) 0xb9, (byte) 0x96, 0x2c, (byte) 0xeb, (byte) 0x8f, 61 (byte) 0xbc, 0x6e, 0x40, (byte) 0xe6, (byte) 0xe2, (byte) 0xfc, (byte) 0xf1, 0x7f, 0x73, (byte) 0xa7, (byte) 0x9d, (byte) 0xde, (byte) 0xc7, (byte) 0x88, 62 0x57, 0x51, (byte) 0x84, (byte) 0xed, (byte) 0x96, (byte) 0xfb, (byte) 0xe1, 0x38, (byte) 0xef, 0x08, 0x2b, (byte) 0xf3, (byte) 0xc7, (byte) 0xc3, 63 0x5d, (byte) 0xfe, (byte) 0xf9, 0x51, (byte) 0xe6, 0x29, (byte) 0xfc, (byte) 0xe5, 0x0d, (byte) 0xa1, 0x0d, (byte) 0xa8, (byte) 0xb4, (byte) 0xae, 64 0x26, 0x18, 0x19, 0x4d, 0x6c, 0x0c, 0x3b, 0x12, (byte) 0xba, (byte) 0xbc, 0x5f, 0x32, (byte) 0xb3, (byte) 0xbe, 65 (byte) 0x9d, 0x17, 0x0d, 0x4d, 0x2f, 0x1a, 0x48, (byte) 0xb7, (byte) 0xac, (byte) 0xf7, 0x1a, 0x43, 0x01, (byte) 0x97, 66 (byte) 0xf4, (byte) 0xf8, 0x4c, (byte) 0xbb, 0x6a, (byte) 0xbc, 0x33, (byte) 0xe1, 0x73, 0x1e, (byte) 0x86, (byte) 0xfb, 0x2e, (byte) 0xb1, 67 0x63, 0x75, (byte) 0x85, (byte) 0xdc, (byte) 0x82, 0x6c, 0x28, (byte) 0xf1, (byte) 0xe3, (byte) 0x90, 0x63, (byte) 0x9d, 0x3d, 0x48, 68 (byte) 0x8a, (byte) 0x8c, 0x47, (byte) 0xe2, 0x10, 0x0b, (byte) 0xef, (byte) 0x91, (byte) 0x94, (byte) 0xb0, 0x6c, 0x4c, (byte) 0x80, 0x76, 69 0x03, (byte) 0xe1, (byte) 0xb6, (byte) 0x90, (byte) 0x87, (byte) 0xd9, (byte) 0xae, (byte) 0xf4, (byte) 0x8e, (byte) 0xe0, (byte) 0x9f, (byte) 0xe7, 0x3a, 0x2c, 70 0x2f, 0x21, (byte) 0xd4, 0x46, (byte) 0xba, (byte) 0x95, 0x70, (byte) 0xa9, 0x5b, 0x20, 0x2a, (byte) 0xfa, 0x52, 0x3e, 71 (byte) 0x9d, (byte) 0xd9, (byte) 0xef, 0x28, (byte) 0xc5, (byte) 0xd1, 0x60, (byte) 0x89, 0x68, 0x6e, 0x7f, (byte) 0xd7, (byte) 0x9e, (byte) 0x89, 72 0x4c, (byte) 0xeb, 0x4d, (byte) 0xd2, (byte) 0xc6, (byte) 0xf4, 0x2d, 0x02, 0x5d, (byte) 0xda, (byte) 0xde, 0x33, (byte) 0xfe, (byte) 0xc1, 73 0x7e, (byte) 0xde, 0x4f, 0x1f, (byte) 0x9b, 0x6e, 0x6f, 0x0f, 0x66, 0x71, 0x19, (byte) 0xe9, 0x43, 0x3c, 74 (byte) 0x83, 0x0a, 0x0f, 0x28, 0x21, (byte) 0xc8, 0x38, (byte) 0xd3, 0x4e, 0x48, (byte) 0xdf, (byte) 0xd4, (byte) 0x99, (byte) 0xb5, 75 (byte) 0xc6, (byte) 0x8d, (byte) 0xd4, (byte) 0xc1, 0x69, 0x58, 0x79, (byte) 0x82, 0x32, (byte) 0x82, (byte) 0xd4, (byte) 0x86, (byte) 0xe2, 0x04, 76 0x08, 0x63, (byte) 0x87, (byte) 0xf0, 0x2a, (byte) 0xf6, (byte) 0xec, 0x3e, 0x51, 0x0f, (byte) 0xda, (byte) 0xb4, 0x67, 0x19, 77 0x5e, 0x16, 0x02, (byte) 0x9f, (byte) 0xf1, 0x19, 0x0c, 0x3e, (byte) 0xb8, 0x04, 0x49, 0x07, 0x53, 0x02, 78 0x03, 0x01, 0x00, 0x01 79 }; 80 81 private static final String WINDOWS_ROOT = "Windows-ROOT"; 46 82 47 83 @Override … … 138 174 } 139 175 140 @Override 141 public void setupHttpsCertificate(KeyStore.PrivateKeyEntry privateKeyEntry) 142 throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException { 143 KeyStore ks = KeyStore.getInstance("Windows-ROOT"); 176 /** 177 * Loads Windows-ROOT keystore. 178 * @return Windows-ROOT keystore 179 * @throws NoSuchAlgorithmException if the algorithm used to check the integrity of the keystore cannot be found 180 * @throws CertificateException if any of the certificates in the keystore could not be loaded 181 * @throws IOException if there is an I/O or format problem with the keystore data, if a password is required but not given 182 * @throws KeyStoreException if no Provider supports a KeyStore implementation for the type "Windows-ROOT" 183 */ 184 private KeyStore getWindowsKeystore() throws NoSuchAlgorithmException, CertificateException, IOException, KeyStoreException { 185 KeyStore ks = KeyStore.getInstance(WINDOWS_ROOT); 144 186 ks.load(null, null); 187 return ks; 188 } 189 190 /** 191 * Removes potential insecure certificates installed with previous versions of JOSM on Windows. 192 * @throws NoSuchAlgorithmException on unsupported signature algorithms 193 * @throws CertificateException if any of the certificates in the Windows keystore could not be loaded 194 * @throws KeyStoreException if no Provider supports a KeyStoreSpi implementation for the type "Windows-ROOT" 195 * @throws IOException if there is an I/O or format problem with the keystore data, if a password is required but not given 196 * @since 7335 197 */ 198 public void removeInsecureCertificates() throws NoSuchAlgorithmException, CertificateException, KeyStoreException, IOException { 199 // We offered before a public private key we need now to remove from Windows PCs as it might be a huge security risk (see #10230) 200 PublicKey insecurePubKey = null; 201 try { 202 insecurePubKey = KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(INSECURE_PUBLIC_KEY)); 203 } catch (InvalidKeySpecException | NoSuchAlgorithmException e) { 204 Main.error(e); 205 return; 206 } 207 KeyStore ks = getWindowsKeystore(); 145 208 Enumeration<String> en = ks.aliases(); 209 Collection<String> insecureCertificates = new ArrayList<>(); 146 210 while (en.hasMoreElements()) { 147 211 String alias = en.nextElement(); 148 Certificate c = ks.getCertificate(alias); 149 if (ks.isKeyEntry(alias) && c.equals(privateKeyEntry.getCertificate())) { 212 // Look for certificates associated with a private key 213 if (ks.isKeyEntry(alias)) { 214 try { 215 ks.getCertificate(alias).verify(insecurePubKey); 216 // If no exception, this is a certificate signed with the insecure key -> remove it 217 insecureCertificates.add(alias); 218 } catch (InvalidKeyException | NoSuchProviderException | SignatureException e) { 219 // If exception this is not a certificate related to JOSM, just trace it 220 Main.trace(alias + " --> " + e.getClass().getName()); 221 } 222 } 223 } 224 // Remove insecure certificates 225 if (!insecureCertificates.isEmpty()) { 226 StringBuilder message = new StringBuilder("<html>"); 227 message.append(tr("A previous version of JOSM has installed a custom certificate in order to provide HTTPS support for Remote Control:")); 228 message.append("<br><ul>"); 229 for (String alias : insecureCertificates) { 230 message.append("<li>"); 231 message.append(alias); 232 message.append("</li>"); 233 } 234 message.append("</ul>"); 235 message.append(tr("It appears it could be an important <b>security risk</b>.<br><br>"+ 236 "You are now going to be prompted by Windows to remove this insecure certificate.<br>For your own safety, <b>please click Yes</b> in next dialog.")); 237 message.append("</html>"); 238 JOptionPane.showMessageDialog(Main.parent, message.toString(), tr("Warning"), JOptionPane.WARNING_MESSAGE); 239 for (String alias : insecureCertificates) { 240 Main.warn(tr("Removing insecure certificate from {0} keystore: {1}", WINDOWS_ROOT, alias)); 241 try { 242 ks.deleteEntry(alias); 243 } catch (KeyStoreException e) { 244 Main.error(tr("Unable to remove insecure certificate from keystore: {0}", e.getMessage())); 245 } 246 } 247 } 248 } 249 250 @Override 251 public void setupHttpsCertificate(KeyStore.TrustedCertificateEntry trustedCert) 252 throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException { 253 KeyStore ks = getWindowsKeystore(); 254 Enumeration<String> en = ks.aliases(); 255 256 while (en.hasMoreElements()) { 257 String alias = en.nextElement(); 258 // Look for certificate to install 259 if (ks.isKeyEntry(alias) && ks.getCertificate(alias).equals(trustedCert.getTrustedCertificate())) { 150 260 // JOSM certificate found, return 151 261 return; … … 153 263 } 154 264 // JOSM certificate not found, install it 155 Main.info("Adding JOSM localhost certificate to Windows-ROOTkeystore");156 ks.setEntry("josm_localhost", privateKeyEntry, new KeyStore.PasswordProtection("josm_ssl".toCharArray()));265 Main.info(tr("Adding JOSM localhost certificate to {0} keystore", WINDOWS_ROOT)); 266 ks.setEntry("josm_localhost", trustedCert, null); 157 267 } 158 268 }
Note:
See TracChangeset
for help on using the changeset viewer.