Flexinets.Radius.RadiusServer icon indicating copy to clipboard operation
Flexinets.Radius.RadiusServer copied to clipboard

Vendors for the dictionary

Open JoshClose opened this issue 6 years ago • 7 comments

Could you explain your vendor format? I'm looking to add some vendors to my file, but I'm seeing differences from the files I have. I'm using ones from WireShark, but they look like they came from FreeRadius. I'm looking at Cisco vendor 9 as an example. Not everything is included in your file. Some of the names match up and some have cisco- in front when it doesn't in the freeradius file. Casing is different. Are values not put in your file?

To me, this looks to be the format:

# VendorId 25053
VendorSpecificAttribute	25053	1	Ruckus-User-Groups	string

This is the file I want to use.

# -*- text -*-
# Copyright (C) 2015 The FreeRADIUS Server project and contributors
#
#	Ruckus Wireless, Inc. dictionary
#
#

VENDOR		Ruckus				25053

BEGIN-VENDOR	Ruckus

# Value Format:    group_attr1,group_attr2,...
ATTRIBUTE	Ruckus-User-Groups			1	string
ATTRIBUTE	Ruckus-Sta-RSSI				2	integer
ATTRIBUTE	Ruckus-SSID				3	string
ATTRIBUTE	Ruckus-Wlan-Id				4	integer
ATTRIBUTE	Ruckus-Location				5	string
ATTRIBUTE	Ruckus-Grace-Period			6	integer
ATTRIBUTE	Ruckus-SCG-CBlade-IP			7	integer
ATTRIBUTE	Ruckus-SCG-DBlade-IP			8	integer
ATTRIBUTE	Ruckus-VLAN-ID				9	integer
ATTRIBUTE	Ruckus-Sta-Expiration			10	integer # not used by AP anymore. Please check SCG-33602
ATTRIBUTE	Ruckus-Sta-UUID				11	string
ATTRIBUTE	Ruckus-Accept-Enhancement-Reason	12	integer
ATTRIBUTE	Ruckus-Sta-Inner-Id			13	string
ATTRIBUTE	Ruckus-BSSID				14	octets

ATTRIBUTE	Ruckus-WSG-User				10	string

ATTRIBUTE	Ruckus-Triplets				101	octets
ATTRIBUTE	Ruckus-IMSI				102	octets
ATTRIBUTE	Ruckus-MSISDN				103	octets
ATTRIBUTE	Ruckus-APN-NI				104	string
ATTRIBUTE	Ruckus-QoS				105	octets
ATTRIBUTE	Ruckus-Selection-Mode			106	integer
ATTRIBUTE	Ruckus-APN-Resolution-Req		107	integer
ATTRIBUTE	Ruckus-Start-Time			108	octets
ATTRIBUTE	Ruckus-NAS-Type				109	integer
ATTRIBUTE	Ruckus-Status				110	integer
ATTRIBUTE	Ruckus-APN-OI				111	string
ATTRIBUTE	Ruckus-Auth-Type			112	integer
ATTRIBUTE	Ruckus-Gn-User-Name			113	string
ATTRIBUTE	Ruckus-Brand-Code			114	string
ATTRIBUTE	Ruckus-Policy-Name			115	string
ATTRIBUTE	Ruckus-Client-Local-IP			116	ipaddr
ATTRIBUTE	Ruckus-SGSN-IP				117	ipaddr
ATTRIBUTE	Ruckus-Charging-Charac			118	octets
ATTRIBUTE	Ruckus-PDP-Type				119	octets
ATTRIBUTE	Ruckus-Dynamic-Address-Flag		120	octets
ATTRIBUTE	Ruckus-ChCh-Selection-Mode		121	octets
ATTRIBUTE	Ruckus-AAA-IP				122	ipaddr
ATTRIBUTE	Ruckus-CDR-TYPE				123	integer
ATTRIBUTE	Ruckus-SGSN-Number			124	octets
ATTRIBUTE	Ruckus-Session-Type			125	integer
ATTRIBUTE	Ruckus-Accounting-Status		126	integer
ATTRIBUTE	Ruckus-Zone-Id				127	string
ATTRIBUTE	Ruckus-Auth-Server-Id			128	string
ATTRIBUTE	Ruckus-Utp-Id				129	string
ATTRIBUTE	Ruckus-Area-Code			130	octets
ATTRIBUTE	Ruckus-Cell-Identifier			131	octets
ATTRIBUTE	Ruckus-Wispr-Redirect-Policy		132	string
ATTRIBUTE	Ruckus-Eth-Profile-Id			133	integer
ATTRIBUTE	Ruckus-Zone-Name			134	string
ATTRIBUTE	Ruckus-Wlan-Name			135	string

