Example #1
0
        /// <summary>
        /// TODO: Documentation ConnectionBind
        /// </summary>
        /// <param name="connectionId"></param>
        /// <param name="username"></param>
        /// <param name="password"></param>
        public void ConnectionBind(StunAttribute connectionId, String username, String password)
        {
            this.TurnTcpManager = new TurnManager(this.StunClient.ServerEP,
                                                  this.StunClient.ProtocolType,
                                                  this.StunClient.ClientCertificate,
                                                  this.StunClient.RemoteCertificateValidation);

            this.TurnTcpManager.OnAllocateSucceed += (object sender, TurnAllocation allocation, StunMessage sentMsg, StunMessage receivedMsg) =>
            {
                StunMessage msg = new StunMessage(StunMethodType.ConnectionBind, StunMethodClass.Request, StunUtilities.NewTransactionId);

                msg.Turn.ConnectionId = connectionId;
                msg.Stun.Username     = new UTF8Attribute(StunAttributeType.Username, allocation.Username);
                msg.Stun.Realm        = new UTF8Attribute(StunAttributeType.Realm, allocation.Realm);
                msg.Stun.Nonce        = new UTF8Attribute(StunAttributeType.Nonce, allocation.Nonce);

                msg.AddMessageIntegrity(allocation.Password, true);

                this.TurnTcpManager.StunClient.BeginSendMessage(msg, this.TurnTcpManager.StunClient.Socket);
            };

            this.TurnTcpManager.OnConnectionBindSucceed += (object sender, Socket connectedSocket, StunMessage receivedMsg) =>
            {
                this.TurnTcpManager.Allocations.Clear();
                this.TurnTcpManager.StunClient.Cancel = true;

                if (this.OnConnectionBindSucceed != null)
                {
                    this.OnConnectionBindSucceed(sender, connectedSocket, receivedMsg);
                }
            };

            this.TurnTcpManager.Connect();
            this.TurnTcpManager.Allocate(username, password);
        }
Example #2
0
        /// <summary>
        /// Parses an array of bytes containing every attributes of a message and
        /// add them to managed and unmanaged attributes lists
        /// </summary>
        /// <param name="attributes">The array of byte which contains every attributes of a message</param>
        private void ImportAttributes(byte[] attributes)
        {
            Int32 offset           = 0;
            Int32 attributesLength = attributes.Length;

            while (offset < attributesLength)
            {
                // We retrieve length and add it attribute header length (4 bytes)
                UInt16 valueLength     = BitConverter.ToUInt16(StunUtilities.SubArray(attributes, offset + 2, 2), 0);
                UInt16 attributeLength = (UInt16)(StunUtilities.ReverseBytes(valueLength) + 4);

                // Adjust original length to a padded 32bit length
                if (attributeLength % 4 != 0)
                {
                    attributeLength = (UInt16)(attributeLength + (4 - attributeLength % 4));
                }

                StunAttribute attr = StunUtilities.SubArray(attributes, offset, attributeLength);

                // When doing auto conversion of a byte array, according to STUN RFC 5389
                // only the first attribute of a given type must be taken into account
                this.SetAttribute(attr, false);

                offset += attributeLength;
            }
        }
Example #3
0
 /// <summary>
 /// Add an attribute to this message
 /// If the attribute is not managed by this library, it will be added to the UnmanagedAttributes list
 /// </summary>
 /// <param name="attribute">The attribute to add</param>
 /// <param name="replaceExistingAttribute">
 /// If TRUE, any existing attribute of the same type as the attribute parameter
 /// will be replaced by the attribute in parameter
 /// </param>
 public void SetAttribute(StunAttribute attribute, Boolean replaceExistingAttribute)
 {
     if (attribute.Type == StunAttributeType.Unmanaged)
     {
         this.unmanagedAttributesList.Add(attribute);
     }
     else
     {
         if (!this.attributesList.ContainsKey(attribute.Type))
         {
             this.attributesList.Add(attribute.Type, attribute);
         }
         else
         if (replaceExistingAttribute)
         {
             this.attributesList[attribute.Type] = attribute;
         }
     }
 }
