def main ():
    '''Parses the options supplied on the command line and writes to a log.

    The first item is assumed to be the name of the log to write to in the path.
    Ther est of the arguments are joined as the message for the log entry.
    '''

    parser = argparse.ArgumentParser(prog='Management Logger',
                                     description="Used to output information to a log.  The first word is the name of the log, and the rest is the message.")
    parser.add_argument('-v', '--version', action='version', version='%(prog)s 1.2')
    parser.add_argument('-p', '--path',
                        help="A different directory to put the log file in.",
                        default='')
    parser.add_argument('-l', '--level',
                        type=int,
                        default=20,
                        help="Specify the logging level.  Lower numbers mean that the logger will record more events (higher numbers are more restrictive).")
    parser.add_argument('name',
                        help="The name of the log file.")
    parser.add_argument('message',
                        nargs='+',
                        help="The stuff to put into the log entry.")
    args = parser.parse_args()

    logger = loggers.file_logger(name=args.name, level=-5, path=args.path)
    message = ' '.join(args.message)

    logger.log(args.level, message)
def setup_logger(log, log_dest):
    try:
        from management_tools import loggers
    except ImportError as e:
        print "You need the 'Management Tools' module to be installed first."
        print "https://github.com/univ-of-utah-marriott-library-apple/management_tools"
        raise e

    if not log:
        logger = loggers.stream_logger(1)
    else:
        if log_dest:
            logger = loggers.file_logger(options["name"], path=log_dest)
        else:
            logger = loggers.file_logger(options["name"])
    return logger
    def __init__(self, name, log, log_dest=''):
        try:
            from management_tools import loggers
        except ImportError as e:
            print(
                "You need the 'Management Tools' module to be installed first.")
            print(
                "https://github.com/univ-of-utah-marriott-library-apple/" +
                "management_tools")
            raise e

        if not log:
            self.logger = loggers.stream_logger(1)
        else:
            if log_dest:
                self.logger = loggers.file_logger(name, path=log_dest)
            else:
                self.logger = loggers.file_logger(name)
def setup_logger():
    '''Creates the logger to be used throughout.

    If it was not specified not to create a log, the log will be created in either
    the default location (as per management_tools) or a specified location.

    Otherwise, the logger will just be console output.
    '''

    global logger
    if options['log']:
        # A logger!
        if not options['log_dest']:
            logger = loggers.file_logger(options['name'])
        else:
            logger = loggers.file_logger(options['name'], path=options['log_dest'])
    else:
        # A dummy logger.  It won't record anything to file.
        logger = loggers.stream_logger(1)
def setup_logger ():
    '''Creates the logger to be used throughout.

    If it was not specified not to create a log, the log will be created in either
    the default location (as per helpful_tools) or a specified location.

    Otherwise, the logger will just be console output.
    '''

    global logger
    if options['log']:
        # Write the logs to files.
        if not options['log_dest']:
            # If no destination is explicitly given, use the defaults.
            logger = loggers.file_logger(options['name'])
        else:
            # Otherwise, use the specified value.
            logger = loggers.file_logger(options['name'], path=options['log_dest'])
    else:
        # A dummy logger.  It won't record anything to file.
        logger = loggers.stream_logger(1)
def logger (log, log_dest='', name=''):
    '''Creates and returns the logger to be used throughout.

    If it was not specified not to create a log, the log will be created in either
    the default location (as per management_tools) or a specified location.

    Otherwise, the logger will just be console output.
    '''

    if not name:
        name = 'unnamed'

    if log:
        # A logger!
        if not log_dest:
            return loggers.file_logger(name)
        else:
            return loggers.file_logger(name, path=log_dest)
    else:
        # A dummy logger.  It won't record anything to file.
        return loggers.stream_logger(1)
Exemple #7
0
def logger(log, log_dest='', name=''):
    '''Creates and returns the logger to be used throughout.

    If it was not specified not to create a log, the log will be created in either
    the default location (as per management_tools) or a specified location.

    Otherwise, the logger will just be console output.
    '''

    if not name:
        name = 'unnamed'

    if log:
        # A logger!
        if not log_dest:
            return loggers.file_logger(name)
        else:
            return loggers.file_logger(name, path=log_dest)
    else:
        # A dummy logger.  It won't record anything to file.
        return loggers.stream_logger(1)
Exemple #8
0
def setup_logger():
    '''Creates the logger to be used throughout.

    If it was not specified not to create a log, the log will be created in either
    the default location (as per helpful_tools) or a specified location.

    Otherwise, the logger will just be console output.
    '''

    global logger
    if options['log']:
        # Write the logs to files.
        if not options['log_dest']:
            # If no destination is explicitly given, use the defaults.
            logger = loggers.file_logger(options['name'])
        else:
            # Otherwise, use the specified value.
            logger = loggers.file_logger(options['name'],
                                         path=options['log_dest'])
    else:
        # A dummy logger.  It won't record anything to file.
        logger = loggers.stream_logger(1)
Exemple #9
0
def main():
    '''Parses the options supplied on the command line and writes to a log.

    The first item is assumed to be the name of the log to write to in the path.
    Ther est of the arguments are joined as the message for the log entry.
    '''

    parser = argparse.ArgumentParser(
        prog='Management Logger',
        description=
        "Used to output information to a log.  The first word is the name of the log, and the rest is the message."
    )
    parser.add_argument('-v',
                        '--version',
                        action='version',
                        version='%(prog)s 1.2')
    parser.add_argument('-p',
                        '--path',
                        help="A different directory to put the log file in.",
                        default='')
    parser.add_argument(
        '-l',
        '--level',
        type=int,
        default=20,
        help=
        "Specify the logging level.  Lower numbers mean that the logger will record more events (higher numbers are more restrictive)."
    )
    parser.add_argument('name', help="The name of the log file.")
    parser.add_argument('message',
                        nargs='+',
                        help="The stuff to put into the log entry.")
    args = parser.parse_args()

    logger = loggers.file_logger(name=args.name, level=-5, path=args.path)
    message = ' '.join(args.message)

    logger.log(args.level, message)