#
#  Integer Translations
#

#  Ruckus-Selection-Mode Values

VALUE	Ruckus-Selection-Mode		Subscribed		0
VALUE	Ruckus-Selection-Mode		SentByMS		1
VALUE	Ruckus-Selection-Mode		ChosenBySGSN		2

#  Ruckus-APN-Resolution-Req Values

VALUE	Ruckus-APN-Resolution-Req	NotRequired		0
VALUE	Ruckus-APN-Resolution-Req	Required		1

#  Ruckus-Status Values

VALUE	Ruckus-Status			Success			0
VALUE	Ruckus-Status			Failure			1

#  Ruckus-Auth-Type Values

VALUE	Ruckus-Auth-Type		PPP-SIM			1
VALUE	Ruckus-Auth-Type		DummyIMSI		2
VALUE	Ruckus-Auth-Type		SoftSIM			3
VALUE	Ruckus-Auth-Type		RadiusSIM		4
VALUE	Ruckus-Auth-Type		Postpaid		5
VALUE	Ruckus-Auth-Type		Prepaid			6
VALUE	Ruckus-Auth-Type		LocalRadius		7
VALUE	Ruckus-Auth-Type		ProxyRadius		8
VALUE	Ruckus-Auth-Type		Voucher			9
VALUE	Ruckus-Auth-Type		EAP-SIM			10

# Ruckus-Session-Type Values
# Updated as per SCG2.1
#Value (1) No more valid for SCG2.1
VALUE	Ruckus-Session-Type		TTG			2
VALUE	Ruckus-Session-Type		Local-Breakout		3
VALUE	Ruckus-Session-Type		Local-Breakout-AP	4
VALUE	Ruckus-Session-Type		L3GRE			5
VALUE	Ruckus-Session-Type		L2GRE			6
VALUE	Ruckus-Session-Type		QinQL3			7
VALUE	Ruckus-Session-Type		PMIP			8

#RUCKUS-NAS_Type

VALUE	Ruckus-NAS-Type			SCG			1
VALUE	Ruckus-NAS-Type			Others			2

#Ruckus-Accounting-Status
VALUE	Ruckus-Accounting-Status	Accounting-On		1
VALUE	Ruckus-Accounting-Status	Accounting-Off		0

END-VENDOR Ruckus

JoshClose avatar Feb 01 '19 05:02 JoshClose

I ended up writing a new RadiusDictionary that parses the freeradius files. I didn't want to copy and paste a bunch of stuff. It seems to parse fine, but I haven't ran it against anything yet.

Is there any reason those files wouldn't work in your system?

Here is my source if you want to see.

using Flexinets.Radius.Core;
using log4net;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

namespace InfinitWifi.RadiusServer
{
	public class RadiusDictionary : IRadiusDictionary
	{
		private readonly List<DictionaryVendorAttribute> vendorSpecificAttributes = new List<DictionaryVendorAttribute>();
		private readonly Dictionary<byte, DictionaryAttribute> attributes = new Dictionary<byte, DictionaryAttribute>();
		private readonly Dictionary<string, DictionaryAttribute> attributeNames = new Dictionary<string, DictionaryAttribute>();
		private readonly ILog log = LogManager.GetLogger(typeof(RadiusDictionary));

		public RadiusDictionary(string dictionaryFilePath)
		{
			ParseFile(dictionaryFilePath);

			log.Info($"Parsed {attributes.Count} attributes and {vendorSpecificAttributes.Count} vendor attributes from file");
		}

		public DictionaryAttribute GetAttribute(byte code) => attributes[code];

