All Downloads are FREE. Search and download functionalities are using the official Maven repository.

spinoco.protocol.stun.StunAttribute.scala Maven / Gradle / Ivy

The newest version!
package spinoco.protocol.stun

import java.net.{Inet4Address, InetAddress, InetSocketAddress}

import scodec.bits.ByteVector


sealed trait StunAttribute


object StunAttribute {

  /**
    * The MAPPED-ADDRESS attribute indicates a reflexive transport address
    * of the client.
    *
    * https://tools.ietf.org/html/rfc5389#section-15.1
    *
    * @param address  Reflective address of the client
    */
  case class MappedAddress (
   address:InetSocketAddress
  ) extends StunAttribute

  /**
    * The MAPPED-ADDRESS attribute indicates a reflexive transport address
    * of the client.
    *
    * https://tools.ietf.org/html/rfc5389#section-15.2
    *
    * @param port       Port of Reflective address of the client
    * @param address    Contains address of the client in raw, xor-ed from. address can be decoded via
    *                   decode function.
    */
  case class XorMappedAddress (
    port:Int
    , address:ByteVector
  ) extends StunAttribute  {

    /** decodes address. ipv6 requires transactionId for decoding **/
    def decode(tx:TransactionId):InetSocketAddress = {
      ???
    }

  }

  /**
    *  The USERNAME attribute is used for message integrity.  It identifies
    *  the username and password combination used in the message-integrity
    *  check.
    *
    *  https://tools.ietf.org/html/rfc5389#section-15.3
    *
    * @param authorization      The value of USERNAME is a variable-length value.  It MUST contain a
    *                           UTF-8 [RFC3629] encoded sequence of less than 513 bytes, and MUST
    *                           have been processed using SASLprep [RFC4013].
    */
  case class UserName (
    authorization:String
  ) extends StunAttribute


  /**
    * The MESSAGE-INTEGRITY attribute contains an HMAC-SHA1 [RFC2104] of
    * the STUN message.  The MESSAGE-INTEGRITY attribute can be present in
    * any STUN message type.  Since it uses the SHA1 hash, the HMAC will be
    * 20 bytes.  The text used as input to HMAC is the STUN message,
    * including the header, up to and including the attribute preceding the
    * MESSAGE-INTEGRITY attribute.  With the exception of the FINGERPRINT
    * attribute, which appears after MESSAGE-INTEGRITY, agents MUST ignore
    * all other attributes that follow MESSAGE-INTEGRITY.
    *
    * https://tools.ietf.org/html/rfc5389#section-15.4
    *
    * @param hash   The key for the HMAC depends on whether long-term or short-term
    *               credentials are in use.
    *
    *               For long-term credentials, the key is 16 bytes:
    *
    *               key = MD5(username ":" realm ":" SASLprep(password))
    *
    *               That is, the 16-byte key is formed by taking the MD5 hash of the
    *               result of concatenating the following five fields: (1) the username,
    *               with any quotes and trailing nulls removed, as taken from the
    *               USERNAME attribute (in which case SASLprep has already been applied);
    *               (2) a single colon; (3) the realm, with any quotes and trailing nulls
    *               removed; (4) a single colon; and (5) the password, with any trailing
    *               nulls removed and after processing using SASLprep.  For example, if
    *               the username was 'user', the realm was 'realm', and the password was
    *               'pass', then the 16-byte HMAC key would be the result of performing
    *               an MD5 hash on the string 'user:realm:pass', the resulting hash being
    *               0x8493fbc53ba582fb4c044c456bdc40eb.
    *
    *               For short-term credentials:
    *
    *                 key = SASLprep(password)
    *
    *               where MD5 is defined in RFC 1321 [RFC1321] and SASLprep() is defined
    *               in RFC 4013 [RFC4013].
    *
    *
    */
  case class MessageIntegrity(
    hash:ByteVector
  )  extends StunAttribute

  /**
    * The FINGERPRINT attribute MAY be present in all STUN messages.
    *
    * https://tools.ietf.org/html/rfc5389#section-15.5
    *
    * @param crc32    The value of the attribute is computed as the CRC-32 of the STUN message
    *                 up to (but excluding) the FINGERPRINT attribute itself, XOR'ed with
    *                 the 32-bit value 0x5354554e (the XOR helps in cases where an
    *                 application packet is also using CRC-32 in it).
    */
  case class FingerPrint(
    crc32: Long
  ) extends StunAttribute

  /**
    * The ERROR-CODE attribute is used in error response messages.
    *
    * https://tools.ietf.org/html/rfc5389#section-15.6
    *
    * @param cause      Numeric error code value in the range of 300 to 699 plus a
    *                   textual reason phrase encoded in UTF-8 [RFC3629], and is consistent
    *                   in its code assignments and semantics with SIP [RFC3261] and HTTP
    *                   [RFC2616].
    *
    * @param phrase     The reason phrase is meant for user consumption, and can
    *                   be anything appropriate for the error code.  Recommended reason
    *                   phrases for the defined error codes are included in the IANA registry
    *                   for error codes.  The reason phrase MUST be a UTF-8 [RFC3629] encoded
    *                   sequence of less than 128 characters (which can be as long as 763
    *                   bytes).
    */
  case class ErrorCode(
    cause: ErrorCause.Value
    , phrase: String
  ) extends StunAttribute


  /**
    *  The REALM attribute may be present in requests and responses.
    *
    *  https://tools.ietf.org/html/rfc5389#section-15.7
    *
    *  @param realm     It  contains text that meets the grammar for "realm-value" as described
    *                   in RFC 3261 [RFC3261] but without the double quotes and their
    *                   surrounding whitespace.  That is, it is an unquoted realm-value (and
    *                   is therefore a sequence of qdtext or quoted-pair).  It MUST be a
    *                   UTF-8 [RFC3629] encoded sequence of less than 128 characters (which
    *                   can be as long as 763 bytes), and MUST have been processed using
    *                   SASLprep [RFC4013].
    */
  case class Realm(
    realm:String
  ) extends StunAttribute


