def show_iface(iface_name=None, is_verbose=False, use_html=False): """enable the given interface by calling ifup.""" theResult = str("""UNKNOWN""") if is_verbose is True: theResult = str(get_iface_status_raw(iface_name)) else: try: if use_html: format_pattern = str("""{}{}{}{}""") else: format_pattern = str("""{} {} {} {}""") theResult = str(format_pattern).format( get_iface_name(iface_name, use_html), get_iface_mac(iface_name, use_html), get_iface_ip_list(iface_name, use_html), get_iface_status(iface_name, use_html)) if use_html: theResult = html_generator.gen_html_tr( theResult, str(u'iface_status_row_{}').format(iface_name)) except Exception as cmdErr: logs.log(str(cmdErr), "Error") logs.log(str((cmdErr.args)), "Error") theResult = str("""UNKNOWN""") return theResult
def upgradePiAPlib_webui(): """Upgrade PiAP version via update script.""" upsream_repo_depends = str( "https://raw.githubusercontent.com/reactive-firewall" + "/Pocket-PiAP/stable/upgrade.sh" ) script_prefix = str("""/opt/PiAP/sbin/""") if os.path.isdir(os.path.abspath("""/opt/PiAP/sbin/""")) is False: script_prefix = str("""/var/tmp/""") utils.getFileResource(upsream_repo_depends, str(script_prefix + "upgrade.sh")) # check script # lock state try: upgrade_thread = threading.Thread( name='PiAP Upgrade Thread', target=doPythonCommand, args=(["bash", str(script_prefix + "upgrade.sh")], None,) ) upgrade_thread.start() except Exception: logs.log(str("PANIC - upgrade failed to start"), "CRITICAL") # not sure if this is needed utils.cleanFileResource("upgrade.sh") try: wait_for_threads_to_drain(['PiAP Upgrade Thread']) except Exception: logs.log(str("PANIC - upgrade failed to stop safely"), "CRITICAL") return None
def trylog(*args, **kwargs): """wrapper for try/catch around piaplib.book.log.log()""" try: logs.log(*args, **kwargs) except Exception as logError: if logError: logError = None del (logError)
def logOrPrint(*args, **kwargs): """wrapper for try/catch around piaplib.book.log.log()""" try: logs.log(*args, **kwargs) except Exception as logError: if args[0]: print(str(args[0])) logError = None del (logError)
def get_user_ttys(user=None, use_html=False): """Generate output of the user ttys.""" if (user is None) and (use_html is not True): return None elif (user is None) and (use_html is True): return html_generator.gen_html_label(u'UNKNOWN', u'warning') # otherwise theResult = None try: raw_data = get_user_work_status_raw(user) if raw_data is None: return u'UNKNOWN' tty_list_txt = utils.extractTTYs(raw_data) if use_html is not True: if tty_list_txt is not None and len(tty_list_txt) > 0: theResult = str(tty_list_txt) else: theResult = u'console' else: theResult = html_generator.gen_html_td( html_generator.gen_html_ul(tty_list_txt), str(u'user_status_tty_{}').format(user) ) except Exception as errcrit: if not use_html: logs.log( str("user_check_status.get_user_ttys: ERROR: ACTION will not be completed! ABORT!"), "Error" ) logs.log(str(type(errcrit)), "Error") logs.log(str(errcrit), "Error") logs.log(str((errcrit.args)), "Error") theResult = None return theResult
def wait_for_threads_to_drain(names=[]): main_thread = threading.currentThread() for t in threading.enumerate(): if t is main_thread: continue elif names is not None and (len(names) > 0): if t.getName() in names: logs.log(str("joining {}").format(t.getName()), "Debug") t.join() else: continue else: logs.log(str("joining {}").format(t.getName()), "Debug") t.join() return None
def upgradeAPT(): """Upgrade system via apt.""" try: import apt import apt.cache cache = apt.Cache() cache.update() cache.open(None) cache.upgrade() for pkg in cache.get_changes(): logs.log(str((pkg.name, pkg.isupgradeable)), "Info") raise NotImplementedError("[CWE-758] - Pocket upgrade upgradeAPT() not implemented. Yet.") except Exception as permErr: remediation.error_breakpoint(permErr, "upgradeAPT") permErr = None del(permErr) return None
def cleanFileResource(theFile): """cleans up a downloaded given file.""" theResult = False try: os.remove(str(theFile)) theResult = True except OSError: theResult = False except Exception: logs.log(str("Error: Failed to remove file"), "Warning") theResult = False try: if theResult: logs.log(str("purged file {}").format(theFile), "Debug") except Exception: pass return theResult
def useCheckTool(tool, arguments=[None]): """Handler for launching pocket-tools.""" if tool is None: return None if tool in CHECK_UNITS.keys(): theResult = None try: logs.log(str("check launching: " + str(tool)), "DEBUG") theResult = CHECK_UNITS[tool].main(arguments) except Exception: logs.log( str("An error occurred while handling the health check tool. Cascading failure." ), "WARNING") theResult = None return theResult else: return None
def getFileResource(someURL, outFile): """Downloads a file from the given URL.""" theResult = True try: urlretrieve(url=someURL, filename=outFile) except Exception as err: logs.log( str("Failed to fetched file {}").format(str(someURL)), "Debug") piaplib.pku.remediation.error_breakpoint(error=err, context=getFileResource) theResult = False try: if theResult: logs.log(str("fetched file {}").format(someURL), "Debug") except Exception: pass return theResult
def moveFileResource(theSrc, theDest): """cleans up a downloaded given file.""" theResult = False try: os.rename(str(theSrc), str(theDest)) theResult = True except OSError: theResult = False except Exception: logs.log(str("Error: Failed to rename file"), "Warning") theResult = False try: if theResult: logs.log( str("Moved file {} to {}").format(theSrc, theDest), "Debug") except Exception: pass return theResult
def unsafe_main(unsafe_input=None, chrootpath=None, uid=None, gid=None, passOutput=False): """ The main unsafe work. Fork and drop privileges try to chroot. Then run unsafe input. """ ppid = os.getpid() pid = os.fork() if pid is not None and pid > ppid: # this is the parent process... do whatever needs to be done as the parent logs.log( str("""OK - PiAP Launched pid {} as SANDBOXED COMMAND.""").format( pid), "Debug") exit(0) else: try: # we are the child process... lets do that plugin thing! if chrootpath is not None: chworkingdir(chrootpath) if taint_int(uid): os.seteuid(int(uid)) if taint_int(gid): os.setgid(int(gid)) except Exception as unsafeErr: remediation.error_breakpoint(unsafeErr) unsafeErr = None del unsafeErr os.abort() # POSIX.1-2008 Sec. 11.2.3 - refork tainted_pid = os.fork() if tainted_pid is not None and tainted_pid > 0: # this is the parent process... do whatever needs to be done as the parent logs.log( str("""OK - PiAP Launched pid {} as TAINTED COMMAND."""). format(tainted_pid), "Warn") exit(0) else: tainted_output = runUnsafeCommand(unsafe_input) if (passOutput is not None and passOutput is True): return tainted_output return None
def main(argv=None): """The main function.""" (args, extras) = parseArgs(argv) try: verbose = False output_html = False if args.verbose_mode is not None: verbose = args.verbose_mode if args.output_html is not None: output_html = bool(args.output_html) if args.show_all is True: showAlliFace(verbose, output_html) elif args.list is True: try: for iface_name in get_iface_list(): print(str(iface_name)) except Exception as err: remediation.error_breakpoint(err) else: interface = args.interface print(show_iface(interface, verbose, output_html)) return 0 except Exception as main_err: logs.log( str("iface_check_status: REALLY BAD ERROR: ACTION will not be completed! ABORT!" ), "Error") logs.log(str(main_err), "Error") logs.log(str(main_err.args), "Error") return 1
def show_user(user_name=None, is_verbose=False, use_html=False): """show the given user.""" theResult = None try: if use_html is True: format_pattern = str(u'{}{}{}{}') else: format_pattern = str(u'{} {} {} {}') theResult = str(format_pattern).format( get_user_name(user_name, use_html), get_user_ttys(user_name, use_html), get_user_ip(user_name, use_html), get_user_status(get_user_name(user_name, False), use_html) ) if use_html: the_temp_Result = html_generator.gen_html_tr( theResult, str(u'user_status_row_{}').format(get_user_name(user_name, False)) ) theResult = utils.literal_str(the_temp_Result) except Exception as cmdErr: if not use_html: logs.log(str(type(cmdErr)), "Error") logs.log(str(cmdErr), "Error") logs.log(str((cmdErr.args)), "Error") theResult = "UNKNOWN" return theResult
def chworkingdir(sandboxPath=None): if sandboxPath is None: sandboxPath = os.path.abspath("/tmp") try: if os.access(os.path.abspath(sandboxPath), os.F_OK): if os.geteuid() > 0: os.chdir(str(os.path.abspath(sandboxPath))) else: os.chroot(str(os.path.abspath(sandboxPath))) else: os.abort() except OSError as badChrootErr: remediation.error_breakpoint(badChrootErr) badChrootErr = None del badChrootErr try: os.chdir(str(os.path.abspath(sandboxPath))) except Exception: logs.log(str("""CRASH - PiAP aborted from sandboxing"""), "CRITICAL") os.abort() return None
def main(argv=None): """The main event""" try: try: (args, extra) = parseArgs(argv) chk_cmd = args.check_unit useCheckTool(chk_cmd, argv[1:]) except Exception as cerr: logs.log( str("An error occurred while handling the arguments. Command failure." ), "ERROR") logs.log(str(type(cerr)), "ERROR") logs.log(str(cerr), "ERROR") logs.log(str((cerr.args)), "ERROR") cerr = None del (cerr) return 3 except Exception: logs.log( str("An error occurred while handling the failure. Cascading failure." ), "ERROR") return 3 return 0
def get_sort_cmd_path(): """Either /usr/bin/sort or sort depending on system.""" try: if (str(sys.platform).lower().startswith(str("""darwin""")) is True): return str("""/usr/bin/sort""") else: return str("""sort""") except Exception as someErr: logs.log(str(type(someErr)), "Error") logs.log(str(someErr), "Error") logs.log(str((someErr.args)), "Error") return str("""sort""")
def get_w_cmd_args(): """Either -his or -wnh depending on system.""" try: if (str(sys.platform).lower().startswith(str("""darwin""")) is True): return str("""-hi""") else: return str("""-his""") except Exception as someErr: logs.log(str(type(someErr)), "Error") logs.log(str(someErr), "Error") logs.log(str((someErr.args)), "Error") return str("""-h""")
def isLineForUser(someLine=None, username=None): """determins if a raw output line is for a user""" doesMatch = False try: doesMatch = utils.isLineForMatch(someLine, username) except Exception as matchErr: logs.log(str(type(matchErr)), "Error") logs.log(str(matchErr), "Error") logs.log(str((matchErr.args)), "Error") matchErr = None del matchErr doesMatch = False return doesMatch
def get_user_ip(user=None, use_html=False): """Generate output of the user IP.""" theResult = None try: raw_data = get_user_work_status_raw(user) if raw_data is not None: ip_list_txt = utils.extractIPv4(raw_data) if use_html is not True: if (ip_list_txt is not None) and (len(ip_list_txt) > 0): theResult = str(ip_list_txt[0]) else: theResult = getLocalhostName() else: if (ip_list_txt is not None) and (len(ip_list_txt) > 0): theResult = html_generator.gen_html_td( html_generator.gen_html_ul(ip_list_txt), str(u'user_status_ips_{}').format(user) ) else: theResult = html_generator.gen_html_td( html_generator.gen_html_label(getLocalhostName(), u'disabled'), str(u'user_status_ips_{}').format(user) ) else: if (use_html is True): theResult = html_generator.gen_html_label(u'UNKNOWN', u'warning') else: theResult = "UNKNOWN" except Exception as errcrit: if not use_html: logs.log( str("user_check_status.get_user_ip: ERROR: ACTION will not be completed! ABORT!"), "Error" ) logs.log(str(type(errcrit)), "Error") logs.log(str(errcrit), "Error") logs.log(str((errcrit.args)), "Error") theResult = "UNKNOWN" return theResult
def usePKUTool(tool, arguments=[None]): """Handler for launching pocket-tools.""" theExitCode = 1 if tool is None: theExitCode = 0 elif tool in PKU_UNITS.keys(): try: logs.log(str("pku launching: {}").format(str(tool)), "DEBUG") theExitCode = 0 PKU_UNITS[tool].main(arguments) except Exception: logs.log(str("An error occurred while handling the PKU tool. "), "WARNING") logs.log(str("PKU failure."), "Error") theExitCode = 3 return theExitCode
def main_func(*args, **kwargs): """Wraps a function in try-except""" theOutput = 5 try: theOutput = func(*args, **kwargs) except Exception as err: error_breakpoint(error=err, context=func) logs.log(str("[CWE-691] Action will not be completed! ABORT!"), "CRITICAL") logs.log( str("[CWE-209] You found a bug. Please report this to my creator." ), "Error") logs.log(str(""), "CRITICAL") err = None del err theOutput = 3 return theOutput
def main(argv=None): # noqa C901 """The main function.""" (args, extras) = parseArgs(argv) try: verbose = False if args.verbose_mode is not None: verbose = (args.verbose_mode is True) if args.output_html is not None: output_html = (args.output_html is True) if args.show_all is True: output = str("") if output_html: output = str("<table class=\"table table-striped\">") output += str("<thead><th>User</th><th>TTYs</th><th>Host</th>") output += str("<th>Activity</th></thead><tbody>") try: for user_name in get_user_list(): output += str(show_user(user_name, verbose, output_html)) output += str("""\n""") except Exception as content_err: if output_html: # might need to add error alert here content_err = None del(content_err) else: logs.log(str(type(content_err)), "Error") logs.log(str(content_err), "Error") logs.log(str((content_err.args)), "Error") content_err = None del(content_err) print(output) if output_html: print("</tbody></table>") else: if args.list is True: for user_name in get_user_list(): print(user_name) else: user = args.user print(show_user(user, verbose, output_html)) return 0 return 0 except Exception as main_err: logs.log(str( "{}: REALLY BAD ERROR: ACTION will not be completed! ABORT!" ).format(__prog__), "Error") logs.log(str(main_err), "Error") logs.log(str((main_err.args)), "Error") return 1
def warned_func(*args, **kwargs): """Wraps a function in try-except""" theOutput = None try: theOutput = func(*args, **kwargs) except Exception as err: timestamp = getTimeStamp() logs.log( str("An exception occurred at {}").format(timestamp), "Warning") logs.log(str(func), "Debug") logs.log(str(type(err)), "Debug") logs.log(str(err), "Warning") logs.log(str((err.args)), "Debug") logs.log(str(""), "Warning") # sys.exc_clear() err = None del err theOutput = None return theOutput
def error_breakpoint(error, context): """Just logs the error and returns None""" timestamp = getTimeStamp() logs.log(str("=" * 40), "Warning") logs.log(str("An error occurred at {}").format(timestamp), "Error") if context is not None: logs.log(str(context), "Debug") logs.log(str(type(error)), "Debug") logs.log(str(error), "Error") if isinstance(error, PiAPError): logs.log(str("=" * 40), "Warning") logs.log(str("Caused by:"), "Warning") logs.log(str(error.cause), "Error") logs.log(str(type(error.cause)), "Debug") else: if isinstance(error, Exception): logs.log(str((error.args)), "Error") else: logs.log(str("[CWE-209] Cause Redacted!"), "Debug") return None
def get_system_work_status_raw(user_name=None): """list the raw status of system work.""" theuserState = None try: import subprocess try: # hard-coded white-list cmds p1 = subprocess.Popen( [utils.literal_str(get_ps_cmd_path()), str("-eo"), str("user,command")], shell=False, stdout=subprocess.PIPE, stderr=None, close_fds=True ) p2 = subprocess.Popen( [ str("tr"), str("-s"), utils.literal_str("""' '"""), utils.literal_str("""' '""") ], shell=False, stdin=p1.stdout, stdout=subprocess.PIPE, close_fds=True ) p3 = subprocess.Popen( [ str("sed"), str("-E"), str("-e"), str(utils.literal_str("""s/[\\[\\(]{1}[^]]+[]\\)]{1}/SYSTEM/g""")) ], shell=False, stdin=p2.stdout, stdout=subprocess.PIPE, close_fds=True ) p4 = subprocess.Popen( [utils.literal_str(get_sort_cmd_path())], shell=False, stdin=p3.stdout, stdout=subprocess.PIPE, close_fds=True ) p5 = subprocess.Popen( [utils.literal_str("""uniq""")], shell=False, stdin=p4.stdout, stdout=subprocess.PIPE, close_fds=True ) p4.stdout.close() # Allow p4 to receive a SIGPIPE if p5 exits. (output, stderrors) = p5.communicate() p3.stdout.close() # Allow p4 to receive a SIGPIPE when p5 exits. p2.stdout.close() # Allow p4 to receive a SIGPIPE when p5 exits. p1.stdout.close() # Allow p4 to receive a SIGPIPE when p5 exits. if (isinstance(output, bytes)): output = output.decode('utf8') if (output is not None) and (len(output) > 0): lines = [ utils.literal_str(x) for x in output.splitlines() if isLineForUser(x, user_name) ] theuserState = str("") for line in lines: if (line is not None) and (len(line) > 0): theuserState = str("{}{}\n").format(str(theuserState), str(line)) del lines else: theuserState = None except subprocess.CalledProcessError as subErr: subErr = None del subErr theuserState = None except Exception as cmdErr: logs.log(str(type(cmdErr)), "Error") logs.log(str(cmdErr), "Error") logs.log(str((cmdErr.args)), "Error") theuserState = None except Exception as importErr: logs.log(str(importErr), "Warning") logs.log(str((importErr.args)), "Warning") theuserState = None return theuserState
def get_user_work_status_raw(user_name=None): """list the raw status of user work.""" theRawOutput = None try: import subprocess output = None stderrors = None try: # hard-coded white-list cmds p1 = subprocess.Popen( [str("w"), str(get_w_cmd_args())], shell=False, stdout=subprocess.PIPE, stderr=None ) p2 = subprocess.Popen( [ str("tr"), str("-s"), utils.literal_str("""' '"""), utils.literal_str("""' '""") ], shell=False, stdin=p1.stdout, stdout=subprocess.PIPE, close_fds=True ) p1.stdout.close() # Allow p1 to receive a SIGPIPE if p2 exits. (output, stderrors) = p2.communicate() except subprocess.CalledProcessError as subErr: p1.kill() p2.kill() subErr = None del(subErr) theRawOutput = None except Exception as cmdErr: p1.kill() p2.kill() logs.log(str(type(cmdErr)), "Error") logs.log(str(cmdErr), "Error") logs.log(str((cmdErr.args)), "Error") theRawOutput = None finally: p2.wait() p1.wait() if stderrors: output = None if (isinstance(output, bytes)): output = output.decode('utf8') if output is not None and len(output) > 0: lines = [ utils.literal_str(x) for x in output.splitlines() if isLineForUser(x, user_name) ] theRawOutput = str("") for line in lines: if (line is not None) and (len(line) > 0): theRawOutput = str("{}{}\n").format(str(theRawOutput), str(line)) del(lines) else: theRawOutput = None except Exception as importErr: logs.log(str(type(importErr)), "Warning") logs.log(str(importErr), "Warning") logs.log(str((importErr.args)), "Warning") theRawOutput = None return theRawOutput
def format_raw_user_list(theRawuserState=None): """formate raw list of the available users.""" theResult = None try: if theRawuserState is None: theResult = [] return theResult try: theResult = utils.compactList( [str(str(x).split(u' ', 1)[0]) for x in theRawuserState.split(u'\n') if (u' ' in x)] ) except Exception as cmdErr: logs.log(str(type(cmdErr)), "Error") logs.log(str(cmdErr), "Error") logs.log(str((cmdErr.args)), "Error") theResult = [] # while one line is probably faster here, two is more readable for reserved_lines in ["UID", "message+", str("""USER""")]: theResult = [x for x in theResult if utils.xstr(reserved_lines) not in utils.xstr(x)] except Exception as parseErr: logs.log( str("{}.get_user_list: ERROR: ACTION will not be completed! ABORT!").fromat(__file__), "Error" ) logs.log(str(type(parseErr)), "Error") logs.log(str(parseErr), "Error") logs.log(str((parseErr.args)), "Error") theResult = [] return theResult
def get_user_status(user_name=None, use_html=False): # noqa C901 """Generate the status""" theResult = None try: user_tty = None status_list = [] t_user_name = taint_name(user_name) if taint_name(user_name) is not None: user_tty = get_user_ttys(t_user_name, False) status_txt = get_system_work_status_raw(t_user_name) if (user_tty is not None) and (str(user_tty).lower() not in str("console")): status_txt = get_user_work_status_raw(t_user_name) if status_txt is None: status_list = ["UNKNOWN"] else: status_list = utils.compactList( [str( str(x).split(u' ', 4)[-1] ) for x in status_txt.split(u'\n') if (x is not None) and (len(x) > 0)] ) elif status_txt is not None: if (str("root SYSTEM\n") not in status_txt): theWorks = utils.compactList( [str( str(x).split(u' ', 1)[1:] ) for x in status_txt.split("""\n""") if (x is not None) and (len(x) > 0)] ) known_work_cases = getKnownProcessesTable() for theWork in theWorks: temp_txt = "UNKNOWN" if ("SYSTEM" in theWork): temp_txt = "SYSTEM" else: for known_case in known_work_cases.keys(): if (known_case in theWork): temp_txt = known_work_cases[known_case] status_list.append(str(_util_generate_user_status_lable(temp_txt, use_html))) status_list = utils.compactList(status_list) else: if use_html is True: status_list = [str(html_generator.gen_html_label(u'System', u'info'))] else: status_list = ["SYSTEM"] if use_html is not True: theResult = status_list else: theResult = html_generator.gen_html_td( html_generator.gen_html_ul(status_list), str(u'user_status_what_{}').format(t_user_name) ) status_list = None del status_list status_txt = None del status_txt user_tty = None del user_tty except Exception as errcrit: if not use_html: logs.log( str("user_check_status.get_user_status: ERROR: ACTION will not be completed! ABORT!"), "Error" ) logs.log(str(type(errcrit)), "Error") logs.log(str(errcrit), "Error") logs.log(str((errcrit.args)), "Error") theResult = None return theResult
for iface_name in get_iface_list(): print(str(iface_name)) except Exception as err: remediation.error_breakpoint(err) else: interface = args.interface print(show_iface(interface, verbose, output_html)) return 0 except Exception as main_err: logs.log( str("iface_check_status: REALLY BAD ERROR: ACTION will not be completed! ABORT!" ), "Error") logs.log(str(main_err), "Error") logs.log(str(main_err.args), "Error") return 1 if __name__ == u'__main__': try: exitcode = 3 if (sys.argv is not None and len(sys.argv) > 0): exitcode = main(sys.argv[1:]) exit(exitcode) except Exception as main_err: logs.log( str("iface_check_status: REALLY BAD ERROR: ACTION will not be completed! ABORT!" ), "Error") logs.log(str(main_err), "Error") logs.log(str(main_err.args), "Error") exit(3)