Example #1
0
    def _radius_auth_func(self, server, **kwargs):
        """More private method used to authenticate a user and password against the current RADIUS server. Returns
           False if the user is rejected, True if the user is accepted. Raises CurrentServerFailed if there was an
           error with the request (such as a timeout)."""
        try:
            auth_port = self.server_dict[server]['auth_port']
            secret = self.server_dict[server]['secret']

            srv = Client(server=server,
                         authport=auth_port,
                         secret=secret,
                         dict=self.dictionary)
            srv.timeout = self.server_timeout
            if self.client_bind_ip is not None:
                # Binding to port 0 is the official way to bind to a OS-assigned random port.
                srv.bind((self.client_bind_ip, 0))
            req = srv.CreateAuthPacket(code=pyrad.packet.AccessRequest,
                                       User_Name=kwargs['user'],
                                       NAS_Identifier=self.nas_identifier)
            req["User-Password"] = req.PwCrypt(kwargs['password'])
            reply = srv.SendPacket(req)
            if reply.code == pyrad.packet.AccessAccept:
                return True
            else:
                return False
        except (pyrad.packet.PacketError, pyrad.client.Timeout, socket.error):
            raise CurrentServerFailed
Example #2
0
class SocketTests(unittest.TestCase):
    def setUp(self):
        self.server = object()
        self.client = Client(self.server)
        self.orgsocket = socket.socket
        socket.socket = MockSocket

    def tearDown(self):
        socket.socket = self.orgsocket

    def testReopen(self):
        self.client._SocketOpen()
        sock = self.client._socket
        self.client._SocketOpen()
        self.failUnless(sock is self.client._socket)

    def testBind(self):
        self.client.bind((BIND_IP, BIND_PORT))
        self.assertEqual(self.client._socket.address, (BIND_IP, BIND_PORT))
        self.assertEqual(self.client._socket.options,
                [(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)])

    def testBindClosesSocket(self):
        s = MockSocket(socket.AF_INET, socket.SOCK_DGRAM)
        self.client._socket = s
        self.client.bind((BIND_IP, BIND_PORT))
        self.assertEqual(s.closed, True)

    def testSendPacket(self):
        def MockSend(self, pkt, port):
            self._mock_pkt = pkt
            self._mock_port = port

        _SendPacket = Client._SendPacket
        Client._SendPacket = MockSend

        self.client.SendPacket(AuthPacket())
        self.assertEqual(self.client._mock_port, self.client.authport)

        self.client.SendPacket(AcctPacket())
        self.assertEqual(self.client._mock_port, self.client.acctport)

        Client._SendPacket = _SendPacket

    def testNoRetries(self):
        self.client.retries = 0
        self.assertRaises(Timeout, self.client._SendPacket, None, None)

    def testSingleRetry(self):
        self.client.retries = 1
        self.client.timeout = 0
        packet = MockPacket(AccessRequest)
        self.assertRaises(Timeout, self.client._SendPacket, packet, 432)
        self.assertEqual(self.client._socket.output,
                [("request packet", (self.server, 432))])

    def testDoubleRetry(self):
        self.client.retries = 2
        self.client.timeout = 0
        packet = MockPacket(AccessRequest)
        self.assertRaises(Timeout, self.client._SendPacket, packet, 432)
        self.assertEqual(self.client._socket.output,
                [("request packet", (self.server, 432)),
                 ("request packet", (self.server, 432))])

    def testAuthDelay(self):
        self.client.retries = 2
        self.client.timeout = 1
        packet = MockPacket(AccessRequest)
        self.assertRaises(Timeout, self.client._SendPacket, packet, 432)
        self.failIf("Acct-Delay-Time" in packet)

    def testSingleAccountDelay(self):
        self.client.retries = 2
        self.client.timeout = 1
        packet = MockPacket(AccountingRequest)
        self.assertRaises(Timeout, self.client._SendPacket, packet, 432)
        self.assertEqual(packet["Acct-Delay-Time"], [1])

    def testDoubleAccountDelay(self):
        self.client.retries = 3
        self.client.timeout = 1
        packet = MockPacket(AccountingRequest)
        self.assertRaises(Timeout, self.client._SendPacket, packet, 432)
        self.assertEqual(packet["Acct-Delay-Time"], [2])

    def testIgnorePacketError(self):
        self.client.retries = 1
        self.client.timeout = 1
        self.client._socket = MockSocket(1, 2, six.b("valid reply"))
        packet = MockPacket(AccountingRequest, verify=True, error=True)
        self.assertRaises(Timeout, self.client._SendPacket, packet, 432)

    def testValidReply(self):
        self.client.retries = 1
        self.client.timeout = 1
        self.client._socket = MockSocket(1, 2, six.b("valid reply"))
        packet = MockPacket(AccountingRequest, verify=True)
        reply = self.client._SendPacket(packet, 432)
        self.failUnless(reply is packet.reply)

    def testInvalidReply(self):
        self.client.retries = 1
        self.client.timeout = 1
        self.client._socket = MockSocket(1, 2, six.b("invalid reply"))
        packet = MockPacket(AccountingRequest, verify=False)
        self.assertRaises(Timeout, self.client._SendPacket, packet, 432)
Example #3
0
class SocketTests(unittest.TestCase):
    def setUp(self):
        self.server = object()
        self.client = Client(self.server)
        self.orgsocket = socket.socket
        socket.socket = MockSocket

    def tearDown(self):
        socket.socket = self.orgsocket

    def testReopen(self):
        self.client._SocketOpen()
        sock = self.client._socket
        self.client._SocketOpen()
        self.failUnless(sock is self.client._socket)

    def testBind(self):
        self.client.bind((BIND_IP, BIND_PORT))
        self.assertEqual(self.client._socket.address, (BIND_IP, BIND_PORT))
        self.assertEqual(self.client._socket.options,
                         [(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)])

    def testBindClosesSocket(self):
        s = MockSocket(socket.AF_INET, socket.SOCK_DGRAM)
        self.client._socket = s
        self.client._poll = MockPoll()
        self.client.bind((BIND_IP, BIND_PORT))
        self.assertEqual(s.closed, True)

    def testSendPacket(self):
        def MockSend(self, pkt, port):
            self._mock_pkt = pkt
            self._mock_port = port

        _SendPacket = Client._SendPacket
        Client._SendPacket = MockSend

        self.client.SendPacket(AuthPacket())
        self.assertEqual(self.client._mock_port, self.client.authport)

        self.client.SendPacket(AcctPacket())
        self.assertEqual(self.client._mock_port, self.client.acctport)

        Client._SendPacket = _SendPacket

    def testNoRetries(self):
        self.client.retries = 0
        self.assertRaises(Timeout, self.client._SendPacket, None, None)

    def testSingleRetry(self):
        self.client.retries = 1
        self.client.timeout = 0
        packet = MockPacket(AccessRequest)
        self.assertRaises(Timeout, self.client._SendPacket, packet, 432)
        self.assertEqual(self.client._socket.output,
                         [("request packet", (self.server, 432))])

    def testDoubleRetry(self):
        self.client.retries = 2
        self.client.timeout = 0
        packet = MockPacket(AccessRequest)
        self.assertRaises(Timeout, self.client._SendPacket, packet, 432)
        self.assertEqual(self.client._socket.output,
                         [("request packet", (self.server, 432)),
                          ("request packet", (self.server, 432))])

    def testAuthDelay(self):
        self.client.retries = 2
        self.client.timeout = 1
        packet = MockPacket(AccessRequest)
        self.assertRaises(Timeout, self.client._SendPacket, packet, 432)
        self.failIf("Acct-Delay-Time" in packet)

    def testSingleAccountDelay(self):
        self.client.retries = 2
        self.client.timeout = 1
        packet = MockPacket(AccountingRequest)
        self.assertRaises(Timeout, self.client._SendPacket, packet, 432)
        self.assertEqual(packet["Acct-Delay-Time"], [1])

    def testDoubleAccountDelay(self):
        self.client.retries = 3
        self.client.timeout = 1
        packet = MockPacket(AccountingRequest)
        self.assertRaises(Timeout, self.client._SendPacket, packet, 432)
        self.assertEqual(packet["Acct-Delay-Time"], [2])

    def testIgnorePacketError(self):
        self.client.retries = 1
        self.client.timeout = 1
        self.client._socket = MockSocket(1, 2, six.b("valid reply"))
        packet = MockPacket(AccountingRequest, verify=True, error=True)
        self.assertRaises(Timeout, self.client._SendPacket, packet, 432)

    def testValidReply(self):
        self.client.retries = 1
        self.client.timeout = 1
        self.client._socket = MockSocket(1, 2, six.b("valid reply"))
        self.client._poll = MockPoll()
        MockPoll.results = [(1, select.POLLIN)]
        packet = MockPacket(AccountingRequest, verify=True)
        reply = self.client._SendPacket(packet, 432)
        self.failUnless(reply is packet.reply)

    def testInvalidReply(self):
        self.client.retries = 1
        self.client.timeout = 1
        self.client._socket = MockSocket(1, 2, six.b("invalid reply"))
        MockPoll.results = [(1, select.POLLIN)]
        packet = MockPacket(AccountingRequest, verify=False)
        self.assertRaises(Timeout, self.client._SendPacket, packet, 432)
Example #4
0
def ifAccountThread():
    """Runs as a thread to account from traffic on an interface"""
    global _accountingInfo, _runIfAccount, nas_id, nas_ip
    global radius_update_interval, radius_acct_server, radius_auth_server

    try:
        # Is interface accounting enabled
        enabled = config_getboolean("accounting", "enabled", True)
        if not enabled:
            log_info("Interface accounting disabled.")
            return
        _runIfAccount = True

        # What interval shall we check hosts at
        check_interval = config_get("accounting", "check_interval", DEFAULT_CHECK_INTERVAL)
        radius_update_interval = config_getint("accounting", "update_interval", DEFAULT_UPDATE_INTERVAL)

        # Initialise the interface list
        default_user_file = "%s/accounting_users" % os.path.dirname(DEFAULT_CONFFILE)
        user_file = config_get("accounting", "user_file", default_user_file)
        if not os.path.exists(user_file):
            log_error("Interface accounting disabled. No user file: %s" % user_file)
            _runIfAccount = False
            return

        # Initialise the RADIUS connection
        try:
            dummy0 = getInterfaces(returnOne="dummy0")[0]
            dummy0ip = dummy0["address"].split("/")[0]
        except:
            log_error("Could not determine host loopback address!", sys.exc_info())
            dummy0ip = "127.0.0.1"
        acct_server = config_get("accounting", "acct_server", "radius")
        acct_secret = config_get_required("accounting", "acct_secret")
        auth_server = config_get("accounting", "auth_server", "radius")
        auth_secret = config_get_required("accounting", "auth_secret")
        nas_id = config_get("accounting", "nas_id", getFQDN())
        nas_ip = config_get("accounting", "nas_ip", dummy0ip)
        radius_acct_server = Client(server=acct_server, secret=acct_secret, dict=Dictionary(RADIUS_DICTIONARY))
        radius_auth_server = Client(server=auth_server, secret=auth_secret, dict=Dictionary(RADIUS_DICTIONARY))
        # FreeRADIUS at least auths based on IP address, make sure our
        # packets come from the right place
        radius_acct_server.bind((nas_ip, 0))
        radius_auth_server.bind((nas_ip, 0))

        # Read and parse the user file
        parseUserFile(user_file)

        # Initialise interface state
        initialiseInterfaceState()

        # Loop forever reading byte counters as appropriate
        while _runIfAccount:
            # wait a bit before checking
            time.sleep(check_interval)
            # Send any queued packets
            processRADIUSQueue()
            # Try and re-authenticate any dead interfaces
            for ifname, iface in _accountingInfo.items():
                if iface["authenticated"]:
                    continue
                age = time.time() - iface["last_auth_check"]
                if age > radius_update_interval:
                    doRADIUSAuthentication(ifname)
            # Update traffic details
            updateTrafficCounters()
            # Generate interim-updates
            processInterimUpdates()

    except:
        (etype, value, tb) = sys.exc_info()
        log_error("Exception in interface accounting thread! - %s" % value, (etype, value, tb))

    log_info("Exiting interface accounting thread")