noodlefrenzy/node-amqp10

View on GitHub
resources/security.xml

Summary

Maintainability
Test Coverage
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="amqp.xsl"?>

<!--
  Copyright Notice
  ================
  (c) Copyright Bank of America, N.A., Barclays Bank PLC, Cisco Systems, Credit Suisse, Deutsche
  Boerse, Envoy Technologies Inc., Goldman Sachs, HCL Technologies Ltd, IIT Software GmbH, iMatix
  Corporation, INETCO Systems Limited, Informatica Corporation, JPMorgan Chase & Co., Kaazing
  Corporation, N.A, Microsoft Corporation, my-Channels, Novell, Progress Software, Red Hat Inc.,
  Software AG, Solace Systems Inc., StormMQ Ltd., Tervela Inc., TWIST Process Innovations Ltd,
  VMware, Inc., and WS02 Inc.
  2006-2011. All rights reserved.

  License
  =======

  Bank of America, N.A., Barclays Bank PLC, Cisco Systems, Credit Suisse, Deutsche Boerse, Goldman
  Sachs, HCL Technologies Ltd, IIT Software GmbH, INETCO Systems Limited, Informatica Corporation,
  JPMorgan Chase & Co., Kaazing Corporation, N.A, Microsoft Corporation, my-Channels, Novell,
  Progress Software, Red Hat Inc., Software AG, Solace Systems Inc., StormMQ Ltd., Tervela Inc.,
  TWIST Process Innovations Ltd, VMware, Inc., and WS02 Inc. (collectively, the "Authors") each
  hereby grants to you a worldwide, perpetual, royalty-free, nontransferable, nonexclusive license
  to (i) copy, display, distribute and implement the Advanced Message Queuing Protocol ("AMQP")
  Specification and (ii) the Licensed Claims that are held by the Authors, all for the purpose of
  implementing the Advanced Message Queuing Protocol Specification. Your license and any rights
  under this Agreement will terminate immediately without notice from any Author if you bring any
  claim, suit, demand, or action related to the Advanced Message Queuing Protocol Specification
  against any Author. Upon termination, you shall destroy all copies of the Advanced Message Queuing
  Protocol Specification in your possession or control.

  As used hereunder, "Licensed Claims" means those claims of a patent or patent application,
  throughout the world, excluding design patents and design registrations, owned or controlled, or
  that can be sublicensed without fee and in compliance with the requirements of this Agreement, by
  an Author or its affiliates now or at any future time and which would necessarily be infringed by
  implementation of the Advanced Message Queuing Protocol Specification. A claim is necessarily
  infringed hereunder only when it is not possible to avoid infringing it because there is no
  plausible non-infringing alternative for implementing the required portions of the Advanced
  Message Queuing Protocol Specification. Notwithstanding the foregoing, Licensed Claims shall not
  include any claims other than as set forth above even if contained in the same patent as Licensed
  Claims; or that read solely on any implementations of any portion of the Advanced Message Queuing
  Protocol Specification that are not required by the Advanced Message Queuing Protocol
  Specification, or that, if licensed, would require a payment of royalties by the licensor to
  unaffiliated third parties. Moreover, Licensed Claims shall not include (i) any enabling
  technologies that may be necessary to make or use any Licensed Product but are not themselves
  expressly set forth in the Advanced Message Queuing Protocol Specification (e.g., semiconductor
  manufacturing technology, compiler technology, object oriented technology, networking technology,
  operating system technology, and the like); or (ii) the implementation of other published
  standards developed elsewhere and merely referred to in the body of the Advanced Message Queuing
  Protocol Specification, or (iii) any Licensed Product and any combinations thereof the purpose or
  function of which is not required for compliance with the Advanced Message Queuing Protocol
  Specification. For purposes of this definition, the Advanced Message Queuing Protocol
  Specification shall be deemed to include both architectural and interconnection requirements
  essential for interoperability and may also include supporting source code artifacts where such
  architectural, interconnection requirements and source code artifacts are expressly identified as
  being required or documentation to achieve compliance with the Advanced Message Queuing Protocol
  Specification.

  As used hereunder, "Licensed Products" means only those specific portions of products (hardware,
  software or combinations thereof) that implement and are compliant with all relevant portions of
  the Advanced Message Queuing Protocol Specification.

  The following disclaimers, which you hereby also acknowledge as to any use you may make of the
  Advanced Message Queuing Protocol Specification:

  THE ADVANCED MESSAGE QUEUING PROTOCOL SPECIFICATION IS PROVIDED "AS IS," AND THE AUTHORS MAKE NO
  REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, WARRANTIES OF
  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, OR TITLE; THAT THE CONTENTS
  OF THE ADVANCED MESSAGE QUEUING PROTOCOL SPECIFICATION ARE SUITABLE FOR ANY PURPOSE; NOR THAT THE
  IMPLEMENTATION OF THE ADVANCED MESSAGE QUEUING PROTOCOL SPECIFICATION WILL NOT INFRINGE ANY THIRD
  PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS.

  THE AUTHORS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL
  DAMAGES ARISING OUT OF OR RELATING TO ANY USE, IMPLEMENTATION OR DISTRIBUTION OF THE ADVANCED
  MESSAGE QUEUING PROTOCOL SPECIFICATION.

  The name and trademarks of the Authors may NOT be used in any manner, including advertising or
  publicity pertaining to the Advanced Message Queuing Protocol Specification or its contents
  without specific, written prior permission. Title to copyright in the Advanced Message Queuing
  Protocol Specification will at all times remain with the Authors.

  No other rights are granted by implication, estoppel or otherwise.

  Upon termination of your license or rights under this Agreement, you shall destroy all copies of
  the Advanced Message Queuing Protocol Specification in your possession or control.

  Trademarks
  ==========
  "JPMorgan", "JPMorgan Chase", "Chase", the JPMorgan Chase logo and the Octagon Symbol are
  trademarks of JPMorgan Chase & Co.

  RED HAT is a registered trademarks of Red Hat, Inc. in the US and other countries.

  Other company, product, or service names may be trademarks or service marks of others.

  Link to full AMQP specification:
  =================================
  http://www.amqp.org/confluence/display/AMQP/AMQP+Specification
