Uploaded image for project: 'Qpid'
  1. Qpid
  2. QPID-8490

Java broker crashes on sending non-LDH virtual hostname from cpp client

    XMLWordPrintableJSON

Details

    Description

      When cpp client specifies virtual_host connection option, containing invalid characters, java broker crashes on connection attempt.

      Steps to reproduce:

      1. Install java broker

       2. Prepare broker and client certificates 

       3. Install Qpid::Proton 0.28.0

      wget http://archive.apache.org/dist/qpid/proton/0.28.0/qpid-proton-0.28.0.tar.gz

      gunzip qpid-proton-0.28.0.tar.gz

      mkdir -p qpid-proton-0.28.0/build && pushd qpid-proton-0.28.0/build && cmake .. && make all && popd

      4. Replace and edit example qpid-proton-0.28.0/cpp/examples/simple_recv.cpp with the one attached

      5. Build again

      cd qpid-proton-0.28.0/build

      make

      6. Break the broker

      ./cpp/examples/simple_recv

      The error is triggered by this line in simple_recv.cpp:

      co.virtual_host("_");

      Virtual host may contain alphanumerical characters as well as few others (dots, hyphens), so e.g. co.virtual_host("127.0.0.1"); is handled normally but co.virtual_host("http://127.0.0.1"); leads to broker crash.

      Logs

      On client side following error is seen:

      amqp:connection:framing-error: SSL Failure: error:140780E5:SSL routines:ssl23_read:ssl handshake failure
      

      On broker side following stacktrace is seen in log:

      2020-12-03 12:43:03,940 DEBUG [IO-pool-Port-amqps-9] (o.a.q.s.t.NonBlockingConnection) - Identified transport encryption as TLS
      2020-12-03 12:43:03,940 DEBUG [IO-pool-Port-amqps-9] (o.a.q.s.t.NonBlockingConnection) - Identified transport encryption as TLS
      2020-12-03 12:43:03,945 DEBUG [IO-/10.112.45.3:60700] (o.a.q.s.t.NonBlockingConnection) - Read 299 byte(s)
      #########################################################################
      2020-12-03 12:43:03,956 ERROR [IO-/10.112.45.3:60700] (o.a.q.s.Main) - Uncaught exception, shutting down.java.lang.IllegalArgumentException: Contains non-LDH ASCII characters 
      at java.net.IDN.toASCIIInternal(IDN.java:296) at java.net.IDN.toASCII(IDN.java:122) 
      at javax.net.ssl.SNIHostName.<init>(SNIHostName.java:99) 
      at org.apache.qpid.server.transport.NonBlockingConnectionTLSDelegate.processData(NonBlockingConnectionTLSDelegate.java:105) 
      at org.apache.qpid.server.transport.NonBlockingConnection.doRead(NonBlockingConnection.java:496) 
      at org.apache.qpid.server.transport.NonBlockingConnection.doWork(NonBlockingConnection.java:270) 
      at org.apache.qpid.server.transport.NetworkConnectionScheduler.processConnection(NetworkConnectionScheduler.java:134) 
      at org.apache.qpid.server.transport.SelectorThread$ConnectionProcessor.processConnection(SelectorThread.java:575) 
      at org.apache.qpid.server.transport.SelectorThread$SelectionTask.performSelect(SelectorThread.java:366) 
      at org.apache.qpid.server.transport.SelectorThread$SelectionTask.run(SelectorThread.java:97) 
      at org.apache.qpid.server.transport.SelectorThread.run(SelectorThread.java:533) 
      at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) 
      at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) 
      at org.apache.qpid.server.bytebuffer.QpidByteBufferFactory.lambda$null$0(QpidByteBufferFactory.java:464) 
      at java.lang.Thread.run(Thread.java:748)
      # Unhandled Exception java.lang.IllegalArgumentException: Contains non-LDH ASCII characters in Thread IO-/10.112.45.3:60700
      ## Exiting#########################################################################
      java.lang.IllegalArgumentException: Contains non-LDH ASCII characters at java.net.IDN.toASCIIInternal(IDN.java:296) 
      at java.net.IDN.toASCII(IDN.java:122) 
      at javax.net.ssl.SNIHostName.<init>(SNIHostName.java:99) 
      at org.apache.qpid.server.transport.NonBlockingConnectionTLSDelegate.processData(NonBlockingConnectionTLSDelegate.java:105) 
      at org.apache.qpid.server.transport.NonBlockingConnection.doRead(NonBlockingConnection.java:496) 
      at org.apache.qpid.server.transport.NonBlockingConnection.doWork(NonBlockingConnection.java:270) 
      at org.apache.qpid.server.transport.NetworkConnectionScheduler.processConnection(NetworkConnectionScheduler.java:134) 
      at org.apache.qpid.server.transport.SelectorThread$ConnectionProcessor.processConnection(SelectorThread.java:575) 
      at org.apache.qpid.server.transport.SelectorThread$SelectionTask.performSelect(SelectorThread.java:366) 
      at org.apache.qpid.server.transport.SelectorThread$SelectionTask.run(SelectorThread.java:97) 
      at org.apache.qpid.server.transport.SelectorThread.run(SelectorThread.java:533) 
      at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) 
      at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) 
      at org.apache.qpid.server.bytebuffer.QpidByteBufferFactory.lambda$null$0(QpidByteBufferFactory.java:464) 
      at java.lang.Thread.run(Thread.java:748)
      

       Error was reproduced in java 1.8:

      java -version
       openjdk version "1.8.0_262"
       OpenJDK Runtime Environment (build 1.8.0_262-b10)
       OpenJDK 64-Bit Server VM (build 25.262-b10, mixed mode)
      

      And in java 11:

       java -version
      openjdk version "11.0.9" 2020-10-20 LTS
      OpenJDK Runtime Environment 18.9 (build 11.0.9+11-LTS)
      OpenJDK 64-Bit Server VM 18.9 (build 11.0.9+11-LTS, mixed mode, sharing)
      

      Analysis

      javax.net.ssl.SNIHostName checks hostname validity according to RFC 1123 rules. If hostname contains invalid characters (e.g. underscore "_"), an IllegalArgumentException is thrown. As runtime exceptions are not handled by NonBlockingConnection, it leads to broker crash.

      There are two places where new SNIHostName instance is created:

      1) org.apache.qpid.server.transport.NonBlockingConnectionTLSDelegate.processData()

      2) org.apache.qpid.server.transport.network.security.ssl.SSLUtil.getServerNameFromTLSClientHello()

      Attachments

        1. simple_recv.cpp
          2 kB
          Daniil Kirilyuk

        Activity

          People

            Unassigned Unassigned
            daniel.kirilyuk Daniil Kirilyuk
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: