Ejemplo n.º 1
0
    def __init__(self, init=False, gpg_ids=None):
        # initialize avendesora (these should already be done if called from 
        # main, but it is safe to call them again)
        read_config()
        GnuPG.initialize()

        # check the integrity of avendesora
        validate_componenets()

        # create the avendesora data directory
        if init:
            self.initialize(gpg_ids, init)
            terminate()

        # read the accounts files
        self.all_accounts = set()
        for filename in get_setting('accounts_files', []):
            try:
                path = to_path(get_setting('settings_dir'), filename)
                account_file = PythonFile(path)
                contents = account_file.run()
                master_password = contents.get('master_password')

                # traverse through all accounts, determine which are new, bind
                # required information to new accounts, and update account list.
                for account in Account.all_accounts():
                    if account not in self.all_accounts:
                        account.add_fileinfo(master_password, account_file)

                        # save a copy of account so it is not garbage collected
                        self.all_accounts.add(account)
            except Error as err:
                err.terminate()
        terminate_if_errors()
Ejemplo n.º 2
0
def main():
    try:
        # read config file
        read_config()

        # read command line
        cmdline = docopt(
            __doc__.format(commands=Command.summarize()),
            version='avendesora {} ({})'.format(__version__, __released__),
            options_first=True,
        )

        # start logging
        logfile = BufferedFile(get_setting('log_file'), True)
        Inform(logfile=logfile,
               hanging_indent=False,
               stream_policy='header',
               notify_if_no_tty=True)
        shlib.set_prefs(use_inform=True, log_cmd=True)

        # run the requested command
        Command.execute(cmdline['<command>'], cmdline['<args>'])
        done()
    except KeyboardInterrupt:
        output('\nTerminated by user.')
        terminate()
    except (PasswordError, Error) as e:
        e.terminate()
    except OSError as e:
        fatal(os_error(e))
    done()
Ejemplo n.º 3
0
def main():
    with Inform() as inform:
        # read command line
        cmdline = docopt(
            __doc__.format(commands=Command.summarize()),
            options_first=True
        )
        config = cmdline['--config']
        command = cmdline['<command>']
        args = cmdline['<args>']
        options = cull([
            'verbose' if cmdline['--verbose'] else '',
            'narrate' if cmdline['--narrate'] else '',
            'trial-run' if cmdline['--trial-run'] else '',
        ])
        if cmdline['--narrate']:
            inform.narrate = True

        try:
            cmd, name = Command.find(command)

            with Settings(config, cmd.REQUIRES_EXCLUSIVITY) as settings:
                cmd.execute(name, args, settings, options)

        except KeyboardInterrupt:
            display('Terminated by user.')
        except Error as err:
            err.terminate()
        except OSError as err:
            fatal(os_error(err))
        terminate()
Ejemplo n.º 4
0
def main():
    with Inform(error_status=2, flush=True, version=version) as inform:
        # read command line
        cmdline = docopt(expanded_synopsis, options_first=True, version=version)
        config = cmdline["--config"]
        command = cmdline["<command>"]
        args = cmdline["<args>"]
        if cmdline["--mute"]:
            inform.mute = True
        if cmdline["--quiet"]:
            inform.quiet = True
        emborg_opts = cull(
            [
                "verbose" if cmdline["--verbose"] else "",
                "narrate" if cmdline["--narrate"] else "",
                "dry-run" if cmdline["--dry-run"] else "",
                "no-log" if cmdline["--no-log"] else "",
            ]
        )
        if cmdline["--narrate"]:
            inform.narrate = True

        try:
            # find the command
            cmd, cmd_name = Command.find(command)

            # execute the command initialization
            exit_status = cmd.execute_early(cmd_name, args, None, emborg_opts)
            if exit_status is not None:
                terminate(exit_status)

            worst_exit_status = 0
            try:
                while True:
                    with Settings(config, cmd, emborg_opts) as settings:
                        try:
                            exit_status = cmd.execute(
                                cmd_name, args, settings, emborg_opts
                            )
                        except Error as e:
                            settings.fail(e, cmd=' '.join(sys.argv))
                            e.terminate()

                    if exit_status and exit_status > worst_exit_status:
                        worst_exit_status = exit_status
            except NoMoreConfigs:
                pass

            # execute the command termination
            exit_status = cmd.execute_late(cmd_name, args, None, emborg_opts)
            if exit_status and exit_status > worst_exit_status:
                worst_exit_status = exit_status

        except KeyboardInterrupt:
            display("Terminated by user.")
        except Error as e:
            e.terminate()
        except OSError as e:
            fatal(os_error(e))
        terminate(worst_exit_status)