Example #4
0
        /// <summary>
        /// Add the MESSAGE-INTEGRITY attribute to the message.
        /// This should be fired just before a call to StunClient.SendMessage as it needs existing
        /// attribute to be computed. But these attributes MUST be added before the MESSAGE-ATTRIBUTE
        /// except for FINGERPRINT attribute which MUST be added at the end of the StunMessage
        /// and also used in the MESSAGE-INTEGRITY computation
        /// </summary>
        /// <param name="password">The password used to authenticate the StunMessage</param>
        /// <param name="useLongTermCredentials">True if this StunMessage should authenticate using longterm credentials</param>
        public void AddMessageIntegrity(String password, Boolean useLongTermCredentials)
        {
            password = new SASLprep().Prepare(password);

            byte[] hmacSha1Key;

            if (useLongTermCredentials)
            {
                if (this.Stun.Username == null)
                {
                    throw new ArgumentException("USERNAME attribute is mandatory for long-term credentials MESSAGE-INTEGRITY creation", "this.Username");
                }

                if (this.Stun.Realm == null)
                {
                    throw new ArgumentException("REALM attribute is mandatory for long-term credentials MESSAGE-INTEGRITY creation", "this.Realm");
                }

                using (MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider())
                {
                    String valueToHashMD5 = String.Format(CultureInfo.CurrentCulture,
                                                          "{0}:{1}:{2}",
                                                          this.Stun.Username.ValueString,
                                                          this.Stun.Realm.ValueString,
                                                          password);

                    hmacSha1Key = md5.ComputeHash(StunMessage.Encoder.GetBytes(valueToHashMD5));
                }
            }
            else
            {
                hmacSha1Key = StunMessage.Encoder.GetBytes(password);
            }

            StunAttribute messageIntegrity = new StunAttribute(StunAttributeType.MessageIntegrity,
                                                               this.ComputeHMAC(hmacSha1Key));

            this.SetAttribute(messageIntegrity);
        }
Example #5
0
        /// <summary>
        /// TODO: Documentation ConnectionBind
        /// </summary>
        /// <param name="connectionId"></param>
        /// <param name="username"></param>
        /// <param name="password"></param>
        public void ConnectionBind(StunAttribute connectionId, String username, String password)
        {
            this.TurnTcpManager = new TurnManager(this.StunClient.ServerEP,
                                                  this.StunClient.ProtocolType,
                                                  this.StunClient.ClientCertificate,
                                                  this.StunClient.RemoteCertificateValidation);

            this.TurnTcpManager.OnAllocateSucceed += (object sender, TurnAllocation allocation, StunMessage sentMsg, StunMessage receivedMsg) =>
                {
                    StunMessage msg = new StunMessage(StunMethodType.ConnectionBind, StunMethodClass.Request, StunUtilities.NewTransactionId);

                    msg.Turn.ConnectionId = connectionId;
                    msg.Stun.Username = new UTF8Attribute(StunAttributeType.Username, allocation.Username);
                    msg.Stun.Realm = new UTF8Attribute(StunAttributeType.Realm, allocation.Realm);
                    msg.Stun.Nonce = new UTF8Attribute(StunAttributeType.Nonce, allocation.Nonce);

                    msg.AddMessageIntegrity(allocation.Password, true);

                    this.TurnTcpManager.StunClient.BeginSendMessage(msg, this.TurnTcpManager.StunClient.Socket);
                };

            this.TurnTcpManager.OnConnectionBindSucceed += (object sender, Socket connectedSocket, StunMessage receivedMsg) =>
                {
                    this.TurnTcpManager.Allocations.Clear();
                    this.TurnTcpManager.StunClient.Cancel = true;

                    if (this.OnConnectionBindSucceed != null)
                        this.OnConnectionBindSucceed(sender, connectedSocket, receivedMsg);
                };

            this.TurnTcpManager.Connect();
            this.TurnTcpManager.Allocate(username, password);
        }
