Example #1
0
    def finish(self):
        super().finish(
        )  # Flush the Data to Client & Then Write To Database [Currently Sqlite is Used]
        try:
            database_handler = AccessDatabaseHandler()
            with database_handler.get_connection(
            ) as db_connection:  # Db Context Way to Insert and Commit Quickly
                AccessDatabaseHandler.insert_to_access_db(
                    db_connection=db_connection,
                    client_data_holder=self.client_data_holder)
                ## Insert Into DB
                ## Commit [Currently each insert is committed we we actually later on change it to 1000 Transaction and then commit it]
            database_handler.close_db_connection()

        except AttributeError as client_data_holder_not_present:
            logger.error(
                f"[Reason: AttributeError], Details: [{client_data_holder_not_present}]"
            )
        except Exception as all_exception:
            print(
                f"[EXCEPTION: {all_exception}], client_Data_holder to insert: ",
                self.client_data_holder)
            logger.error(
                f"[EXCEPTION: {all_exception}], client_Data_holder to insert: {self.client_data_holder}"
            )
Example #2
0
    def validate_and_dns_name_setup(self, dns_request, client_address):
        logger.debug(f"[Process : Validate & Dns Name Setup]")  ## Debugging
        validation_result = False
        validation_info = "Improper/Forged Dns Request"
        custom_parsed_dns_response = None
        try:
            parsed_dns_request = DNSRecord.parse(dns_request)
            req_dns_name = str(parsed_dns_request.questions[0].qname)
            req_dns_type = int(parsed_dns_request.questions[0].qtype)
            if req_dns_name in self.dns_name.keys():
                dns_name_to_set = self.dns_name[req_dns_name]
                logger.debug(f"IP ADDR LIST: {dns_name_to_set.split(',')}")
                custom_parsed_dns_response = DnsBuilder.create_dns_response(
                    parsed_dns_request=parsed_dns_request,
                    req_dns_name=req_dns_name,
                    req_dns_type=req_dns_type,
                    ip_address_list=dns_name_to_set.split(","))
                validation_info = ""
            else:
                validation_result = True
                validation_info = ""
                self.domain_name_extractor(
                    requested_domain_name=req_dns_name,
                    requested_domain_name_type=req_dns_type
                )  #Extract Proper Info From the Dns Requested Domain

        except (dnslib.buffer.BufferError,
                dnslib.dns.DNSError) as dns_parsing_error:
            logger.error(
                f"[Process: Validation By using parse()] "
                f"[Error: DnsRecord.parse() Exception, Data Received is INCORRECT, "
                f"Exception: [{dns_parsing_error}]",
                exc_info=True)
            # Enable StackTrace in Logs
            validation_info = validation_info + f", Exception: [{dns_parsing_error}]"
        except Exception as all_exception:
            logger.error(
                f"[Process: Validation By using parse()] "
                f"[Error: Unknown Exception] "
                f"Exception: [{all_exception}]",
                exc_info=True)
            # Enable StackTrace in Logs
            validation_info = validation_info + f", Exception: [{all_exception}]"
        finally:
            if validation_result:
                logger.debug(
                    f"Process Complete Validation INFO: [{validation_info}, {custom_parsed_dns_response}]"
                )
                return validation_result
            else:
                if validation_info == "":
                    self.send_response_to_client(
                        client_address=client_address,
                        raw_dns_response=DNSRecord.pack(
                            custom_parsed_dns_response),
                        status_tag=validation_info)
                return None
    def start_server(self):
        logger.debug(
            f"Dns Service Running @ {self.DNS_SERVER_UDP_SOCKET.getsockname()} "
        )

        while True:
            try:
                dns_request, client_address = self.DNS_SERVER_UDP_SOCKET.recvfrom(
                    1024)
                ## Received Data from Socket
                #self.validate_and_handle_client(uniq_id, dns_request, client_address); ## Single Threaded
                handler_thread = Thread(
                    target=self.validate_and_handle_client,
                    args=(dns_request,
                          client_address))  ## Making it MultiThreaded
                #handler_thread.setName(f"Dns-Query-Handler-Thread-{uniq_id}")
                logger.debug(
                    f"[Process: Starting Thread: {handler_thread.getName()} with uniq_id: [{uniq_id}]]"
                )
                handler_thread.start()
                ## Start The Thread For Processing
            except ConnectionResetError as conn_reset:
                logger.error(
                    f"[Reason: ConnectionResetError]: [ERROR: {conn_reset}]")
            except KeyboardInterrupt as key_cancel:
                logger.error(
                    f"[Reason: KeyboardInterrupt]: [ERROR: {key_cancel}]")
                self.stop_server()
            except Exception as all_exception:
                logger.error(
                    f"[Reason: Exception]: [All Exceptions are handled here][ERROR: {all_exception}]"
                )
                logger.error(traceback.print_exc())
                self.stop_server()
 def start_server(self):
     logger.debug(f"[Process: Starting Dns Server @ [{self.server_address}]");
     print(f"[Process: Starting Dns Server @ [{self.server_address}]");
     reason = None;
     try:
         self.serve_forever(); #Start The Server
     except ConnectionResetError as conn_reset:
         logger.error(f"[Reason: ConnectionResetError]: [ERROR: {conn_reset}]", exc_info=True); # Stack Trace the Exception
         reason = conn_reset;
     except KeyboardInterrupt as key_cancel:
         logger.error(f"[Reason: KeyboardInterrupt]: [ERROR: {key_cancel}]", exc_info=True); # Stack Trace the Exception
         reason = key_cancel;
     except Exception as all_exception:
         logger.error(f"[Reason: Exception]: [All Exceptions are handled here][ERROR: {all_exception}]", exc_info=True); # Stack Trace the Exception
         reason = all_exception;
     finally:
         self.stop_server(reason=reason)
 def stop_server(self, reason):
     logger.error(f"[Reason: {reason}] Closing/Shutting Dns Service");
     self.server_close()
     exit();
    def process(self, client_data_holder):
        self.client_data_holder = client_data_holder
        self.generate_parsed_dns_request()

        self.process_dns_request()
        PolicyHandler.process_policy_check_for_dns_request(
            client_data_holder=client_data_holder
        )  # Request Filter set the query value to to ALLOW or BLOCK

        if client_data_holder.policy_status.split(":")[0] == "BLOCK":
            self.cache_check()
            # Check in Cache [Later change that it also return True or False]
            if client_data_holder.cache_status:
                self.fetch_from_cache(
                )  # Get From Cache [It Returns Raw Dns Response]
                return client_data_holder
                # now it can be send therefore return it
            else:
                custom_parsed_dns_reponse = DnsBuilder.create_dns_response(
                    parsed_dns_request=client_data_holder.parsed_dns_request,
                    req_dns_name=client_data_holder.requested_domain,
                    req_dns_type=client_data_holder.requested_query_type
                )  # Create a Block Response
                client_data_holder.parsed_dns_response = custom_parsed_dns_reponse
                self.dns_response_for_sending()
                return client_data_holder

        #self.cache_check_and_fetch()
        self.cache_check()

        # Getting the Raw Dns Response [From Cache ] OR [ From Auth Server]
        if self.client_data_holder.cache_status:
            self.fetch_from_cache()
        else:
            self.fetch_from_auth_dns_server()

        if client_data_holder.raw_dns_response:
            self.generate_parsed_dns_response()
        else:
            logger.error(
                f"[Reason: Cache OR Auth Server Had some Issue and return None "
                f"-> [{client_data_holder.raw_dns_response}], "
                f"[Temp Solution: Return Raw Dns Request as Raw Dns Response")
            client_data_holder.raw_dns_response = client_data_holder.raw_dns_request

        self.process_dns_response()
        PolicyHandler.process_policy_check_for_dns_response(
            client_data_holder=client_data_holder)  # Response Filter

        ## Left To Implement Response Filter if BLOCKED

        if not client_data_holder.cache_status and not client_data_holder.dns_auth_server_timedout:
            logger.debug(
                f"[Process: Adding Data To Cache], "
                f"Key: [{client_data_holder.unique_key}], "
                f"Value: [{client_data_holder.raw_dns_response}], "
                f"Cache Details: [{web_category_cache.show_cache()}], "
                f"[Socket TimeOut: [{client_data_holder.dns_auth_server_timedout}]] "
            )
            web_category_cache.add_to_cache(
                client_data_holder.unique_key,
                client_data_holder.raw_dns_response)
        else:
            logger.debug(
                f"[Process: Don't Add it To Cache], Cache Status: [{client_data_holder.cache_status}] "
                f"Key: [{client_data_holder.unique_key}], "
                f"Value: [{client_data_holder.raw_dns_response}], "
                f"Cache Details: [{web_category_cache.show_cache()}], "
                f"[Socket TimeOut: [{client_data_holder.dns_auth_server_timedout}]] "
            )

        self.dns_response_for_sending()
        return client_data_holder
 def stop_server(self):
     logger.error(
         "[Reason: KeyboardInterrupt] Closing/Shutting Dns Service")
     exit()