-->

<!DOCTYPE amqp SYSTEM "amqp.dtd">

<amqp xmlns="http://www.amqp.org/schema/amqp.xsd"
      name="security" label="working version">

  <section name="security-layers" title="Security Layers" label="Security Layers">
    <doc>
      <p>
        Security Layers are used to establish an authenticated and/or encrypted transport over which
        regular AMQP traffic can be tunneled. Security Layers may be tunneled over one another (for
        instance a Security Layer used by the peers to do authentication may be tunneled over a
        Security Layer established for encryption purposes).
      </p>

      <p>
        The framing and protocol definitions for security layers are expected to be defined
        externally to the AMQP specification as in the case of TLS. An exception to this is the SASL
        security layer which depends on its host protocol to provide framing. Because of this we
        define the frames necessary for SASL to function in <xref name="sasl"/> below. When a
        security layer terminates (either before or after a secure tunnel is established), the TCP
        Connection MUST be closed by first shutting down the outgoing stream and then reading the
        incoming stream until it is terminated.
      </p>
    </doc>
  </section>

  <section name="tls" title="TLS" label="TLS Security Layer">
    <doc>
      <p>
        To establish a TLS tunnel, each peer MUST start by sending a protocol header. The protocol
        header consists of the upper case ASCII letters "AMQP" followed by a protocol id of two,
        followed by three unsigned bytes representing the major, minor, and revision of the
        specification version (currently <xref name="TLS-MAJOR"/>, <xref name="TLS-MINOR"/>,
        <xref name="TLS-REVISION"/>). In total this is an 8-octet sequence:
      </p>

      <picture><![CDATA[
  4 OCTETS   1 OCTET   1 OCTET   1 OCTET   1 OCTET
+----------+---------+---------+---------+----------+
|  "AMQP"  |   %d2   |  major  |  minor  | revision |
+----------+---------+---------+---------+----------+
]]>
      </picture>

      <p>
        Other than using a protocol id of two, the exchange of TLS tunnel headers follows the same
        rules specified in the version negotiation section of the transport specification (See
        <xref name="version-negotiation"/>).
      </p>
    </doc>

    <doc>
      <p>
        The following diagram illustrates the interaction involved in creating a TLS Security Layer:
      </p>
      <picture><![CDATA[
TCP Client                 TCP Server
=========================================
AMQP%d2.1.0.0  --------->
               <---------  AMQP%d2.1.0.0
                    :
                    :
            <TLS negotiation>
                    :
                    :
AMQP%d0.1.0.0  --------->                (over TLS secured connection)
               <---------  AMQP%d0.1.0.0
         open  --------->
               <---------  open
]]>
      </picture>

      <p>
        When the use of the TLS Security Layer is negotiated, the following rules apply:
      </p>

      <ul>
        <li>
          <p>
            The TLS client peer and TLS server peer are determined by the TCP client peer and TCP
            server peer respectively.
          </p>
        </li>

        <li>
          <p>
            The TLS client peer SHOULD use the server name indication extension as described in
            RFC-4366. If it does so, then it is implementation-specific what happens if this
            differs to hostname in the <xref type="type" name="sasl-init"/> and
            <xref type="type" name="open"/> frame frames.
          </p>
          <p>
            This field can be used by AMQP proxies to determine the correct back-end service to
            connect the client to, and to determine the domain to validate the client's
            credentials against if TLS client certificates are being used.
          </p>
        </li>

        <li>
          <p>
            The TLS client MUST validate the certificate presented by the TLS server.
          </p>
        </li>

        <li>
          <p>
            Implementations MAY choose to use TLS with unidirectional shutdown, i.e. an application
            initiating shutdown using close_notify is not obliged to wait for the peer to respond,
            and MAY close the write-half of the TCP socket.
          </p>
        </li>
      </ul>
    </doc>

    <doc title="Alternative Establishment">
      <p>
        In certain situations, such as connecting through firewalls, it may not be possible to
        establish a TLS security layer using tunnelling. This might be because a deep packet
        inspecting firewall sees the first few bytes of the connection 'as not being TLS'.
      </p>

      <p>
        As an alternative, implementations MAY run a pure TLS server, i.e., one that does not
        expect the tunnel negotiation handshake. The IANA service name for this is amqps and the
        port is <xref name="SECURE-PORT"/> (5671). Implementations may also choose to run this pure
        TLS server on other ports, should this be operationally required (e.g. to tunnel through a
        legacy firewall that only expects TLS traffic on port 443).
       </p>
    </doc>

    <definition name="TLS-MAJOR" value="1" label="major protocol version" />
    <definition name="TLS-MINOR" value="0" label="minor protocol version" />
    <definition name="TLS-REVISION" value="0" label="protocol revision" />

  </section>

  <!-- == Section: sasl ======================================================================== -->

  <section name="sasl" title="SASL" label="SASL Security Layer">
    <doc>
      <p>
        To establish a SASL tunnel, each peer MUST start by sending a protocol header. The protocol
        header consists of the upper case ASCII letters "AMQP" followed by a protocol id of three,
        followed by three unsigned bytes representing the major, minor, and revision of the
        specification version (currently <xref name="SASL-MAJOR"/>, <xref name="SASL-MINOR"/>,
        <xref name="SASL-REVISION"/>). In total this is an 8-octet sequence:
      </p>

      <picture><![CDATA[
  4 OCTETS   1 OCTET   1 OCTET   1 OCTET   1 OCTET
+----------+---------+---------+---------+----------+
|  "AMQP"  |   %d3   |  major  |  minor  | revision |
+----------+---------+---------+---------+----------+
]]>
      </picture>

      <p>
        Other than using a protocol id of three, the exchange of SASL tunnel headers follows the
        same rules specified in the version negotiation section of the transport specification (See
        <xref name="version-negotiation"/>).
      </p>

      <p>
        The following diagram illustrates the interaction involved in creating a SASL Security
        Layer:
      </p>

      <picture><![CDATA[
TCP Client                 TCP Server
=========================================
AMQP%d3.1.0.0  --------->
               <---------  AMQP%d3.1.0.0
                    :
                    :
            <SASL negotiation>
                    :
                    :
AMQP%d0.1.0.0  --------->                (over SASL secured connection)
               <---------  AMQP%d0.1.0.0
         open  --------->
               <---------  open
]]>
      </picture>
    </doc>

    <doc title="SASL Frames">
       <p>
         SASL is negotiated using <xref name="framing"/>. A SASL frame has a type code of 0x01.
         Bytes 6 and 7 of the header are ignored. Implementations SHOULD set these to 0x00. The
         extended header is ignored. Implementations SHOULD therefore set DOFF to 0x02.
       </p>

      <picture title="SASL Frame"><![CDATA[
              type: 0x01 - SASL frame

           +0       +1       +2       +3
       +-----------------------------------+ -.
     0 |                SIZE               |  |
       +-----------------------------------+  |---> Frame Header
     4 |  DOFF  |  TYPE  |   <IGNORED>*1   |  |      (8 bytes)
       +-----------------------------------+ -'
       +-----------------------------------+ -.
     8 |                ...                |  |
       .                                   .  |---> Extended Header
       .             <IGNORED>*2           .  |  (DOFF * 4 - 8) bytes
       |                ...                |  |
       +-----------------------------------+ -'
       +-----------------------------------+ -.
4*DOFF |                                   |  |
       .                                   .  |
       .                                   .  |
       .    Sasl Mechanisms / Sasl Init    .  |
       .   Sasl Challenge / Sasl Response  .  |---> Frame Body
       .           Sasl Outcome            .  |  (SIZE - DOFF * 4) bytes
       .                                   .  |
       .                                   .  |
       .                           ________|  |
       |                ...       |           |
       +--------------------------+          -'

        *1 SHOULD be set to 0x0000
        *2 Ignored, so DOFF should be set to 0x02
]]>
      </picture>

      <p>
        The maximum size of a SASL frame is defined by <xref name="MIN-MAX-FRAME-SIZE"/>. There is
        no mechanism within the SASL negotiation to negotiate a different size. The frame body of a
        SASL frame may contain exactly one AMQP type, whose type encoding must have
        <![CDATA[ provides="sasl-frame" ]]>. Receipt of an empty frame is an irrecoverable error.
      </p>
    </doc>

    <doc title="SASL Negotiation">
      <p>
        The peer acting as the SASL Server must announce supported authentication mechanisms using
        the <xref name="sasl-mechanisms"/> frame. The partner must then choose one of the supported
        mechanisms and initiate a sasl exchange.
      </p>

      <picture title="SASL Exchange"><![CDATA[
SASL Client       SASL Server
================================
              <-- SASL-MECHANISMS
SASL-INIT     -->
              ...
              <-- SASL-CHALLENGE *
SASL-RESPONSE -->
              ...
              <-- SASL-OUTCOME
--------------------------------
  * Note that the SASL
    challenge/response step may
    occur zero or more times
    depending on the details of
    the SASL mechanism chosen.
]]>
      </picture>

      <p>
        The peer playing the role of the SASL Client and the peer playing the role of the SASL
        server MUST correspond to the TCP client and server respectively.
      </p>
    </doc>

    <doc title="Security Frame Bodies"/>

    <!-- - Frame: sasl-mechanisms  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->

    <type class="composite" name="sasl-mechanisms" source="list" provides="sasl-frame"
          label="advertise available sasl mechanisms">
      <doc>
        <p>
          Advertises the available SASL mechanisms that may be used for authentication.
        </p>
      </doc>

      <descriptor name="amqp:sasl-mechanisms:list" code="0x00000000:0x00000040"/>

      <field name="sasl-server-mechanisms" type="symbol" multiple="true" mandatory="true"
             label="supported sasl mechanisms">
        <doc>
          <p>
            A list of the sasl security mechanisms supported by the sending peer. It is invalid
            for this list to be null or empty. If the sending peer does not require its partner
            to authenticate with it, then it should send a list of one element with its value as
            the SASL mechanism <i>ANONYMOUS</i>. The server mechanisms are ordered in decreasing
            level of preference.
          </p>
        </doc>
      </field>
    </type>

    <!-- - Frame: sasl-init  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->

    <type class="composite" name="sasl-init" source="list" provides="sasl-frame"
          label="initiate sasl exchange">
      <doc>
        <p>Selects the sasl mechanism and provides the initial response if needed.</p>
      </doc>

      <descriptor name="amqp:sasl-init:list" code="0x00000000:0x00000041"/>

      <field name="mechanism" type="symbol" label="selected security mechanism" mandatory="true">
        <doc>
          <p>
            The name of the SASL mechanism used for the SASL exchange. If the selected mechanism is
            not supported by the receiving peer, it MUST close the Connection with the
            authentication-failure close-code. Each peer MUST authenticate using the highest-level
            security profile it can handle from the list provided by the partner.
          </p>
        </doc>
      </field>

      <field name="initial-response" type="binary" label="security response data">
        <doc>
          <p>
            A block of opaque data passed to the security mechanism. The contents of this data are
            defined by the SASL security mechanism.
          </p>
        </doc>
      </field>

      <field name="hostname" type="string" label="the name of the target host">
        <doc>
          <p>
            The DNS name of the host (either fully qualified or relative) to which the sending peer
            is connecting. It is not mandatory to provide the hostname. If no hostname is provided
            the receiving peer should select a default based on its own configuration.
          </p>

          <p>
            This field can be used by AMQP proxies to determine the correct back-end service to
            connect the client to, and to determine the domain to validate the client's credentials
            against.
          </p>

          <p>
            This field may already have been specified by the server name indication extension as
            described in RFC-4366, if a TLS layer is used, in which case this field SHOULD be null
            or contain the same value. It is undefined what a different value to those already
            specific means.
          </p>
        </doc>
      </field>
    </type>

    <!-- - Frame: sasl-challenge - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->

    <type class="composite" name="sasl-challenge" source="list" provides="sasl-frame"
          label="security mechanism challenge">
      <doc>
        <p>Send the SASL challenge data as defined by the SASL specification.</p>
      </doc>

      <descriptor name="amqp:sasl-challenge:list" code="0x00000000:0x00000042"/>

      <field name="challenge" type="binary" label="security challenge data" mandatory="true">
        <doc>
          <p>
            Challenge information, a block of opaque binary data passed to the security
            mechanism.
          </p>
        </doc>
      </field>
    </type>

    <!-- - Frame: sasl-response  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->

    <type class="composite" name="sasl-response" source="list" provides="sasl-frame"
          label="security mechanism response">
      <doc>
        <p>Send the SASL response data as defined by the SASL specification.</p>
      </doc>

      <descriptor name="amqp:sasl-response:list" code="0x00000000:0x00000043"/>

      <field name="response" type="binary" label="security response data" mandatory="true">
        <doc>
          <p>
            A block of opaque data passed to the security mechanism. The contents of this data are
            defined by the SASL security mechanism.
          </p>
        </doc>
      </field>
    </type>

    <!-- - Frame: sasl-outcome - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->

    <type class="composite" name="sasl-outcome" source="list" provides="sasl-frame"
          label="indicates the outcome of the sasl dialog">
      <doc>
        <p>
          This frame indicates the outcome of the SASL dialog. Upon successful completion of the
          SASL dialog the Security Layer has been established, and the peers must exchange protocol
          headers to either start a nested Security Layer, or to establish the AMQP Connection.
        </p>
      </doc>

      <descriptor name="amqp:sasl-outcome:list" code="0x00000000:0x00000044"/>

      <field name="code" type="sasl-code" mandatory="true"
             label="indicates the outcome of the sasl dialog">
        <doc>
          <p>A reply-code indicating the outcome of the SASL dialog.</p>
        </doc>
      </field>

      <field name="additional-data" type="binary" label="additional data as specified in RFC-4422">
        <doc>
          <p>
            The additional-data field carries additional data on successful authentication outcome
            as specified by the SASL specification (RFC-4422). If the authentication is
            unsuccessful, this field is not set.
          </p>
        </doc>
      </field>
    </type>

    <type class="restricted" name="sasl-code" source="ubyte"
          label="codes to indicate the outcome of the sasl dialog">
      <choice name="ok" value="0">
        <doc>
          <p>Connection authentication succeeded.</p>
        </doc>
      </choice>
      <choice name="auth" value="1">
        <doc>
          <p>
            Connection authentication failed due to an unspecified problem with the supplied
            credentials.
          </p>
        </doc>
      </choice>
      <choice name="sys" value="2">
        <doc>
          <p>Connection authentication failed due to a system error.</p>
        </doc>
      </choice>
      <choice name="sys-perm" value="3">
        <doc>
          <p>
            Connection authentication failed due to a system error that is unlikely to be corrected
            without intervention.
          </p>
        </doc>
      </choice>
      <choice name="sys-temp" value="4">
        <doc>
          <p>
            Connection authentication failed due to a transient system error.
          </p>
        </doc>
      </choice>
    </type>

    <definition name="SASL-MAJOR" value="1" label="major protocol version" />
    <definition name="SASL-MINOR" value="0" label="minor protocol version" />
    <definition name="SASL-REVISION" value="0" label="protocol revision" />

  </section>

</amqp>