Ejemplo n.º 5
0
    def generate(self, field_name, field_key, account):
        try:
            if self.secret:
                return
        except AttributeError:
            pass
        account_name = account.get_name()
        account_seed = account.get_seed()
        if self.master is None:
            master = account.get_field("master", default=None)
            master_source = account.get_field("_master_source", default=None)
        else:
            master = self.master
            master_source = "secret"
        if not master:
            master = get_setting("user_key")
            master_source = "user_key"
        if not master:
            try:
                try:
                    master = getpass.getpass("master password for %s: " % account_name)
                    master_source = "user"
                except EOFError:
                    output()
                if not master:
                    warn("master password is empty.")
            except (EOFError, KeyboardInterrupt):
                terminate()
        log("Generating secret, source of master seed:", master_source)
        field_key = self.get_key(field_key)
        if self.version:
            version = self.version
        else:
            version = account.get_field("version", default="")

        if account.request_seed():
            try:
                try:
                    interactive_seed = getpass.getpass("seed for %s: " % account_name)
                except EOFError:
                    output()
                if not interactive_seed:
                    warn("seed is empty.")
            except (EOFError, KeyboardInterrupt):
                terminate()
        else:
            interactive_seed = ""

        seeds = [master, account_seed, field_name, field_key, version, interactive_seed]
        key = " ".join([str(seed) for seed in seeds])

        # Convert the key into 512 bit number
        digest = hashlib.sha512((key).encode("utf-8")).digest()
        bits_per_byte = 8
        radix = 1 << bits_per_byte
        bits = 0
        for byte in digest:
            bits = radix * bits + byte
        self.pool = bits
Ejemplo n.º 6
0
def main():
    with Inform(error_status=2, flush=True, version=version) as inform:
        # read command line
        cmdline = docopt(expanded_synopsis, options_first=True, version=version)
        config = cmdline['--config']
        command = cmdline['<command>']
        args = cmdline['<args>']
        if cmdline['--mute']:
            inform.mute = True
        if cmdline['--quiet']:
            inform.quiet = True
        options = cull([
            'verbose' if cmdline['--verbose'] else '',
            'narrate' if cmdline['--narrate'] else '',
            'trial-run' if cmdline['--trial-run'] else '',
            'no-log' if cmdline['--no-log'] else '',
        ])
        if cmdline['--narrate']:
            inform.narrate = True

        try:
            # find the command
            cmd, cmd_name = Command.find(command)

            # execute the command initialization
            exit_status = cmd.execute_early(cmd_name, args, None, options)
            if exit_status is not None:
                terminate(exit_status)

            worst_exit_status = 0
            try:
                while True:
                    with Settings(config, cmd, options) as settings:
                        try:
                            exit_status = cmd.execute(cmd_name, args, settings, options)
                        except Error as e:
                            settings.fail(e)
                            e.terminate()

                    if exit_status and exit_status > worst_exit_status:
                        worst_exit_status = exit_status
            except NoMoreConfigs:
                pass

            # execute the command termination
            exit_status = cmd.execute_late(cmd_name, args, None, options)
            if exit_status and exit_status > worst_exit_status:
                worst_exit_status = exit_status

        except KeyboardInterrupt:
            display('Terminated by user.')
        except Error as e:
            e.terminate()
        except OSError as e:
            fatal(os_error(e))
        terminate(worst_exit_status)
