GSF.Communication.Radius.RadiusPacket.CreateRequestAuthenticator C# (CSharp) Method

CreateRequestAuthenticator() public static method

Generates an "Authenticator" value used in a RADIUS request packet sent by the client to server.
public static CreateRequestAuthenticator ( string sharedSecret ) : byte[]
sharedSecret string The shared secret to be used in generating the output.
return byte[]
        public static byte[] CreateRequestAuthenticator(string sharedSecret)
        {
            // We create a input buffer that'll be used to create a 16-byte value using the RSA MD5 algorithm.
            // Since the output value (The Authenticator) has to be unique over the life of the shared secret,
            // we prepend a randomly generated "salt" text to ensure the uniqueness of the output value.
            byte[] randomBuffer = new byte[16];
            byte[] secretBuffer = Encoding.GetBytes(sharedSecret);
            Random.GetBytes(randomBuffer);

            return new MD5CryptoServiceProvider().ComputeHash(randomBuffer.Combine(secretBuffer));
        }

Usage Example

Example #1
0
        /// <summary>
        /// Authenticates the username and password against the RADIUS server.
        /// </summary>
        /// <param name="username">Username to be authenticated.</param>
        /// <param name="password">Password to be authenticated.</param>
        /// <param name="state">State value from a previous challenge response.</param>
        /// <returns>Response packet received from the server for the authentication request.</returns>
        /// <remarks>
        /// <para>
        /// The type of response packet (if any) will be one of the following:
        /// <list>
        /// <item>AccessAccept: If the authentication is successful.</item>
        /// <item>AccessReject: If the authentication is not successful.</item>
        /// <item>AccessChallenge: If the server need more information from the user.</item>
        /// </list>
        /// </para>
        /// <para>
        /// When an AccessChallenge response packet is received from the server, it contains a State attribute
        /// that must be included in the AccessRequest packet that is being sent in response to the AccessChallenge
        /// response. So if this method returns an AccessChallenge packet, then this method is to be called again
        /// with the requested information (from ReplyMessage attribute) in the password field and the value State
        /// attribute.
        /// </para>
        /// </remarks>
        public RadiusPacket Authenticate(string username, string password, byte[] state)
        {
            CheckDisposed();

            if (string.IsNullOrEmpty(username) || string.IsNullOrEmpty(password))
            {
                throw new ArgumentException("Username and Password cannot be null.");
            }

            RadiusPacket request = new RadiusPacket(PacketType.AccessRequest);

            byte[] authenticator = RadiusPacket.CreateRequestAuthenticator(m_sharedSecret);

            request.Authenticator = authenticator;
            request.Attributes.Add(new RadiusPacketAttribute(AttributeType.UserName, username));
            request.Attributes.Add(new RadiusPacketAttribute(AttributeType.UserPassword, RadiusPacket.EncryptPassword(password, m_sharedSecret, authenticator)));

            // State attribute is used when responding to a AccessChallenge response.
            if ((object)state != null)
            {
                request.Attributes.Add(new RadiusPacketAttribute(AttributeType.State, state));
            }

            return(ProcessRequest(request));
        }