Beispiel #1
0
        public bool stopAccounting(string username, Packet.Acct_Terminate_CauseType? terminateCause)
        {
            Packet accountingRequest = new Packet(Packet.Code.Accounting_Request, identifier, sharedKey);
            accountingRequest.addAttribute(Packet.AttributeType.User_Name, username);
            if(String.IsNullOrEmpty(sessionId))
                throw new RADIUSException("Session ID must be present for accounting.");
            accountingRequest.addAttribute(Packet.AttributeType.Acct_Session_Id, sessionId);
            accountingRequest.addAttribute(Packet.AttributeType.Acct_Status_Type, (int)Packet.Acct_Status_TypeType.Stop);
            if(terminateCause != null)
                accountingRequest.addAttribute(Packet.AttributeType.Acct_Terminate_Cause, (int) Packet.Acct_Terminate_CauseType.User_Request);

            //Accounting request packet created, sending data...
            UdpClient client = new UdpClient(server, accountingPort);
            client.Client.SendTimeout = timeout;
            client.Client.ReceiveTimeout = timeout;

            m_logger.DebugFormat("Attempting to send {0} for user {1}", accountingRequest.code, username);
            int retryCt = 0;
            while (true)
            {
                try
                {
                    client.Send(accountingRequest.toBytes(), accountingRequest.length);

                    //Listen for response, since the server has been specified, we don't need to re-specify server
                    IPEndPoint RemoteIpEndPoint = new IPEndPoint(IPAddress.Any, 0);
                    byte[] respBytes = client.Receive(ref RemoteIpEndPoint);
                    Packet responsePacket = new Packet(respBytes);

                    //Verify packet response is good, authenticator should be MD5(Code+ID+Length+RequestAuth+Attributes+Secret)
                    if (!responsePacket.verifyResponseAuthenticator(accountingRequest.authenticator, sharedKey))
                        throw new RADIUSException(String.Format("Received response to accounting request with code: {0}, but an incorrect response authenticator was supplied.", responsePacket.code));

                    lastReceievedPacket = responsePacket;

                    client.Close();

                    m_logger.DebugFormat("Received accounting response: {0} for user {1}", responsePacket.code, username);

                    return responsePacket.code == Packet.Code.Accounting_Response;
                    //SocketException is thrown if the  server does not respond by end of timeout
                }
                catch (SocketException se)
                {
                    m_logger.DebugFormat("Accounting stop attempt {0}/{1} failed. Reason: {2}", retryCt + 1, maxRetries, se.Message);
                    retryCt++;
                    if (retryCt >= maxRetries)
                        throw new RADIUSException(String.Format("No response from server after {0} tries.", maxRetries), se);
                }
                catch (Exception e)
                {
                    throw new RADIUSException("Unexpected error while trying stop accounting.", e);
                }
            }
        }
Beispiel #2
0
        public bool interimUpdate(string username)
        {
            Packet p = new Packet(Packet.Code.Accounting_Request, this.identifier, this.sharedKey);
            p.addAttribute(Packet.AttributeType.User_Name, username);
            if (String.IsNullOrEmpty(sessionId))
                throw new RADIUSException("Session ID must be present for accounting.");
            p.addAttribute(Packet.AttributeType.Acct_Session_Id, sessionId);
            p.addAttribute(Packet.AttributeType.Acct_Status_Type, (int)Packet.Acct_Status_Type.Interim_Update);

            p.addAttribute(Packet.AttributeType.Acct_Session_Time, (int)(DateTime.Now - accountingStartTime).TotalSeconds);

            if (NAS_IP_Address != null)
                p.addAttribute(Packet.AttributeType.NAS_IP_Address, NAS_IP_Address);
            if (!String.IsNullOrEmpty(NAS_Identifier))
                p.addAttribute(Packet.AttributeType.NAS_Identifier, NAS_Identifier);
            if (!String.IsNullOrEmpty(called_station_id))
                p.addAttribute(Packet.AttributeType.Called_Station_Id, called_station_id);


            m_logger.DebugFormat("Attempting to send interim-update for user {0}", username);

            for (int retryCt = 0; retryCt <= maxRetries; retryCt++)
            {
                foreach (string server in servers)
                {
                    //Accounting request packet created, sending data...
                    UdpClient client = new UdpClient(server, accountingPort);
                    client.Client.SendTimeout = timeout;
                    client.Client.ReceiveTimeout = timeout;

                    try
                    {
                        client.Send(p.toBytes(), p.length);

                        //Listen for response, since the server has been specified, we don't need to re-specify server
                        IPEndPoint RemoteIpEndPoint = new IPEndPoint(IPAddress.Any, 0);
                        byte[] respBytes = client.Receive(ref RemoteIpEndPoint);
                        Packet responsePacket = new Packet(respBytes);

                        //Verify packet response is good, authenticator should be MD5(Code+ID+Length+RequestAuth+Attributes+Secret)
                        if (!responsePacket.verifyResponseAuthenticator(p.authenticator, sharedKey))
                            throw new RADIUSException(String.Format("Received response to interim-update with code: {0}, but an incorrect response authenticator was supplied.", responsePacket.code));

                        lastReceievedPacket = responsePacket;

                        client.Close();

                        m_logger.DebugFormat("Received interim-update response: {0} for user {1}", responsePacket.code, username);

                        return responsePacket.code == Packet.Code.Accounting_Response;
                        //SocketException is thrown if the  server does not respond by end of timeout
                    }
                    catch (SocketException se)
                    {
                        m_logger.DebugFormat("Accounting interim-update attempt {0}/{1} using {2} failed. Reason: {3}", retryCt + 1, maxRetries + 1, server, se.Message);
                    }
                    catch (Exception e)
                    {
                        throw new RADIUSException("Unexpected error while sending interim-update.", e);
                    }
                }
            }
            throw new RADIUSException(String.Format("No response from server(s) after {0} tries.", maxRetries + 1));
        }
Beispiel #3
0
        //Connects to the RADIUS server and attempts to authenticate the specified user info
        //Sets username value and authenticated members IFF successful
        public bool Authenticate(string username, string password)
        {
            UdpClient client = new UdpClient(server, authenticationPort);
            client.Client.SendTimeout = timeout;
            client.Client.ReceiveTimeout = timeout;

            Packet authPacket = new Packet(Packet.Code.Access_Request, identifier, sharedKey);
            authPacket.sharedKey = sharedKey;

            authPacket.addAttribute(Packet.AttributeType.User_Name, username);

            authPacket.addAttribute(Packet.AttributeType.User_Password, password);
            if(!String.IsNullOrEmpty(sessionId))
                authPacket.addAttribute(Packet.AttributeType.Acct_Session_Id, sessionId);

            if (NAS_Identifier == null && NAS_IP_Address == null)
                throw new RADIUSException("A NAS_Identifier or NAS_IP_Address (or both) must be supplied.");
            if(NAS_IP_Address != null)
                authPacket.addRawAttribute(Packet.AttributeType.NAS_IP_Address, NAS_IP_Address);
            if (NAS_Identifier != null)
                authPacket.addAttribute(Packet.AttributeType.NAS_Identifier, NAS_Identifier);

            m_logger.DebugFormat("Attempting to send {0} for user {1}", authPacket.code, username);

            int retryCt = 0;
            while (true)
            {
                try
                {
                    client.Send(authPacket.toBytes(), authPacket.length);

                    //Listen for response, since the server has been specified, we don't need to re-specify server
                    IPEndPoint RemoteIpEndPoint = new IPEndPoint(IPAddress.Any, 0);
                    byte[] respBytes = client.Receive(ref RemoteIpEndPoint);
                    Packet responsePacket = new Packet(respBytes);

                    //Verify packet authenticator is correct
                    if (!responsePacket.verifyResponseAuthenticator(authPacket.authenticator, sharedKey))
                        throw new RADIUSException(String.Format("Received response to authentication with code: {0}, but an incorrect response authenticator was supplied.", responsePacket.code));

                    lastReceievedPacket = responsePacket;

                    client.Close();

                    m_logger.DebugFormat("Received authentication response: {0} for user {1}", responsePacket.code, username);

                    if (responsePacket.code == Packet.Code.Access_Accept)
                    {
                        this.authenticated = true;
                        return true;
                    }

                    else
                        return false;
                }

                //SocketException is thrown if the  server does not respond by end of timeout
                catch (SocketException se)
                {
                    m_logger.DebugFormat("Authentication attempt {0}/{1} failed. Reason: {2}", retryCt+1, maxRetries, se.Message);
                    retryCt++;
                    if (retryCt >= maxRetries)
                        throw new RADIUSException(String.Format("No response from server after {0} tries.", maxRetries), se);
                }
                catch (Exception e)
                {
                    throw new RADIUSException("Unexpected error while trying to authenticate.", e);
                }

            }
        }