def main():
    """
    Master Control Function.
    """

    #
    # require root to run.
    if os.geteuid():
        print "Must be root to run script."
        exit(2)

    #
    # parse option definitions
    parser = argparse.ArgumentParser(
        description='Manages the firmware password on Apple Computers.')
    #
    # required, mutually exclusive commands
    prime_group = parser.add_argument_group('Required management settings',
                                            'Choosing one of these options is required \
                                            to run FWPM. They tell FWPM how you \
                                            want to manage the firmware password.')
    subprime = prime_group.add_mutually_exclusive_group(required=True)
    subprime.add_argument('-r', '--remove', action="store_true",
                          default=False, help='Remove the firmware password')
    subprime.add_argument('-m', '--management', default=None,
                          help='Set a custom nvram management string')
    subprime.add_argument('-#', '--hash', action="store_true", default=False,
                          help='Set nvram string to hash of keyfile')
    subprime.add_argument('-n', '--nostring', action="store_true", default=False,
                          help='Do not set an nvram management string')

    keyfile_group = parser.add_argument_group('Keyfile options', 'The keyfile is \
                                               required to use FWPM. These options \
                                               allow you to set the location and \
                                               format of the keyfile.')
    keyfile_group.add_argument('-k', '--keyfile', help='Set the path to your keyfile',
                               required=True)
    keyfile_group.add_argument('-o', '--obfuscated', action="store_true", default=False,
                               help='Tell FWPM your keylist is an obfuscated plist.')

    slack_group = parser.add_argument_group('Slack integration',
                                            'FWPM allows you to send informational \
                                            and error messages to your Slack team. \
                                            Additionally you can select different \
                                            methods of identifiying clients.')
    slack_group.add_argument('-s', '--slack', action="store_true",
                             default=False, help='Send important messages to Slack.')
    slack_group.add_argument('-i', '--identifier', default=None,
                             choices=['IP', 'hostname', 'MAC', 'computername', 'serial'],
                             required=False, help='Set slack identifier.')

    parser.add_argument('-b', '--reboot', action="store_true", default=False,
                        help='Reboots the computer after the script completes successfully.')
    parser.add_argument('-t', '--testmode', action="store_true", default=False,
                        help='Test mode. Verbose logging, will not delete keyfile.')
    parser.add_argument('-v', '--version', action='version', version='%(prog)s 2.1.5')

    args = parser.parse_args()

    if args.testmode:
        print args

    #
    # Open log file
    logger = loggers.file_logger(name='FWPW_Manager2')
    logger.info("Running Firmware Password Manager 2")

    #
    # set up slack channel(s)
    slack_info_url = 'your FWPM slack info URL'
    slack_info_channel = '#your FWPM slack info channel'
    info_bot = IWS(slack_info_url, bot_name="FWPM informational message", channel=slack_info_channel)

    slack_error_url = 'your FWPM slack error URL'
    slack_error_channel = '#your FWPM slack error channel'
    error_bot = IWS(slack_error_url, bot_name="FWPM error message", channel=slack_error_channel)

    local_identifier = None

    if args.slack:
        full_ioreg = subprocess.check_output(['ioreg', '-l'])
        serial_number_raw = re.findall(r'\"IOPlatformSerialNumber\" = \"(.*)\"', full_ioreg)
        serial_number = serial_number_raw[0]
        if args.testmode:
            print "Serial number: %r" % serial_number

        if args.identifier == 'IP' or args.identifier == 'MAC' or args.identifier == 'hostname':
            processed_device_list = []

            # Get ordered list of network devices
            base_network_list = subprocess.check_output(["/usr/sbin/networksetup", "-listnetworkserviceorder"])
            network_device_list = re.findall(r'\) (.*)\n\(.*Device: (.*)\)', base_network_list)
            for device in network_device_list:
                device_name = device[0]
                port_name = device[1]
                try:
                    device_info_raw = subprocess.check_output(["/sbin/ifconfig", port_name])
                    mac_address = re.findall(r'ether (.*) \n', device_info_raw)
                    if args.testmode:
                        print "%r" % mac_address
                    ether_address = re.findall(r'inet (.*) netmask', device_info_raw)
                    if args.testmode:
                        print "%r" % ether_address
                    processed_device_list.append([device_name, port_name, ether_address[0], mac_address[0]])
                except:
                    pass

            if len(processed_device_list) > 0:
                logger.info("1 or more active IP addresses. Choosing primary.")
                if args.testmode:
                    print processed_device_list
                if args.identifier == 'IP':
                    local_identifier = processed_device_list[0][2] + " (" + processed_device_list[0][0] + ":" + processed_device_list[0][1] + ")"

                if args.identifier == 'MAC':
                    local_identifier = processed_device_list[0][3] + " (" + processed_device_list[0][0] + ":" + processed_device_list[0][1] + ")"

                if args.identifier == 'hostname':
                    try:
                        local_identifier = socket.getfqdn()
                    except:
                        logger.error("error discovering hostname info.")
                        local_identifier = serial_number

            elif len(processed_device_list) == 0:
                logger.error("error discovering IP info.")
                local_identifier = serial_number

        elif args.identifier == 'computername':
            try:
                cname_identifier_raw = subprocess.check_output(['/usr/sbin/scutil', '--get', 'ComputerName'])
                local_identifier = cname_identifier_raw.split('\n')[0]
                logger.info("Computername: " + local_identifier)
            except:
                logger.info("error discovering computername.")
                local_identifier = serial_number
        elif args.identifier == 'serial':
            local_identifier = serial_number
            logger.info("Serial number: " + local_identifier)
        else:
            logger.info("bad or no identifier flag, defaulting to serial number.")
            local_identifier = serial_number

        if args.testmode:
            print "Local identifier: %r" % local_identifier

    #
    # keyfile checks
    path_to_keyfile_exists = os.path.exists(args.keyfile)

    if not path_to_keyfile_exists:
        logger.critical(args.keyfile + " does not exist. Exiting.")
        if args.slack:
            error_bot.send_message("_*" + local_identifier + "*_ :no_entry_sign:\n" + "Keyfile does not exist.")
        exit(2)

    #
    # generate hash from incoming keyfile
    logger.info("Checking incoming hash.")
    if args.management:
        fwpw_managed_string = args.management
    elif args.hash:
        incoming_hash = subprocess.check_output(["/usr/bin/openssl", "dgst", "-sha256", args.keyfile])
        incoming_hash = incoming_hash.rstrip('\r\n')
        fwpw_managed_string = incoming_hash.split(" ")[1]
        # prepend '2:' to denote hash created with v2 of script, will force a password change from v1
        fwpw_managed_string = '2:' + fwpw_managed_string
    else:
        fwpw_managed_string = None

    if args.testmode:
        print "Incoming hash: %s" % fwpw_managed_string

    #
    # compare incoming hash with current nvram hash
    existing_keyfile_hash = None
    logger.info("Checking existing hash.")
    if not args.remove:
        try:
            existing_keyfile_hash = subprocess.check_output(["/usr/sbin/nvram", "fwpw-hash"])
            existing_keyfile_hash = existing_keyfile_hash.rstrip('\r\n')
            existing_keyfile_hash = existing_keyfile_hash.split("\t")[1]

            if args.testmode:
                print "Existing hash: %s" % existing_keyfile_hash

        except Exception as this_exception:
            logger.warning("nvram failed with " + str(this_exception) + " (fwpw probably not set).")

        if existing_keyfile_hash == fwpw_managed_string:
            if args.hash:
                logger.info("Hashes match. Exiting.")
                if args.slack:
                    info_bot.send_message("_*" + local_identifier + "*_ :white_check_mark:\n" + "Hashes match. No Change.")
                secure_delete_keyfile(logger, args, error_bot, local_identifier)
                if args.reboot:
                    logger.info("Reboot not required, canceling.")
                # return a value?
                exit(0)
            else:
                logger.info("Management strings match. Continuing.")

    #
    # firmwarepasswd tool checks
    new_fw_tool_path = '/usr/sbin/firmwarepasswd'
    new_fw_tool_exists = os.path.exists(new_fw_tool_path)

    if not new_fw_tool_exists:
        logger.critical("No Firmware password tool available. Exiting.")
        secure_delete_keyfile(logger, args, error_bot, local_identifier)
        if args.slack:
            error_bot.send_message("_*" + local_identifier + "*_ :no_entry:\n" + "No Firmware password tool available.")
        exit(1)

    #
    # checking for existing fw password
    logger.info("Checking for existing firmware password")

    existing_fw_pw = subprocess.check_output([new_fw_tool_path, "-check"])
    logger.info("New tools says " + existing_fw_pw)
    if 'No' in existing_fw_pw:
        if args.remove:
            logger.critical("Asked to delete, no password set. Exiting.")
            secure_delete_keyfile(logger, args, error_bot, local_identifier)
            if args.slack:
                error_bot.send_message("_*" + local_identifier + "*_ :no_entry:\n" + "Asked to Delete, no password set.")
            try:
                modify_nvram = subprocess.call(["/usr/sbin/nvram", "-d", "fwpw-hash"])
                logger.info("nvram entry pruned.")
            except:
                logger.warning("nvram reported error attempting to remove hash. Hash may not have existed.")
            exit(1)
        else:
            logger.info("No firmware password set.")
            existing_password = False
    elif 'Yes' in existing_fw_pw:
        logger.info("Existing firmware password set.")
        existing_password = True
    else:
        logger.critical("Firmwarepasswd bad response at -check. Exiting.")
        secure_delete_keyfile(logger, args, error_bot, local_identifier)
        if args.slack:
            error_bot.send_message("_*" + local_identifier + "*_ :no_entry:\n" + "Firmwarepasswd bad response at -check.")
        exit(1)

    logger.info("Reading password file")

    if args.obfuscated:
        #
        # unobfuscate plist
        logger.info("Reading plist")
        passwords = []
        try:
            input_plist = plistlib.readPlist(args.keyfile)
        except:
            logger.critical("Error reading plist. Exiting.")
            if args.slack:
                error_bot.send_message("_*" + local_identifier + "*_ :no_entry:\n" + "Error reading plist.")
            exit(1)
        content_raw = input_plist["data"]

        content_raw = base64.b64decode(content_raw)
        content_raw = content_raw.split(",")
        content_raw = [x for x in content_raw if x]

        for item in content_raw:
            label, pword = item.split(':')
            pword = base64.b64decode(pword)
            try:
                commented = label.split('#')[1]
                commented = base64.b64decode(commented)
                is_commented = True
            except:
                is_commented = False

            if is_commented:
                output_string = "#" + commented + ":"+pword
            else:
                output_string = label + ":"+pword
            passwords.append(output_string)

    else:
        #
        #  read keyfile
        logger.info("Reading plain text")

        try:
            with open(args.keyfile, "r") as keyfile:
                passwords = keyfile.read().splitlines()
        except:
            logger.critical("Error reading keyfile. Exiting.")
            if args.slack:
                error_bot.send_message("_*" + local_identifier + "*_ :no_entry:\n" + "Error reading keyfile.")
            exit(1)

        logger.info("Closed password file")

    new_password = None
    other_password_list = []

    #
    # parse data from keyfile and build list of passwords
    for entry in passwords:
        try:
            key, value = entry.split(":", 1)
        except Exception as this_exception:
            logger.critical("Malformed keyfile, key:value format required. " + this_exception + ". Quitting.")
            secure_delete_keyfile(logger, args, error_bot, local_identifier)
            if args.slack:
                error_bot.send_message("_*" + local_identifier + "*_ :no_entry:\n" + "Malformed keyfile.")
            exit(1)

        if args.testmode:
            logger.info(key + ":" + value)

        if key.lower() == 'new':
            if new_password is not None:
                logger.critical("Malformed keyfile, multiple new keys. Quitting.")
                secure_delete_keyfile(logger, args, error_bot, local_identifier)
                if args.slack:
                    error_bot.send_message("_*" + local_identifier + "*_ :no_entry:\n" + "Malformed keyfile.")
                exit(1)
            else:
                new_password = value
                other_password_list.append(value)
        else:
            other_password_list.append(value)

    logger.info("Sanity checking password file contents")

    if new_password is None and not args.remove:
        logger.critical("Malformed keyfile, no \'new\' key. Quitting.")
        secure_delete_keyfile(logger, args, error_bot, local_identifier)
        if args.slack:
            error_bot.send_message("_*" + local_identifier + "*_ :no_entry:\n" + "Malformed keyfile.")
        exit(1)

    exit_normal = False
    known_current_password = False

    #
    # if a password is set, attempt to discover it using keyfile
    if existing_password:
        logger.info("Verifying current FW password")
        new_fw_tool_cmd = [new_fw_tool_path, '-verify']
        logger.info(' '.join(new_fw_tool_cmd))

        for keyfile_index in reversed(xrange(len(other_password_list))):
            child = pexpect.spawn(' '.join(new_fw_tool_cmd))
            child.expect('Enter password:'******'Correct', 'Incorrect'])

            if result == 0:
                #
                # correct password, exit loop
                current_password = other_password_list[keyfile_index]
                known_current_password = True
                break
            else:
                #
                # wrong password, keep going
                continue

        #
        # We've discovered the currently set firmware password
        if known_current_password:

            #
            # Deleting firmware password
            if args.remove:
                logger.info("Deleting FW password")

                new_fw_tool_cmd = [new_fw_tool_path, '-delete']
                logger.info(' '.join(new_fw_tool_cmd))

                child = pexpect.spawn(' '.join(new_fw_tool_cmd))
                child.expect('Enter password:'******'removed', 'incorrect'])

                if result == 0:
                    #
                    # password accepted, log result and exit
                    logger.info("Finished. Password should be removed. Restart required. [" + (keyfile_index + 1) + "]")
                    exit_normal = True
                else:
                    logger.critical("Asked to delete, current password not accepted. Exiting.")
                    secure_delete_keyfile(logger, args, error_bot, local_identifier)
                    if args.slack:
                        error_bot.send_message("_*" + local_identifier + "*_ :no_entry:\n" + "Asked to delete, current password not accepted.")
                    exit(1)

            #
            # Current and new password are identical
            elif current_password == new_password:
                logger.info("Match, no change required. Exiting.")
                exit_normal = True

            #
            # Change current firmware password to new password
            else:
                logger.info("Updating FW password")

                new_fw_tool_cmd = [new_fw_tool_path, '-setpasswd']
                logger.info(' '.join(new_fw_tool_cmd))

                child = pexpect.spawn(' '.join(new_fw_tool_cmd))

                result = child.expect('Enter password:'******'Enter new password:'******'Re-enter new password:'******'-setpasswd']
        logger.info(' '.join(new_fw_tool_cmd))

        child = pexpect.spawn(' '.join(new_fw_tool_cmd))

        result = child.expect('Enter new password:'******'Re-enter new password:'******'t exist.
                logger.info("Assuming nvram entry doesn't exist.")
                if args.slack:
                    info_bot.send_message("_*" + local_identifier + "*_ :closed_lock_with_key:\n" + "FWPW updated.")

        if args.management or args.hash:
            try:
                modify_nvram = subprocess.call(["/usr/sbin/nvram", "fwpw-hash="+fwpw_managed_string])
                logger.info("nvram modified.")
                if args.slack:
                    info_bot.send_message("_*" + local_identifier + "*_ :closed_lock_with_key:\n" + "FWPW updated.")
            except:
                logger.warning("nvram modification failed. nvram reported error.")
                exit(1)

        if args.reboot:
            logger.warning("Normal completion. Rebooting.")
            os.system('reboot')
        else:
            exit(0)

    #
    # Errors detected during run.
    else:
        logger.critical("An error occured. Failed to modify firmware password.")
        if args.slack:
            error_bot.send_message("_*" + local_identifier + "*_ :no_entry:\n" + "An error occured. Failed to modify firmware password.")
        exit(1)
def main():

    #
    # require root to run.
    if os.geteuid():
        print "Must be root to script."
        exit(2)

    #
    # parse option definitions
    parser = argparse.ArgumentParser(description='Manages the firmware password on Apple Computers.')
    parser.add_argument('-r', '--remove', action="store_true", default=False, help='Remove firmware password')
    parser.add_argument('-k', '--keyfile', help='Set path to keyfile', required=True)
    parser.add_argument('-t', '--testmode', action="store_true", default=False, help='Test mode. Verbose logging, will not delete keyfile.')
    parser.add_argument('-v', '--version', action='version', version='%(prog)s 2.0.0')
    parser.add_argument('-m', '--management', default=None, help='Set nvram management string')
    parser.add_argument('-#', '--hash', action="store_true", default=False, help='Set nvram string to hash of keyfile')
    parser.add_argument('-n', '--nostring', action="store_true", default=False, help='Do not set nvram management string')
    parser.add_argument('-s', '--slack', action="store_true", default=False, help='Send important messages to Slack.')
    args = parser.parse_args()

    if args.testmode:
        print args

    #
    # Open log file
    logger = loggers.file_logger(name='FWPW_Manager2')
    logger.info("Running Firmware Password Manager 2")

    #
    # test flags for conflicts
    if args.management is not None and (args.hash or args.nostring or args.remove):
        conflicting_flags = True
    elif args.hash and (args.nostring or args.remove):
        conflicting_flags = True
    elif args.nostring and args.remove:
        conflicting_flags = True
    else:
        conflicting_flags = False

    if conflicting_flags:
        logger.info("Remove, Hash, Management and \'No string\' flags are mutually exclusive. Select one. Exiting.")
        secure_delete_keyfile(logger, args)
        exit(2)
    else:
        logger.info("Flags okay.")

    #
    # check for no flags set.
    if args.management is None and not args.hash and not args.nostring and not args.remove:
        logger.critical("A specific flag is required: Remove, Hash, Management and \'No string\'. Select one. Exiting.")
        secure_delete_keyfile(logger, args)
        exit(2)

    #
    # get local Local identifier
    local_identifier = socket.gethostbyname(socket.gethostname())
    if args.testmode:
        print "Local identifier: %r" % local_identifier

    #
    # if we get localhost or no return, use serial number instead.
    if (local_identifier == '127.0.0.1') or (local_identifier == ''):
        # logger.info ('Reporting $s as IP, hrm....' % local_identifier)

        if args.slack:
            full_ioreg    = subprocess.check_output(['ioreg', '-l'])
            pattern       = '(IOPlatformSerialNumber.*)'
            serial_data_raw   = re.findall(pattern, full_ioreg)
            serial_data_raw   = serial_data_raw[0]
            serial_number = serial_data_raw.split("= ")[1]
            serial_number = re.findall('(\w*)', serial_number)[1]
            if args.testmode:
                print "Serial number :%r" % serial_number
            logger.info("Serial number :%r" % serial_number)

            local_identifier = serial_number

    #
    # keyfile checks
    path_to_keyfile_exists = os.path.exists(args.keyfile)

    if not path_to_keyfile_exists:
        logger.critical("%s does not exist. Exiting." % args.keyfile)
        if args.slack:
            send_slack_message("Keyfile does not exist.", 'critical', local_identifier)
        exit(2)

    #
    # generate hash from incoming keyfile
    logger.info("Checking incoming hash.")
    if args.management:
        fwpw_managed_string = args.management
    elif args.hash:
        incoming_hash       = subprocess.check_output(["/usr/bin/openssl", "dgst", "-sha256", args.keyfile])
        incoming_hash       = incoming_hash.rstrip('\r\n')
        fwpw_managed_string = incoming_hash.split(" ")[1]
        # prepend '2:' to denote hash created with v2 of script, will force a password change from v1
        fwpw_managed_string = '2:' + fwpw_managed_string
    else:
    	fwpw_managed_string = None

    if args.testmode:
        print "Incoming hash: %s" % fwpw_managed_string


    #
    # compare incoming hash with current nvram hash
    existing_keyfile_hash = None
    logger.info("Checking existing hash.")
    if not args.remove:
        try:
            existing_keyfile_hash = subprocess.check_output(["/usr/sbin/nvram", "fwpw-hash"])
            existing_keyfile_hash = existing_keyfile_hash.rstrip('\r\n')
            existing_keyfile_hash = existing_keyfile_hash.split("\t")[1]

            if args.testmode:
                print "Existing hash: %s" % existing_keyfile_hash

        except Exception as this_Exception:
            logger.warning("nvram failed on %r (value probably doesn't exist)." % this_Exception)

        matching_passwords = False
        if existing_keyfile_hash == fwpw_managed_string:
            matching_passwords = True
            if args.slack:
                send_slack_message("Hashes match. No Change.", 'success', local_identifier)
            if args.hash:
                logger.info("Hashes match. Exiting.")
            elif args.management:
                logger.info("FWPW managed. Exiting.")
            secure_delete_keyfile(logger, args)
            # return a value?
            exit(0)

    #
    # firmwarepasswd tool checks
    new_fw_tool_path = '/usr/sbin/firmwarepasswd'
    new_fw_tool_exists = os.path.exists(new_fw_tool_path)

    if not new_fw_tool_exists:
        logger.critical("No Firmware password tool available. Exiting.")
        secure_delete_keyfile(logger, args)
        if args.slack:
            send_slack_message("No Firmware password tool available.", 'critical', local_identifier)
        exit(1)

    #
    # checking for existing fw password
    logger.info("Checking for existing firmware password")

    existing_fw_pw = subprocess.check_output([new_fw_tool_path, "-check"])
    logger.info("New tools says %r " % existing_fw_pw)
    if 'No' in existing_fw_pw:
        if args.remove:
            logger.critical("Asked to delete, no password set. Exiting.")
            secure_delete_keyfile(logger, args)
            if args.slack:
                send_slack_message("Asked to Delete, no password set.", 'critical', local_identifier)
            exit(1)
        else:
            logger.info("No firmware password set.")
            existing_password = False
    elif 'Yes' in existing_fw_pw:
        logger.info("Existing firmware password set.")
        existing_password = True
    else:
        logger.critical("Firmwarepasswd bad response at -check. Exiting.")
        secure_delete_keyfile(logger, args)
        if args.slack:
            send_slack_message("Firmwarepasswd bad response at -check.", 'critical', local_identifier)
        exit(1)

    #
    # read keyfile
    logger.info("Reading password file")

    with open(args.keyfile) as f:
        passwords = f.read().splitlines()
    f.close()

    logger.info("Closed password file")

    new_password = None
    other_password_list = []

    #
    # parse data from keyfile and build list of passwords
    for entry in passwords:
        try:
            key, value = entry.split(":", 1)
        except Exception as this_Exception:
            logger.critical("Malformed keyfile, key:value format required. %r. Quitting." % this_Exception)
            secure_delete_keyfile(logger, args)
            if args.slack:
                send_slack_message("Malformed keyfile.", 'critical', local_identifier)
            exit(1)

        if args.testmode:
            logger.info('%s:%s' % (key, value))

        if key.lower() == 'new':
            if new_password is not None:
                logger.critical("Malformed keyfile, multiple new keys. Quitting.")
                secure_delete_keyfile(logger, args)
                if args.slack:
                    send_slack_message("Malformed keyfile.", 'critical', local_identifier)
                exit(1)
            else:
                new_password = value
                other_password_list.append(value)
        else:
            other_password_list.append(value)

    logger.info("Sanity checking password file contents")

    if new_password is None and not args.remove:
            logger.critical("Malformed keyfile, no \'new\' key. Quitting.")
            secure_delete_keyfile(logger, args)
            if args.slack:
                send_slack_message("Malformed keyfile.", 'critical', local_identifier)
            exit(1)

    exit_Normal = False
    known_current_password = False

    #
    # if a password is set, attempt to discover it using keyfile
    if existing_password:
        logger.info("Verifying current FW password")
        new_fw_tool_cmd = [new_fw_tool_path, '-verify']
        logger.info(' '.join(new_fw_tool_cmd))

        for index in reversed(xrange(len(other_password_list))):
            child = pexpect.spawn(' '.join(new_fw_tool_cmd))
            child.expect('Enter password:'******'Correct', 'Incorrect'])

            if result == 0:
                #
                # correct password, exit loop
                current_password = other_password_list[index]
                known_current_password = True
                break
            else:
                #
                # wrong password, keep going
                continue

        #
        # We've discovered the currently set firmware password
        if known_current_password:

            #
            # Deleting firmware password
            if args.remove:
                logger.info("Deleting FW password")

                new_fw_tool_cmd = [new_fw_tool_path, '-delete']
                logger.info(' '.join(new_fw_tool_cmd))

                child = pexpect.spawn(' '.join(new_fw_tool_cmd))
                child.expect('Enter password:'******'removed', 'incorrect'])

                if result == 0:
                    #
                    # password accepted, log result and exit
                    logger.info("Finished. Password should be removed. Restart required. [%i]" % (index + 1))
                    exit_Normal = True
                else:
                    logger.critical("Asked to delete, current password not accepted. Exiting.")
                    secure_delete_keyfile(logger, args)
                    if args.slack:
                        send_slack_message("Asked to delete, current password not accepted.", 'critical', local_identifier)
                    exit(1)

            #
            # Current and new password are identical
            elif current_password == new_password:
                logger.info("Match, no change required. Exiting.")
                exit_Normal = True

            #
            # Change current firmware password to new password
            else:
                logger.info("Updating FW password")

                new_fw_tool_cmd = [new_fw_tool_path, '-setpasswd']
                logger.info(' '.join(new_fw_tool_cmd))

                child = pexpect.spawn(' '.join(new_fw_tool_cmd))

                result = child.expect('Enter password:'******'critical', local_identifier)
                    exit(1)
                child.sendline(current_password)

                result = child.expect('Enter new password:'******'critical', local_identifier)
                    exit(1)
                child.sendline(new_password)

                result = child.expect('Re-enter new password:'******'critical', local_identifier)
                    exit(1)
                child.sendline(new_password)

                child.expect(pexpect.EOF)
                child.close()

                logger.info("Updated FW Password.")
                exit_Normal = True

        #
        # Unable to match current password with contents of keyfile
        else:
            logger.critical("Current FW password not in keyfile. Quitting.")
            secure_delete_keyfile(logger, args)
            if args.slack:
                send_slack_message("Current FW password not in keyfile.", 'critical', local_identifier)
            exit(1)

    #
    # No current firmware password, setting it
    else:
        new_fw_tool_cmd = [new_fw_tool_path, '-setpasswd']
        logger.info(' '.join(new_fw_tool_cmd))

        child = pexpect.spawn(' '.join(new_fw_tool_cmd))

        result = child.expect('Enter new password:'******'critical', local_identifier)
            exit(1)
        child.sendline(new_password)

        result = child.expect('Re-enter new password:'******'critical', local_identifier)
            exit(1)
        child.sendline(new_password)

        child.expect(pexpect.EOF)
        child.close()

        logger.info("Added FW Password.")
        exit_Normal = True

    #
    # Delete keyfile securely.
    secure_delete_keyfile(logger, args)

    #
    # closing reports
    logger.info("Closing out.")


    #
    # No errors detected during run.
    if exit_Normal:
        if args.slack:
            if args.remove:
                send_slack_message("FWPW removed.", 'remove', local_identifier)
            else:
                send_slack_message("FWPW updated.", 'success', local_identifier)
        if not args.remove and not args.nostring and not matching_passwords:
            try:
                modify_nvram = subprocess.call(["/usr/sbin/nvram", "fwpw-hash="+fwpw_managed_string])
                logger.info("nvram modified.")
            except:
                logger.warning("nvram reported error.")
        elif args.remove or args.nostring:
            try:
                modify_nvram = subprocess.call(["/usr/sbin/nvram", "-d", "fwpw-hash"])
                logger.info("nvram pruned.")
            except:
                logger.warning("nvram reported error.")
        exit(0)

    #
    # Errors detected during run.
    else:
        logger.critical("An error occured. Failed to modify firmware password.")
        if args.slack:
            send_slack_message("An error occured. Failed to modify firmware password.", 'critical', local_identifier)
        exit(1)