Ejemplo n.º 7
0
def main():
    """
    Construct, encrypt, and publish backup keys.  

    As the primary entry point for the end user, this function is also 
    responsible for integrating information from command-line arguments, 
    configuration files, and `setuptools` plugins.
    """
    set_shlib_prefs(use_inform=True, log_cmd=True)
    args = docopt.docopt(__doc__)

    if args['--verbose']:
        set_output_prefs(verbose=True, narrate=True)
    elif args['--quiet']:
        set_output_prefs(quiet=True)

    try:
        config_path, config = load_config()
        try:
            if args['plugins']:
                list_plugins(config)
                sys.exit()

            # Get the passcode before building the archive, so if something
            # goes wrong with the passcode, we don't need to worry about
            # cleaning up the unencrypted archive.
            passcode = query_passcode(config)
            batch = args['--yes'] or args['--quiet']
            archive = build_archive(config, not batch)
            encrypt_archive(config, archive, passcode)
            publish_archive(config, archive)

        except ConfigError as e:
            e.reraise(culprit=config_path)
        finally:
            if 'archive' in locals():
                delete_archive(config, archive)

    except KeyboardInterrupt:
        print()

    except Error as e:
        if args['--verbose']: raise
        else: e.report()

    except OSError as e:
        fatal(os_error(e))

    terminate()
Ejemplo n.º 8
0
def main():
    # read config file
    read_config()

    # read command line
    cmdline = docopt(
        __doc__.format(commands=Command.summarize()),
        options_first=True
    )

    # start logging
    logfile = BufferedFile(get_setting('log_file'), True)
    with Inform(logfile=logfile, hanging_indent=False):
        try:
            Command.execute(cmdline['<command>'], cmdline['<args>'])
        except KeyboardInterrupt:
            output('Terminated by user.')
        except Error as err:
            err.terminate()
        except OSError as err:
            fatal(os_error(err))

        terminate()
Ejemplo n.º 9
0
def main():
    with Inform(error_status=2, flush=True, version=version) as inform:
        # read command line
        cmdline = docopt(expanded_synopsis, options_first=True, version=version)
        config = cmdline['--config']
        command = cmdline['<command>']
        args = cmdline['<args>']
        if cmdline['--mute']:
            inform.mute = True
        options = cull([
            'verbose' if cmdline['--verbose'] else '',
            'narrate' if cmdline['--narrate'] else '',
            'trial-run' if cmdline['--trial-run'] else '',
            'no-log' if cmdline['--no-log'] else '',
        ])
        if cmdline['--narrate']:
            inform.narrate = True

        try:
            cmd, cmd_name = Command.find(command)

            with Settings(config, cmd.REQUIRES_EXCLUSIVITY, options) as settings:
                try:
                    exit_status = cmd.execute(cmd_name, args, settings, options)
                except Error as e:
                    settings.fail(e)
                    e.terminate(True)

        except KeyboardInterrupt:
            display('Terminated by user.')
            exit_status = 0
        except Error as e:
            e.terminate()
        except OSError as e:
            fatal(os_error(e))
        terminate(exit_status)
