class AutoBackup(plugins.Plugin): __author__ = '*****@*****.**' __version__ = '1.0.0' __license__ = 'GPL3' __description__ = 'This plugin backups files when internet is available.' def __init__(self): self.ready = False self.tries = 0 self.status = StatusFile('/root/.auto_backup') def on_loaded(self): for opt in ['files', 'interval', 'commands', 'max_tries']: if opt not in self.options or (opt in self.options and self.options[opt] is None): logging.error(f"[auto_backup] Option {opt} is not set.") return self.ready = True logging.info("[auto_backup] Successfully loaded.") def on_internet_available(self, agent): if not self.ready: return if self.options[ 'max_tries'] and self.tries >= self.options['max_tries']: return if self.status.newer_then_days(self.options['interval']): return # Only backup existing files to prevent errors existing_files = list( filter(lambda f: os.path.exists(f), self.options['files'])) files_to_backup = " ".join(existing_files) try: display = agent.view() logging.info("[auto_backup] Backing up...") display.set('status', 'Backing up...') display.update() for cmd in self.options['commands']: logging.info( f"[auto_backup] Running {cmd.format(files=files_to_backup)}" ) process = subprocess.Popen(cmd.format(files=files_to_backup), shell=True, stdin=None, stdout=open("/dev/null", "w"), stderr=None, executable="/bin/bash") process.wait() if process.returncode > 0: raise OSError(f"Command failed (rc: {process.returncode})") logging.info("[auto_backup] Backup done.") display.set('status', 'Backup done!') display.update() self.status.update() except OSError as os_e: self.tries += 1 logging.info(f"[auto_backup] Error: {os_e}") display.set('status', 'Backup failed!') display.update()
class GitBackup(plugins.Plugin): __author__ = '*****@*****.**' __version__ = '1.0.0' __license__ = 'GPL3' __description__ = 'git_backup' def __init__(self): self.ready = False self.tries = 0 logging.debug("GIT BACKUP") self.status = StatusFile('/root/.git_backup') # called when http://<host>:<port>/plugins/<plugin>/ is called # must return a html page # IMPORTANT: If you use "POST"s, add a csrf-token (via csrf_token() and render_template_string) def on_webhook(self, path, request): pass # called when the plugin is loaded def on_loaded(self): self.ready = True logging.info("GIT-BACKUP: Successfully loaded.") # called before the plugin is unloaded def on_unload(self, ui): pass # called hen there's internet connectivity def on_internet_available(self, agent): if not self.ready: return if self.tries >= 2: return if self.status.newer_then_days(self.options['interval']): return try: f = open("/home/pi/git_err.txt", "a+") display = agent.view() logging.info("GITBACKUP: Backing up ...") display.set('status', 'Backing up ...') display.update() logging.info(f"GIT-BACKUP: Running") process = subprocess.Popen([ 'sudo cp -r /root/brain.nn /root/brain.json /root/.api-report.json /root/handshakes/ /root/peers/ /etc/pwnagotchi/ /var/log/pwnagotchi.log /root/Pwnagotchi/ && cd /root/Pwnagotchi/ && sudo git pull && sudo git add . && sudo git commit -am "backup" && sudo git push' ], shell=True, stderr=f, stdin=f) process.wait() f.close() logging.info("GIT-BACKUP: backup done") display.set('status', 'GIT-Backup done!') display.update() self.status.update() except OSError as os_e: self.tries += 1 logging.info(f"GIT-BACKUP: Error: {os_e}") display.set('status', 'Backup failed!') display.update() # called to setup the ui elements def on_ui_setup(self, ui): pass # called when the ui is updated def on_ui_update(self, ui): pass # update those elements # called when the hardware display setup is done, display is an hardware specific object def on_display_setup(self, display): pass # called when everything is ready and the main loop is about to start def on_ready(self, agent): logging.info("unit is ready") # you can run custom bettercap commands if you want # agent.run('ble.recon on') # or set a custom state # agent.set_bored() # called when the AI finished loading def on_ai_ready(self, agent): pass # called when the AI finds a new set of parameters def on_ai_policy(self, agent, policy): pass # called when the AI starts training for a given number of epochs def on_ai_training_start(self, agent, epochs): pass # called after the AI completed a training epoch def on_ai_training_step(self, agent, _locals, _globals): pass # called when the AI has done training def on_ai_training_end(self, agent): pass # called when the AI got the best reward so far def on_ai_best_reward(self, agent, reward): pass # called when the AI got the worst reward so far def on_ai_worst_reward(self, agent, reward): pass # called when a non overlapping wifi channel is found to be free def on_free_channel(self, agent, channel): pass # called when the status is set to bored def on_bored(self, agent): pass # called when the status is set to sad def on_sad(self, agent): pass # called when the status is set to excited def on_excited(self, agent): pass # called when the status is set to lonely def on_lonely(self, agent): pass # called when the agent is rebooting the board def on_rebooting(self, agent): pass # called when the agent is waiting for t seconds def on_wait(self, agent, t): pass # called when the agent is sleeping for t seconds def on_sleep(self, agent, t): pass # called when the agent refreshed its access points list def on_wifi_update(self, agent, access_points): pass # called when the agent refreshed an unfiltered access point list # this list contains all access points that were detected BEFORE filtering def on_unfiltered_ap_list(self, agent, access_points): pass # called when the agent is sending an association frame def on_association(self, agent, access_point): pass # called when the agent is deauthenticating a client station from an AP def on_deauthentication(self, agent, access_point, client_station): pass # callend when the agent is tuning on a specific channel def on_channel_hop(self, agent, channel): pass # called when a new handshake is captured, access_point and client_station are json objects # if the agent could match the BSSIDs to the current list, otherwise they are just the strings of the BSSIDs def on_handshake(self, agent, filename, access_point, client_station): pass # called when an epoch is over (where an epoch is a single loop of the main algorithm) def on_epoch(self, agent, epoch, epoch_data): pass # called when a new peer is detected def on_peer_detected(self, agent, peer): pass # called when a known peer is lost def on_peer_lost(self, agent, peer): pass