001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.io.remotecontrol; 003 004import java.io.File; 005import java.net.Inet4Address; 006import java.net.Inet6Address; 007import java.net.InetAddress; 008import java.net.UnknownHostException; 009 010import org.openstreetmap.josm.data.preferences.BooleanProperty; 011import org.openstreetmap.josm.io.remotecontrol.handler.RequestHandler; 012import org.openstreetmap.josm.spi.preferences.Config; 013import org.openstreetmap.josm.tools.Logging; 014 015/** 016 * Manager class for remote control operations. 017 * 018 * IMPORTANT! increment the minor version on compatible API extensions 019 * and increment the major version and set minor to 0 on incompatible changes. 020 */ 021public class RemoteControl { 022 023 /** 024 * If the remote control feature is enabled or disabled. If disabled, 025 * it should not start the server. 026 */ 027 public static final BooleanProperty PROP_REMOTECONTROL_ENABLED = new BooleanProperty("remotecontrol.enabled", false); 028 029 /** 030 * If the remote control feature is enabled or disabled for HTTPS. If disabled, 031 * only HTTP access will be available. 032 * @since 7335 033 */ 034 public static final BooleanProperty PROP_REMOTECONTROL_HTTPS_ENABLED = new BooleanProperty( 035 "remotecontrol.https.enabled", false); 036 037 /** 038 * RemoteControl HTTP protocol version. Change minor number for compatible 039 * interface extensions. Change major number in case of incompatible 040 * changes. 041 */ 042 static final int protocolMajorVersion = 1; 043 static final int protocolMinorVersion = 8; 044 045 /** 046 * Starts the remote control server 047 */ 048 public static void start() { 049 RemoteControlHttpServer.restartRemoteControlHttpServer(); 050 if (supportsHttps()) { 051 RemoteControlHttpsServer.restartRemoteControlHttpsServer(); 052 } 053 } 054 055 /** 056 * Stops the remote control server 057 * @since 5861 058 */ 059 public static void stop() { 060 RemoteControlHttpServer.stopRemoteControlHttpServer(); 061 if (supportsHttps()) { 062 RemoteControlHttpsServer.stopRemoteControlHttpsServer(); 063 } 064 } 065 066 /** 067 * Determines if the current JVM support HTTPS remote control. 068 * @return {@code true} if the JVM provides {@code sun.security.x509} classes 069 * @since 12703 070 */ 071 public static boolean supportsHttps() { 072 try { 073 return Class.forName("sun.security.x509.GeneralName") != null; 074 } catch (ClassNotFoundException | SecurityException e) { 075 Logging.trace(e); 076 return false; 077 } 078 } 079 080 /** 081 * Adds external request handler. 082 * Can be used by plugins that want to use remote control. 083 * 084 * @param command The command name. 085 * @param handlerClass The additional request handler. 086 */ 087 public void addRequestHandler(String command, Class<? extends RequestHandler> handlerClass) { 088 RequestProcessor.addRequestHandlerClass(command, handlerClass); 089 } 090 091 /** 092 * Returns the remote control directory. 093 * @return The remote control directory 094 * @since 7335 095 */ 096 public static String getRemoteControlDir() { 097 return new File(Config.getDirs().getUserDataDirectory(true), "remotecontrol").getAbsolutePath(); 098 } 099 100 /** 101 * Returns the IPv6 address used for remote control. 102 * @return the IPv6 address used for remote control 103 * @throws UnknownHostException if the local host name could not be resolved into an address. 104 * @since 8337 105 */ 106 public static InetAddress getInet6Address() throws UnknownHostException { 107 for (InetAddress a : InetAddress.getAllByName(Config.getPref().get("remote.control.host.ipv6", "::1"))) { 108 if (a instanceof Inet6Address) { 109 return a; 110 } 111 } 112 throw new UnknownHostException(); 113 } 114 115 /** 116 * Returns the IPv4 address used for remote control. 117 * @return the IPv4 address used for remote control 118 * @throws UnknownHostException if the local host name could not be resolved into an address. 119 * @since 8337 120 */ 121 public static InetAddress getInet4Address() throws UnknownHostException { 122 // Return an address to the loopback interface by default 123 for (InetAddress a : InetAddress.getAllByName(Config.getPref().get("remote.control.host.ipv4", "127.0.0.1"))) { 124 if (a instanceof Inet4Address) { 125 return a; 126 } 127 } 128 throw new UnknownHostException(); 129 } 130}