Example #1
0
 /// <summary>
 ///  Encodes this Radius response packet and sends it to the specified output
 ///  stream.
 ///  @param out output stream to use
 ///  @param sharedSecret shared secret to be used to encode this packet
 ///  @param request Radius request packet
 ///  @exception IOException communication error
 /// </summary>
 public void EncodeResponsePacket(Stream @out, String sharedSecret, RadiusPacket request)
 {
     if (request == null)
     {
         throw new ArgumentNullException("request", "request cannot be null");
     }
     EncodePacket(@out, sharedSecret, request);
 }
        /**
         * Creates a RadiusProxyConnection object.
         * @param radiusServer server endpoint
         * @param radiusClient client endpoint
         * @param port port the proxied packet arrived at originally 
         */

        public RadiusProxyConnection(RadiusEndpoint radiusServer, RadiusEndpoint radiusClient, RadiusPacket packet,
                                     int port)
        {
            RadiusServer = radiusServer;
            RadiusClient = radiusClient;
            Packet = packet;
            Port = port;
        }
Example #3
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));
 }
        public override RadiusPacket AccessRequestReceived(AccessRequest accessRequest, IPEndPoint client)
        {
            try
            {
                string ip = GetIP(accessRequest);
                string macAddr = GetMacAddress(ip);
                RadiusPacket answer;
                if (ServiceCfg.Instance.TinyConfig.ValidateByLdap)
                {
                    Logger.InfoFormat("尝试通过Ldap检查用户,账户:{0},密码:{1},Mac:{2},IP:{3}", accessRequest.UserName,
                                      accessRequest.Password,
                                      macAddr, ip);
                    if (ServiceCfg.Instance.TinyConfig.LdapSetting.IsAuthenticated(accessRequest.UserName,
                                                                                   accessRequest.Password))
                    {
                        Logger.InfoFormat("Ldap登录成功,账户:{0},密码:{1},Mac:{2},IP:{3}", accessRequest.UserName, accessRequest.Password, macAddr, ip);
                        Logger.InfoFormat("{0} login by Ldap success.", accessRequest.UserName);
                        answer = new RadiusPacket(RadiusPacket.AccessAccept, accessRequest.Identifier);
                        CopyProxyState(accessRequest, answer);
                        return answer;
                    }
                    Logger.InfoFormat("Ldap登录失败,账户:{0},密码:{1},Mac:{2},IP:{3}", accessRequest.UserName, accessRequest.Password,
                                      macAddr, ip);
                }

                if (ServiceCfg.Instance.TinyConfig.ValidateByDatabase)
                {
                    Logger.InfoFormat("通过本地数据库检查Mac地址,账户:{0},密码:{1},Mac:{2},IP:{3}", accessRequest.UserName,
                                      accessRequest.Password,
                                      macAddr, ip);
                    Logger.Debug("检查Mac地址");
                    if (!IsMacCorrect(accessRequest.UserName, macAddr))
                    {
                        Logger.InfoFormat("Mac地址不正确,账户:{0},密码:{1},Mac:{2},IP:{3}", accessRequest.UserName,
                                          accessRequest.Password, macAddr, ip);
                        answer = new RadiusPacket(RadiusPacket.AccessReject, accessRequest.Identifier);
                        CopyProxyState(accessRequest, answer);
                        return answer;
                    }
                    return base.AccessRequestReceived(accessRequest, client);
                }
                answer = new RadiusPacket(RadiusPacket.AccessReject, accessRequest.Identifier);
                CopyProxyState(accessRequest, answer);
                return answer;
            }
            catch (Exception ex)
            {
                Logger.Error("some error happend.", ex);
                return new RadiusPacket(RadiusPacket.AccessReject, accessRequest.Identifier);
            }
        }
