//******************************************************************************************************
// 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
}
}