Beispiel #4
0
        //Sends a start accounting request to the RADIUS server, returns true on acknowledge of request
        public bool startAccounting(string username, Packet.Acct_Authentic authType)
        {               
            //Create accounting request packet
            Packet accountingRequest = new Packet(Packet.Code.Accounting_Request, identifier, sharedKey);
            accountingRequest.addAttribute(Packet.AttributeType.User_Name, username);
            accountingRequest.addAttribute(Packet.AttributeType.Acct_Status_Type, (int)Packet.Acct_Status_Type.Start);
            if (String.IsNullOrEmpty(sessionId)) //Create new guid
                sessionId = Guid.NewGuid().ToString();
            accountingRequest.addAttribute(Packet.AttributeType.Acct_Session_Id, sessionId);

            if (String.IsNullOrEmpty(NAS_Identifier) && NAS_IP_Address == null)
                throw new RADIUSException("A NAS_Identifier or NAS_IP_Address (or both) must be supplied.");
            if (NAS_IP_Address != null)
                accountingRequest.addAttribute(Packet.AttributeType.NAS_IP_Address, NAS_IP_Address);
            if (!String.IsNullOrEmpty(NAS_Identifier))
                accountingRequest.addAttribute(Packet.AttributeType.NAS_Identifier, NAS_Identifier);
            if (!String.IsNullOrEmpty(called_station_id))
                accountingRequest.addAttribute(Packet.AttributeType.Called_Station_Id, called_station_id);

            if (authType != Packet.Acct_Authentic.Not_Specified)
                accountingRequest.addAttribute(Packet.AttributeType.Acct_Authentic, (int)authType);

            //m_logger.DebugFormat("Attempting to send {0} for user {1}", accountingRequest.code, username);

            for (int retryCt = 0; retryCt <= maxRetries; retryCt++)
            {
                foreach (string server in servers)
                {
                    //Accounting request packet created, sending data...
                    UdpClient client = new UdpClient(server, accountingPort);
                    client.Client.SendTimeout = timeout;
                    client.Client.ReceiveTimeout = timeout;

                    try
                    {
                        client.Send(accountingRequest.toBytes(), accountingRequest.length);

                        //Listen for response, since the server has been specified, we don't need to re-specify server
                        IPEndPoint RemoteIpEndPoint = new IPEndPoint(IPAddress.Any, 0);
                        byte[] respBytes = client.Receive(ref RemoteIpEndPoint);
                        Packet responsePacket = new Packet(respBytes);

                        //Verify packet response is good, authenticator should be MD5(Code+ID+Length+RequestAuth+Attributes+Secret)
                        if (!responsePacket.verifyResponseAuthenticator(accountingRequest.authenticator, sharedKey))
                            throw new RADIUSException(String.Format("Received response to accounting request with code: {0}, but an incorrect response authenticator was supplied.", responsePacket.code));

                        lastReceievedPacket = responsePacket;

                        client.Close();

                        m_logger.DebugFormat("Received accounting response: {0} for user {1}", responsePacket.code, username);

                        if (responsePacket.code == Packet.Code.Accounting_Response)
                            accountingStartTime = DateTime.Now;

                        return responsePacket.code == Packet.Code.Accounting_Response;
                    }

                    //SocketException is thrown if the  server does not respond by end of timeout
                    catch (SocketException se)
                    {
                        m_logger.DebugFormat("Accounting start attempt {0}/{1} using {2} failed. Reason: {3}", retryCt + 1, maxRetries + 1, server, se.Message);
                    }
                    catch (Exception e)
                    {
                        throw new RADIUSException("Unexpected error while trying start accounting.", e);
                    }
                }
            }
            throw new RADIUSException(String.Format("No response from server(s) after {0} tries.", maxRetries + 1));
        }