/// <summary>
        /// Parses a VALUE line containing an enumeration value.
        /// </summary>
        private static void ParseValueLine(IWritableDictionary dictionary, string[] tok, int lineNum)
        {
            try
            {
                if (tok.Length != 4)
                {
                    throw new IOException("expect 4 columns but actual is " + tok.Length);
                }

                String typeName = tok[1].Trim();
                String enumName = tok[2].Trim();
                String valStr   = tok[3].Trim();

                AttributeType at = dictionary.GetAttributeTypeByName(typeName);
                if (at == null)
                {
                    throw new IOException("unknown attribute type: " + typeName + ", line: " + lineNum);
                }
                at.AddEnumerationValue(Convert.ToInt32(valStr), enumName);
            }
            catch (Exception ex)
            {
                throw new IOException("syntax error on line" + lineNum, ex);
            }
        }
Exemple #2
0
 /// <summary>
 ///  Reads a Radius response packet from the given input stream and
 ///  creates an appropiate RadiusPacket descendant object.
 ///  Reads in all attributes and returns the object.
 ///  Checks the packet authenticator.
 ///  @param dictionary dictionary to use for attributes
 ///  @param in InputStream to read packet from
 ///  @param sharedSecret shared secret to be used to decode this packet
 ///  @param request Radius request packet
 ///  @return new RadiusPacket object
 ///  @exception IOException IO error
 ///  @exception RadiusException malformed packet
 /// </summary>
 public RadiusPacket DecodeResponsePacket(IWritableDictionary dictionary, Stream @in,
                                          String sharedSecret, RadiusPacket request)
 {
     if (request == null)
     {
         throw new ArgumentNullException("request", "request may not be null");
     }
     return(DecodePacket(dictionary, @in, sharedSecret, request));
 }
        /// <summary>
        /// Parses a line containing a vendor declaration.
        /// </summary>
        private static void ParseVendorLine(IWritableDictionary dictionary, string[] tok, int lineNum)
        {
            if (tok.Length != 3)
            {
                throw new IOException("syntax error on line " + lineNum);
            }

            int    vendorId   = Convert.ToInt32(tok[1].Trim());
            String vendorName = tok[2].Trim();

            dictionary.AddVendor(vendorId, vendorName);
        }
        /// <summary>
        /// Returns a new dictionary filled with the contents
        /// from the given input stream.
        /// @param source input stream
        /// @return dictionary object
        /// @throws IOException
        /// </summary>
        //public static IDictionary ParseDictionary(Stream source)
        //{
        //    IWritableDictionary d = new MemoryDictionary();
        //    ParseDictionary(source, d);
        //    return d;
        //}
        /// <summary>
        /// Parses the dictionary from the specified InputStream.
        /// @param source input stream
        /// @param dictionary dictionary data is written to
        /// @throws IOException syntax errors
        /// @throws NotImplementedException syntax errors
        /// </summary>
        public static void ParseDictionary(Stream source, IWritableDictionary dictionary)
        {
            // read each line separately
            var @in = new StreamReader(source);

            String line;
            int    lineNum = -1;

            while ((line = @in.ReadLine()) != null)
            {
                // ignore comments
                lineNum++;
                line = line.Trim();
                if (line.StartsWith("#") || line.Length == 0)
                {
                    continue;
                }

                // tokenize line by whitespace
                string[] tok      = Regex.Split(line, "[\\t ]+");
                String   lineType = tok[0].ToUpper();
                switch (lineType)
                {
                case ("ATTRIBUTE"):
                    parseAttributeLine(dictionary, tok, lineNum);
                    break;

                case ("VALUE"):
                    ParseValueLine(dictionary, tok, lineNum);
                    break;

                case ("$INCLUDE"):
                    IncludeDictionaryFile(dictionary, tok, lineNum);
                    break;

                case ("VENDORATTR"):
                    ParseVendorAttributeLine(dictionary, tok, lineNum);
                    break;

                case ("VENDOR"):
                    ParseVendorLine(dictionary, tok, lineNum);
                    break;

                default:
                    throw new IOException("unknown line type: " + lineType + " line: " + lineNum);
                }
            }
        }
        /// <summary>
        /// Parses a line that declares a Vendor-Specific attribute.
        /// </summary>
        private static void ParseVendorAttributeLine(IWritableDictionary dictionary, string[] tok, int lineNum)
        {
            if (tok.Length != 5)
            {
                throw new IOException("syntax error on line " + lineNum);
            }

            String vendor  = tok[1].Trim();
            String name    = tok[2].Trim();
            int    code    = Convert.ToInt32(tok[3].Trim());
            String typeStr = tok[4].Trim();

            Type type = GetAttributeTypeClass(code, typeStr);
            var  at   = new AttributeType(Convert.ToInt32(vendor), code, name, type);

            dictionary.AddAttributeType(at);
        }
        /// <summary>
        /// Parse a line that declares an attribute.
        /// </summary>
        private static void parseAttributeLine(IWritableDictionary dictionary, string[] tok, int lineNum)
        {
            if (tok.Length != 4)
            {
                throw new IOException("syntax error on line " + lineNum);
            }

            // read name, code, type
            String name    = tok[1];
            int    code    = Convert.ToInt32(tok[2]);
            String typeStr = tok[3];

            // translate type to class
            Type type = code == VendorSpecificAttribute.VENDOR_SPECIFIC
                            ? typeof(VendorSpecificAttribute)
                            : GetAttributeTypeClass(code, typeStr);

            // create and cache object
            dictionary.AddAttributeType(new AttributeType(code, name, type));
        }
        /// <summary>
        /// Parse a line that declares an attribute.
        /// </summary>
        private static void parseAttributeLine(IWritableDictionary dictionary, string[] tok, int lineNum)
        {
            if (tok.Length != 4)
            {
                throw new IOException("syntax error on line " + lineNum);
            }

            // read name, code, type
            String name = tok[1];
            int code = Convert.ToInt32(tok[2]);
            String typeStr = tok[3];

            // translate type to class
            Type type = code == VendorSpecificAttribute.VENDOR_SPECIFIC
                            ? typeof (VendorSpecificAttribute)
                            : GetAttributeTypeClass(code, typeStr);

            // create and cache object
            dictionary.AddAttributeType(new AttributeType(code, name, type));
        }
        /// <summary>
        /// Returns a new dictionary filled with the contents
        /// from the given input stream.
        /// @param source input stream
        /// @return dictionary object
        /// @throws IOException
        /// </summary>
        //public static IDictionary ParseDictionary(Stream source)
        //{
        //    IWritableDictionary d = new MemoryDictionary();
        //    ParseDictionary(source, d);
        //    return d;
        //}
        /// <summary>
        /// Parses the dictionary from the specified InputStream.
        /// @param source input stream
        /// @param dictionary dictionary data is written to
        /// @throws IOException syntax errors
        /// @throws NotImplementedException syntax errors
        /// </summary>
        public static void ParseDictionary(Stream source, IWritableDictionary dictionary)
        {
            // read each line separately
            var @in = new StreamReader(source);

            String line;
            int lineNum = -1;
            while ((line = @in.ReadLine()) != null)
            {
                // ignore comments
                lineNum++;
                line = line.Trim();
                if (line.StartsWith("#") || line.Length == 0)
                    continue;

                // tokenize line by whitespace
                string[] tok = Regex.Split(line, "[\\t ]+");
                String lineType = tok[0].ToUpper();
                switch (lineType)
                {
                    case ("ATTRIBUTE"):
                        parseAttributeLine(dictionary, tok, lineNum);
                        break;
                    case ("VALUE"):
                        ParseValueLine(dictionary, tok, lineNum);
                        break;
                    case ("$INCLUDE"):
                        IncludeDictionaryFile(dictionary, tok, lineNum);
                        break;
                    case ("VENDORATTR"):
                        ParseVendorAttributeLine(dictionary, tok, lineNum);
                        break;
                    case ("VENDOR"):
                        ParseVendorLine(dictionary, tok, lineNum);
                        break;
                    default:
                        throw new IOException("unknown line type: " + lineType + " line: " + lineNum);
                }
            }
        }
        /// <summary>
        /// Includes a dictionary file.
        /// </summary>
        private static void IncludeDictionaryFile(IWritableDictionary dictionary, string[] tok, int lineNum)
        {
            if (tok.Length != 2)
            {
                throw new IOException("syntax error on line " + lineNum);
            }
            String includeFile = tok[1];

            var incf = new FileInfo(includeFile);

            if (!incf.Exists)
            {
                throw new IOException("inclueded file '" + includeFile + "' not found, line " + lineNum);
            }

            FileStream fs = incf.OpenRead();

            ParseDictionary(fs, dictionary);

            // line numbers begin with 0 again, but file name is
            // not mentioned in exceptions
            // furthermore, this method does not allow to include
            // classpath resources
        }