Example #5
0
        /// <summary>
        ///  Encodes this Radius packet and sends it to the specified output
        ///  stream.
        ///  @param out output stream to use
        ///  @param sharedSecret shared secret to be used to encode this packet
        ///  @param request Radius request packet if this packet to be encoded
        ///  is a response packet, null if this packet is a request packet
        ///  @exception IOException communication error
        ///  @exception NotImplementedException if required packet data has not been set
        /// </summary>
        protected void EncodePacket(Stream outputStream, 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 NotImplementedException("request authenticator not set");
            }

            // request packet authenticator
            if (request == null)
            {
                // first create authenticator, then encode attributes
                // (User-Password attribute needs the authenticator)
                Authenticator = CreateRequestAuthenticator(sharedSecret);
                EncodeRequestAttributes(sharedSecret);
            }

            byte[] attributes   = GetAttributeBytes();
            int    packetLength = RadiusHeaderLength + attributes.Length;

            if (packetLength > MaxPacketLength)
            {
                throw new NotImplementedException("packet too long");
            }

            // response packet authenticator
            Authenticator = request != null
                                ? CreateResponseAuthenticator(sharedSecret, packetLength, attributes,
                                                              request.Authenticator)
                                : UpdateRequestAuthenticator(sharedSecret, packetLength, attributes);

            outputStream.WriteByte(Convert.ToByte(Type));
            outputStream.WriteByte(Convert.ToByte(Identifier));
            byte[] lengthBytes = BitConverter.GetBytes(Convert.ToInt16(packetLength));
            Array.Reverse(lengthBytes);
            outputStream.Write(lengthBytes, 0, lengthBytes.Length);
            byte[] authen = Authenticator;
            outputStream.Write(authen, 0, authen.Length);
            outputStream.Write(attributes, 0, attributes.Length);
        }
Example #6
0
 public override RadiusEndpoint GetProxyServer(RadiusPacket packet,
                                               RadiusEndpoint client)
 {
     // always proxy
     try
     {
         IPAddress address = IPAddress.Parse("127.0. 0. 1 ");
         int port = 10000;
         if (typeof (AccountingRequest).IsInstanceOfType(packet))
             port = 10001;
         return new RadiusEndpoint(new IPEndPoint(address, port), "testing123");
     }
     catch
     {
         return null;
     }
 }
        public override RadiusPacket AccessRequestReceived(AccessRequest accessRequest, IPEndPoint client)
        {
            /*if (ServiceCfg.Instance.TinyConfig.ValidateByLdap)
            {
                string struser = accessRequest.UserName;
                string strpwd = accessRequest.Password;
                string path = ServiceCfg.Instance.TinyConfig.LdapSetting.Path;

                int type = RadiusPacket.AccessReject;

                var auth = new LdapAuthentication(path);
                if (auth.IsAuthenticated(ServiceCfg.Instance.TinyConfig.LdapSetting.DomainName, struser, strpwd))
                {
                    type = RadiusPacket.AccessAccept;
                }


                if (type == RadiusPacket.AccessAccept)
                {
                    var answer = new RadiusPacket(type, accessRequest.Identifier);
                    CopyProxyState(accessRequest, answer);
                    return answer;
                }
            }*/

            string struser = accessRequest.UserName;
            string strpwd = accessRequest.Password;
            this.Logger.InfoFormat("通过Ldap检查用户,用户{0},密码{1}", struser, strpwd);
            if (!LdapAuthentication.IsAuthenticated(struser, strpwd))
            {
                this.Logger.InfoFormat("用户(账户{0},密码{1})Ldap登录失败,尝试本地数据库登陆", struser, strpwd);
                return base.AccessRequestReceived(accessRequest, client);
            }
            else
            {
                this.Logger.InfoFormat("用户(账户{0},密码{1})Ldap登录成功.", struser, strpwd);
                const int type = RadiusPacket.AccessAccept;
                var answer = new RadiusPacket(type, accessRequest.Identifier);
                CopyProxyState(accessRequest, answer);
                return answer;
            }
        }