		public DictionaryAttribute GetAttribute(string name)
		{
			attributeNames.TryGetValue(name, out var attributeType);

			return attributeType;
		}

		public DictionaryVendorAttribute GetVendorAttribute(uint vendorId, byte vendorCode) =>
			vendorSpecificAttributes.FirstOrDefault(a => a.VendorId == vendorId && a.VendorCode == vendorCode);

		private void ParseFile(string dictionaryFilePath)
		{
			using (var reader = new StreamReader(dictionaryFilePath))
			{
				var vendorName = string.Empty;
				uint vendorId = 0;

				while (!reader.EndOfStream)
				{
					var line = reader.ReadLine();
					if (line.StartsWith("$INCLUDE"))
					{
						var lineParts = SplitLine(line);
						var fileName = lineParts[1];
						var filePath = Path.Combine(Path.GetDirectoryName(dictionaryFilePath), fileName);
						ParseFile(filePath);
					}
					else if (line.StartsWith("VENDOR"))
					{
						var lineParts = SplitLine(line);
						vendorName = lineParts[1];
						vendorId = Convert.ToUInt32(lineParts[2]);
					}
					else if (line.StartsWith("END-VENDOR"))
					{
						vendorName = string.Empty;
						vendorId = 0;
					}
					else if (line.StartsWith("ATTRIBUTE"))
					{
						var lineParts = SplitLine(line);
						if (vendorId == 0)
						{
							var name = lineParts[1];
							if (!byte.TryParse(lineParts[2], out var code))
							{
								continue;
							}

							var type = lineParts[3];
							var attribute = new DictionaryAttribute(name, code, type);
							attributes[code] = attribute;
							attributeNames[name] = attribute;
						}
						else
						{
							var name = lineParts[1];
							if (!uint.TryParse(lineParts[2], out var code))
							{
								continue;
							}

							var type = lineParts[3];
							var attribute = new DictionaryVendorAttribute(vendorId, name, code, type);
							vendorSpecificAttributes.Add(attribute);
						}
					}
				}
			}
		}

		private string[] SplitLine(string line)
		{
			return line.Split(new char[] { '\t', '\x20' }, StringSplitOptions.RemoveEmptyEntries);
		}
	}
}

JoshClose avatar Feb 01 '19 06:02 JoshClose

Hi,

The current dictionary is actually based on the format Radiator uses. So it looks a bit like FreeRADIUS, but not quite.
I actually started creating a parser for FreeRADIUS dictionaries, but havent had the time to finish it. Anyway, as you noticed the dictionary is very deliberately wrapped in the IRadiusDictionary interface, so of course any dictionary conforming to it should work. If you want to do a PR for a FreeRADIUS dictionary parser thats also fine :p

vforteli avatar Feb 01 '19 08:02 vforteli

I'll probably do a PR. This will parse the 202 FreeRADIUS files that come with Wireshark seemingly fine. I'll write up some tests.

JoshClose avatar Feb 01 '19 14:02 JoshClose

Do you want me to add all the files for FreeRADIUS so they can be tested and used if someone wants to grab them?

JoshClose avatar Feb 01 '19 15:02 JoshClose

I guess it would be nice to have the dictionaries, however I havent checked license compatibility. Im not sure if a radius dictionary actually is something that can be copyrighted in the first place though.
Btw, dictionary stuff should go in the Flexinets.Radius.Core repo and not this one. The radius client project also shares the core code and would benefit from the dictionary as well.

cheers, verner

vforteli avatar Feb 01 '19 18:02 vforteli

Yes, sorry. I forked the core project and am doing the work there.

JoshClose avatar Feb 01 '19 18:02 JoshClose

I'm seeing some types that the RadiusPacket.ParseContentBytes doesn't handle. One instance is the Message-Authenticator has a type of octets, not octet.

Here is a list of them. Do you see any others that need to be handled/added?

"abinary"
"byte"
"bytes"
"combo-ip"
"date"
"extended"
"ifid"
"integer"
"integer64"
"ipaddr"
"ipv4prefix"
"ipv6addr"
"ipv6prefix"
"long-extended"
"octets"
"short"
"signed"
"string"
"String"
"tlv"

JoshClose avatar Feb 01 '19 20:02 JoshClose