Class StanzaHandler

java.lang.Object
org.jivesoftware.openfire.net.StanzaHandler
Direct Known Subclasses:
ClientStanzaHandler, ComponentStanzaHandler, MultiplexerStanzaHandler, RespondingServerStanzaHandler, ServerStanzaHandler

public abstract class StanzaHandler extends Object
A StanzaHandler is the main responsible for handling incoming stanzas. Some stanzas like startTLS are totally managed by this class. The rest of the stanzas are just forwarded to the router.
Author:
Gaston Dombiak
  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    protected Connection
     
    static final SystemProperty<Boolean>
     
    protected PacketRouter
    Router used to route incoming packets to the correct channels.
    protected boolean
    Flag that indicates that SASL2 authentication succeeded by inline-resuming a pre-existing session (XEP-0198 § 9.2), rather than by binding a (new or Bind2) resource.
    SASL status based on the last SASL interaction
    protected LocalSession
    Session associated with the socket reader.
    protected boolean
     
    protected boolean
    Flag that indicates that the client requested to be authenticated.
    protected boolean
    Flag that indicates that the client requested to use TLS and TLS has been negotiated.
    protected boolean
    Flag that indicates that the client used SASL2 (rather than the older, multi-roundtrip SASL(1)) to authenticate.
    protected boolean
     
  • Constructor Summary

    Constructors
    Constructor
    Description
    StanzaHandler(PacketRouter router, Connection connection)
    Creates a dedicated reader for a socket.
  • Method Summary

    Modifier and Type
    Method
    Description
    protected void
    adoptSasl2ResumedSession(LocalSession authenticatingSession)
    Adopts the pre-existing session that a SASL2 authentication resumed inline (XEP-0198 § 9.2), replacing the temporary session that was negotiating the SASL2 authentication.
    protected void
    Close the connection since TLS was mandatory and the entity never negotiated TLS.
    protected boolean
    compressClient(org.dom4j.Element doc)
    Start using compression but first check if the connection can and should use compression.
    protected void
    After compression was successful we should open a new stream and offer new stream features such as resource binding and session establishment.
    protected void
    createSession(org.xmlpull.v1.XmlPullParser xpp)
    Uses the XPP to grab the opening stream tag and create an active session object.
    protected void
    Delivers post-authentication stream features for SASL2 (XEP-0388).
    protected org.dom4j.Element
    Helper to generate stream:features, populated simply from the session.,
    org.xmpp.packet.JID
    Obtain the address of the XMPP entity for which this StanzaHandler handles stanzas.
    protected org.dom4j.Document
     
    protected void
     
    protected boolean
    Checks if the provided XML data represents the end / closing of an XMPP stream.
    protected boolean
     
    protected boolean
    Checks if the provided XML data represents the beginning of a new XMPP stream.
    protected boolean
    isStreamManagementStanza(org.dom4j.Element stanza)
    Determines whether stanza's namespace matches XEP-0198 namespace
    protected boolean
    Tries to encrypt the connection using TLS.
    void
    process(String stanza, XMPPPacketReader reader)
     
    protected void
    processIQ(org.xmpp.packet.IQ packet)
    Process the received IQ packet.
    protected void
    processMessage(org.xmpp.packet.Message packet)
    Process the received Message packet.
    protected void
    processPresence(org.xmpp.packet.Presence packet)
    Process the received Presence packet.
    protected void
     
    protected void
    recordClaimedIdentity(org.xmlpull.v1.XmlPullParser xpp)
    Records the identity that the peer claims in the 'from' attribute of the stream header that is currently being processed, as an unverified hint (RFC 6120 § 4.7.1, XEP-0388).
    protected void
    Emits post-authentication stream features for SASL2 (XEP-0388), which does NOT restart the stream.
    protected void
    After SASL authentication was successful we should open a new stream and offer new stream features such as resource binding and session establishment.
    void
     
    protected void
    tlsNegotiated(org.xmlpull.v1.XmlPullParser xpp)
    TLS negotiation was successful so open a new stream and offer the new stream features.

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Field Details

    • PROPERTY_OVERWRITE_EMPTY_TO

      public static final SystemProperty<Boolean> PROPERTY_OVERWRITE_EMPTY_TO
    • connection

      protected Connection connection
    • sessionCreated

      protected boolean sessionCreated
    • startedTLS

      protected boolean startedTLS
      Flag that indicates that the client requested to use TLS and TLS has been negotiated. Once the client sent a new initial stream header the value will return to false. Note that this is capturing the status of TLS 'in flight', not a durable fact that TLS was established.
    • startedSASL

      protected boolean startedSASL
      Flag that indicates that the client requested to be authenticated. Once the authentication process is over the value will return to false. Note that this is capturing the status of SASL 'in flight', not a durable fact that SASL was used.
    • usingSASL2

      protected boolean usingSASL2
      Flag that indicates that the client used SASL2 (rather than the older, multi-roundtrip SASL(1)) to authenticate. Unlike startedTLS and startedSASL this captures a durable fact that SASL2 was used.
    • sasl2SessionResumed

      protected boolean sasl2SessionResumed
      Flag that indicates that SASL2 authentication succeeded by inline-resuming a pre-existing session (XEP-0198 § 9.2), rather than by binding a (new or Bind2) resource. When set, sasl2Successful() must not (re)send post-authentication stream features, per XEP-0198 § 9.2.
    • saslStatus

      protected SASLAuthentication.Status saslStatus
      SASL status based on the last SASL interaction
    • waitingCompressionACK

      protected boolean waitingCompressionACK
    • session

      protected LocalSession session
      Session associated with the socket reader.
    • router

      protected PacketRouter router
      Router used to route incoming packets to the correct channels.
  • Constructor Details

    • StanzaHandler

      public StanzaHandler(PacketRouter router, Connection connection)
      Creates a dedicated reader for a socket.
      Parameters:
      router - the router for sending packets that were read.
      connection - the connection being read.
  • Method Details

    • setSession

      public void setSession(LocalSession session)
    • process

      public void process(String stanza, XMPPPacketReader reader) throws Exception
      Throws:
      Exception
    • initiateSession

      protected void initiateSession(String stanza, XMPPPacketReader reader) throws Exception
      Throws:
      Exception
    • processStanza

      protected void processStanza(String stanza, XMPPPacketReader reader) throws Exception
      Throws:
      Exception
    • processIQ

      protected void processIQ(org.xmpp.packet.IQ packet) throws UnauthorizedException
      Process the received IQ packet. Registered PacketInterceptor will be invoked before and after the packet was routed.

      Subclasses may redefine this method for different reasons such as modifying the sender of the packet to avoid spoofing, rejecting the packet or even process the packet in another thread.

      Parameters:
      packet - the received packet.
      Throws:
      UnauthorizedException - if service is not available to sender.
    • processPresence

      protected void processPresence(org.xmpp.packet.Presence packet) throws UnauthorizedException
      Process the received Presence packet. Registered PacketInterceptor will be invoked before and after the packet was routed.

      Subclasses may redefine this method for different reasons such as modifying the sender of the packet to avoid spoofing, rejecting the packet or even process the packet in another thread.

      Parameters:
      packet - the received packet.
      Throws:
      UnauthorizedException - if service is not available to sender.
    • processMessage

      protected void processMessage(org.xmpp.packet.Message packet) throws UnauthorizedException
      Process the received Message packet. Registered PacketInterceptor will be invoked before and after the packet was routed.

      Subclasses may redefine this method for different reasons such as modifying the sender of the packet to avoid spoofing, rejecting the packet or even process the packet in another thread.

      Parameters:
      packet - the received packet.
      Throws:
      UnauthorizedException - if service is not available to sender.
    • negotiateTLS

      protected boolean negotiateTLS()
      Tries to encrypt the connection using TLS. If the connection is encrypted then reset the parser to use the new encrypted reader. But if the connection failed to be encrypted then send a stanza and close the connection.
      Returns:
      true if the connection was encrypted.
    • tlsNegotiated

      protected void tlsNegotiated(org.xmlpull.v1.XmlPullParser xpp) throws org.xmlpull.v1.XmlPullParserException, IOException
      TLS negotiation was successful so open a new stream and offer the new stream features. The new stream features will include available SASL mechanisms and specific features depending on the session type such as auth for Non-SASL authentication and register for in-band registration.
      Throws:
      org.xmlpull.v1.XmlPullParserException
      IOException
    • saslSuccessful

      protected void saslSuccessful()
      After SASL authentication was successful we should open a new stream and offer new stream features such as resource binding and session establishment. Notice that resource binding and session establishment should only be offered to clients (i.e. not to servers or external components)
    • sasl2Successful

      protected void sasl2Successful()
      Emits post-authentication stream features for SASL2 (XEP-0388), which does NOT restart the stream. When the SASL2 authentication succeeded by inline-resuming a pre-existing session (XEP-0198 § 9.2), features are deliberately not (re)sent: the resumed stream is considered re-established immediately after the <success/> element, and XEP-0198 § 9.2 mandates that stream features MUST NOT be sent in this case.
    • deliverSasl2Features

      protected void deliverSasl2Features()
      Delivers post-authentication stream features for SASL2 (XEP-0388). On TCP the features element is sent inline in the existing stream. Transports with different framing (e.g. RFC 7395 WebSocket) override this.
    • adoptSasl2ResumedSession

      protected void adoptSasl2ResumedSession(LocalSession authenticatingSession)
      Adopts the pre-existing session that a SASL2 authentication resumed inline (XEP-0198 § 9.2), replacing the temporary session that was negotiating the SASL2 authentication. The <success/> response (including the <resumed/> element) has already been delivered, over the resumed session, by SASLAuthentication, and XEP-0198 § 9.2 forbids sending stream features after it. This method therefore only switches this handler over to the resumed session; no features are sent. The sasl2SessionResumed flag it sets guards sasl2Successful() against a future caller that would. Note that transferring the connection re-initializes it for its new owner, which on some transports already replaces this handler's session. The switch is performed here regardless, so that this does not depend on the transport. For the same reason, the session that negotiated the authentication (which holds the outcome of that negotiation) must be provided by the caller, rather than read from session.
      Parameters:
      authenticatingSession - the session that negotiated the SASL2 authentication (cannot be null).
    • generateFeatures

      protected org.dom4j.Element generateFeatures()
      Helper to generate stream:features, populated simply from the session.,
      Returns:
      Element <stream:features/>
    • compressClient

      protected boolean compressClient(org.dom4j.Element doc)
      Start using compression but first check if the connection can and should use compression. The connection will be closed if the requested method is not supported, if the connection is already using compression or if client requested to use compression but this feature is disabled.
      Parameters:
      doc - the element sent by the client requesting compression. Compression method is included.
      Returns:
      true if it was possible to use compression.
    • compressionSuccessful

      protected void compressionSuccessful()
      After compression was successful we should open a new stream and offer new stream features such as resource binding and session establishment. Notice that resource binding and session establishment should only be offered to clients (i.e. not to servers or external components)
    • isStreamManagementStanza

      protected boolean isStreamManagementStanza(org.dom4j.Element stanza)
      Determines whether stanza's namespace matches XEP-0198 namespace
      Parameters:
      stanza - Stanza to be checked
      Returns:
      whether stanza's namespace matches XEP-0198 namespace
    • getStreamHeader

      protected org.dom4j.Document getStreamHeader()
    • closeNeverEncryptedConnection

      protected void closeNeverEncryptedConnection()
      Close the connection since TLS was mandatory and the entity never negotiated TLS. Before closing the connection a stream error will be sent to the entity.
    • createSession

      protected void createSession(org.xmlpull.v1.XmlPullParser xpp) throws org.xmlpull.v1.XmlPullParserException, IOException
      Uses the XPP to grab the opening stream tag and create an active session object. The session to create will depend on the sent namespace. In all cases, the method obtains the opening stream tag, checks for errors, and either creates a session or returns an error and kills the connection. If the connection remains open, the XPP will be set to be ready for the first packet. A call to next() should result in an START_TAG state with the first packet in the stream.
      Parameters:
      xpp - the pull parser
      Throws:
      org.xmlpull.v1.XmlPullParserException - if an exception occurs reading from the pull parser
      IOException - if an IO exception occurs reading from the pull parser
    • recordClaimedIdentity

      protected void recordClaimedIdentity(org.xmlpull.v1.XmlPullParser xpp) throws org.xmlpull.v1.XmlPullParserException, IOException
      Records the identity that the peer claims in the 'from' attribute of the stream header that is currently being processed, as an unverified hint (RFC 6120 § 4.7.1, XEP-0388). When the header carries no 'from' attribute, any claim made on a previous stream is cleared: a claim is scoped to the stream on which it was made. This is significant for the restart that follows TLS negotiation, where a claim made on the preceding unprotected stream (which an active attacker can modify) must not be allowed to influence what is advertised on the protected stream.
      Parameters:
      xpp - a parser for the stream header, which need not have been advanced to the element yet.
      Throws:
      org.xmlpull.v1.XmlPullParserException
      IOException
    • isHostUnknown

      protected boolean isHostUnknown(String host)
    • getAddress

      public org.xmpp.packet.JID getAddress()
      Obtain the address of the XMPP entity for which this StanzaHandler handles stanzas. Note that the value that is returned for this method can change over time. For example, if no session has been established yet, this method will return null, or, if resource binding occurs, the returned value might change. Values obtained from this method are therefore best not cached.
      Returns:
      The address of the XMPP entity for.
    • isStartOfStream

      protected boolean isStartOfStream(String xml)
      Checks if the provided XML data represents the beginning of a new XMPP stream.
      Parameters:
      xml - The XML to verify
      Returns:
      'true' if the provided data represents the beginning of an XMPP stream.
    • isEndOfStream

      protected boolean isEndOfStream(String xml)
      Checks if the provided XML data represents the end / closing of an XMPP stream.
      Parameters:
      xml - The XML to verify
      Returns:
      'true' if the provided data represents the end of an XMPP stream.