Beispiel #1
0
        /// <summary>
        /// Send a request to the server and waits for a response back.
        /// </summary>
        /// <param name="request">Request to be sent to the server.</param>
        /// <returns>Response packet if a valid reponse is received from the server; otherwise Nothing.</returns>
        public RadiusPacket ProcessRequest(RadiusPacket request)
        {
            CheckDisposed();
            RadiusPacket response = null;
            // We wait indefinately for the connection to establish. But since this is UDP, the connection
            // will always be successful (locally we're binding to any available UDP port).
            if (m_udpClient.CurrentState == ClientState.Connected)
            {
                // We have a UDP socket we can use for exchanging packets.
                DateTime stopTime;
                for (int i = 1; i <= m_requestAttempts; i++)
                {
                    m_responseBytes = null;
                    m_udpClient.Send(request.BinaryImage());

                    stopTime = DateTime.Now.AddMilliseconds(m_reponseTimeout);
                    while (true)
                    {
                        Thread.Sleep(1);
                        // Stay in the loop until:
                        // 1) We receive a response OR
                        // 2) We exceed the response timeout duration
                        if ((m_responseBytes != null) || DateTime.Now > stopTime)
                        {
                            break;
                        }
                    }

                    if (m_responseBytes != null)
                    {
                        // The server sent a response.
                        response = new RadiusPacket(m_responseBytes, 0, m_responseBytes.Length);
                        if (response.Identifier == request.Identifier && response.Authenticator.CompareTo(RadiusPacket.CreateResponseAuthenticator(m_sharedSecret, request, response)) == 0)
                        {
                            // The response has passed the verification.
                            break;
                        }
                        else
                        {
                            // The response failed the verification, so we'll silently discard it.
                            response = null;
                        }
                    }
                }
            }

            return response;
        }
Beispiel #2
0
        /// <summary>
        /// Generates an "Authenticator" value used in a RADIUS response packet sent by the server to client.
        /// </summary>
        /// <param name="sharedSecret">The shared secret key.</param>
        /// <param name="requestPacket">RADIUS packet sent from client to server.</param>
        /// <param name="responsePacket">RADIUS packet sent from server to client.</param>
        /// <returns>A byte array.</returns>
        public static byte[] CreateResponseAuthenticator(string sharedSecret, RadiusPacket requestPacket, RadiusPacket responsePacket)
        {
            // Response authenticator is generated as follows:
            // MD5(Code + Identifier + Length + Request Authenticator + Attributes + Shared Secret)
            //   where:
            //   Code, Identifier, Length & Attributes are from the response RADIUS packet
            //   Request Authenticator is from the request RADIUS packet
            //   Shared Secret is the shared secret ket
            int length = responsePacket.BinaryLength;
            byte[] sharedSecretBytes = Encoding.GetBytes(sharedSecret);
            byte[] buffer = BufferPool.TakeBuffer(length + sharedSecretBytes.Length);

            try
            {
                responsePacket.GenerateBinaryImage(buffer, 0);
                Buffer.BlockCopy(requestPacket.BinaryImage(), 4, buffer, 4, 16);
                Buffer.BlockCopy(sharedSecretBytes, 0, buffer, length, sharedSecretBytes.Length);

                return new MD5CryptoServiceProvider().ComputeHash(buffer);
            }
            finally
            {
                if (buffer != null)
                    BufferPool.ReturnBuffer(buffer);
            }
        }