Ejemplo n.º 10
0
def main():
    version = f'{__version__} ({__released__})'
    cmdline = docopt(__doc__, version=version)
    quiet = cmdline['--quiet']
    problem = False
    with Inform(flush=True, quiet=quiet, version=version) as inform:

        # read the settings file
        settings_file = PythonFile(CONFIG_DIR, OVERDUE_FILE)
        settings_filename = settings_file.path
        settings = settings_file.run()

        # gather needed settings
        default_maintainer = settings.get('default_maintainer')
        default_max_age = settings.get('default_max_age', 28)
        dumper = settings.get('dumper', f'{getusername()}@{gethostname()}')
        repositories = settings.get('repositories')
        root = settings.get('root')

        # process repositories table
        backups = []
        if is_str(repositories):
            for line in repositories.split('\n'):
                line = line.split('#')[0].strip()  # discard comments
                if not line:
                    continue
                backups.append([c.strip() for c in line.split('|')])
        else:
            for each in repositories:
                backups.append([
                    each.get('host'),
                    each.get('path'),
                    each.get('maintainer'),
                    each.get('max_age')
                ])

        def send_mail(recipient, subject, message):
            if cmdline['--mail']:
                display(f'Reporting to {recipient}.\n')
                mail_cmd = ['mailx', '-r', dumper, '-s', subject, recipient]
                Run(mail_cmd, stdin=message, modes='soeW0')

        # check age of repositories
        now = arrow.now()
        display(f'current time = {now}')
        for host, path, maintainer, max_age in backups:
            maintainer = default_maintainer if not maintainer else maintainer
            max_age = int(max_age) if max_age else default_max_age
            try:
                path = to_path(root, path)
                if not path.is_dir():
                    raise Error('does not exist or is not a directory.',
                                culprit=path)
                paths = list(path.glob('index.*'))
                if not paths:
                    raise Error('no sentinel file found.', culprit=path)
                if len(paths) > 1:
                    raise Error('too many sentinel files.',
                                *paths,
                                sep='\n    ')
                path = paths[0]
                mtime = arrow.get(path.stat().st_mtime)
                delta = now - mtime
                age = 24 * delta.days + delta.seconds / 3600
                report = age > max_age
                display(
                    dedent(f"""
                    HOST: {host}
                        sentinel file: {path!s}
                        last modified: {mtime}
                        since last change: {age:0.1f} hours
                        maximum age: {max_age} hours
                        overdue: {report}
                """))

                if report:
                    problem = True
                    subject = f"backup of {host} is overdue"
                    msg = overdue_message.format(host=host, path=path, age=age)
                    send_mail(maintainer, subject, msg)
            except OSError as e:
                problem = True
                msg = os_error(e)
                error(msg)
                if maintaner:
                    send_mail(maintainer, f'{get_prog_name()} error',
                              error_message.format(msg))
            except Error as e:
                problem = True
                e.report()
                if maintaner:
                    send_mail(maintainer, f'{get_prog_name()} error',
                              error_message.format(str(e)))
        terminate(problem)
Ejemplo n.º 11
0
def main():
    version = f"{__version__} ({__released__})"
    cmdline = docopt(__doc__, version=version)
    quiet = cmdline["--quiet"]
    problem = False
    use_color = Color.isTTY() and not cmdline["--no-color"]
    passes = Color("green", enable=use_color)
    fails = Color("red", enable=use_color)
    if cmdline["--verbose"]:
        overdue_message = verbose_overdue_message
    else:
        overdue_message = terse_overdue_message

    # prepare to create logfile
    log = to_path(DATA_DIR, OVERDUE_LOG_FILE) if OVERDUE_LOG_FILE else False
    if log:
        data_dir = to_path(DATA_DIR)
        if not data_dir.exists():
            try:
                # data dir does not exist, create it
                data_dir.mkdir(mode=0o700, parents=True, exist_ok=True)
            except OSError as e:
                warn(os_error(e))
                log = False

    with Inform(flush=True, quiet=quiet, logfile=log, version=version):

        # read the settings file
        try:
            settings_file = PythonFile(CONFIG_DIR, OVERDUE_FILE)
            settings = settings_file.run()
        except Error as e:
            e.terminate()

        # gather needed settings
        default_maintainer = settings.get("default_maintainer")
        default_max_age = settings.get("default_max_age", 28)
        dumper = settings.get("dumper", f"{username}@{hostname}")
        repositories = settings.get("repositories")
        root = settings.get("root")

        # process repositories table
        backups = []
        if is_str(repositories):
            for line in repositories.split("\n"):
                line = line.split("#")[0].strip()  # discard comments
                if not line:
                    continue
                backups.append([c.strip() for c in line.split("|")])
        else:
            for each in repositories:
                backups.append([
                    each.get("host"),
                    each.get("path"),
                    each.get("maintainer"),
                    each.get("max_age"),
                ])

        def send_mail(recipient, subject, message):
            if cmdline["--mail"]:
                if cmdline['--verbose']:
                    display(f"Reporting to {recipient}.\n")
                mail_cmd = ["mailx", "-r", dumper, "-s", subject, recipient]
                Run(mail_cmd, stdin=message, modes="soeW0")

        # check age of repositories
        for host, path, maintainer, max_age in backups:
            maintainer = default_maintainer if not maintainer else maintainer
            max_age = float(max_age) if max_age else default_max_age
            try:
                path = to_path(root, path)
                if path.is_dir():
                    paths = list(path.glob("index.*"))
                    if not paths:
                        raise Error("no sentinel file found.", culprit=path)
                    if len(paths) > 1:
                        raise Error("too many sentinel files.",
                                    *paths,
                                    sep="\n    ")
                    path = paths[0]
                mtime = arrow.get(path.stat().st_mtime)
                delta = now - mtime
                age = 24 * delta.days + delta.seconds / 3600
                report = age > max_age
                overdue = ' -- overdue' if report else ''
                color = fails if report else passes
                if report or not cmdline["--no-passes"]:
                    display(color(fmt(overdue_message)))

                if report:
                    problem = True
                    subject = f"backup of {host} is overdue"
                    msg = fmt(mail_overdue_message)
                    send_mail(maintainer, subject, msg)
            except OSError as e:
                problem = True
                msg = os_error(e)
                error(msg)
                if maintainer:
                    send_mail(
                        maintainer,
                        f"{get_prog_name()} error",
                        error_message.format(msg),
                    )
            except Error as e:
                problem = True
                e.report()
                if maintainer:
                    send_mail(
                        maintainer,
                        f"{get_prog_name()} error",
                        error_message.format(str(e)),
                    )
        terminate(problem)