Example #8
0
        /// <summary>
        ///  Creates a RadiusPacket object. Depending on the passed type, the
        ///  appropiate successor is chosen. Sets the type, but does not touch
        ///  the packet identifier.
        ///  @param type packet type
        ///  @return RadiusPacket object
        /// </summary>
        public static RadiusPacket CreateRadiusPacket(int type)
        {
            RadiusPacket rp;

            switch (type)
            {
            case AccessRequest:
                rp = new AccessRequest();
                break;

            case AccountingRequest:
                rp = new AccountingRequest();
                break;

            case AccessAccept:
            case AccessReject:
            case AccountingResponse:
            default:
                rp = new RadiusPacket();
                break;
            }
            rp.Type = type;
            return(rp);
        }
        /// <summary>
        ///  Creates a RadiusPacket object. Depending on the passed type, the
        ///  appropiate successor is chosen. Sets the type, but does not touch
        ///  the packet identifier.
        ///  @param type packet type
        ///  @return RadiusPacket object
        /// </summary>
        public static RadiusPacket CreateRadiusPacket(int type)
        {
            RadiusPacket rp;
            switch (type)
            {
                case AccessRequest:
                    rp = new AccessRequest();
                    break;

                case AccountingRequest:
                    rp = new AccountingRequest();
                    break;
                case AccessAccept:
                case AccessReject:
                case AccountingResponse:
                default:
                    rp = new RadiusPacket();
                    break;
            }
            rp.Type = type;
            return rp;
        }
Example #10
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);
 }
Example #11
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 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 static RadiusPacket DecodeResponsePacket(Stream @in, String sharedSecret, RadiusPacket request)
 {
     if (request == null)
         throw new ArgumentNullException("request", "request may not be null");
     return DecodePacket(DefaultDictionary.GetDefaultDictionary(), @in, sharedSecret, request);
 }
Example #12
0
 /// <summary>
 ///  Encodes this Radius response packet and sends it to the specified output
 ///  stream.
 ///  @param out output stream to use
 ///  @param sharedSecret shared secret to be used to encode this packet
 ///  @param request Radius request packet
 ///  @exception IOException communication error
 /// </summary>
 public void EncodeResponsePacket(Stream @out, String sharedSecret, RadiusPacket request)
 {
     if (request == null)
         throw new ArgumentNullException("request", "request cannot be null");
     EncodePacket(@out, sharedSecret, request);
 }
Example #13
0
        /**
         * Proxies the given packet to the server given in the Proxy connection.
         * Stores the Proxy connection object in the cache with a key that
         * is added to the packet in the "Proxy-State" attribute.
         * @param packet the packet to Proxy
         * @param proxyCon the RadiusProxyConnection for this packet
         * @throws IOException
         */

        protected void proxyPacket(RadiusPacket packet, RadiusProxyConnection proxyConnection)
        {
            lock (typeof (RadiusProxy))
            {
                // add Proxy-State attribute
                proxyIndex++;
                String proxyIndexStr = proxyIndex.ToString();
                packet.AddAttribute(new RadiusAttribute(33, Encoding.UTF8.GetBytes(proxyIndexStr)));

                // store RadiusProxyConnection object
                proxyConnections.Add(proxyIndexStr, proxyConnection);
            }

            // get server address
            //IPAddress serverAddress = proxyConnection.getRadiusServer().EndpointAddress.Address;
            //int serverPort = proxyConnection.getRadiusServer().EndpointAddress.Port;
            String serverSecret = proxyConnection.RadiusServer.SharedSecret;

            // save request authenticator (will be calculated new)
            byte[] auth = packet.Authenticator;

            // encode new packet (with new authenticator)
            var bos = new MemoryStream();
            packet.EncodeRequestPacket(bos, serverSecret);
            byte[] data = bos.ToArray();
            bos.Dispose();


            //var datagram = new DatagramPacket(data, data.Length, serverAddress, serverPort);

            // restore original authenticator
            packet.Authenticator = auth;

            // send packet
            //Socket proxySocket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.IP);
            proxySocket.Send(data, data.Length);
            //proxySocket.send(datagram);
        }
Example #14
0
        /// <summary>
        /// Constructs an answer for an Access-Request packet. Either this
        /// method or isUserAuthenticated should be overriden.
        /// @param accessRequest Radius request packet
        /// @param client address of Radius client
        /// @return response packet or null if no packet shall be sent
        /// @exception RadiusException malformed request packet; if this
        /// exception is thrown, no answer will be sent
        /// </summary>
        public virtual RadiusPacket AccessRequestReceived(AccessRequest accessRequest, IPEndPoint client)
        {
            String plaintext = GetUserPassword(accessRequest.UserName);
            int type = RadiusPacket.AccessReject;
            if (plaintext != null && accessRequest.VerifyPassword(plaintext))
                type = RadiusPacket.AccessAccept;

            var answer = new RadiusPacket(type, accessRequest.Identifier);
            CopyProxyState(accessRequest, answer);
            return answer;
        }