Exemple #10
0
        /// <summary>
        ///  Creates a RadiusAttribute object of the appropriate type.
        ///  @param dictionary Hashtable to use
        ///  @param vendorId vendor ID or -1
        ///  @param attributeType attribute type
        ///  @return RadiusAttribute object
        /// </summary>
        public static RadiusAttribute CreateRadiusAttribute(IWritableDictionary dictionary, int vendorId,
                                                            int attributeType)
        {
            var attribute = new RadiusAttribute();

            AttributeType at = dictionary.GetAttributeTypeByCode(vendorId, attributeType);

            if (at != null && at.Class != null)
            {
                try
                {
                    attribute = (RadiusAttribute)Activator.CreateInstance(at.Class);
                }
                catch (Exception e)
                {
                    // error instantiating class - should not occur
                }
            }

            attribute.Type       = attributeType;
            attribute.Dictionary = dictionary;
            attribute.VendorId   = vendorId;
            return(attribute);
        }
Exemple #11
0
 /// <summary>
 ///  Reads a Radius request packet from the given input stream and
 ///  creates an appropiate RadiusPacket descendant object.
 ///  Reads in all attributes and returns the object.
 ///  Decodes the encrypted fields and attributes of the packet.
 ///  @param dictionary dictionary to use for attributes
 ///  @param in InputStream to read packet from
 ///  @param sharedSecret shared secret to be used to decode this packet
 ///  @return new RadiusPacket object
 ///  @exception IOException IO error
 ///  @exception RadiusException malformed packet
 /// </summary>
 public RadiusPacket DecodeRequestPacket(IWritableDictionary dictionary, Stream @in, String sharedSecret)
 {
     return(DecodePacket(dictionary, @in, sharedSecret, null));
 }
        /// <summary>
        ///  Creates a RadiusAttribute object of the appropriate type.
        ///  @param dictionary Hashtable to use
        ///  @param vendorId vendor ID or -1
        ///  @param attributeType attribute type
        ///  @return RadiusAttribute object
        /// </summary>
        public static RadiusAttribute CreateRadiusAttribute(IWritableDictionary dictionary, int vendorId,
                                                            int attributeType)
        {
            var attribute = new RadiusAttribute();

            AttributeType at = dictionary.GetAttributeTypeByCode(vendorId, attributeType);
            if (at != null && at.Class != null)
            {
                try
                {
                    attribute = (RadiusAttribute) Activator.CreateInstance(at.Class);
                }
                catch (Exception e)
                {
                    // error instantiating class - should not occur
                }
            }

            attribute.Type = attributeType;
            attribute.Dictionary = dictionary;
            attribute.VendorId = vendorId;
            return attribute;
        }
        /// <summary>
        /// Parses a line containing a vendor declaration.
        /// </summary>
        private static void ParseVendorLine(IWritableDictionary dictionary, string[] tok, int lineNum)
        {
            if (tok.Length != 3)
                throw new IOException("syntax error on line " + lineNum);

            int vendorId = Convert.ToInt32(tok[1].Trim());
            String vendorName = tok[2].Trim();
            dictionary.AddVendor(vendorId, vendorName);
        }
        /// <summary>
        /// Includes a dictionary file.
        /// </summary>
        private static void IncludeDictionaryFile(IWritableDictionary dictionary, string[] tok, int lineNum)
        {
            if (tok.Length != 2)
                throw new IOException("syntax error on line " + lineNum);
            String includeFile = tok[1];

            var incf = new FileInfo(includeFile);
            if (!incf.Exists)
                throw new IOException("inclueded file '" + includeFile + "' not found, line " + lineNum);

            FileStream fs = incf.OpenRead();
            ParseDictionary(fs, dictionary);

            // line numbers begin with 0 again, but file name is
            // not mentioned in exceptions
            // furthermore, this method does not allow to include
            // classpath resources
        }
        /// <summary>
        /// Parses a VALUE line containing an enumeration value.
        /// </summary>
        private static void ParseValueLine(IWritableDictionary dictionary, string[] tok, int lineNum)
        {
            try
            {
                if (tok.Length != 4)
                    throw new IOException("expect 4 columns but actual is " + tok.Length);

                String typeName = tok[1].Trim();
                String enumName = tok[2].Trim();
                String valStr = tok[3].Trim();

                AttributeType at = dictionary.GetAttributeTypeByName(typeName);
                if (at == null)
                    throw new IOException("unknown attribute type: " + typeName + ", line: " + lineNum);
                at.AddEnumerationValue(Convert.ToInt32(valStr), enumName);
            }
            catch (Exception ex)
            {
                throw new IOException("syntax error on line" + lineNum, ex);
            }
        }
        /// <summary>
        /// Parses a line that declares a Vendor-Specific attribute.
        /// </summary>
        private static void ParseVendorAttributeLine(IWritableDictionary dictionary, string[] tok, int lineNum)
        {
            if (tok.Length != 5)
                throw new IOException("syntax error on line " + lineNum);

            String vendor = tok[1].Trim();
            String name = tok[2].Trim();
            int code = Convert.ToInt32(tok[3].Trim());
            String typeStr = tok[4].Trim();

            Type type = GetAttributeTypeClass(code, typeStr);
            var at = new AttributeType(Convert.ToInt32(vendor), code, name, type);
            dictionary.AddAttributeType(at);
        }
        /// <summary>
        ///  Reads a Radius packet from the given input stream and
        ///  creates an appropiate RadiusPacket descendant object.
        ///  Reads in all attributes and returns the object. 
        ///  Decodes the encrypted fields and attributes of the packet.
        ///  @exception IOException if an IO error occurred
        ///  @exception RadiusException if the Radius packet is malformed
        /// </summary>
        /// <param name="dictionary">dictionary to use for attributes</param>
        /// <param name="inputStream"></param>
        /// <param name="request">Radius request packet if this is a response packet to be 
        ///  decoded, null if this is a request packet to be decoded</param>
        /// <param name="sharedSecret">shared secret to be used to decode this packet</param>
        /// <returns>RadiusPacket object</returns>
        protected static RadiusPacket DecodePacket(IWritableDictionary dictionary, Stream inputStream,
                                                   String sharedSecret,
                                                   RadiusPacket request)
        {
            // check shared secret
            if (string.IsNullOrEmpty(sharedSecret))
                throw new ArgumentNullException("sharedSecret", "no shared secret has been set");

            // check request authenticator
            if (request != null && request.Authenticator == null)
                throw new ArgumentNullException("request", "request authenticator not set");

            // read and check header
            int type = inputStream.ReadByte() & 0x0ff;
            int identifier = inputStream.ReadByte() & 0x0ff;
            int length = (inputStream.ReadByte() & 0x0ff) << 8 | (inputStream.ReadByte() & 0x0ff);

            if (request != null && request.Identifier != identifier)
                throw new RadiusException("bad packet: invalid packet identifier (request: " +
                                          request.Identifier + ", response: " + identifier);
            if (length < RadiusHeaderLength)
                throw new RadiusException("bad packet: packet too short (" + length + " bytes)");
            if (length > MaxPacketLength)
                throw new RadiusException("bad packet: packet too long (" + length + " bytes)");

            // read rest of packet
            var authenticator = new byte[16];
            var attributeData = new byte[length - RadiusHeaderLength];
            inputStream.Read(authenticator, 0, 16);
            inputStream.Read(attributeData, 0, attributeData.Length);

            // check and count attributes
            int pos = 0;

            while (pos < attributeData.Length)
            {
                if (pos + 1 >= attributeData.Length)
                    throw new RadiusException("bad packet: attribute Length mismatch");
                int attributeLength = attributeData[pos + 1] & 0x0ff;
                if (attributeLength < 2)
                    throw new RadiusException("bad packet: invalid attribute Length");
                pos += attributeLength;
            }
            if (pos != attributeData.Length)
                throw new RadiusException("bad packet: attribute Length mismatch");

            // create RadiusPacket object; set properties
            RadiusPacket rp = CreateRadiusPacket(type);
            rp.Type = type;
            rp.Identifier = identifier;
            rp.Authenticator = authenticator;

            // load attributes
            pos = 0;
            while (pos < attributeData.Length)
            {
                int attributeType = attributeData[pos] & 0x0ff;
                int attributeLength = attributeData[pos + 1] & 0x0ff;
                RadiusAttribute a = RadiusAttribute.CreateRadiusAttribute(dictionary, -1, attributeType);
                a.ReadAttribute(attributeData, pos, attributeLength);
                rp.AddAttribute(a);
                pos += attributeLength;
            }

            // request packet?
            if (request == null)
            {
                // decode attributes
                rp.DecodeRequestAttributes(sharedSecret);
                rp.CheckRequestAuthenticator(sharedSecret, length, attributeData);
            }
            else
            {
                // response packet: check authenticator
                rp.CheckResponseAuthenticator(sharedSecret, length, attributeData, request.Authenticator);
            }

            return rp;
        }
 /// <summary>
 ///  Reads a Radius response packet from the given input stream and
 ///  creates an appropiate RadiusPacket descendant object.
 ///  Reads in all attributes and returns the object.
 ///  Checks the packet authenticator. 
 ///  @param dictionary dictionary to use for attributes
 ///  @param in InputStream to read packet from
 ///  @param sharedSecret shared secret to be used to decode this packet
 ///  @param request Radius request packet
 ///  @return new RadiusPacket object
 ///  @exception IOException IO error
 ///  @exception RadiusException malformed packet
 /// </summary>
 public RadiusPacket DecodeResponsePacket(IWritableDictionary dictionary, Stream @in,
                                          String sharedSecret, RadiusPacket request)
 {
     if (request == null)
         throw new ArgumentNullException("request", "request may not be null");
     return DecodePacket(dictionary, @in, sharedSecret, request);
 }
 /// <summary>
 ///  Reads a Radius request packet from the given input stream and
 ///  creates an appropiate RadiusPacket descendant object.
 ///  Reads in all attributes and returns the object. 
 ///  Decodes the encrypted fields and attributes of the packet.
 ///  @param dictionary dictionary to use for attributes
 ///  @param in InputStream to read packet from
 ///  @param sharedSecret shared secret to be used to decode this packet
 ///  @return new RadiusPacket object
 ///  @exception IOException IO error
 ///  @exception RadiusException malformed packet
 /// </summary>
 public RadiusPacket DecodeRequestPacket(IWritableDictionary dictionary, Stream @in, String sharedSecret)
 {
     return DecodePacket(dictionary, @in, sharedSecret, null);
 }