Ejemplo n.º 12
0
def main():
    with Inform(
            error_status=2,
            flush=True,
            logfile=LoggingCache(),
            prog_name='emborg',
            version=version,
    ) as inform:

        # read command line
        cmdline = docopt(expanded_synopsis,
                         options_first=True,
                         version=version)
        config = cmdline["--config"]
        command = cmdline["<command>"]
        args = cmdline["<args>"]
        if cmdline["--mute"]:
            inform.mute = True
        if cmdline["--quiet"]:
            inform.quiet = True
        if cmdline["--relocated"]:
            os.environ['BORG_RELOCATED_REPO_ACCESS_IS_OK'] = 'YES'
        emborg_opts = cull([
            "verbose" if cmdline["--verbose"] else "",
            "narrate" if cmdline["--narrate"] else "",
            "dry-run" if cmdline["--dry-run"] else "",
            "no-log" if cmdline["--no-log"] else "",
        ])
        if cmdline["--narrate"]:
            inform.narrate = True

        Hooks.provision_hooks()
        worst_exit_status = 0

        try:
            # find the command
            cmd, cmd_name = Command.find(command)

            # execute the command initialization
            exit_status = cmd.execute_early(cmd_name, args, None, emborg_opts)
            if exit_status is not None:
                terminate(exit_status)

            queue = ConfigQueue(cmd)
            while queue:
                with Settings(config, emborg_opts, queue) as settings:
                    try:
                        exit_status = cmd.execute(cmd_name, args, settings,
                                                  emborg_opts)
                    except Error as e:
                        exit_status = 2
                        settings.fail(e, cmd=' '.join(sys.argv))
                        e.terminate()

                if exit_status and exit_status > worst_exit_status:
                    worst_exit_status = exit_status

            # execute the command termination
            exit_status = cmd.execute_late(cmd_name, args, None, emborg_opts)
            if exit_status and exit_status > worst_exit_status:
                worst_exit_status = exit_status

        except KeyboardInterrupt:
            display("Terminated by user.")
        except Error as e:
            e.report()
            exit_status = 2
        except OSError as e:
            exit_status = 2
            error(os_error(e))
        if exit_status and exit_status > worst_exit_status:
            worst_exit_status = exit_status
        terminate(worst_exit_status)
