def __init__(self, debug=False, config_path=None, file_list=None, vt_api_key=None): # Initialize parent class super().__init__(debug, config_path, file_list, vt_api_key) if self.os_name: try: # Load threads self._WORKERS = self.config_dict[ self.os_name]["scanner"]["clamav"]["threads"] except KeyError: self.logger.log("Could not load configuration for: {}".format( self.os_name), logtype="error") sys.exit(0) else: self.logger.log("Could not determine the OS", logtype="error") sys.exit(0) # Setup Clam AV object self.clamd_client = clamd.ClamdUnixSocket()
def status(): try: clamd.ClamdUnixSocket().ping() except Exception: return '', 500 return 'ok', 200
def scan(): if 'document' not in request.files: abort( 400, 'The file for scanning should be uploaded under the name `document`.' ) file = request.files['document'] try: client = clamd.ClamdUnixSocket() with logged_duration_for_external_request( service='ClamAV', description='instream scan via unix socket'): scan_result = client.instream(BytesIO( file.stream.read()))['stream'] except clamd.ClamdError as e: current_app.logger.error(f'Unable to scan file: {str(e)}') return abort(500) response_json = { 'infectionFound': False if scan_result[0] == 'OK' else True, 'details': scan_result[1:] } return jsonify(response_json), 200
def scan(): sys.stderr.write("scan()") start = time.time() if not request.json: jsonify({'status': 'failed'}), 401 file = request.json["file"] if not file: jsonify({'status': 'failed'}), 401 file_data = base64.b64decode(file) cd = clamd.ClamdUnixSocket() last_result = cd.instream(BytesIO(file_data)) scan = { 'status': last_result } elapsed_time = time.time() - start sys.stderr.write(str(elapsed_time)) return jsonify(scan)
def _get_connection(self): """ :return: A different connection for each time you call the method. Thought about having a connection pool, but it doesn't make much sense; plus it adds complexity due to the threads. """ return clamd.ClamdUnixSocket(path=self._clamd_socket)
def get_clamAV_results(file_object): # Connects to UNIX socket on /var/run/clamav/clamd.ctl clam_daemon = clamd.ClamdUnixSocket() clamd_res = clam_daemon.instream(BytesIO(file_object.content)) return clamd_res["stream"][0]
def connect_to_clamav(connection_string: str) -> clamd.ClamdNetworkSocket: if connection_string.startswith("unix://"): return clamd.ClamdUnixSocket(connection_string.replace("unix://", "")) elif ":" in connection_string: host, port = connection_string.split(":") return clamd.ClamdNetworkSocket(host, int(port)) else: raise Exception("ClamAV connection string is invalid. It must be unix socket path with 'unix://' prefix or IP:PORT.")
def clamd_client(): init_daemon() client = clamd.ClamdUnixSocket(_clamd_sock) # smoke-test client.ping() return client
def test(socket='/var/run/clamav/clamd.ctl'): try: client = clamd.ClamdUnixSocket(socket) client.ping() show_ok('ClamavDeamon') except clamd.ConnectionError, e: show_ko('ClamavDeamon', 'Try: systemctl restart clamav-daemon.socket', e)
def virusScan(self, files_to_scan): files_results = [] cd = clamd.ClamdUnixSocket() for file_to_scan in files_to_scan: scan_result = cd.scan(file_to_scan) if scan_result[file_to_scan][0] == "FOUND": files_results.append({ 'name': file_to_scan, 'result': "INFECTED" }) else: hasher = hashlib.md5() with open(file_to_scan, 'rb') as afile: buf = afile.read() hasher.update(buf) params = { 'apikey': VT_API_KEY, 'resource': hasher.hexdigest() } url = requests.get( 'https://www.virustotal.com/vtapi/v2/file/report', params=params) if url.status_code == 200: json_response = url.json() response = int(json_response.get('response_code')) if response == 0: files_results.append({ 'name': file_to_scan, 'result': "NOT INFECTED" }) elif response == 1: positives = int(json_response.get('positives')) if positives == 0: files_results.append({ 'name': file_to_scan, 'result': "NOT INFECTED" }) else: files_results.append({ 'name': file_to_scan, 'result': "INFECTED" }) else: files_results.append({ 'name': file_to_scan, 'result': " MAY BE NOT INFECTED" }) else: files_results.append({ 'name': file_to_scan, 'result': "MAY BE NOT INFECTED" }) return files_results
def clamav_scan(stream): cd = clamd.ClamdUnixSocket() result = cd.instream(stream) if result['stream'][0] == 'FOUND': current_app.logger.error('VIRUS FOUND {}'.format(result['stream'][1])) return False else: return True
def get_scanner(): """Lazy get scanner configured scanner when needed""" import clamd from . import conf if conf.CLAMAV_USE_TCP: return clamd.ClamdNetworkSocket(conf.CLAMAV_TCP_ADDR, conf.CLAMAV_TCP_PORT) return clamd.ClamdUnixSocket(conf.CLAMAV_UNIX_SOCKET)
def _make_clamd(type, **kwargs): timeout = kwargs.get('timeout', 10.0) if type == 'socket': socketpath = kwargs.get('socketpath', '/var/run/clamd') return clamd.ClamdUnixSocket(path=socketpath, timeout=timeout) elif type == 'net': host = kwargs.get('host', 'localhost') port = kwargs.get('port', 3310) return clamd.ClamdNetworkSocket(host=host, port=port, timeout=timeout) else: raise ScanError('Invalid call')
def __init__(self, handler, config): self.handler = handler self.config = config clamd_debug = config.get('pyramid_clamav.debug', 'False') if clamd_debug.lower().strip() in ('false', '0', 'no'): clamd_debug = False if sys.platform == 'darwin': self.clamd = clamd.ClamdUnixSocket('/tmp/clamd.socket') else: self.clamd = clamd.ClamdUnixSocket() if clamd_debug: try: self.clamd.ping() except clamd.ConnectionError: self.scanning = False if not self.scanning: clamlog.warn('Virus scanning deactivated. (pyramid_clamav.debug ' 'is true and clamav not properly configured!') else: clamlog.info('Found clamd and its responding. Virus scanning ' 'activated.')
def get_scanner(socket, timeout=None): if socket.startswith('unix://'): return clamd.ClamdUnixSocket(socket[7:], timeout) elif socket.startswith('tcp://'): uri = urlparse(socket) return clamd.ClamdNetworkSocket(uri.hostname, uri.port or 3310, timeout) else: raise NotImplementedError( 'Missed or unsupported ClamAV connection string schema. ' 'Only tcp:// or unix:// is allowed.')
def submit(self, fileName=None, block=False, timeout=CLAM_SUBMIT_TIMEOUT_SEC): clamavResult = AnalyzerResult() allowed = False connected = False # timeout only applies if block=True timeoutTime = int(time.time()) + timeout # while limit only repeats if block=True while (not allowed) and (not clamavResult.finished): if not connected: if self.verboseDebug: eprint(f"{get_ident()}: ClamAV attempting connection") clamAv = clamd.ClamdUnixSocket(path=self.socketFileName) if self.socketFileName is not None else clamd.ClamdUnixSocket() try: clamAv.ping() connected = True if self.verboseDebug: eprint(f"{get_ident()}: ClamAV connected!") except Exception as e: connected = False if self.debug: eprint(f"{get_ident()}: ClamAV connection failed: {str(e)}") if connected: # first make sure we haven't exceeded rate limits if (self.scanningFilesCount.increment() <= CLAM_MAX_REQS): # we've got fewer than the allowed requests open, so we're good to go! allowed = True else: self.scanningFilesCount.decrement() if connected and allowed: try: if self.verboseDebug: eprint(f'{get_ident()} ClamAV scanning: {fileName}') clamavResult.result = clamAv.scan(fileName) if self.verboseDebug: eprint(f'{get_ident()} ClamAV scan result: {clamavResult.result}') clamavResult.success = (clamavResult.result is not None) clamavResult.finished = True except Exception as e: if clamavResult.result is None: clamavResult.result = str(e) if self.debug: eprint(f'{get_ident()} ClamAV scan error: {clamavResult.result}') finally: self.scanningFilesCount.decrement() elif block and (nowTime < timeoutTime): # rate limited, wait for a bit and come around and try again time.sleep(1) else: break return clamavResult
def clamscan_file(file): """ Uses ClamAV to scan given file. :param file: file to be scanned :return: """ cd = clamd.ClamdUnixSocket() open('/tmp/EICAR', 'wb').write(clamd.EICAR) scan_result = cd.scan(file).__str__() if 'FOUND' in scan_result: print('ClamAV has detected an infected file!') print(f'ClamAV\'s output: {scan_result}') else: print('ClamAV has not detected malicious code.')
def check_clamav(document_id): document = Document.objects.get(pk=document_id) clam = clamd.ClamdUnixSocket(settings.CLAMAV_SOCKET) status, sig = clam.scan(document.pdf.path)[document.pdf.path] if status == 'OK': document.isClean = True elif status == 'FOUND': document.isClean = False print("Signature found", sig) else: # unknown state document.isClean = False print("Unknown return of clamav", status, sig) document.save()
def clamd_scan(url): try: clamd_socket = clamd.ClamdUnixSocket() body = fetch(url)[0] result = clamd_socket.scan_stream(body) if result: if "FOUND" in str(result): print result, url return 1 return 0 except RequestException: pass except Exception as e: print e.message return 0.5
def virus_scanner_init(): try: import clamd cd = clamd.ClamdUnixSocket() def clamd_scan(fpath): r = cd.scan(fpath) found, msg = r.values()[0] return (found == 'FOUND', msg) return clamd_scan except ImportError as e: return lambda fpath: (False, None)
def virus_scan_device(self, mountpoint_path): """ Scans a device for viruses :param mountpoint_path: The path to the mountpoint directory of the connected device """ clam_daemon = clamd.ClamdUnixSocket() clam_daemon.reload() Logger().log('> Initiating virus scan.') scan_result = clam_daemon.scan(mountpoint_path) Logger().log('> {}'.format(scan_result), silent=True) return 'OK' in str(scan_result)
def get_clamd_status(): client = clamd.ClamdUnixSocket() try: if client.ping() == 'PONG': return { 'clamd': { 'status': 'OK', 'stats': client.stats() }, } except clamd.ClamdError as e: raise StatusError(str(e)) raise StatusError('Unknown error')
def is_safe(self, content=None): if content: cd = clamd.ClamdUnixSocket() if cd.ping() == 'PONG': cd.reload() file_buffer = BytesIO() file_buffer.write(content) file_buffer.seek(0) result = cd.instream(file_buffer) if result['stream'] == ('OK', None): return [True, "File is very safe."] else: return [False, "The file looks malicious."] else: return [False, "Clamd Cannot be reached."] else: return [True, "No content. So it is very safe."]
def __init__(self, handler, config): self.handler = handler clamd_debug = config.get('pyramid_clamav.debug', 'False') if clamd_debug.lower().strip() in ('false', '0', 'no'): clamd_debug = False clamd_socket_location = config.get('pyramid_clamav.socket', CLAMD_DEFAULT) if not os.path.exists(clamd_socket_location) and clamd_debug: self.scanning = False self.clamd = clamd.ClamdUnixSocket(clamd_socket_location) if clamd_debug: try: self.clamd.ping() except clamd.ConnectionError: self.scanning = False if not self.scanning: clamlog.warn('Virus scanning deactivated. (pyramid_clamav.debug ' 'is true and clamav not properly configured!')
def malwareScanClick(self): cd = clamd.ClamdUnixSocket() try: cd.ping() Dialog = QtWidgets.QDialog() ui = Ui_MalwareScanWindow() ui.setupUi(Dialog) Dialog.show() Dialog.exec_() except ConnectionError as e: msgBox = QtWidgets.QMessageBox() msgBox.setIcon(QtWidgets.QMessageBox.Critical) msgBox.setText("Error") msgBox.setInformativeText( 'Sorry the antivirus daemon is still in initilization mode, retry in few minutes please.' ) msgBox.setWindowTitle("Antivirus initialization") msgBox.exec_()
def main(): options, args = opt_args() if not (len(options.users) or options.all): print('Run `zarafa-scan-attachments.py --help` for parameters') return clam = clamd.ClamdUnixSocket() if not clam.ping(): print('No ClamAV Daemon connection') else: conn = kopano.Server(options=options) for user in conn.users(): print('Scanning user: [%s]' % user.name) for folder in user.store.folders(): print('\tScanning folder: [%s]' % folder.name) for item in folder.items(): scanmail(clam, item, options.autoremove)
def scanall(mntns, namespace, podname, container, scancache): '''Scan all processes in a given mount namespace''' clam = clamd.ClamdUnixSocket(path='/var/run/clamd.scan/clamd.sock') # iterated over all running processes for pid in [pid for pid in os.listdir('/proc') if pid.isdigit()]: try: # get the process's mount namespace this_mntns = os.stat('/proc/{pid}/ns/mnt'.format(pid=pid)).st_ino except OSError: # no worries if we tried to open it and failed. The process has probably gone away pass # ignore processes that don't have the requested mount namespace if this_mntns == mntns: # scan the process and iterate over the results. for fname, found in scanpid(pid, scancache, clam).iteritems(): print "Found in {ns}/{pod}/{container}:{file}: {result}".format( ns=namespace, pod=podname, container=container, file=fname, result=found)
def get_clamav(self): """Get Yara signatures matches. @return: matched Yara signatures. """ matches = None if HAVE_CLAMAV: if os.path.getsize(self.file_path) > 0: try: cd = clamd.ClamdUnixSocket() except: log.warning("failed to connect to clamd socket") return matches try: r = cd.scan(self.file_path) except Exception as e: log.warning("failed to scan file with clamav %s", e) return matches for key in r: if r[key][0] == "FOUND": matches = r[key][1] return matches
def __init__(self, debug=False, config_path=None, file_list=None, vt_api_key=None): """ Initialize ClamAVScanner. Args: debug (bool): Log on terminal or not config_path (str): Configuration JSON file path file_list (list): List of files to scan vt_api_key (str): Virus Total API Key Raises: None Returns: None """ # Initialize parent class super().__init__(debug, config_path, file_list, vt_api_key) if self.os_name: try: # Load threads self._WORKERS = self.config_dict[ self.os_name]["scanner"]["clamav"]["threads"] except KeyError: self.logger.log("Could not load configuration for: {}".format( self.os_name), logtype="error") sys.exit(0) else: self.logger.log("Could not determine the OS", logtype="error") sys.exit(0) # Setup Clam AV object self.clamd_client = clamd.ClamdUnixSocket()
def run_scan(cls, path=None): if path is None: path = cls.CONFIG.get('DEFAULT_SCAN_PATH') if not path.startswith(cls.CONFIG.get('DEFAULT_SCAN_PATH')): flash("Due to security reasons, the path must start with {}".format(cls.CONFIG.get('DEFAULT_SCAN_PATH')), "error") return [] events = [] try: clam = clamd.ClamdUnixSocket() files = clam.multiscan(path) for file in files: result = files[file][0] msg = files[file][1] if result == 'FOUND': event = HostEvent(cls.__name__) event.file = file event.signature = msg events.append(event) flash("Found {} in file {}!".format(msg, file), "warning") elif result == 'ERROR': flash("Error in file {}: {}".format(file, msg), "error") elif result == 'OK': flash("Nothing found in path/file: {}".format(file), "success") else: print("ClamAV: unhandled result in file {}: {}, Msg: {}".format(file, result, msg)) except Exception: flash(traceback.format_exc(0), "error") return events