Exemple #20
0
        /// <summary>
        ///  Creates a Radius attribute. The default dictionary is
        ///  used.
        ///  @param attributeType attribute type
        ///  @return RadiusAttribute instance
        /// </summary>
        public static RadiusAttribute CreateRadiusAttribute(int attributeType)
        {
            IWritableDictionary dictionary = DefaultDictionary.GetDefaultDictionary();

            return(CreateRadiusAttribute(dictionary, -1, attributeType));
        }
Exemple #21
0
        /// <summary>
        ///  Reads a Radius packet from the given input stream and
        ///  creates an appropiate RadiusPacket descendant object.
        ///  Reads in all attributes and returns the object.
        ///  Decodes the encrypted fields and attributes of the packet.
        ///  @exception IOException if an IO error occurred
        ///  @exception RadiusException if the Radius packet is malformed
        /// </summary>
        /// <param name="dictionary">dictionary to use for attributes</param>
        /// <param name="inputStream"></param>
        /// <param name="request">Radius request packet if this is a response packet to be
        ///  decoded, null if this is a request packet to be decoded</param>
        /// <param name="sharedSecret">shared secret to be used to decode this packet</param>
        /// <returns>RadiusPacket object</returns>
        protected static RadiusPacket DecodePacket(IWritableDictionary dictionary, Stream inputStream,
                                                   String sharedSecret,
                                                   RadiusPacket request)
        {
            // check shared secret
            if (string.IsNullOrEmpty(sharedSecret))
            {
                throw new ArgumentNullException("sharedSecret", "no shared secret has been set");
            }

            // check request authenticator
            if (request != null && request.Authenticator == null)
            {
                throw new ArgumentNullException("request", "request authenticator not set");
            }

            // read and check header
            int type       = inputStream.ReadByte() & 0x0ff;
            int identifier = inputStream.ReadByte() & 0x0ff;
            int length     = (inputStream.ReadByte() & 0x0ff) << 8 | (inputStream.ReadByte() & 0x0ff);

            if (request != null && request.Identifier != identifier)
            {
                throw new RadiusException("bad packet: invalid packet identifier (request: " +
                                          request.Identifier + ", response: " + identifier);
            }
            if (length < RadiusHeaderLength)
            {
                throw new RadiusException("bad packet: packet too short (" + length + " bytes)");
            }
            if (length > MaxPacketLength)
            {
                throw new RadiusException("bad packet: packet too long (" + length + " bytes)");
            }

            // read rest of packet
            var authenticator = new byte[16];
            var attributeData = new byte[length - RadiusHeaderLength];

            inputStream.Read(authenticator, 0, 16);
            inputStream.Read(attributeData, 0, attributeData.Length);

            // check and count attributes
            int pos = 0;

            while (pos < attributeData.Length)
            {
                if (pos + 1 >= attributeData.Length)
                {
                    throw new RadiusException("bad packet: attribute Length mismatch");
                }
                int attributeLength = attributeData[pos + 1] & 0x0ff;
                if (attributeLength < 2)
                {
                    throw new RadiusException("bad packet: invalid attribute Length");
                }
                pos += attributeLength;
            }
            if (pos != attributeData.Length)
            {
                throw new RadiusException("bad packet: attribute Length mismatch");
            }

            // create RadiusPacket object; set properties
            RadiusPacket rp = CreateRadiusPacket(type);

            rp.Type          = type;
            rp.Identifier    = identifier;
            rp.Authenticator = authenticator;

            // load attributes
            pos = 0;
            while (pos < attributeData.Length)
            {
                int             attributeType   = attributeData[pos] & 0x0ff;
                int             attributeLength = attributeData[pos + 1] & 0x0ff;
                RadiusAttribute a = RadiusAttribute.CreateRadiusAttribute(dictionary, -1, attributeType);
                a.ReadAttribute(attributeData, pos, attributeLength);
                rp.AddAttribute(a);
                pos += attributeLength;
            }

            // request packet?
            if (request == null)
            {
                // decode attributes
                rp.DecodeRequestAttributes(sharedSecret);
                rp.CheckRequestAuthenticator(sharedSecret, length, attributeData);
            }
            else
            {
                // response packet: check authenticator
                rp.CheckResponseAuthenticator(sharedSecret, length, attributeData, request.Authenticator);
            }

            return(rp);
        }