Example #15
0
 /// <summary>
 /// Creates a Radius response datagram packet from a RadiusPacket to be send. 
 /// @param packet RadiusPacket
 /// @param secret shared secret to encode packet
 /// @param request request packet
 /// @return new datagram packet
 /// @throws IOException
 /// </summary>
 protected Byte[] MakeDatagramPacket(RadiusPacket packet, String secret, RadiusPacket request)
 {
     var bos = new MemoryStream();
     try
     {
         packet.EncodeResponsePacket(bos, secret, request);
         return bos.ToArray();
     }
     finally
     {
         bos.Close();
         bos.Dispose();
     }
 }
Example #16
0
 /// <summary>
 /// Sets the address the server listens on.
 /// Must be called before start().
 /// Defaults to null, meaning listen on every
 /// local address (wildcard address).
 /// @param listenAddress listen address or null
 /// </summary>
 /// <summary>
 /// Copies all Proxy-State attributes from the request
 /// packet to the response packet.
 /// @param request request packet
 /// @param answer response packet
 /// </summary>
 protected void CopyProxyState(RadiusPacket request, RadiusPacket answer)
 {
     IList<RadiusAttribute> proxyStateAttrs = request.GetAttributes(33);
     foreach (RadiusAttribute proxyStateAttr in proxyStateAttrs)
     {
         //RadiusAttribute proxyStateAttr = (RadiusAttribute)i.next();
         answer.AddAttribute(proxyStateAttr);
     }
 }
Example #17
0
        /**
         * Creates a RadiusPacket from a received datagram packet.
         * @param packet received datagram
         * @param request Radius request packet
         * @return RadiusPacket object
         */

        protected RadiusPacket MakeRadiusPacket(byte[] data, RadiusPacket request)
        {
            var memoryStream = new MemoryStream(data);
            try
            {
                return RadiusPacket.DecodeResponsePacket(memoryStream, SharedSecret, request);
            }
            finally
            {
                memoryStream.Dispose();
            }
        }
Example #18
0
        /**
         * Returns the socket used for the server communication. It is
         * bound to an arbitrary free local port number.
         * @return local socket
         * @throws SocketException
         */

        /**
         * Creates a datagram packet from a RadiusPacket to be send. 
         * @param packet RadiusPacket
         * @param port destination port number
         * @return new datagram packet
         * @throws IOException
         */

        protected byte[] MakeDatagramPacket(RadiusPacket packet)
        {
            using (var bos = new MemoryStream())
            {
                packet.EncodeRequestPacket(bos, SharedSecret);
                byte[] data = bos.ToArray();
                bos.Close();
                bos.Dispose();
                return data;
            }
        }
Example #19
0
        /**
         * Sends the specified packet to the specified Radius server endpoint.
         * @param remoteServer Radius endpoint consisting of server address,
         * port number and shared secret
         * @param request Radius packet to be sent 
         * @return received response packet
         * @throws RadiusException malformed packet
         * @throws IOException error while communication
         */

        public static RadiusPacket Communicate(RadiusEndpoint remoteServer, RadiusPacket request)
        {
            var rc = new RadiusClient(remoteServer.EndpointAddress.Address, remoteServer.SharedSecret);
            return rc.Communicate(request, remoteServer.EndpointAddress.Port);
        }
