Exemple #1
0
        /// <summary>
        ///  Returns the value of the Radius attribute of the given type or
        ///  null if there is no such attribute.
        ///  Also returns sub-attributes.
        ///  @param type attribute type name
        ///  @return value of the attribute as a string or null if there
        ///  is no such attribute
        ///  @throws ArgumentException if the type name is unknown
        ///  @throws NotImplementedException attribute occurs multiple times
        /// </summary>
        public String GetAttributeValue(String type)
        {
            RadiusAttribute attr = GetAttribute(type);

            if (attr == null)
            {
                return(null);
            }
            else
            {
                return(attr.Value);
            }
        }
Exemple #2
0
        /// <summary>
        ///  Removes the last occurence of the attribute of the given
        ///  type from the packet.
        ///  @param type attribute type code
        /// </summary>
        public void RemoveLastAttribute(int type)
        {
            IList <RadiusAttribute> attrs = GetAttributes(type);

            if (attrs == null || attrs.Count == 0)
            {
                return;
            }

            RadiusAttribute lastAttribute =
                attrs[attrs.Count - 1];

            RemoveAttribute(lastAttribute);
        }
Exemple #3
0
        /**
         * Sends an answer to a proxied packet back to the original host.
         * Retrieves the RadiusProxyConnection object from the cache employing
         * the Proxy-State attribute.
         * @param packet packet to be sent back
         * @param remote the server the packet arrived from
         * @throws IOException
         */

        protected void proxyPacketReceived(RadiusPacket packet, IPEndPoint remote)
        {
            // retrieve my Proxy-State attribute (the last)
            IList <RadiusAttribute> proxyStates = packet.GetAttributes(33);

            if (proxyStates == null || proxyStates.Count == 0)
            {
                throw new RadiusException("Proxy packet without Proxy-State attribute");
            }
            RadiusAttribute proxyState = proxyStates[proxyStates.Count - 1];

            // retrieve Proxy connection from cache
            string state           = BitConverter.ToString(proxyState.Data);
            var    proxyConnection = (RadiusProxyConnection)proxyConnections[state];

            proxyConnections.Remove(state);
            if (proxyConnection == null)
            {
                logger.Warn("received packet on Proxy port without saved Proxy connection - duplicate?");
                return;
            }

            // retrieve client
            RadiusEndpoint client = proxyConnection.RadiusClient;

            if (logger.IsInfoEnabled)
            {
                logger.Info("received Proxy packet: " + packet);
                logger.Info("forward packet to " + client.EndpointAddress + " with secret " +
                            client.SharedSecret);
            }

            // remove only own Proxy-State (last attribute)
            packet.RemoveLastAttribute(33);

            // re-encode answer packet with authenticator of the original packet
            var answer = new RadiusPacket(packet.Type, packet.Identifier, packet.Attributes);

            byte[] datagram = MakeDatagramPacket(answer, client.SharedSecret, proxyConnection.Packet);

            // send back using correct socket
            UdpClient socket = proxyConnection.Port == AuthPort?GetAuthSocket() : GetAcctSocket();

            socket.Send(datagram, datagram.Length, remote);
        }
Exemple #4
0
 /// <summary>
 ///  Adds a Radius attribute to this packet. Can also be used
 ///  to add Vendor-Specific sub-attributes. If a attribute with
 ///  a vendor code != -1 is passed in, a VendorSpecificAttribute
 ///  is created for the sub-attribute.
 ///  @param attribute RadiusAttribute object
 /// </summary>
 public void AddAttribute(RadiusAttribute attribute)
 {
     if (attribute == null)
     {
         throw new ArgumentNullException("attribute", "attribute is null");
     }
     attribute.Dictionary = Dictionary;
     if (attribute.VendorId == -1)
     {
         _attributes.Add(attribute);
     }
     else
     {
         var vsa = new VendorSpecificAttribute(attribute.VendorId);
         vsa.AddSubAttribute(attribute);
         _attributes.Add(vsa);
     }
 }
Exemple #5
0
        /// <summary>
        ///  Adds a Radius attribute to this packet.
        ///  Uses AttributeTypes to lookup the type code and converts
        ///  the value.
        ///  Can also be used to add sub-attributes.
        ///  @param typeName name of the attribute, for example "NAS-Ip-Address"
        ///  @param value value of the attribute, for example "127.0.0.1"
        ///  @throws ArgumentException if type name is unknown
        /// </summary>
        public void AddAttribute(String typeName, String value)
        {
            if (string.IsNullOrEmpty(typeName))
            {
                throw new ArgumentException("type name is empty");
            }
            if (string.IsNullOrEmpty(value))
            {
                throw new ArgumentException("value is empty");
            }

            AttributeType type = Dictionary.GetAttributeTypeByName(typeName);

            if (type == null)
            {
                throw new ArgumentException("unknown attribute type '" + typeName + "'");
            }

            RadiusAttribute attribute = RadiusAttribute.CreateRadiusAttribute(Dictionary, type.VendorId,
                                                                              type.TypeCode);

            attribute.Value = value;
            AddAttribute(attribute);
        }
Exemple #6
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);
        }