vforteli / Flexinets.Radius.RadiusServer

Radius server for .Net. Packets handled in pluggable IPacketHandlers
MIT License
45 stars 22 forks source link

Vendors for the dictionary #10

Open JoshClose opened 5 years ago

JoshClose commented 5 years ago

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 commented 5 years ago

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);
        }
    }
}
vforteli commented 5 years ago

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

JoshClose commented 5 years ago

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 commented 5 years ago

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

vforteli commented 5 years ago

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

JoshClose commented 5 years ago

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

JoshClose commented 5 years ago

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"