Example #20
0
        /**
         * Sets the retry count for failed transmissions.
         * @param retryCount retry count, >0
         */


        /**
         * Sends a Radius packet to the server and awaits an answer.
         * @param request packet to be sent
         * @param port server port number
         * @return response Radius packet
         * @exception RadiusException malformed packet
         * @exception IOException communication error (after getRetryCount()
         * retries)
         */

        public RadiusPacket Communicate(RadiusPacket request, int port)
        {
            var packetIn = new byte[RadiusPacket.MaxPacketLength];
            byte[] packetOut = MakeDatagramPacket(request);

            Socket socket = Socket;
            for (int i = 1; i <= RetryCount; i++)
            {
                try
                {
                    var endPoint = new IPEndPoint(Ip, port);

                    socket.SendTo(packetOut, endPoint);
                    socket.Receive(packetIn);
                    return MakeRadiusPacket(packetIn, request);
                }
                catch (IOException ioex)
                {
                    if (i == RetryCount)
                    {
                        if (logger.IsErrorEnabled)
                        {
                            logger.Error("communication failure, no more retries", ioex);
                        }
                        throw ioex;
                    }
                    if (logger.IsInfoEnabled)
                        logger.Info("communication failure, retry " + i);
                    // TODO increase Acct-Delay-Time by getSocketTimeout()/1000
                    // this changes the packet authenticator and requires packetOut to be
                    // calculated again (call makeDatagramPacket)
                }
            }

            return null;
        }
Example #21
0
        /// <summary>
        ///  Encodes this Radius packet and sends it to the specified output
        ///  stream.
        ///  @param out output stream to use
        ///  @param sharedSecret shared secret to be used to encode this packet
        ///  @param request Radius request packet if this packet to be encoded
        ///  is a response packet, null if this packet is a request packet
        ///  @exception IOException communication error
        ///  @exception NotImplementedException if required packet data has not been set 
        /// </summary>
        protected void EncodePacket(Stream outputStream, 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 NotImplementedException("request authenticator not set");

            // request packet authenticator
            if (request == null)
            {
                // first create authenticator, then encode attributes
                // (User-Password attribute needs the authenticator)
                Authenticator = CreateRequestAuthenticator(sharedSecret);
                EncodeRequestAttributes(sharedSecret);
            }

            byte[] attributes = GetAttributeBytes();
            int packetLength = RadiusHeaderLength + attributes.Length;
            if (packetLength > MaxPacketLength)
                throw new NotImplementedException("packet too long");

            // response packet authenticator
            Authenticator = request != null
                                ? CreateResponseAuthenticator(sharedSecret, packetLength, attributes,
                                                              request.Authenticator)
                                : UpdateRequestAuthenticator(sharedSecret, packetLength, attributes);

            outputStream.WriteByte(Convert.ToByte(Type));
            outputStream.WriteByte(Convert.ToByte(Identifier));
            byte[] lengthBytes = BitConverter.GetBytes(Convert.ToInt16(packetLength));
            Array.Reverse(lengthBytes);
            outputStream.Write(lengthBytes, 0, lengthBytes.Length);
            byte[] authen = Authenticator;
            outputStream.Write(authen, 0, authen.Length);
            outputStream.Write(attributes, 0, attributes.Length);
        }
Example #22
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 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 static RadiusPacket DecodeResponsePacket(Stream @in, String sharedSecret, RadiusPacket request)
 {
     if (request == null)
     {
         throw new ArgumentNullException("request", "request may not be null");
     }
     return(DecodePacket(DefaultDictionary.GetDefaultDictionary(), @in, sharedSecret, request));
 }
Example #23
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;
        }
Example #24
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);
        }
Example #25
0
 /// <summary>
 /// Constructs an answer for an Accounting-Request packet. This method
 /// should be overriden if accounting is supported.
 /// @param accountingRequest Radius request packet
 /// @param client address of Radius client
 /// @return response packet or null if no packet shall be sent
 /// @exception RadiusException malformed request packet; if this
 /// exception is thrown, no answer will be sent
 /// </summary>
 public RadiusPacket AccountingRequestReceived(AccountingRequest accountingRequest, IPEndPoint client)
 {
     var answer = new RadiusPacket(RadiusPacket.AccountingResponse, accountingRequest.Identifier);
     CopyProxyState(accountingRequest, answer);
     return answer;
 }
Example #26
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);
        }