Ejemplo n.º 13
0
def main():
    version = f'{__version__} ({__released__})'
    cmdline = docopt(__doc__, version=version)
    quiet = cmdline['--quiet']
    problem = False
    use_color = Color.isTTY() and not cmdline['--no-color']
    passes = Color('green', enable=use_color)
    fails = Color('red', enable=use_color)

    # prepare to create logfile
    log = to_path(DATA_DIR, OVERDUE_LOG_FILE) if OVERDUE_LOG_FILE else False
    if log:
        data_dir = to_path(DATA_DIR)
        if not data_dir.exists():
            try:
                # data dir does not exist, create it
                data_dir.mkdir(mode=0o700, parents=True, exist_ok=True)
            except OSError as e:
                warn(os_error(e))
                log = False

    with Inform(flush=True, quiet=quiet, logfile=log, version=version):

        # read the settings file
        try:
            settings_file = PythonFile(CONFIG_DIR, OVERDUE_FILE)
            settings = settings_file.run()
        except Error as e:
            e.terminate()

        # gather needed settings
        default_maintainer = settings.get('default_maintainer')
        default_max_age = settings.get('default_max_age', 28)
        dumper = settings.get('dumper', f'{username}@{hostname}')
        repositories = settings.get('repositories')
        root = settings.get('root')

        # process repositories table
        backups = []
        if is_str(repositories):
            for line in repositories.split('\n'):
                line = line.split('#')[0].strip()  # discard comments
                if not line:
                    continue
                backups.append([c.strip() for c in line.split('|')])
        else:
            for each in repositories:
                backups.append([
                    each.get('host'),
                    each.get('path'),
                    each.get('maintainer'),
                    each.get('max_age')
                ])

        def send_mail(recipient, subject, message):
            if cmdline['--mail']:
                display(f'Reporting to {recipient}.\n')
                mail_cmd = ['mailx', '-r', dumper, '-s', subject, recipient]
                Run(mail_cmd, stdin=message, modes='soeW0')

        # check age of repositories
        for host, path, maintainer, max_age in backups:
            maintainer = default_maintainer if not maintainer else maintainer
            max_age = float(max_age) if max_age else default_max_age
            try:
                path = to_path(root, path)
                if path.is_dir():
                    paths = list(path.glob('index.*'))
                    if not paths:
                        raise Error('no sentinel file found.', culprit=path)
                    if len(paths) > 1:
                        raise Error('too many sentinel files.',
                                    *paths,
                                    sep='\n    ')
                    path = paths[0]
                mtime = arrow.get(path.stat().st_mtime)
                delta = now - mtime
                age = 24 * delta.days + delta.seconds / 3600
                report = age > max_age
                color = fails if report else passes
                if report or not cmdline['--no-passes']:
                    display(
                        color(
                            dedent(f"""
                        HOST: {host}
                            sentinel file: {path!s}
                            last modified: {mtime}
                            since last change: {age:0.1f} hours
                            maximum age: {max_age} hours
                            overdue: {report}
                    """).lstrip()))

                if report:
                    problem = True
                    subject = f"backup of {host} is overdue"
                    msg = overdue_message.format(host=host, path=path, age=age)
                    send_mail(maintainer, subject, msg)
            except OSError as e:
                problem = True
                msg = os_error(e)
                error(msg)
                if maintainer:
                    send_mail(maintainer, f'{get_prog_name()} error',
                              error_message.format(msg))
            except Error as e:
                problem = True
                e.report()
                if maintainer:
                    send_mail(maintainer, f'{get_prog_name()} error',
                              error_message.format(str(e)))
        terminate(problem)
Ejemplo n.º 14
0
def main():
    try:
        # Read command line {{{1
        cmdline = docopt(__doc__)
        keys = cmdline["--keys"].split(",") if cmdline["--keys"] else []
        update = cmdline["--update"].split(",") if cmdline["--update"] else []
        skip = cmdline["--skip"].split(",") if cmdline["--skip"] else []
        Inform(
            narrate=cmdline["--narrate"] or cmdline["--verbose"],
            verbose=cmdline["--verbose"],
            logfile=".sshdeploy.log",
            prog_name=False,
            flush=True,
            version=__version__,
        )
        if keys and not cmdline["--trial-run"]:
            fatal(
                "Using the --keys option results in incomplete authorized_keys files.",
                "It may only be used for testing purposes.",
                "As such, --trial-run must also be specified when using --keys.",
                sep="\n",
            )

        # Generated detailed help {{{1
        if cmdline["manual"]:
            from pkg_resources import resource_string

            try:
                Run(cmd=["less"], modes="soeW0", stdin=resource_string("src", "manual.rst").decode("utf8"))
            except OSError as err:
                error(os_error(err))
            terminate()

        # Read config file {{{1
        try:
            config_file = cmdline.get("--config-file")
            config_file = config_file if config_file else "sshdeploy.conf"
            contents = to_path(config_file).read_text()
        except OSError as err:
            fatal(os_error(err))
        code = compile(contents, config_file, "exec")
        config = {}
        try:
            exec(code, config)
        except Exception as err:
            fatal(err)

        # Move into keydir {{{1
        keydir = cmdline["--keydir"]
        keydir = to_path(keydir if keydir else "keys-" + date)
        if cmdline["generate"]:
            comment("creating key directory:", keydir)
            rm(keydir)
            mkdir(keydir)
            cd(keydir)
        elif cmdline["distribute"]:
            cd(keydir)

        # determine default values for key options
        defaults = {}
        for name, default in [
            ("keygen-options", DefaultKeygenOpts),
            ("abraxas-account", DefaultAbraxasAccount),
            ("remote-include-filename", DefaultRemoteIncludeFilename),
        ]:
            defaults[name] = config.get(name, default)

        # Generate keys {{{1
        if cmdline["generate"]:
            for keyname in sorted(config["keys"].keys()):
                data = config["keys"][keyname]
                if keys and keyname not in keys:
                    # user did not request this key
                    continue

                # get default values for missing key options
                for option in defaults:
                    data[option] = data.get(option, defaults[option])

                # generate the key
                key = Key(keyname, data, update, skip, cmdline["--trial-run"])
                key.generate()

        # Publish keys {{{1
        elif cmdline["distribute"]:
            for keyname in sorted(config["keys"].keys()):
                data = config["keys"][keyname]
                if keys and keyname not in keys:
                    continue  # user did not request this key

                # get default values for missing key options
                for option in defaults:
                    data[option] = data.get(option, defaults[option])

                # publish the key pair to clients
                key = Key(keyname, data, update, skip, cmdline["--trial-run"])
                key.publish_private_key()
                key.gather_public_keys()

            # publish authorized_keys files to servers {{{1
            if cmdline["distribute"]:
                for each in sorted(AuthKeys.known):
                    authkey = AuthKeys.known[each]
                    authkey.publish()
                    authkey.verify()

        # Process hosts {{{1
        elif cmdline["test"] or cmdline["clean"] or cmdline["hosts"]:
            hosts = set()
            for keyname, data in config["keys"].items():
                if keys and keyname not in keys:
                    continue  # user did not request this key

                # add servers to list of hosts
                for server, options in data["servers"].items():
                    if update and server not in update or server in skip:
                        continue
                    if "bypass" not in options:
                        hosts.add(server)

                # add clients to list of hosts
                for client in data["clients"].keys():
                    if update and client not in update or client in skip:
                        continue
                    hosts.add(client)

            # process the hosts
            if cmdline["test"]:
                # test host
                for host in sorted(hosts):
                    test_access(host)
            elif cmdline["clean"]:
                # clean host
                for host in sorted(hosts):
                    clean(host)
            else:
                # list hosts
                for host in sorted(hosts):
                    display(host)

    except OSError as err:
        error(os_error(err))
    except KeyboardInterrupt:
        display("Killed by user")
    done()
