Initial Commit

master
Harald Christian Joachim Wolff 2019-04-23 09:24:09 +02:00
commit 1eb36046b6
22 changed files with 11689 additions and 0 deletions

View File

@ -0,0 +1,19 @@
// /**
// * File: RadiusAttributesCollection.cs
// * Author: haraldwolff
// *
// * This file and it's content is copyrighted by the Author and / or copyright holder.
// * Any use wihtout proper permission is illegal and may lead to legal actions.
// *
// *
// **/
using System;
namespace ln.radius
{
public class AttributesCollection
{
public AttributesCollection()
{
}
}
}

View File

@ -0,0 +1,35 @@
// /**
// * File: AssemblyInfo.cs
// * Author: haraldwolff
// *
// * This file and it's content is copyrighted by the Author and / or copyright holder.
// * Any use wihtout proper permission is illegal and may lead to legal actions.
// *
// *
// **/
using System.Reflection;
using System.Runtime.CompilerServices;
// Information about this assembly is defined by the following attributes.
// Change them to the values specific to your project.
[assembly: AssemblyTitle("ln.radius")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("")]
[assembly: AssemblyCopyright("")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
// The form "{Major}.{Minor}.*" will automatically update the build and revision,
// and "{Major}.{Minor}.{Build}.*" will update just the revision.
[assembly: AssemblyVersion("1.0.*")]
// The following attributes are used to specify the signing key for the assembly,
// if desired. See the Mono documentation for more information about signing.
//[assembly: AssemblyDelaySign(false)]
//[assembly: AssemblyKeyFile("")]

216
RadiusAttribute.cs 100644
View File

@ -0,0 +1,216 @@
// /**
// * File: RadiusAttribute.cs
// * Author: haraldwolff
// *
// * This file and it's content is copyrighted by the Author and / or copyright holder.
// * Any use wihtout proper permission is illegal and may lead to legal actions.
// *
// *
// **/
using System;
using System.IO;
using ln.types;
using System.Collections.Generic;
using System.Text;
using ln.types.net;
namespace ln.radius
{
public delegate RadiusAttribute RadiusAttributeFactory(byte attributeType);
public class RadiusAttribute
{
public byte Type { get; private set; }
public string Name => AttributeName(Type);
public virtual byte[] Bytes { get; set; }
public RadiusAttribute(byte type)
{
Type = type;
}
public byte[] ToBytes()
{
byte[] vBytes = Bytes;
byte[] bytes = new byte[vBytes.Length + 2];
bytes[0] = Type;
bytes[1] = (byte)bytes.Length;
Array.Copy(vBytes, 0, bytes, 2, vBytes.Length);
return bytes;
}
public static RadiusAttribute Read(Stream stream)
{
byte atype = (byte)stream.ReadByte();
byte alength = (byte)stream.ReadByte();
byte[] abytes = stream.ReadBytes(alength - 2);
RadiusAttribute radiusAttribute = RadiusAttribute.Create(atype);
radiusAttribute.Bytes = abytes;
return radiusAttribute;
}
public override string ToString()
{
foreach (byte by in Bytes)
{
if (by < 0x20)
return String.Format("[RadiusAttribute Type={0} {1}]", Name, BitConverter.ToString(Bytes));
}
return String.Format("[RadiusAttribute Type={0} {1}]", Name, Encoding.ASCII.GetString(Bytes));
}
static Dictionary<byte, string> attributeNames = new Dictionary<byte, string>();
static Dictionary<byte, RadiusAttributeFactory> attributeFactories = new Dictionary<byte, RadiusAttributeFactory>();
public static RadiusAttribute Create(byte attributeType)
{
if (attributeFactories.ContainsKey(attributeType))
return attributeFactories[attributeType](attributeType);
return new RadiusAttribute(attributeType);
}
public static String AttributeName(byte type)
{
if (attributeNames.ContainsKey(type))
return attributeNames[type];
return type.ToString();
}
public static void RegisterAttributeFactory(byte attributeType, string attributeName, RadiusAttributeFactory factory)
{
attributeFactories.Add(attributeType, factory);
attributeNames.Add(attributeType, attributeName);
}
static RadiusAttribute()
{
RegisterAttributeFactory(0x01, "User-Name", (type) => new RadiusAttribute(type));
RegisterAttributeFactory(0x02, "User-Password", (type) => new RadiusAttribute(type));
RegisterAttributeFactory(0x03, "CHAP-Password", (type) => new RadiusAttribute(type));
RegisterAttributeFactory(0x04, "NAS-IP-Address", (type) => new IPv4Attribute(type));
RegisterAttributeFactory(0x05, "NAS-Port", (type) => new IntAttribute(type));
RegisterAttributeFactory(0x06, "Service-Type", (type) => new IntAttribute(type));
RegisterAttributeFactory(0x07, "Framed-Protocol", (type) => new IntAttribute(type));
RegisterAttributeFactory(0x08, "Framed-IP-Address", (type) => new IPv4Attribute(type));
RegisterAttributeFactory(0x09, "Framed-IP-Netmask", (type) => new IPv4Attribute(type));
RegisterAttributeFactory(0x0A, "Framed-Routing", (type) => new IntAttribute(type));
RegisterAttributeFactory(0x0B, "Filter-Id", (type) => new TextAttribute(type));
RegisterAttributeFactory(0x0C, "Framed-MTU", (type) => new IntAttribute(type));
RegisterAttributeFactory(0x0D, "Framed-Compression", (type) => new IntAttribute(type));
RegisterAttributeFactory(0x0E, "Login-IP-Host", (type) => new IPv4Attribute(type));
RegisterAttributeFactory(0x0F, "Login-Service", (type) => new IntAttribute(type));
RegisterAttributeFactory(0x10, "Login-TCP-Port", (type) => new IntAttribute(type));
//RegisterAttributeFactory(0x11, "", (type) => new RadiusAttribute(type)); // Reserved
RegisterAttributeFactory(0x12, "Reply-Message", (type) => new TextAttribute(type));
RegisterAttributeFactory(0x13, "Callback-Number", (type) => new RadiusAttribute(type));
RegisterAttributeFactory(0x14, "Callback-Id", (type) => new RadiusAttribute(type));
//RegisterAttributeFactory(0x15, "", (type) => new RadiusAttribute(type)); // Reserved
RegisterAttributeFactory(0x16, "Framed-Route", (type) => new TextAttribute(type));
RegisterAttributeFactory(0x17, "Framed-IPX-Network", (type) => new IntAttribute(type));
RegisterAttributeFactory(0x18, "State", (type) => new RadiusAttribute(type));
RegisterAttributeFactory(0x19, "Class", (type) => new RadiusAttribute(type));
RegisterAttributeFactory(0x1A, "Vendor-Specific", (type) => new RadiusAttribute(type));
RegisterAttributeFactory(0x1B, "Session-Timeout", (type) => new IntAttribute(type));
RegisterAttributeFactory(0x1C, "Idle-Timeout", (type) => new IntAttribute(type));
RegisterAttributeFactory(0x1D, "Termination-Action", (type) => new IntAttribute(type));
RegisterAttributeFactory(0x1E, "Called-Station-Id", (type) => new RadiusAttribute(type));
RegisterAttributeFactory(0x1F, "Calling-Station-Id", (type) => new RadiusAttribute(type));
RegisterAttributeFactory(0x20, "NAS-Identifier", (type) => new RadiusAttribute(type));
RegisterAttributeFactory(0x21, "Proxy-State", (type) => new RadiusAttribute(type));
RegisterAttributeFactory(0x22, "Login-LAT-Service", (type) => new RadiusAttribute(type));
RegisterAttributeFactory(0x23, "Login-LAT-Node", (type) => new RadiusAttribute(type));
RegisterAttributeFactory(0x24, "Login-LAT-Group", (type) => new RadiusAttribute(type));
RegisterAttributeFactory(0x25, "Framed-AppleTalk-Link", (type) => new IntAttribute(type));
RegisterAttributeFactory(0x26, "Framed-AppleTalk-Network", (type) => new IntAttribute(type));
RegisterAttributeFactory(0x27, "Framed-AppleTalk-Zone", (type) => new RadiusAttribute(type));
RegisterAttributeFactory(0x3C, "CHAP-Challenge", (type) => new RadiusAttribute(type));
RegisterAttributeFactory(0x3D, "NAS-Port-Type", (type) => new IntAttribute(type));
RegisterAttributeFactory(0x3E, "Port-Limit", (type) => new IntAttribute(type));
RegisterAttributeFactory(0x3F, "Login-LAT-Port", (type) => new RadiusAttribute(type));
}
class TextAttribute : RadiusAttribute
{
public String Text { get; set; }
public override byte[] Bytes
{
get => Encoding.UTF8.GetBytes(Text);
set => Text = Encoding.UTF8.GetString(value);
}
public TextAttribute(byte type)
: base(type)
{ }
public override string ToString()
{
return string.Format("[RadiusAttribute Type={0} {1}]", Name, Text);
}
}
class IPv4Attribute : RadiusAttribute
{
public IPv4 IP { get; set; }
public override byte[] Bytes
{
get => IP.IPBytes;
set => IP = new IPv4(value);
}
public IPv4Attribute(byte type)
: base(type)
{ }
public override string ToString()
{
return string.Format("[RadiusAttribute Type={0} {1}]", Name, IP.ToString());
}
}
class IntAttribute : RadiusAttribute
{
public UInt32 UInt32 { get; set; }
public override byte[] Bytes
{
get => UInt32.GetBytes(true);
set => UInt32 = BitConverter.ToUInt32(value.BigEndian(), 0);
}
public IntAttribute(byte type)
: base(type)
{ }
public override string ToString()
{
return string.Format("[RadiusAttribute Type={0} {1}]", Name, UInt32);
}
}
class TimeAttribute : RadiusAttribute
{
DateTimeOffset DateTimeOffset { get; set; }
public override byte[] Bytes
{
get => ((uint)DateTimeOffset.ToUnixTimeSeconds()).GetBytes(true);
set => DateTimeOffset = DateTimeOffset.FromUnixTimeSeconds(BitConverter.ToUInt32(value.BigEndian(),0));
}
public TimeAttribute(byte type)
: base(type)
{ }
public override string ToString()
{
return string.Format("[RadiusAttribute Type={0} {1}]", Name, DateTimeOffset);
}
}
}
}

121
RadiusMessage.cs 100644
View File

@ -0,0 +1,121 @@
// /**
// * File: RadiusMessage.cs
// * Author: haraldwolff
// *
// * This file and it's content is copyrighted by the Author and / or copyright holder.
// * Any use wihtout proper permission is illegal and may lead to legal actions.
// *
// *
// **/
using System;
using System.Net;
using System.Collections.Generic;
using System.IO;
using ln.types;
using System.Security.Cryptography;
namespace ln.radius
{
public enum RadiusCode : byte {
AccessRequest = 1,
AccessAccept = 2,
AccessReject = 3,
AccountingRequest = 4,
AccountingResponse = 5,
AccessChallenge = 11,
StatusServer = 12,
StatusClient = 13,
Reserved = 255
}
public class RadiusMessage
{
public IPEndPoint EndPoint { get; set; }
public RadiusCode Code { get; set; }
byte identifier;
public byte Identifier
{
get => identifier;
set
{
identifier = value;
Authenticator = Guid.NewGuid().ToByteArray();
}
}
public byte[] Authenticator { get; set; }
List<RadiusAttribute> radiusAttributes = new List<RadiusAttribute>();
public RadiusMessage(IPEndPoint endPoint,RadiusCode radiusCode)
{
EndPoint = endPoint;
Code = radiusCode;
}
public byte[] Authenticate(byte[] secret)
{
byte[] packet = ToBytes();
MD5 md5 = MD5.Create();
md5.TransformBlock(packet, 0, packet.Length, null, 0);
md5.TransformFinalBlock(secret, 0, secret.Length);
Array.Copy(md5.Hash, 0, packet, 4, 16);
return packet;
}
public byte[] ToBytes()
{
using (MemoryStream memoryStream = new MemoryStream())
{
memoryStream.WriteByte((byte)Code);
memoryStream.WriteByte((byte)Identifier);
memoryStream.WriteShort((short)0);
memoryStream.WriteBytes(Authenticator);
foreach (RadiusAttribute radiusAttribute in radiusAttributes)
memoryStream.WriteBytes(radiusAttribute.ToBytes());
byte[] bytes = memoryStream.ToArray();
Array.Copy(
BitConverter.GetBytes((short)bytes.Length), 0,
bytes, 2,
2
);
return bytes;
}
}
public override string ToString()
{
return String.Format("[RadiusMessage Code={0} Identifier={1} Attributes: {2}]",Code,Identifier,String.Join(", ",radiusAttributes));
}
public static RadiusMessage FromBytes(byte[] bytes,IPEndPoint remoteEndpoint)
{
if ((bytes.Length < 20) || (bytes.Length > 4096))
throw new ArgumentOutOfRangeException(nameof(bytes),"Radius packet needs to be sized between 20 and 4095 bytes");
RadiusMessage radiusMessage = new RadiusMessage(remoteEndpoint, (RadiusCode)bytes[0]);
using (Stream stream = new MemoryStream(bytes))
{
stream.ReadByte();
radiusMessage.Identifier = (byte)stream.ReadByte();
short plength = stream.ReadShort(true);
if (plength != bytes.Length)
throw new ArgumentException("packet: length != bytes.length");
radiusMessage.Authenticator = stream.ReadBytes(16);
while (stream.Position < stream.Length)
radiusMessage.radiusAttributes.Add(RadiusAttribute.Read(stream));
}
return radiusMessage;
}
}
}

91
RadiusServer.cs 100644
View File

@ -0,0 +1,91 @@
// /**
// * File: RadiusServer.cs
// * Author: haraldwolff
// *
// * This file and it's content is copyrighted by the Author and / or copyright holder.
// * Any use wihtout proper permission is illegal and may lead to legal actions.
// *
// *
// **/
using System;
using System.Net.Sockets;
using System.Net;
using System.Collections.Generic;
using System.Threading;
using System.Linq;
using ln.logging;
using ln.types.threads;
namespace ln.radius
{
public delegate byte[] LookupSecretDelegate(IPEndPoint endPoint);
public delegate void RadiusMessageReceived(RadiusServer radiusServer, RadiusMessage radiusMessage);
public class RadiusServer : IDisposable
{
public LookupSecretDelegate LookupSecret { get; set; }
public RadiusMessageReceived MessageReceived { get; set; }
public Pool RequestPool { get; } = new Pool(16);
UdpClient udp;
bool contListeners = true;
public RadiusServer()
{}
public RadiusServer(IPEndPoint endPoint)
{
udp = new UdpClient(endPoint);
RequestPool.Enqueue(() => ListenerThread(udp));
}
public void Close()
{
contListeners = false;
udp.Close();
RequestPool.Close();
}
public void Dispose()
{
Close();
}
public void Send(RadiusMessage message)
{
byte[] packet = message.Authenticate(LookupSecret(message.EndPoint));
lock (udp)
{
udp.Send(packet, packet.Length, message.EndPoint);
}
}
private void ListenerThread(UdpClient udp)
{
try
{
while (contListeners)
{
IPEndPoint remoteEndPoint = new IPEndPoint(IPAddress.Any, 0);
byte[] rx = udp.Receive(ref remoteEndPoint);
try
{
RadiusMessage radiusMessage = RadiusMessage.FromBytes(rx, remoteEndPoint);
Logging.Log("RX: {0}",radiusMessage.ToString());
RequestPool.Enqueue(() => MessageReceived(this, radiusMessage));
} catch (Exception e)
{
Logging.Log(e);
}
}
} catch (Exception e)
{
Logging.Log(LogLevel.ERROR, "radius listener thread caught exception: {0}", e);
Logging.Log(e);
}
}
}
}

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

50
ln.radius.csproj 100644
View File

@ -0,0 +1,50 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{100C21CD-1E24-499E-88FF-C17431FC9D2A}</ProjectGuid>
<OutputType>Library</OutputType>
<RootNamespace>ln.radius</RootNamespace>
<AssemblyName>ln.radius</AssemblyName>
<TargetFrameworkVersion>v4.7</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug</OutputPath>
<DefineConstants>DEBUG;</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ConsolePause>false</ConsolePause>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<Optimize>true</Optimize>
<OutputPath>bin\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ConsolePause>false</ConsolePause>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
</ItemGroup>
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="AttributesCollection.cs" />
<Compile Include="RadiusMessage.cs" />
<Compile Include="RadiusAttribute.cs" />
<Compile Include="RadiusServer.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ln.logging\ln.logging.csproj">
<Project>{D471A566-9FB6-41B2-A777-3C32874ECD0E}</Project>
<Name>ln.logging</Name>
</ProjectReference>
<ProjectReference Include="..\ln.types\ln.types.csproj">
<Project>{8D9AB9A5-E513-4BA7-A450-534F6456BF28}</Project>
<Name>ln.types</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
</Project>

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition=" '$(RunConfiguration)' == 'Default' ">
<StartAction>Project</StartAction>
<ConsolePause>true</ConsolePause>
</PropertyGroup>
</Project>

View File

@ -0,0 +1 @@
7aaaa9b53a4c71f7c2e91c2614c0def7213faed9

View File

@ -0,0 +1,28 @@
/home/haraldwolff/src/skyspot/ln.radius/bin/Debug/ln.radius.dll
/home/haraldwolff/src/skyspot/ln.radius/bin/Debug/ln.radius.pdb
/home/haraldwolff/src/skyspot/ln.radius/bin/Debug/ln.types.dll
/home/haraldwolff/src/skyspot/ln.radius/bin/Debug/sharp.logging.dll
/home/haraldwolff/src/skyspot/ln.radius/bin/Debug/Newtonsoft.Json.dll
/home/haraldwolff/src/skyspot/ln.radius/bin/Debug/sharp.logging.pdb
/home/haraldwolff/src/skyspot/ln.radius/bin/Debug/ln.types.pdb
/home/haraldwolff/src/skyspot/ln.radius/bin/Debug/Newtonsoft.Json.pdb
/home/haraldwolff/src/skyspot/ln.radius/bin/Debug/Newtonsoft.Json.xml
/home/haraldwolff/src/skyspot/ln.radius/obj/Debug/ln.radius.csprojAssemblyReference.cache
/home/haraldwolff/src/skyspot/ln.radius/obj/Debug/ln.radius.csproj.CoreCompileInputs.cache
/home/haraldwolff/src/skyspot/ln.radius/obj/Debug/ln.radius.csproj.CopyComplete
/home/haraldwolff/src/skyspot/ln.radius/obj/Debug/ln.radius.dll
/home/haraldwolff/src/skyspot/ln.radius/obj/Debug/ln.radius.pdb
/Volumes/HOMES/haraldwolff/src/skyspot/ln.radius/bin/Debug/ln.radius.dll
/Volumes/HOMES/haraldwolff/src/skyspot/ln.radius/bin/Debug/ln.radius.pdb
/Volumes/HOMES/haraldwolff/src/skyspot/ln.radius/bin/Debug/ln.types.dll
/Volumes/HOMES/haraldwolff/src/skyspot/ln.radius/bin/Debug/sharp.logging.dll
/Volumes/HOMES/haraldwolff/src/skyspot/ln.radius/bin/Debug/Newtonsoft.Json.dll
/Volumes/HOMES/haraldwolff/src/skyspot/ln.radius/bin/Debug/sharp.logging.pdb
/Volumes/HOMES/haraldwolff/src/skyspot/ln.radius/bin/Debug/ln.types.pdb
/Volumes/HOMES/haraldwolff/src/skyspot/ln.radius/bin/Debug/Newtonsoft.Json.pdb
/Volumes/HOMES/haraldwolff/src/skyspot/ln.radius/bin/Debug/Newtonsoft.Json.xml
/Volumes/HOMES/haraldwolff/src/skyspot/ln.radius/obj/Debug/ln.radius.csprojAssemblyReference.cache
/Volumes/HOMES/haraldwolff/src/skyspot/ln.radius/obj/Debug/ln.radius.csproj.CoreCompileInputs.cache
/Volumes/HOMES/haraldwolff/src/skyspot/ln.radius/obj/Debug/ln.radius.csproj.CopyComplete
/Volumes/HOMES/haraldwolff/src/skyspot/ln.radius/obj/Debug/ln.radius.dll
/Volumes/HOMES/haraldwolff/src/skyspot/ln.radius/obj/Debug/ln.radius.pdb

Binary file not shown.

Binary file not shown.