Example #6
0
 /// <summary>
 /// Add an attribute to this message
 /// Any existing attribute of the same type will be replaced by the attribute in parameter.
 /// </summary>
 /// <param name="attribute">The attribute to add</param>
 public void SetAttribute(StunAttribute attribute)
 {
     this.SetAttribute(attribute, true);
 }
Example #7
0
        /// <summary>
        /// Add the MESSAGE-INTEGRITY attribute to the message.
        /// This should be fired just before a call to StunClient.SendMessage as it needs existing
        /// attribute to be computed. But these attributes MUST be added before the MESSAGE-ATTRIBUTE
        /// except for FINGERPRINT attribute which MUST be added at the end of the StunMessage
        /// and also used in the MESSAGE-INTEGRITY computation
        /// </summary>
        /// <param name="password">The password used to authenticate the StunMessage</param>
        /// <param name="useLongTermCredentials">True if this StunMessage should authenticate using longterm credentials</param>
        public void AddMessageIntegrity(String password, Boolean useLongTermCredentials)
        {
            password = new SASLprep().Prepare(password);

            byte[] hmacSha1Key;

            if (useLongTermCredentials)
            {
                if (this.Stun.Username == null)
                    throw new ArgumentException("USERNAME attribute is mandatory for long-term credentials MESSAGE-INTEGRITY creation", "this.Username");

                if (this.Stun.Realm == null)
                    throw new ArgumentException("REALM attribute is mandatory for long-term credentials MESSAGE-INTEGRITY creation", "this.Realm");

                using (MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider())
                {
                    String valueToHashMD5 = String.Format(CultureInfo.CurrentCulture,
                                                          "{0}:{1}:{2}",
                                                          this.Stun.Username.ValueString,
                                                          this.Stun.Realm.ValueString,
                                                          password);

                    hmacSha1Key = md5.ComputeHash(StunMessage.Encoder.GetBytes(valueToHashMD5));
                }
            }
            else
            {
                hmacSha1Key = StunMessage.Encoder.GetBytes(password);
            }

            StunAttribute messageIntegrity = new StunAttribute(StunAttributeType.MessageIntegrity,
                                                               this.ComputeHMAC(hmacSha1Key));
            this.SetAttribute(messageIntegrity);
        }
Example #8
0
 /// <summary>
 /// Add an attribute to this message
 /// If the attribute is not managed by this library, it will be added to the UnmanagedAttributes list
 /// </summary>
 /// <param name="attribute">The attribute to add</param>
 /// <param name="replaceExistingAttribute">
 /// If TRUE, any existing attribute of the same type as the attribute parameter
 /// will be replaced by the attribute in parameter
 /// </param>
 public void SetAttribute(StunAttribute attribute, Boolean replaceExistingAttribute)
 {
     if (attribute.Type == StunAttributeType.Unmanaged)
     {
         this.unmanagedAttributesList.Add(attribute);
     }
     else
     {
         if (!this.attributesList.ContainsKey(attribute.Type))
             this.attributesList.Add(attribute.Type, attribute);
         else
             if (replaceExistingAttribute)
                 this.attributesList[attribute.Type] = attribute;
     }
 }
Example #9
0
 /// <summary>
 /// Add an attribute to this message
 /// Any existing attribute of the same type will be replaced by the attribute in parameter.
 /// </summary>
 /// <param name="attribute">The attribute to add</param>
 public void SetAttribute(StunAttribute attribute)
 {
     this.SetAttribute(attribute, true);
 }
Example #10
0
 /// <summary>
 /// Constructs a new StunAttribute
 /// </summary>
 /// <param name="type">The type of this StunAttribute</param>
 /// <param name="value">The value of this StunAttribute</param>
 public StunAttribute(StunAttributeType type, byte[] value)
     : this(type, StunAttribute.AttributeTypeToBytes(type), value)
 {
 }