//****************************************************************************************************** // RadiusPacketAttribute.cs - Gbtc // // Copyright © 2012, Grid Protection Alliance. All Rights Reserved. // // Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See // the NOTICE file distributed with this work for additional information regarding copyright ownership. // The GPA licenses this file to you under the MIT License (MIT), the "License"; you may // not use this file except in compliance with the License. You may obtain a copy of the License at: // // http://www.opensource.org/licenses/MIT // // Unless agreed to in writing, the subject software distributed under the License is distributed on an // "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the // License for the specific language governing permissions and limitations. // // Code Modification History: // ---------------------------------------------------------------------------------------------------- // 11/26/2010 - Pinal C. Patel // Generated original version of source code. // 11/23/2011 - J. Ritchie Carroll // Modified to support buffer optimized ISupportBinaryImage. // 12/13/2012 - Starlynn Danyelle Gilliam // Modified Header. // //****************************************************************************************************** using System; using System.Net; using GSF.Parsing; namespace GSF.Communication.Radius { #region [ Enumerations ] /// /// Specifies the type of . /// public enum AttributeType { /// /// Attribute indicates the name of the user to be authenticated. /// UserName = 1, /// /// Attribute indicates the password of the user to be authenticated. /// UserPassword = 2, /// /// Attribute indicates the response provided by a PPP CHAP user in reponse to the challenge. /// ChapPassword = 3, /// /// Attribute indicates the identifying IP address of the NAS requesting user authentication. /// NasIpAddress = 4, /// /// Attribute indicates the physical port number of the NAS which is authenticating the user. /// NasPort = 5, /// /// Attribute indicates the type of service the user has requested, or the type of service to be provided. /// ServiceType = 6, /// /// Attribute indicates the framing to be used for framed access. /// FramedProtocol = 7, /// /// Attribute indicates the address to be configured for the user. /// FramedIpAddress = 8, /// /// Attribute indicates the IP netmask to be configured for the user when user is a router to a network. /// FramedIpNetmask = 9, /// /// Attribute indicates the routing method for the user when user is a router to a network. /// FramedRouting = 10, /// /// Attribute indicates the name of the filter list for this user. /// FilterId = 11, /// /// Attribute indicates the MTU to be configured for the user when it is not negotiated by some other means. /// FramedMtu = 12, /// /// Attribute indicates a compression protocol to be used for the link. /// FramedCompression = 13, /// /// Attribute indicates the system with which to connect the user when attribute is included. /// LoginIpHost = 14, /// /// Attribute indicates the service to use to connect the user to the login host. /// LoginService = 15, /// /// Attribute indicates the TCP port with which the user is to be connected when attribute is included. /// LoginTcpPort = 16, /// /// Attribute indicates the text which may be displayed to the user. /// ReplyMessage = 18, /// /// Attribute indicates a dialing string to be used for callback. /// CallbackNumber = 19, /// /// Attribute indicates the name of a place to be called. /// CallbackId = 20, /// /// Attribute provides routing information to be configured for the user on the NAS. /// FramedRoute = 22, /// /// Attribute indicates the IPX Network number to be configured for the user. /// FramedIpxNetwork = 23, /// /// Attribute available to be sent by the server to the client in an and must be /// sent unmodified from the client to the server in the new reply to the challenge. /// State = 24, /// /// Attribute available to be sent by the server to the client in an and should /// be sent unmodified by the client to the accounting server as part of the . /// Class = 25, /// /// Attribute available to allow vendors to support their own extended attributes. /// VendorSpecific = 26, /// /// Attribute sets the maximum number of seconds of service to be provided to the user before termination of the session or prompt. /// SessionTimeout = 27, /// /// Attribute sets the maximum number of consecutive seconds of idle connection allowed to the user before termination of the session or prompt. /// IdleTimeout = 28, /// /// Attribute indicates the action the NAS should take when the specified service is complete. /// TerminationAction = 29, /// /// Attribute indicates the phone number that the user called using DNIS or similar technology. /// CallerStationId = 30, /// /// Attribute indicates the phone number the call came from using ANI or similar technology. /// CallingStationId = 31, /// /// Attribute indicates a string identifier for the NAS originating the AccessRequest. /// NasIdentifier = 32, /// /// Attribute indicates the state a proxy server forwarding requests to the server. /// ProxyState = 33, /// /// Attribute indicates the system with which the user is to be connected by LAT. /// LoginLatService = 34, /// /// Attribute indicates the Node with which the user is to be automatically connected by LAT. /// LoginLatNode = 35, /// /// Attribute indicates the string identifier for the LAT group codes which the user is authorized to use. /// LoginLatGroup = 36, /// /// Attribute indicates the AppleTalk network number which should be used for the serial link to the user. /// FramedAppleTalkLink = 37, /// /// Attribute indicates the AppleTalk Network number which the NAS should probe to allocate an AppleTalk node for the user. /// FramedAppleTalkNetwork = 38, /// /// Attribute indicates the AppleTalk Default Zone to be used for this user. /// FramedAppleTalkZone = 39, /// /// Attribute contains the CHAP Challenge sent by the NAS to a PPP CHAP user. /// ChapChallenge = 60, /// /// Attribute indicates the type of physical port of the NAS which is authenticating the user. /// NasPortType = 61, /// /// Attribute sets the maximum number of ports to be provided to the user by the NAS. /// PortLimit = 62, /// /// Attribute indicates the Port with which the user is to be connected by the LAT. /// LoginLatPort = 63 } #endregion /// /// Represents an attribute of . /// /// /// public class RadiusPacketAttribute : ISupportBinaryImage { // 0 1 2 // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 //+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- //| Type | Length | Value ... //+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- #region [ Members ] // Fields private byte[] m_value; #endregion #region [ Constructors ] /// /// Initializes a new instance of the class. /// public RadiusPacketAttribute() { // No initialization required. } /// /// Initializes a new instance of the class. /// /// Type of the . /// Text value of the . public RadiusPacketAttribute(AttributeType type, string value) : this(type, RadiusPacket.Encoding.GetBytes(value)) { } /// /// Initializes a new instance of the class. /// /// Type of the . /// 32-bit unsigned integer value of the . public RadiusPacketAttribute(AttributeType type, uint value) : this(type, RadiusPacket.EndianOrder.GetBytes(value)) { } /// /// Initializes a new instance of the class. /// /// Type of the . /// IP address value of the . public RadiusPacketAttribute(AttributeType type, IPAddress value) : this(type, value.GetAddressBytes()) { } /// /// Initializes a new instance of the class. /// /// Type of the . /// Byte array value of the . public RadiusPacketAttribute(AttributeType type, byte[] value) { Type = type; Value = value; } /// /// Initializes a new instance of the class. /// /// Buffer containing binary image to be used for initializing . /// 0-based starting index of initialization data in the . /// Valid number of bytes in from . public RadiusPacketAttribute(byte[] buffer, int startIndex, int length) => ParseBinaryImage(buffer, startIndex, length); #endregion #region [ Properties ] /// /// Gets or sets the type of the . /// public AttributeType Type { get; set; } /// /// Gets or sets the value of the . /// /// The value being assigned is null or zero-length byte array. public byte[] Value { get => m_value; set { // By definition, attribute value cannot be null or zero-length. if (value == null || value.Length == 0) throw new ArgumentNullException(nameof(value)); m_value = value; } } /// /// Gets the length of the . /// // 2 bytes are fixed + length of the value public int BinaryLength => 2 + m_value?.Length ?? 0; #endregion #region [ Methods ] /// /// Parses object by parsing the specified containing a binary image. /// /// Buffer containing binary image to parse. /// 0-based starting index in the to start parsing. /// Valid number of bytes within from . /// The number of bytes used for initialization in the (i.e., the number of bytes parsed), or 0 if not enough data. /// is null. public int ParseBinaryImage(byte[] buffer, int startIndex, int length) { if (buffer == null) throw new ArgumentNullException(nameof(buffer)); int imageLength = BinaryLength; // Binary image does not have sufficient data. if (length < imageLength) return 0; // Binary image has sufficient data. Type = (AttributeType)buffer[startIndex]; m_value = new byte[Convert.ToInt16(buffer[startIndex + 1] - 2)]; Buffer.BlockCopy(buffer, startIndex + 2, m_value, 0, m_value.Length); return imageLength; } /// /// Generates a binary representation of this object and copies it into the given buffer. /// /// Buffer used to hold generated binary image of the source object. /// 0-based starting index in the to start writing. /// The number of bytes written to the . /// is null. /// /// or is less than 0 -or- /// and will exceed length. /// public int GenerateBinaryImage(byte[] buffer, int startIndex) { int length = BinaryLength; buffer.ValidateParameters(startIndex, length); // Populate the buffer buffer[startIndex] = Convert.ToByte(Type); buffer[startIndex + 1] = (byte)length; Buffer.BlockCopy(m_value, 0, buffer, startIndex + 2, m_value.Length); return length; } #endregion } }