Example #27
0
        /// <summary>
        /// Handles the received Radius packet and constructs a response. 
        /// @param localAddress local address the packet was received on
        /// @param remoteAddress remote address the packet was sent by
        /// @param request the packet
        /// @return response packet or null for no response
        /// @throws RadiusException
        /// </summary>
        protected virtual RadiusPacket HandlePacket(IPEndPoint localAddress,
                                                    IPEndPoint remoteAddress, RadiusPacket request, String sharedSecret)
        {
            RadiusPacket response = null;

            // check for duplicates
            if (!IsPacketDuplicate(request, remoteAddress))
            {
                if (localAddress.Port == AuthPort)
                {
                    // handle packets on auth port
                    if (typeof(AccessRequest).IsInstanceOfType(request))
                        response = AccessRequestReceived((AccessRequest)request, remoteAddress);
                    else
                        Logger.Error("unknown Radius packet type: " + request.Type);
                }
                else if (localAddress.Port == AcctPort)
                {
                    // handle packets on acct port
                    if (typeof(AccountingRequest).IsInstanceOfType(request))
                        response = AccountingRequestReceived((AccountingRequest)request, remoteAddress);
                    else
                        Logger.Error("unknown Radius packet type: " + request.Type);
                }
                else
                {
                    // ignore packet on unknown port
                }
            }
            else
                Logger.Info("ignore duplicate packet");

            return response;
        }
Example #28
0
 /**
  * This method must be implemented to return a RadiusEndpoint
  * if the given packet is to be proxied. The endpoint represents the
  * Radius server the packet should be proxied to.
  * @param packet the packet in question
  * @param client the client endpoint the packet originated from
  * (containing the address, port number and shared secret)
  * @return a RadiusEndpoint or null if the packet should not be
  * proxied
  */
 public abstract RadiusEndpoint GetProxyServer(RadiusPacket packet, RadiusEndpoint client);
Example #29
0
        /// <summary>
        /// Checks whether the passed packet is a duplicate.
        /// A packet is duplicate if another packet with the same identifier
        /// has been sent from the same host in the last time. 
        /// @param packet packet in question
        /// @param address client address
        /// @return true if it is duplicate
        /// </summary>
        protected bool IsPacketDuplicate(RadiusPacket packet, IPEndPoint address)
        {
            //long now = System.currentTimeMillis();
            DateTime now = DateTime.Now;

            DateTime intervalStart = now - (new TimeSpan(0, 0, 0, 0, DuplicateInterval));

            byte[] authenticator = packet.Authenticator;

            lock (_receivedPackets)
            {
                for (int i = _receivedPackets.Count - 1; i >= 0; i--)
                {
                    ReceivedPacket p = _receivedPackets[i];
                    if (p.ReceiveTime < intervalStart)
                    {
                        _receivedPackets.RemoveAt(i);
                    }
                    else
                    {
                        if (p.Address.Equals(address) && p.PacketIdentifier == packet.Identifier)
                        {
                            return authenticator == null || p.Authenticator == null ||
                                   Equals(p.Authenticator, authenticator);
                        }
                    }
                }
            }

            // add packet to receive list
            var rp = new ReceivedPacket
                         {
                             Address = address,
                             PacketIdentifier = packet.Identifier,
                             ReceiveTime = now,
                             Authenticator = authenticator
                         };
            _receivedPackets.Add(rp);
            return false;
        }
Example #30
0
        /**
         * Handles packets coming in on the Proxy port. Decides whether
         * packets coming in on Auth/Acct ports should be proxied.
         */

        protected override RadiusPacket HandlePacket(IPEndPoint localAddress, IPEndPoint remoteAddress,
                                                     RadiusPacket request, String sharedSecret)
        {
            // handle incoming Proxy packet
            if (localAddress.Port == ProxyPort)
            {
                proxyPacketReceived(request, remoteAddress);
                return null;
            }

            // handle auth/acct packet
            var radiusClient = new RadiusEndpoint(remoteAddress, sharedSecret);
            RadiusEndpoint radiusServer = GetProxyServer(request, radiusClient);
            if (radiusServer != null)
            {
                // Proxy incoming packet to other radius server
                var proxyConnection = new RadiusProxyConnection(radiusServer, radiusClient, request,
                                                                localAddress.Port);
                logger.Info("Proxy packet to " + proxyConnection);
                proxyPacket(request, proxyConnection);
                return null;
            }
            else
                // normal processing
                return base.HandlePacket(localAddress, remoteAddress, request, sharedSecret);
        }