Exemple #12
0
def main():
    """
    Master Control Function.
    """

    #
    # require root to run.
    if os.geteuid():
        print "Must be root to run script."
        exit(2)

    #
    # parse option definitions
    parser = argparse.ArgumentParser(
        description='Manages the firmware password on Apple Computers.')
    #
    # required, mutually exclusive commands
    prime_group = parser.add_argument_group(
        'Required management settings',
        'Choosing one of these options is required \
                                            to run FWPM. They tell FWPM how you \
                                            want to manage the firmware password.'
    )
    subprime = prime_group.add_mutually_exclusive_group(required=True)
    subprime.add_argument('-r',
                          '--remove',
                          action="store_true",
                          default=False,
                          help='Remove the firmware password')
    subprime.add_argument('-m',
                          '--management',
                          default=None,
                          help='Set a custom nvram management string')
    subprime.add_argument('-#',
                          '--hash',
                          action="store_true",
                          default=False,
                          help='Set nvram string to hash of keyfile')
    subprime.add_argument('-n',
                          '--nostring',
                          action="store_true",
                          default=False,
                          help='Do not set an nvram management string')

    keyfile_group = parser.add_argument_group(
        'Keyfile options', 'The keyfile is \
                                               required to use FWPM. These options \
                                               allow you to set the location and \
                                               format of the keyfile.')
    keyfile_group.add_argument('-k',
                               '--keyfile',
                               help='Set the path to your keyfile',
                               required=True)
    keyfile_group.add_argument(
        '-o',
        '--obfuscated',
        action="store_true",
        default=False,
        help='Tell FWPM your keylist is an obfuscated plist.')

    slack_group = parser.add_argument_group(
        'Slack integration', 'FWPM allows you to send informational \
                                            and error messages to your Slack team. \
                                            Additionally you can select different \
                                            methods of identifiying clients.')
    slack_group.add_argument('-s',
                             '--slack',
                             action="store_true",
                             default=False,
                             help='Send important messages to Slack.')
    slack_group.add_argument(
        '-i',
        '--identifier',
        default=None,
        choices=['IP', 'hostname', 'MAC', 'computername', 'serial'],
        required=False,
        help='Set slack identifier.')

    parser.add_argument(
        '-b',
        '--reboot',
        action="store_true",
        default=False,
        help='Reboots the computer after the script completes successfully.')
    parser.add_argument(
        '-t',
        '--testmode',
        action="store_true",
        default=False,
        help='Test mode. Verbose logging, will not delete keyfile.')
    parser.add_argument('-v',
                        '--version',
                        action='version',
                        version='%(prog)s 2.1.4')

    args = parser.parse_args()

    if args.testmode:
        print args

    #
    # Open log file
    logger = loggers.file_logger(name='FWPW_Manager2')
    logger.info("Running Firmware Password Manager 2")

    #
    # set up slack channel(s)
    slack_info_url = 'your FWPM slack info URL'
    slack_info_channel = '#your FWPM slack info channel'
    info_bot = IWS(slack_info_url,
                   bot_name="FWPM informational message",
                   channel=slack_info_channel)

    slack_error_url = 'your FWPM slack error URL'
    slack_error_channel = '#your FWPM slack error channel'
    error_bot = IWS(slack_error_url,
                    bot_name="FWPM error message",
                    channel=slack_error_channel)

    local_identifier = None

    if args.slack:
        full_ioreg = subprocess.check_output(['ioreg', '-l'])
        serial_number_raw = re.findall(
            r'\"IOPlatformSerialNumber\" = \"(.*)\"', full_ioreg)
        serial_number = serial_number_raw[0]
        if args.testmode:
            print "Serial number: %r" % serial_number

        if args.identifier == 'IP' or args.identifier == 'MAC' or args.identifier == 'hostname':
            processed_device_list = []

            # Get ordered list of network devices
            base_network_list = subprocess.check_output(
                ["/usr/sbin/networksetup", "-listnetworkserviceorder"])
            network_device_list = re.findall(r'\) (.*)\n\(.*Device: (.*)\)',
                                             base_network_list)
            for device in network_device_list:
                device_name = device[0]
                port_name = device[1]
                try:
                    device_info_raw = subprocess.check_output(
                        ["/sbin/ifconfig", port_name])
                    mac_address = re.findall(r'ether (.*) \n', device_info_raw)
                    if args.testmode:
                        print "%r" % mac_address
                    ether_address = re.findall(r'inet (.*) netmask',
                                               device_info_raw)
                    if args.testmode:
                        print "%r" % ether_address
                    processed_device_list.append([
                        device_name, port_name, ether_address[0],
                        mac_address[0]
                    ])
                except:
                    pass

            if len(processed_device_list) > 0:
                logger.info("1 or more active IP addresses. Choosing primary.")
                if args.testmode:
                    print processed_device_list
                if args.identifier == 'IP':
                    local_identifier = processed_device_list[0][
                        2] + " (" + processed_device_list[0][
                            0] + ":" + processed_device_list[0][1] + ")"

                if args.identifier == 'MAC':
                    local_identifier = processed_device_list[0][
                        3] + " (" + processed_device_list[0][
                            0] + ":" + processed_device_list[0][1] + ")"

                if args.identifier == 'hostname':
                    try:
                        local_identifier = socket.getfqdn()
                    except:
                        logger.error("error discovering hostname info.")
                        local_identifier = serial_number

            elif len(processed_device_list) == 0:
                logger.error("error discovering IP info.")
                local_identifier = serial_number

        elif args.identifier == 'computername':
            try:
                cname_identifier_raw = subprocess.check_output(
                    ['/usr/sbin/scutil', '--get', 'ComputerName'])
                local_identifier = cname_identifier_raw.split('\n')[0]
                logger.info("Computername: " + local_identifier)
            except:
                logger.info("error discovering computername.")
                local_identifier = serial_number
        elif args.identifier == 'serial':
            local_identifier = serial_number
            logger.info("Serial number: " + local_identifier)
        else:
            logger.info(
                "bad or no identifier flag, defaulting to serial number.")
            local_identifier = serial_number

        if args.testmode:
            print "Local identifier: %r" % local_identifier

    #
    # keyfile checks
    path_to_keyfile_exists = os.path.exists(args.keyfile)

    if not path_to_keyfile_exists:
        logger.critical(args.keyfile + " does not exist. Exiting.")
        if args.slack:
            error_bot.send_message("_*" + local_identifier +
                                   "*_ :no_entry_sign:\n" +
                                   "Keyfile does not exist.")
        exit(2)

    #
    # generate hash from incoming keyfile
    logger.info("Checking incoming hash.")
    if args.management:
        fwpw_managed_string = args.management
    elif args.hash:
        incoming_hash = subprocess.check_output(
            ["/usr/bin/openssl", "dgst", "-sha256", args.keyfile])
        incoming_hash = incoming_hash.rstrip('\r\n')
        fwpw_managed_string = incoming_hash.split(" ")[1]
        # prepend '2:' to denote hash created with v2 of script, will force a password change from v1
        fwpw_managed_string = '2:' + fwpw_managed_string
    else:
        fwpw_managed_string = None

    if args.testmode:
        print "Incoming hash: %s" % fwpw_managed_string

    #
    # compare incoming hash with current nvram hash
    existing_keyfile_hash = None
    logger.info("Checking existing hash.")
    if not args.remove:
        try:
            existing_keyfile_hash = subprocess.check_output(
                ["/usr/sbin/nvram", "fwpw-hash"])
            existing_keyfile_hash = existing_keyfile_hash.rstrip('\r\n')
            existing_keyfile_hash = existing_keyfile_hash.split("\t")[1]

            if args.testmode:
                print "Existing hash: %s" % existing_keyfile_hash

        except Exception as this_exception:
            logger.warning("nvram failed on " + this_exception +
                           " (value probably doesn't exist).")

        if existing_keyfile_hash == fwpw_managed_string:
            if args.hash:
                logger.info("Hashes match. Exiting.")
                if args.slack:
                    info_bot.send_message("_*" + local_identifier +
                                          "*_ :white_check_mark:\n" +
                                          "Hashes match. No Change.")
                secure_delete_keyfile(logger, args, error_bot,
                                      local_identifier)
                if args.reboot:
                    logger.info("Reboot not required, canceling.")
                # return a value?
                exit(0)
            else:
                logger.info("Management strings match. Continuing.")

    #
    # firmwarepasswd tool checks
    new_fw_tool_path = '/usr/sbin/firmwarepasswd'
    new_fw_tool_exists = os.path.exists(new_fw_tool_path)

    if not new_fw_tool_exists:
        logger.critical("No Firmware password tool available. Exiting.")
        secure_delete_keyfile(logger, args, error_bot, local_identifier)
        if args.slack:
            error_bot.send_message("_*" + local_identifier +
                                   "*_ :no_entry:\n" +
                                   "No Firmware password tool available.")
        exit(1)

    #
    # checking for existing fw password
    logger.info("Checking for existing firmware password")

    existing_fw_pw = subprocess.check_output([new_fw_tool_path, "-check"])
    logger.info("New tools says " + existing_fw_pw)
    if 'No' in existing_fw_pw:
        if args.remove:
            logger.critical("Asked to delete, no password set. Exiting.")
            secure_delete_keyfile(logger, args, error_bot, local_identifier)
            if args.slack:
                error_bot.send_message("_*" + local_identifier +
                                       "*_ :no_entry:\n" +
                                       "Asked to Delete, no password set.")
            try:
                modify_nvram = subprocess.call(
                    ["/usr/sbin/nvram", "-d", "fwpw-hash"])
                logger.info("nvram entry pruned.")
            except:
                logger.warning(
                    "nvram reported error attempting to remove hash. Hash may not have existed."
                )
            exit(1)
        else:
            logger.info("No firmware password set.")
            existing_password = False
    elif 'Yes' in existing_fw_pw:
        logger.info("Existing firmware password set.")
        existing_password = True
    else:
        logger.critical("Firmwarepasswd bad response at -check. Exiting.")
        secure_delete_keyfile(logger, args, error_bot, local_identifier)
        if args.slack:
            error_bot.send_message("_*" + local_identifier +
                                   "*_ :no_entry:\n" +
                                   "Firmwarepasswd bad response at -check.")
        exit(1)

    logger.info("Reading password file")

    if args.obfuscated:
        #
        # unobfuscate plist
        logger.info("Reading plist")
        passwords = []
        try:
            input_plist = plistlib.readPlist(args.keyfile)
        except:
            logger.critical("Error reading plist. Exiting.")
            if args.slack:
                error_bot.send_message("_*" + local_identifier +
                                       "*_ :no_entry:\n" +
                                       "Error reading plist.")
            exit(1)
        content_raw = input_plist["data"]

        content_raw = base64.b64decode(content_raw)
        content_raw = content_raw.split(",")
        content_raw = [x for x in content_raw if x]

        for item in content_raw:
            label, pword = item.split(':')
            pword = base64.b64decode(pword)
            try:
                commented = label.split('#')[1]
                commented = base64.b64decode(commented)
                is_commented = True
            except:
                is_commented = False

            if is_commented:
                output_string = "#" + commented + ":" + pword
            else:
                output_string = label + ":" + pword
            passwords.append(output_string)

    else:
        #
        #  read keyfile
        logger.info("Reading plain text")

        try:
            with open(args.keyfile, "r") as keyfile:
                passwords = keyfile.read().splitlines()
        except:
            logger.critical("Error reading keyfile. Exiting.")
            if args.slack:
                error_bot.send_message("_*" + local_identifier +
                                       "*_ :no_entry:\n" +
                                       "Error reading keyfile.")
            exit(1)

        logger.info("Closed password file")

    new_password = None
    other_password_list = []

    #
    # parse data from keyfile and build list of passwords
    for entry in passwords:
        try:
            key, value = entry.split(":", 1)
        except Exception as this_exception:
            logger.critical("Malformed keyfile, key:value format required. " +
                            this_exception + ". Quitting.")
            secure_delete_keyfile(logger, args, error_bot, local_identifier)
            if args.slack:
                error_bot.send_message("_*" + local_identifier +
                                       "*_ :no_entry:\n" +
                                       "Malformed keyfile.")
            exit(1)

        if args.testmode:
            logger.info(key + ":" + value)

        if key.lower() == 'new':
            if new_password is not None:
                logger.critical(
                    "Malformed keyfile, multiple new keys. Quitting.")
                secure_delete_keyfile(logger, args, error_bot,
                                      local_identifier)
                if args.slack:
                    error_bot.send_message("_*" + local_identifier +
                                           "*_ :no_entry:\n" +
                                           "Malformed keyfile.")
                exit(1)
            else:
                new_password = value
                other_password_list.append(value)
        else:
            other_password_list.append(value)

    logger.info("Sanity checking password file contents")

    if new_password is None and not args.remove:
        logger.critical("Malformed keyfile, no \'new\' key. Quitting.")
        secure_delete_keyfile(logger, args, error_bot, local_identifier)
        if args.slack:
            error_bot.send_message("_*" + local_identifier +
                                   "*_ :no_entry:\n" + "Malformed keyfile.")
        exit(1)

    exit_normal = False
    known_current_password = False

    #
    # if a password is set, attempt to discover it using keyfile
    if existing_password:
        logger.info("Verifying current FW password")
        new_fw_tool_cmd = [new_fw_tool_path, '-verify']
        logger.info(' '.join(new_fw_tool_cmd))

        for keyfile_index in reversed(xrange(len(other_password_list))):
            child = pexpect.spawn(' '.join(new_fw_tool_cmd))
            child.expect('Enter password:'******'Correct', 'Incorrect'])

            if result == 0:
                #
                # correct password, exit loop
                current_password = other_password_list[keyfile_index]
                known_current_password = True
                break
            else:
                #
                # wrong password, keep going
                continue

        #
        # We've discovered the currently set firmware password
        if known_current_password:

            #
            # Deleting firmware password
            if args.remove:
                logger.info("Deleting FW password")

                new_fw_tool_cmd = [new_fw_tool_path, '-delete']
                logger.info(' '.join(new_fw_tool_cmd))

                child = pexpect.spawn(' '.join(new_fw_tool_cmd))
                child.expect('Enter password:'******'removed', 'incorrect'])

                if result == 0:
                    #
                    # password accepted, log result and exit
                    logger.info(
                        "Finished. Password should be removed. Restart required. ["
                        + (keyfile_index + 1) + "]")
                    exit_normal = True
                else:
                    logger.critical(
                        "Asked to delete, current password not accepted. Exiting."
                    )
                    secure_delete_keyfile(logger, args, error_bot,
                                          local_identifier)
                    if args.slack:
                        error_bot.send_message(
                            "_*" + local_identifier + "*_ :no_entry:\n" +
                            "Asked to delete, current password not accepted.")
                    exit(1)

            #
            # Current and new password are identical
            elif current_password == new_password:
                logger.info("Match, no change required. Exiting.")
                exit_normal = True

            #
            # Change current firmware password to new password
            else:
                logger.info("Updating FW password")

                new_fw_tool_cmd = [new_fw_tool_path, '-setpasswd']
                logger.info(' '.join(new_fw_tool_cmd))

                child = pexpect.spawn(' '.join(new_fw_tool_cmd))

                result = child.expect('Enter password:'******'Enter new password:'******'Re-enter new password:'******'-setpasswd']
        logger.info(' '.join(new_fw_tool_cmd))

        child = pexpect.spawn(' '.join(new_fw_tool_cmd))

        result = child.expect('Enter new password:'******'Re-enter new password:'******'t exist.
                logger.info("Assuming nvram entry doesn't exist.")
                if args.slack:
                    info_bot.send_message("_*" + local_identifier +
                                          "*_ :closed_lock_with_key:\n" +
                                          "FWPW updated.")

        if args.management or args.hash:
            try:
                modify_nvram = subprocess.call(
                    ["/usr/sbin/nvram", "fwpw-hash=" + fwpw_managed_string])
                logger.info("nvram modified.")
                if args.slack:
                    info_bot.send_message("_*" + local_identifier +
                                          "*_ :closed_lock_with_key:\n" +
                                          "FWPW updated.")
            except:
                logger.warning(
                    "nvram modification failed. nvram reported error.")
                exit(1)

        if args.reboot:
            logger.warning("Normal completion. Rebooting.")
            os.system('reboot')
        else:
            exit(0)

    #
    # Errors detected during run.
    else:
        logger.critical(
            "An error occured. Failed to modify firmware password.")
        if args.slack:
            error_bot.send_message(
                "_*" + local_identifier + "*_ :no_entry:\n" +
                "An error occured. Failed to modify firmware password.")
        exit(1)
Exemple #13
0
def setup_logger():
    '''Creates the logger to be used throughout.'''

    global logger
    logger = loggers.file_logger(options['name'])
Exemple #14
0
def setup_logger():
    '''Creates the logger to be used throughout.'''

    global logger
    logger = loggers.file_logger(options['name'])