  /**
    * The NONCE attribute may be present in requests and responses.
    *
    * https://tools.ietf.org/html/rfc5389#section-15.8
    *
    * @param nonce      sequence of qdtext or quoted-pair, which are defined in
    *                   RFC 3261 [RFC3261].  Note that this means that the NONCE attribute
    *                   will not contain actual quote characters.  See RFC 2617 [RFC2617],
    *                   Section 4.3, for guidance on selection of nonce values in a server.
    *
    */
  case class Nonce(
    nonce:String
  ) extends StunAttribute

  /**
    * The UNKNOWN-ATTRIBUTES attribute is present only in an error response
    * when the response code in the ERROR-CODE attribute is 420.
    *
    * https://tools.ietf.org/html/rfc5389#section-15.9
    *
    * @param attributes   The attribute contains a list of 16-bit values, each of which
    *                     represents an attribute type that was not understood by the server.
    *
    */
  case class UnknownAttributes(
    attributes:Vector[Int]
  ) extends StunAttribute

  /**
    * The SOFTWARE attribute contains a textual description of the software
    * being used by the agent sending the message.
    *
    * https://tools.ietf.org/html/rfc5389#section-15.10
    *
    * @param description   Description of the software
    */
  case class Software(
    description:String
  ) extends StunAttribute

  /**
    * The alternate server represents an alternate transport address
    * identifying a different STUN server that the STUN client should try.
    *
    * https://tools.ietf.org/html/rfc5389#section-15.11
    *
    * @param address Address of the alternate server. Family must match the source request family.
    */
  case class AlternateServer(
    address:InetSocketAddress
  ) extends StunAttribute

  /**
    * The PRIORITY attribute indicates the priority that is to be
    * associated with a peer reflexive candidate, should one be discovered
    * by this check.
    *
    * https://tools.ietf.org/html/rfc5245#section-19.1
    *
    * @param priority   Priority of the candidate
    */
  case class Priority(
    priority:Long
  ) extends StunAttribute

  /**
    * The USE-CANDIDATE attribute indicates that the candidate pair
    * resulting from this check should be used for transmission of media.
    *
    * https://tools.ietf.org/html/rfc5245#section-19.1
    *
    */
  case object UseCandidate extends StunAttribute

  /**
    * The ICE-CONTROLLED attribute is present in a Binding request and
    * indicates that the client believes it is currently in the controlled
    * role.
    *
    * https://tools.ietf.org/html/rfc5245#section-19.1
    *
    * @param rnd  The content of the attribute is a 64-bit unsigned integer in
    *             network byte order, which contains a random number used for tie-
    *             breaking of role conflicts.
    */
  case class IceControlled(rnd:BigInt) extends StunAttribute

  /**
    * The ICE-CONTROLLING attribute is present in a Binding request and
    * indicates that the client believes it is currently in the controlling
    * role.
    *
    * https://tools.ietf.org/html/rfc5245#section-19.1
    *
    * @param rnd  The content of the attribute is a 64-bit unsigned integer in
    *             network byte order, which contains a random number used for tie-
    *             breaking of role conflicts.
    */
  case class IceControlling(rnd:BigInt) extends StunAttribute

}





sealed trait Family

object Family {

  def fromAddress(inetAddress: InetAddress) = inetAddress match {
    case _: Inet4Address => Family.IPv4
    case _: InetAddress => Family.IPv6
  }


  case object IPv4 extends Family

  case object IPv6 extends Family
}


object ErrorCause extends Enumeration {

  /**
    * Try Alternate: The client should contact an alternate server for
    * this request.  This error response MUST only be sent if the
    * request included a USERNAME attribute and a valid MESSAGE-
    * INTEGRITY attribute; otherwise, it MUST NOT be sent and error
    * code 400 (Bad Request) is suggested.  This error response MUST
    * be protected with the MESSAGE-INTEGRITY attribute, and receivers
    * MUST validate the MESSAGE-INTEGRITY of this response before
    * redirecting themselves to an alternate server.
    *
    * Note: Failure to generate and validate message integrity
    *       for a 300 response allows an on-path attacker to falsify a
    *       300 response thus causing subsequent STUN messages to be
    *       sent to a victim.
    */
  val TryAlternate = Value(300)

  /**
    * Bad Request: The request was malformed.  The client SHOULD NOT
    * retry the request without modification from the previous
    * attempt.  The server may not be able to generate a valid
    * MESSAGE-INTEGRITY for this error, so the client MUST NOT expect
    * a valid MESSAGE-INTEGRITY attribute on this response.
    */
  val BadRequest = Value(400)

  /**
    * Unauthorized: The request did not contain the correct
    * credentials to proceed.  The client should retry the request
    * with proper credentials.
    */
  val Unauthorized = Value(401)

  /**
    * Unknown Attribute: The server received a STUN packet containing
    * a comprehension-required attribute that it did not understand.
    * The server MUST put this unknown attribute in the UNKNOWN-
    * ATTRIBUTE attribute of its error response.
    */
  val UnknownAttribute = Value(420)

  /**
    * Stale Nonce: The NONCE used by the client was no longer valid.
    * The client should retry, using the NONCE provided in the
    * response.
    */
  val StaleNonce = Value(438)

  /**
    * Server Error: The server has suffered a temporary error.  The
    * client should try again.
    */
  val ServerError = Value(500)
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy