def test_success_okta(self, a, b): self.server.hosts["127.0.0.1"] = os.getenv('RADIUS_SECRET') self.server.BindToAddress("127.0.0.1") Client(server="127.0.0.1", secret=os.getenv('RADIUS_SECRET').encode(), dict=Dictionary("dictionary")) # create request req = AuthPacket( id=AccessRequest, secret=os.getenv('RADIUS_SECRET').encode(), authenticator=b'01234567890ABCDEF', dict=Dictionary("dictionary") ) req["User-Name"] = '*****@*****.**' req["User-Password"] = req.PwCrypt('fake') req["Proxy-State"] = 'state'.encode("ascii") req.source = ("test", "port") fd = MockFd() req.fd = fd # send request with self.assertLogs('server', level='INFO') as log: self.server.auth_handler(req) self.assertEqual(fd.data, b'\x02\x01\x00\x1b\x82\xb4\x88\xb4G\xbc:\xde\xc1\xe5A\xe0\xe7y\r\x1f!\x07state') self.assertIn('INFO:server:Push approved by [email protected].', log.output)
def test_using_samaccountname_flag(self, o, mock_get, mock_post): self.assertIsNotNone(os.environ.get('OKTA_USE_SAMACCOUNTNAME')) self.server.hosts["127.0.0.1"] = os.getenv('RADIUS_SECRET') self.server.BindToAddress("127.0.0.1") Client(server="127.0.0.1", secret=os.getenv('RADIUS_SECRET').encode(), dict=Dictionary("dictionary")) # create request req = AuthPacket( id=AccessRequest, secret=os.getenv('RADIUS_SECRET').encode(), authenticator=b'01234567890ABCDEF', dict=Dictionary("dictionary") ) req["User-Name"] = 'username' req["User-Password"] = req.PwCrypt('fake') req["Proxy-State"] = 'state'.encode() req.source = ("test", "port") fd = MockFd() req.fd = fd # send request with self.assertLogs('server', level='INFO') as log: o.return_value = '00ub0oNGTSWTBKOLGLNR' self.server.auth_handler(req) o.assert_called_once_with('username') self.assertEqual(fd.data, b'\x02\x01\x00\x1b\x82\xb4\x88\xb4G\xbc:\xde\xc1\xe5A\xe0\xe7y\r\x1f!\x07state') self.assertIn('INFO:server:Push approved by username.', log.output)
def process_request(data, address, secret): error_message = None pkt = AuthPacket(packet=data, secret=secret, dict={}) reply_pkt = pkt.CreateReply() reply_pkt.code = AccessReject try: username = pkt.get(1)[0] try: password = pkt.PwDecrypt(pkt.get(2)[0]) except UnicodeDecodeError: logger.error( "Error decrypting password -- probably incorrect secret") reply_pkt.code = AccessReject return reply_pkt.ReplyPacket() auth_status = auth_with_foxpass(username, password) and two_factor(username) if auth_status: logger.info('Successful auth') reply_pkt.code = AccessAccept return reply_pkt.ReplyPacket() logger.info('Incorrect password') error_message = 'Incorrect password' except Exception as e: logger.exception(e) error_message = 'Unknown error' if error_message: reply_pkt.AddAttribute(18, error_message) return reply_pkt.ReplyPacket()
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 handle(self, data, address): ip, port = address print('from %s, data: %r' % (ip, data)) # 处理 request = AuthPacket(dict=self.dictionary, secret=SECRET, packet=data) is_user = True if is_user: reply = access_accept(request) print('access_accept') else: reply = access_reject(request) print('access_reject') reply['Acct-Interim-Interval'] = 60 # 返回 self.socket.sendto(reply.ReplyPacket(), address)
def CreateAuthPacket(self, **args): """Create a new RADIUS packet. This utility function creates a new RADIUS packet which can be used to communicate with the RADIUS server this client talks to. This is initializing the new packet with the dictionary and secret used for the client. :return: a new empty packet instance :rtype: pyrad.packet.Packet """ if not self.protocol_auth: raise Exception('Transport not initialized') return AuthPacket(dict=self.dict, id=self.protocol_auth.create_id(), secret=self.secret, **args)
def process_request(data, address, secret): error_message = None pkt = AuthPacket(packet=data, secret=secret, dict=Dictionary(io.StringIO(DICTIONARY_DATA))) reply_pkt = pkt.CreateReply() reply_pkt.code = AccessReject try: # [0] is needed because pkt.get returns a list pkt_username = pkt.get('User-Name')[0] logger.info("Auth attempt for '%s'" % (pkt_username, )) try: password = pkt.get('Password') if not password: logger.error("No password field in request") reply_pkt.code = AccessReject return reply_pkt.ReplyPacket() # [0] is needed because pkt.get returns a list password = pkt.PwDecrypt(password[0]) except UnicodeDecodeError: logger.error( "Error decrypting password -- probably incorrect secret") reply_pkt.code = AccessReject return reply_pkt.ReplyPacket() (auth_status, username) = auth_with_foxpass(pkt_username, password) auth_status = auth_status and group_match(username) and two_factor( username) if auth_status: logger.info("Successful auth for '%s'" % (pkt_username, )) reply_pkt.code = AccessAccept return reply_pkt.ReplyPacket() logger.info("Authentication failed for '%s'" % (pkt_username, )) error_message = 'Authentication failed' except Exception as e: logger.exception(e) error_message = str(e) if error_message: reply_pkt.AddAttribute('Reply-Message', error_message) return reply_pkt.ReplyPacket()
def handle(self, data, address): ip, port = address # print('from %s, data: %r' % (ip, data)) # 解析报文 request = AuthPacket(dict=self.dictionary, secret=SECRET, packet=data) # 验证用户 auth_user = verify(request) # 接受或拒绝 reply = access_reject(request) if auth_user.is_valid: if is_unique_session(mac_address=auth_user.mac_address): reply = access_accept(request) # 返回 reply['Acct-Interim-Interval'] = ACCT_INTERVAL self.socket.sendto(reply.ReplyPacket(), address)
def datagram_received(self, data, addr): self.logger.debug('[%s:%d] Received %d bytes from %s', self.ip, self.port, len(data), addr) receive_date = datetime.utcnow() if addr[0] in self.hosts: remote_host = self.hosts[addr[0]] elif '0.0.0.0' in self.hosts: remote_host = self.hosts['0.0.0.0'] else: self.logger.warn('[%s:%d] Drop package from unknown source %s', self.ip, self.port, addr) return try: self.logger.debug('[%s:%d] Received from %s packet: %s', self.ip, self.port, addr, data.hex()) req = Packet(packet=data, dict=self.server.dict) except Exception as exc: self.logger.error('[%s:%d] Error on decode packet: %s', self.ip, self.port, exc) return try: if req.code in (AccountingResponse, AccessAccept, AccessReject, CoANAK, CoAACK, DisconnectNAK, DisconnectACK): raise ServerPacketError('Invalid response packet %d' % req.code) elif self.server_type == ServerType.Auth: if req.code != AccessRequest: raise ServerPacketError( 'Received non-auth packet on auth port') req = AuthPacket(secret=remote_host.secret, dict=self.server.dict, packet=data) if self.server.enable_pkt_verify: if req.VerifyAuthRequest(): raise PacketError('Packet verification failed') elif self.server_type == ServerType.Coa: if req.code != DisconnectRequest and req.code != CoARequest: raise ServerPacketError( 'Received non-coa packet on coa port') req = CoAPacket(secret=remote_host.secret, dict=self.server.dict, packet=data) if self.server.enable_pkt_verify: if req.VerifyCoARequest(): raise PacketError('Packet verification failed') elif self.server_type == ServerType.Acct: if req.code != AccountingRequest: raise ServerPacketError( 'Received non-acct packet on acct port') req = AcctPacket(secret=remote_host.secret, dict=self.server.dict, packet=data) if self.server.enable_pkt_verify: if req.VerifyAcctRequest(): raise PacketError('Packet verification failed') # Call request callback self.request_callback(self, req, addr) except Exception as exc: if self.server.debug: self.logger.exception('[%s:%d] Error for packet from %s', self.ip, self.port, addr) else: self.logger.error('[%s:%d] Error for packet from %s: %s', self.ip, self.port, addr, exc) process_date = datetime.utcnow() self.logger.debug('[%s:%d] Request from %s processed in %d ms', self.ip, self.port, addr, (process_date - receive_date).microseconds / 1000)
def datagram_received(self, data, addr): self.logger.debug('[%s:%d] Received %d bytes from %s', self.ip, self.port, len(data), addr) receive_date = datetime.utcnow() remote_host = self.__get_remote_host__(addr[0]) if remote_host: try: if self.server.debug: self.logger.info('[%s:%d] Received from %s packet: %s.' % (self.ip, self.port, addr, data.hex())) req = Packet(packet=data, dict=self.server.dict) except Exception as exc: self.logger.error( '[%s:%d] Error on decode packet: %s. Ignore it.' % (self.ip, self.port, exc)) req = None if not req: return try: if req.code in (AccountingResponse, AccessAccept, AccessReject, CoANAK, CoAACK, DisconnectNAK, DisconnectACK): raise ServerPacketError('Invalid response packet %d' % req.code) elif self.server_type == ServerType.Auth: if req.code != AccessRequest: raise ServerPacketError( 'Received not-authentication packet ' 'on authentication port') req = AuthPacket(secret=remote_host.secret, dict=self.server.dict, packet=data) if self.server.enable_pkt_verify and \ req.message_authenticator and \ not req.verify_message_authenticator(): raise PacketError( 'Received invalid Message-Authenticator') elif self.server_type == ServerType.Coa: if req.code != DisconnectRequest and \ req.code != CoARequest: raise ServerPacketError( 'Received not-coa packet on coa port') req = CoAPacket(secret=remote_host.secret, dict=self.server.dict, packet=data) if self.server.enable_pkt_verify: if not req.VerifyCoARequest(): raise PacketError('Packet verification failed') if req.message_authenticator and \ not req.verify_message_authenticator(): raise PacketError( 'Received invalid Message-Authenticator') elif self.server_type == ServerType.Acct: if req.code != AccountingRequest: raise ServerPacketError( 'Received not-accounting packet on ' 'accounting port') req = AcctPacket(secret=remote_host.secret, dict=self.server.dict, packet=data) if self.server.enable_pkt_verify: if not req.VerifyAcctRequest(): raise PacketError('Packet verification failed') if req.message_authenticator and not \ req.verify_message_authenticator(): raise PacketError( 'Received invalid Message-Authenticator') # Call request callback self.request_callback(self, req, addr) self.requests += 1 except Exception as e: self.logger.error( '[%s:%d] Unexpected error for packet from %s: %s' % (self.ip, self.port, addr, (e, '\n'.join(traceback.format_exc().splitlines()) )[self.server.debug])) else: self.logger.error('[%s:%d] Drop package from unknown source %s', self.ip, self.port, addr) process_date = datetime.utcnow() self.logger.debug('[%s:%d] Request from %s processed in %d ms', self.ip, self.port, addr, (process_date - receive_date).microseconds / 1000)