Ejemplo n.º 15
0
    def initialize(self, account, field_name, field_key=None):
        if self.secret:
            return
        account_name = account.get_name()
        account_seed = account.get_seed()
        if self.master is None:
            master_seed = account.get_scalar('master_seed', default=None)
            master_source = account.get_scalar('_master_source_', default=None)
        else:
            master_seed = self.master
            master_source = 'secret'
        if not master_seed:
            master_seed = get_setting('user_key')
            master_source = 'user_key'
        if not master_seed:
            try:
                try:
                    master_seed = getpass.getpass('master seed: ')
                    master_source = 'user'
                except EOFError:
                    output()
                if not master_seed:
                    warn("master seed is empty.")
            except (EOFError, KeyboardInterrupt):
                terminate()
        if self.version:
            version = self.version
        else:
            version = account.get_scalar('version', default='')

        log(
            'Generating secret ',
            '.'.join([str(n) for n in cull([account_name, field_name, field_key, version], remove=(None, ''))]),
            ', source of master seed: ',
            master_source,
            sep=''
        )
        field_key = self.get_key_seed(field_key)

        request_seed = account.request_seed()
        interactive_seed = ''
        if request_seed is True:
            try:
                interactive_seed = getpass.getpass('seed: ')
            except (EOFError, KeyboardInterrupt):
                terminate()
        elif callable(request_seed):
            interactive_seed = request_seed()
        elif is_str(request_seed):
            interactive_seed = request_seed
        elif request_seed:
            warn("invalid seed.")
        if request_seed and not interactive_seed:
            warn("seed is empty.")

        seeds = [
            master_seed,
            account_seed,
            field_name,
            field_key,
            version,
            interactive_seed
        ]
        self.set_seeds(seeds)
        assert(self.pool)
Ejemplo n.º 16
0
def test_pardon():
    with messenger() as (msg, stdout, stderr, logfile):
        try:
            terminate()
            assert False
        except SystemExit as e:
            assert e.args == (0,)

        try:
            raise Error('hey now!', culprit='nutz', extra='foo', codicil='putz')
            assert False
        except Error as err:
            assert err.get_message() == 'hey now!'
            assert err.get_culprit() == ('nutz',)
            assert err.get_codicil() == ('putz',)
            assert join_culprit(err.get_culprit()) == 'nutz'
            assert err.extra == 'foo'
            assert str(err) == 'nutz: hey now!'
            assert errors_accrued() == 0  # errors don't accrue until reported

        try:
            raise Error(
                'hey now!',
                culprit=('nutz',  'crunch'),
                extra='foo',
                codicil=('putz',  'toodle'),
            )
            assert False
        except Error as err:
            assert err.get_message() == 'hey now!'
            assert err.get_culprit() == ('nutz', 'crunch')
            assert err.get_codicil() == ('putz', 'toodle')
            assert join_culprit(err.get_culprit()) == 'nutz, crunch'
            assert err.extra == 'foo'
            assert str(err) == 'nutz, crunch: hey now!'
            assert err.get_message() == 'hey now!'
            assert err.get_message('{extra}, {}') == 'foo, hey now!'
            assert err.render() == 'nutz, crunch: hey now!'
            assert err.render('{extra}, {}') == 'nutz, crunch: foo, hey now!'
            assert errors_accrued() == 0  # errors don't accrue until reported
            try:
                err.terminate()
                assert False
            except SystemExit as e:
                assert e.args == (1,)

            try:
                done()
                assert False
            except SystemExit as e:
                assert e.args == (0,)

            try:
                rv = done(exit=False)
                assert rv == 0
            except SystemExit as e:
                assert False

            try:
                terminate()
                assert False
            except SystemExit as e:
                assert e.args == (1,)

            try:
                rv = terminate(exit=False)
                assert rv == 1
            except SystemExit as e:
                assert False

            try:
                rv = terminate(True, exit=False)
                assert rv == 1
            except SystemExit as e:
                assert False

            try:
                rv = terminate('fuxit', exit=False)
                assert rv == 1
            except SystemExit as e:
                assert False

            try:
                rv = terminate(6, exit=False)
                assert rv == 6
            except SystemExit as e:
                assert False

            try:
                terminate_if_errors()
                assert False
            except SystemExit as e:
                assert e.args == (1,)
                assert True

            try:
                rv = terminate_if_errors(exit=False)
                assert rv == 1
            except SystemExit as e:
                assert False

        try:
            raise Error('hey now', culprit=('nutz', 347))
            assert False
        except Error as err:
            assert err.get_message() == 'hey now'
            assert err.get_culprit() == ('nutz', 347)
            assert join_culprit(err.get_culprit()) == 'nutz, 347'
            assert join_culprit(err.get_culprit(66)) == '66, nutz, 347'
            assert join_culprit(err.get_culprit(('a', 'b'))) == 'a, b, nutz, 347'
            assert str(err) == 'nutz, 347: hey now'