Changeset 8339 in josm for trunk


Ignore:
Timestamp:
2015-05-07T17:30:43+02:00 (4 years ago)
Author:
stoecker
Message:

fix #11409 - Remotecontrol on IPv6 and IPv4

Location:
trunk/src/org/openstreetmap/josm
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/data/Preferences.java

    r8324 r8339  
    16951695
    16961696        String[] obsolete = {
     1697                "remote.control.host", // replaced by individual values for IPv4 and IPv6. To remove end of 2015
    16971698                "osm.notes.enableDownload", // was used prior to r8071 when notes was an hidden feature. To remove end of 2015
    16981699                "mappaint.style.migration.switchedToMapCSS", // was used prior to 8315 for MapCSS switch. To remove end of 2015
  • trunk/src/org/openstreetmap/josm/io/remotecontrol/RemoteControl.java

    r8337 r8339  
    8080
    8181    /**
    82      * Returns the inet address used for remote control.
    83      * @return the inet address used for remote control
    84      * @throws UnknownHostException if the local host name could not be resolved into an address.
    85      * @since 7800
    86      */
    87     @Deprecated
    88     public static InetAddress getInetAddress() throws UnknownHostException {
    89         // Return an address to the loopback interface by default
    90         return InetAddress.getByName(Main.pref.get("remote.control.host", null));
    91     }
    92 
    93     /**
    9482     * Returns the IPv6 address used for remote control.
    9583     * @return the IPv6 address used for remote control
     
    9886     */
    9987    public static InetAddress getInet6Address() throws UnknownHostException {
    100         for(InetAddress a : InetAddress.getAllByName(Main.pref.get("remote.control.host", "localhost"))) {
     88        for(InetAddress a : InetAddress.getAllByName(Main.pref.get("remote.control.host.ipv6", "::1"))) {
    10189            if(a instanceof Inet6Address) {
    10290                return a;
     
    114102    public static InetAddress getInet4Address() throws UnknownHostException {
    115103        // Return an address to the loopback interface by default
    116         for(InetAddress a : InetAddress.getAllByName(Main.pref.get("remote.control.host", "localhost"))) {
     104        for(InetAddress a : InetAddress.getAllByName(Main.pref.get("remote.control.host.ipv4", "127.0.0.1"))) {
    117105            if(a instanceof Inet4Address) {
    118106                return a;
  • trunk/src/org/openstreetmap/josm/io/remotecontrol/RemoteControlHttpServer.java

    r8337 r8339  
    2020public class RemoteControlHttpServer extends Thread {
    2121
    22     /** The server socket for IPv4 */
    23     private ServerSocket server4 = null;
    24     /** The server socket for IPv6 */
    25     private ServerSocket server6 = null;
     22    /** The server socket */
     23    private ServerSocket server = null;
    2624
    27     private static volatile RemoteControlHttpServer instance;
     25    /** The server instance for IPv4 */
     26    private static volatile RemoteControlHttpServer instance4 = null;
     27    /** The server instance for IPv6 */
     28    private static volatile RemoteControlHttpServer instance6 = null;
    2829
    2930    /**
     
    3132     */
    3233    public static void restartRemoteControlHttpServer() {
     34        stopRemoteControlHttpServer();
    3335        int port = Main.pref.getInteger("remote.control.port", 8111);
    3436        try {
    35             stopRemoteControlHttpServer();
    36 
    37             instance = new RemoteControlHttpServer(port);
    38             instance.start();
    39         } catch (BindException ex) {
    40             Main.warn(marktr("Cannot start remotecontrol server on port {0}: {1}"),
     37            instance4 = new RemoteControlHttpServer(port, false);
     38            instance4.start();
     39        } catch (Exception ex) {
     40            Main.warn(marktr("Cannot start IPv4 remotecontrol server on port {0}: {1}"),
    4141                    Integer.toString(port), ex.getLocalizedMessage());
    42         } catch (IOException ioe) {
    43             Main.error(ioe);
     42        }
     43        try {
     44            instance6 = new RemoteControlHttpServer(port, true);
     45            instance6.start();
     46        } catch (Exception ex) {
     47            /* only show error when we also have no IPv4 */
     48            if(instance4 == null) {
     49                Main.warn(marktr("Cannot start IPv6 remotecontrol server on port {0}: {1}"),
     50                    Integer.toString(port), ex.getLocalizedMessage());
     51            }
    4452        }
    4553    }
     
    5058     */
    5159    public static void stopRemoteControlHttpServer() {
    52         if (instance != null) {
     60        if (instance4 != null) {
    5361            try {
    54                 instance.stopServer();
    55                 instance = null;
     62                instance4.stopServer();
     63                instance4 = null;
     64            } catch (IOException ioe) {
     65                Main.error(ioe);
     66            }
     67        }
     68        if (instance6 != null) {
     69            try {
     70                instance6.stopServer();
     71                instance6 = null;
    5672            } catch (IOException ioe) {
    5773                Main.error(ioe);
     
    6379     * Constructor
    6480     * @param port The port this server will listen on
     81     * @param ipv6 Whether IPv6 or IPv4 server should be started
    6582     * @throws IOException when connection errors
     83     * @since 8339
    6684     */
    67     public RemoteControlHttpServer(int port) throws IOException {
     85    public RemoteControlHttpServer(int port, boolean ipv6) throws IOException {
    6886        super("RemoteControl HTTP Server");
    6987        this.setDaemon(true);
    70         try {
    71             this.server4 = new ServerSocket(port, 1, RemoteControl.getInet4Address());
    72         } catch (IOException e) {
    73         }
    74         try {
    75             this.server6 = new ServerSocket(port, 1, RemoteControl.getInet6Address());
    76         } catch (IOException e) {
    77             if(this.server4 == null) /* both failed */
    78                 throw e;
    79         }
     88        this.server = new ServerSocket(port, 1, ipv6 ?
     89            RemoteControl.getInet6Address() : RemoteControl.getInet4Address());
    8090    }
    8191
     
    8595    @Override
    8696    public void run() {
    87         if(server4 != null) {
    88             Main.info(marktr("RemoteControl::Accepting IPv4 connections on {0}:{1}"),
    89                 server4.getInetAddress(), Integer.toString(server4.getLocalPort()));
    90         }
    91         if(server6 != null) {
    92             Main.info(marktr("RemoteControl::Accepting IPv6 connections on {0}:{1}"),
    93                 server6.getInetAddress(), Integer.toString(server6.getLocalPort()));
    94         }
     97        Main.info(marktr("RemoteControl::Accepting remote connections on {0}:{1}"),
     98                server.getInetAddress(), Integer.toString(server.getLocalPort()));
    9599        while (true) {
    96             if(server4 != null) {
    97                 try {
    98                     @SuppressWarnings("resource")
    99                     Socket request = server4.accept();
    100                     RequestProcessor.processRequest(request);
    101                 } catch (SocketException se) {
    102                     if (!server4.isClosed())
    103                         Main.error(se);
    104                 } catch (IOException ioe) {
    105                     Main.error(ioe);
    106                 }
    107             }
    108             if(server6 != null) {
    109                 try {
    110                     @SuppressWarnings("resource")
    111                     Socket request = server6.accept();
    112                     RequestProcessor.processRequest(request);
    113                 } catch (SocketException se) {
    114                     if (!server6.isClosed())
    115                         Main.error(se);
    116                 } catch (IOException ioe) {
    117                     Main.error(ioe);
    118                 }
     100            try {
     101                @SuppressWarnings("resource")
     102                Socket request = server.accept();
     103                RequestProcessor.processRequest(request);
     104            } catch (SocketException se) {
     105                if (!server.isClosed())
     106                    Main.error(se);
     107            } catch (IOException ioe) {
     108                Main.error(ioe);
    119109            }
    120110        }
     
    127117     */
    128118    public void stopServer() throws IOException {
    129         if(server4 != null)
    130             server4.close();
    131         if(server6 != null)
    132             server6.close();
    133         Main.info(marktr("RemoteControl::Server stopped."));
     119        Main.info(marktr("RemoteControl::Server {0}:{1} stopped."),
     120        server.getInetAddress(), Integer.toString(server.getLocalPort()));
     121        server.close();
    134122    }
    135123}
  • trunk/src/org/openstreetmap/josm/io/remotecontrol/RemoteControlHttpsServer.java

    r8337 r8339  
    33
    44import static org.openstreetmap.josm.tools.I18n.marktr;
    5 import static org.openstreetmap.josm.tools.I18n.tr;
    65
    76import java.io.IOException;
     
    7271public class RemoteControlHttpsServer extends Thread {
    7372
    74     /** The server socket for IPv4 */
    75     private ServerSocket server4 = null;
    76     /** The server socket for IPv6 */
    77     private ServerSocket server6 = null;
    78 
    79     private static volatile RemoteControlHttpsServer instance;
    80     private boolean initOK = false;
     73    /** The server socket */
     74    private ServerSocket server = null;
     75
     76    /** The server instance for IPv4 */
     77    private static volatile RemoteControlHttpsServer instance4 = null;
     78    /** The server instance for IPv6 */
     79    private static volatile RemoteControlHttpsServer instance6 = null;
     80
     81    /** SSL context information for connections */
    8182    private SSLContext sslContext;
    8283
     84    /* the default port for HTTPS remote control */
    8385    private static final int HTTPS_PORT = 8112;
    8486
     
    271273    }
    272274
    273     private void initialize() {
    274         if (!initOK) {
    275             try {
    276                 KeyStore ks = loadJosmKeystore();
    277 
    278                 KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
    279                 kmf.init(ks, KEYENTRY_PASSWORD.get().toCharArray());
    280 
    281                 TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
    282                 tmf.init(ks);
    283 
    284                 sslContext = SSLContext.getInstance("TLS");
    285                 sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
    286 
    287                 if (Main.isTraceEnabled()) {
    288                     Main.trace("SSL Context protocol: " + sslContext.getProtocol());
    289                     Main.trace("SSL Context provider: " + sslContext.getProvider());
    290                 }
    291 
    292                 setupPlatform(ks);
    293 
    294                 initOK = true;
    295             } catch (IOException | GeneralSecurityException e) {
    296                 Main.error(e);
    297             }
    298         }
     275    /**
     276     * Initializes the TLS basics.
     277     * @throws IOException if an I/O error occurs
     278     * @throws GeneralSecurityException if a security error occurs
     279     */
     280    private void initialize() throws IOException, GeneralSecurityException {
     281        KeyStore ks = loadJosmKeystore();
     282
     283        KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
     284        kmf.init(ks, KEYENTRY_PASSWORD.get().toCharArray());
     285
     286        TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
     287        tmf.init(ks);
     288
     289        sslContext = SSLContext.getInstance("TLS");
     290        sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
     291
     292        if (Main.isTraceEnabled()) {
     293            Main.trace("SSL Context protocol: " + sslContext.getProtocol());
     294            Main.trace("SSL Context provider: " + sslContext.getProvider());
     295        }
     296
     297        setupPlatform(ks);
    299298    }
    300299
     
    322321     */
    323322    public static void restartRemoteControlHttpsServer() {
    324         int port = Main.pref.getInteger("remote.control.https.port", HTTPS_PORT);
    325         try {
    326             stopRemoteControlHttpsServer();
    327 
    328             if (RemoteControl.PROP_REMOTECONTROL_HTTPS_ENABLED.get()) {
    329                 instance = new RemoteControlHttpsServer(port);
    330                 if (instance.initOK) {
    331                     instance.start();
     323        stopRemoteControlHttpsServer();
     324        if (RemoteControl.PROP_REMOTECONTROL_HTTPS_ENABLED.get()) {
     325            int port = Main.pref.getInteger("remote.control.https.port", HTTPS_PORT);
     326            try {
     327                instance4 = new RemoteControlHttpsServer(port, false);
     328                instance4.start();
     329            } catch (Exception ex) {
     330                Main.warn(marktr("Cannot start IPv4 remotecontrol https server on port {0}: {1}"),
     331                        Integer.toString(port), ex.getLocalizedMessage());
     332            }
     333            try {
     334                instance6 = new RemoteControlHttpsServer(port, true);
     335                instance6.start();
     336            } catch (Exception ex) {
     337                /* only show error when we also have no IPv4 */
     338                if(instance4 == null) {
     339                    Main.warn(marktr("Cannot start IPv6 remotecontrol https server on port {0}: {1}"),
     340                        Integer.toString(port), ex.getLocalizedMessage());
    332341                }
    333342            }
    334         } catch (BindException ex) {
    335             Main.warn(marktr("Cannot start remotecontrol https server on port {0}: {1}"),
    336                     Integer.toString(port), ex.getLocalizedMessage());
    337         } catch (IOException ioe) {
    338             Main.error(ioe);
    339         } catch (NoSuchAlgorithmException e) {
    340             Main.error(e);
    341343        }
    342344    }
     
    346348     */
    347349    public static void stopRemoteControlHttpsServer() {
    348         if (instance != null) {
     350        if (instance4 != null) {
    349351            try {
    350                 instance.stopServer();
    351                 instance = null;
     352                instance4.stopServer();
     353                instance4 = null;
    352354            } catch (IOException ioe) {
    353355                Main.error(ioe);
    354356            }
    355357        }
     358        if (instance6 != null) {
     359            try {
     360                instance6.stopServer();
     361                instance6 = null;
     362            } catch (IOException ioe) {
     363                Main.error(ioe);
     364            }
     365        }
    356366    }
    357367
     
    359369     * Constructs a new {@code RemoteControlHttpsServer}.
    360370     * @param port The port this server will listen on
     371     * @param ipv6 Whether IPv6 or IPv4 server should be started
    361372     * @throws IOException when connection errors
    362373     * @throws NoSuchAlgorithmException if the JVM does not support TLS (can not happen)
    363      */
    364     public RemoteControlHttpsServer(int port) throws IOException, NoSuchAlgorithmException {
     374     * @throws GeneralSecurityException in case of SSL setup errors
     375     * @since 8339
     376     */
     377    public RemoteControlHttpsServer(int port, boolean ipv6) throws IOException, NoSuchAlgorithmException, GeneralSecurityException {
    365378        super("RemoteControl HTTPS Server");
    366379        this.setDaemon(true);
    367380
    368381        initialize();
    369 
    370         if (!initOK) {
    371             Main.error(tr("Unable to initialize Remote Control HTTPS Server"));
    372             return;
    373         }
    374382
    375383        // Create SSL Server factory
     
    379387        }
    380388
    381         try {
    382             this.server4 = factory.createServerSocket(port, 1, RemoteControl.getInet4Address());
    383         } catch (IOException e) {
    384         }
    385         try {
    386             this.server6 = factory.createServerSocket(port, 1, RemoteControl.getInet6Address());
    387         } catch (IOException e) {
    388             if(this.server4 == null) /* both failed */
    389                 throw e;
    390         }
     389        this.server = factory.createServerSocket(port, 1, ipv6 ?
     390            RemoteControl.getInet6Address() : RemoteControl.getInet4Address());
    391391
    392392        if (Main.isTraceEnabled()) {
    393             if(server4 instanceof SSLServerSocket) {
    394                 SSLServerSocket sslServer = (SSLServerSocket) server4;
     393            if(server instanceof SSLServerSocket) {
     394                SSLServerSocket sslServer = (SSLServerSocket) server;
    395395                Main.trace("SSL server - Enabled Cipher suites: "+Arrays.toString(sslServer.getEnabledCipherSuites()));
    396396                Main.trace("SSL server - Enabled Protocols: "+Arrays.toString(sslServer.getEnabledProtocols()));
     
    400400                Main.trace("SSL server - Use Client Mode: "+sslServer.getUseClientMode());
    401401            }
    402             if(server6 instanceof SSLServerSocket) {
    403                 SSLServerSocket sslServer = (SSLServerSocket) server6;
    404                 Main.trace("SSL server - Enabled Cipher suites: "+Arrays.toString(sslServer.getEnabledCipherSuites()));
    405                 Main.trace("SSL server - Enabled Protocols: "+Arrays.toString(sslServer.getEnabledProtocols()));
    406                 Main.trace("SSL server - Enable Session Creation: "+sslServer.getEnableSessionCreation());
    407                 Main.trace("SSL server - Need Client Auth: "+sslServer.getNeedClientAuth());
    408                 Main.trace("SSL server - Want Client Auth: "+sslServer.getWantClientAuth());
    409                 Main.trace("SSL server - Use Client Mode: "+sslServer.getUseClientMode());
    410             }
    411402        }
    412403    }
     
    417408    @Override
    418409    public void run() {
    419         if(server4 != null) {
    420             Main.info(marktr("RemoteControl::Accepting secure IPv4 connections on {0}:{1}"),
    421                 server4.getInetAddress(), Integer.toString(server4.getLocalPort()));
    422         }
    423         if(server6 != null) {
    424             Main.info(marktr("RemoteControl::Accepting secure IPv6 connections on {0}:{1}"),
    425                 server6.getInetAddress(), Integer.toString(server6.getLocalPort()));
    426         }
     410        Main.info(marktr("RemoteControl::Accepting secure remote connections on {0}:{1}"),
     411                server.getInetAddress(), Integer.toString(server.getLocalPort()));
    427412        while (true) {
    428             if(server4 != null) {
    429                 try {
    430                     @SuppressWarnings("resource")
    431                     Socket request = server4.accept();
    432                     if (Main.isTraceEnabled() && request instanceof SSLSocket) {
    433                         SSLSocket sslSocket = (SSLSocket) request;
    434                         Main.trace("SSL socket - Enabled Cipher suites: "+Arrays.toString(sslSocket.getEnabledCipherSuites()));
    435                         Main.trace("SSL socket - Enabled Protocols: "+Arrays.toString(sslSocket.getEnabledProtocols()));
    436                         Main.trace("SSL socket - Enable Session Creation: "+sslSocket.getEnableSessionCreation());
    437                         Main.trace("SSL socket - Need Client Auth: "+sslSocket.getNeedClientAuth());
    438                         Main.trace("SSL socket - Want Client Auth: "+sslSocket.getWantClientAuth());
    439                         Main.trace("SSL socket - Use Client Mode: "+sslSocket.getUseClientMode());
    440                         Main.trace("SSL socket - Session: "+sslSocket.getSession());
    441                     }
    442                     RequestProcessor.processRequest(request);
    443                 } catch (SocketException se) {
    444                     if (!server4.isClosed()) {
    445                         Main.error(se);
    446                     }
    447                 } catch (IOException ioe) {
    448                     Main.error(ioe);
     413            try {
     414                @SuppressWarnings("resource")
     415                Socket request = server.accept();
     416                if (Main.isTraceEnabled() && request instanceof SSLSocket) {
     417                    SSLSocket sslSocket = (SSLSocket) request;
     418                    Main.trace("SSL socket - Enabled Cipher suites: "+Arrays.toString(sslSocket.getEnabledCipherSuites()));
     419                    Main.trace("SSL socket - Enabled Protocols: "+Arrays.toString(sslSocket.getEnabledProtocols()));
     420                    Main.trace("SSL socket - Enable Session Creation: "+sslSocket.getEnableSessionCreation());
     421                    Main.trace("SSL socket - Need Client Auth: "+sslSocket.getNeedClientAuth());
     422                    Main.trace("SSL socket - Want Client Auth: "+sslSocket.getWantClientAuth());
     423                    Main.trace("SSL socket - Use Client Mode: "+sslSocket.getUseClientMode());
     424                    Main.trace("SSL socket - Session: "+sslSocket.getSession());
    449425                }
    450             }
    451             if(server6 != null) {
    452                 try {
    453                     @SuppressWarnings("resource")
    454                     Socket request = server6.accept();
    455                     if (Main.isTraceEnabled() && request instanceof SSLSocket) {
    456                         SSLSocket sslSocket = (SSLSocket) request;
    457                         Main.trace("SSL socket - Enabled Cipher suites: "+Arrays.toString(sslSocket.getEnabledCipherSuites()));
    458                         Main.trace("SSL socket - Enabled Protocols: "+Arrays.toString(sslSocket.getEnabledProtocols()));
    459                         Main.trace("SSL socket - Enable Session Creation: "+sslSocket.getEnableSessionCreation());
    460                         Main.trace("SSL socket - Need Client Auth: "+sslSocket.getNeedClientAuth());
    461                         Main.trace("SSL socket - Want Client Auth: "+sslSocket.getWantClientAuth());
    462                         Main.trace("SSL socket - Use Client Mode: "+sslSocket.getUseClientMode());
    463                         Main.trace("SSL socket - Session: "+sslSocket.getSession());
    464                     }
    465                     RequestProcessor.processRequest(request);
    466                 } catch (SocketException se) {
    467                     if (!server6.isClosed()) {
    468                         Main.error(se);
    469                     }
    470                 } catch (IOException ioe) {
    471                     Main.error(ioe);
     426                RequestProcessor.processRequest(request);
     427            } catch (SocketException se) {
     428                if (!server.isClosed()) {
     429                    Main.error(se);
    472430                }
     431            } catch (IOException ioe) {
     432                Main.error(ioe);
    473433            }
    474434        }
     
    481441     */
    482442    public void stopServer() throws IOException {
    483         if(server4 != null)
    484             server4.close();
    485         if(server6 != null)
    486             server6.close();
    487         if(server6 != null || server4 != null)
    488         Main.info(marktr("RemoteControl::Server (IPv6 https) stopped."));
     443        Main.info(marktr("RemoteControl::Server {0}:{1} stopped.\n"),
     444        server.getInetAddress(), Integer.toString(server.getLocalPort()));
     445        server.close();
    489446    }
    490447}
Note: See TracChangeset for help on using the changeset viewer.