コード例 #1
0
ファイル: config.py プロジェクト: webfella/aws-mfa
def initial_setup(logger, config, config_path, no_keychain=False):
    console_input = prompter()

    profile_name = console_input('Profile name to [%s]: ' % ("default"))
    if profile_name is None or profile_name == "":
        profile_name = "default"

    profile_name = "{}-long-term".format(profile_name)
    aws_access_key_id = getpass.getpass('aws_access_key_id: ')
    if aws_access_key_id is None or aws_access_key_id == "":
        log_error_and_exit(logger, "You must supply aws_access_key_id")
    aws_secret_access_key = getpass.getpass('aws_secret_access_key: ')
    if aws_secret_access_key is None or aws_secret_access_key == "":
        log_error_and_exit(logger, "You must supply aws_secret_access_key")

    if no_keychain:
        config.add_section(profile_name)
        config.set(profile_name, 'aws_access_key_id', aws_access_key_id)
        config.set(profile_name, 'aws_secret_access_key',
                   aws_secret_access_key)
        with open(config_path, 'w') as configfile:
            config.write(configfile)
    else:
        keyring.set_password("aws:access_key_id", profile_name,
                             aws_access_key_id)
        keyring.set_password("aws:secret_access_key", profile_name,
                             aws_secret_access_key)
コード例 #2
0
def get_credentials(short_term_name, lt_key_id, lt_access_key, args, config):
    if args.token:
        logger.debug("Received token as argument")
        mfa_token = '%s' % (args.token)
    else:
        console_input = prompter()
        mfa_token = console_input('Enter AWS MFA code for device [%s] '
                                  '(renewing for %s seconds):' %
                                  (args.device, args.duration))

    client = boto3.client('sts',
                          aws_access_key_id=lt_key_id,
                          aws_secret_access_key=lt_access_key)

    if args.assume_role:

        logger.info("Assuming Role - Profile: %s, Role: %s, Duration: %s",
                    short_term_name, args.assume_role, args.duration)
        if args.role_session_name is None:
            log_error_and_exit(
                logger, "You must specify a role session name "
                "via --role-session-name")

        try:
            response = client.assume_role(
                RoleArn=args.assume_role,
                RoleSessionName=args.role_session_name,
                DurationSeconds=args.duration,
                SerialNumber=args.device,
                TokenCode=mfa_token)
        except ClientError as e:
            log_error_and_exit(
                logger, "An error occured while calling "
                "assume role: {}".format(e))
        except ParamValidationError:
            log_error_and_exit(logger, "Token must be six digits")

        config.set(
            short_term_name,
            'assumed_role',
            'True',
        )
        config.set(
            short_term_name,
            'assumed_role_arn',
            args.assume_role,
        )
    else:
        logger.info("Fetching Credentials - Profile: %s, Duration: %s",
                    short_term_name, args.duration)
        try:
            response = client.get_session_token(DurationSeconds=args.duration,
                                                SerialNumber=args.device,
                                                TokenCode=mfa_token)
        except ClientError as e:
            log_error_and_exit(
                logger,
                "An error occured while calling assume role: {}".format(e))
        except ParamValidationError:
            log_error_and_exit(logger, "Token must be six digits")

        config.set(
            short_term_name,
            'assumed_role',
            'False',
        )
        config.remove_option(short_term_name, 'assumed_role_arn')

    # aws_session_token and aws_security_token are both added
    # to support boto and boto3
    options = [
        ('aws_access_key_id', 'AccessKeyId'),
        ('aws_secret_access_key', 'SecretAccessKey'),
        ('aws_session_token', 'SessionToken'),
        ('aws_security_token', 'SessionToken'),
    ]

    for option, value in options:
        config.set(short_term_name, option, response['Credentials'][value])
    # Save expiration individiually, so it can be manipulated
    config.set(
        short_term_name, 'expiration',
        response['Credentials']['Expiration'].strftime('%Y-%m-%d %H:%M:%S'))
    with open(AWS_CREDS_PATH, 'w') as configfile:
        config.write(configfile)
    logger.info("Success! Your credentials will expire in %s seconds at: %s" %
                (args.duration, response['Credentials']['Expiration']))
    sys.exit(0)
コード例 #3
0
def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('--device',
                        required=False,
                        metavar='arn:aws:iam::123456788990:mfa/dudeman',
                        help="The MFA Device ARN. This value can also be "
                        "provided via the environment variable 'MFA_DEVICE' or"
                        " the ~/.aws/credentials variable 'aws_mfa_device'.")
    parser.add_argument('--duration',
                        type=int,
                        help="The duration, in seconds, that the temporary "
                        "credentials should remain valid. Minimum value: "
                        "900 (15 minutes). Maximum: 129600 (36 hours). "
                        "Defaults to 43200 (12 hours), or 3600 (one "
                        "hour) when using '--assume-role'. This value "
                        "can also be provided via the environment "
                        "variable 'MFA_STS_DURATION'. ")
    parser.add_argument('--profile',
                        help="If using profiles, specify the name here. The "
                        "default profile name is 'default'. The value can "
                        "also be provided via the environment variable "
                        "'AWS_PROFILE'.",
                        required=False)
    parser.add_argument('--long-term-suffix',
                        '--long-suffix',
                        help="The suffix appended to the profile name to"
                        "identify the long term credential section",
                        required=False)
    parser.add_argument('--short-term-suffix',
                        '--short-suffix',
                        help="The suffix appended to the profile name to"
                        "identify the short term credential section",
                        required=False)
    parser.add_argument('--assume-role',
                        '--assume',
                        metavar='arn:aws:iam::123456788990:role/RoleName',
                        help="The ARN of the AWS IAM Role you would like to "
                        "assume, if specified. This value can also be provided"
                        " via the environment variable 'MFA_ASSUME_ROLE'",
                        required=False)
    parser.add_argument('--role-session-name',
                        help="Friendly session name required when using "
                        "--assume-role",
                        default=getpass.getuser(),
                        required=False)
    parser.add_argument('--force',
                        help="Refresh credentials even if currently valid.",
                        action="store_true",
                        required=False)
    parser.add_argument(
        '--log-level',
        help="Set log level",
        choices=['CRITICAL', 'ERROR', 'WARNING', 'INFO', 'DEBUG', 'NOTSET'],
        required=False,
        default='DEBUG')
    parser.add_argument('--setup',
                        help="Setup a new long term credentials section",
                        action="store_true",
                        required=False)
    parser.add_argument('--token',
                        '--mfa-token',
                        type=str,
                        help="Provide MFA token as an argument",
                        required=False)
    args = parser.parse_args()

    level = getattr(logging, args.log_level)
    setup_logger(level)

    if not os.path.isfile(AWS_CREDS_PATH):
        console_input = prompter()
        create = console_input("Could not locate credentials file at {}, "
                               "would you like to create one? "
                               "[y/n]".format(AWS_CREDS_PATH))
        if create.lower() == "y":
            with open(AWS_CREDS_PATH, 'a'):
                pass
        else:
            log_error_and_exit(
                logger, 'Could not locate credentials file at '
                '%s' % (AWS_CREDS_PATH, ))

    config = get_config(AWS_CREDS_PATH)

    if args.setup:
        initial_setup(logger, config, AWS_CREDS_PATH)
        return

    validate(args, config)
コード例 #4
0
def get_credentials(short_term_name, long_term_name, lt_key_id, lt_access_key,
                    args, config):
    if args.token:
        logger.debug("Received token as argument")
        mfa_token = '%s' % (args.token)
    else:
        console_input = prompter()
        mfa_token = console_input('Enter AWS MFA code for device [%s] '
                                  '(renewing for %s seconds):' %
                                  (args.device, args.duration))

    client = boto3.client('sts',
                          aws_access_key_id=lt_key_id,
                          aws_secret_access_key=lt_access_key)

    if args.assume_role:

        logger.info("Assuming Role - Profile: %s, Role: %s, Duration: %s",
                    short_term_name, args.assume_role, args.duration)
        if args.role_session_name is None:
            log_error_and_exit(
                logger, "You must specify a role session name "
                "via --role-session-name")

        try:
            response = client.assume_role(
                RoleArn=args.assume_role,
                RoleSessionName=args.role_session_name,
                DurationSeconds=args.duration,
                SerialNumber=args.device,
                TokenCode=mfa_token)
        except ClientError as e:
            log_error_and_exit(
                logger, "An error occured while calling "
                "assume role: {}".format(e))
        except ParamValidationError as e:
            log_error_and_exit(logger, getattr(e, 'message', repr(e)))

        config.set(
            short_term_name,
            'assumed_role',
            'True',
        )
        config.set(
            short_term_name,
            'assumed_role_arn',
            args.assume_role,
        )
    else:
        logger.info("Fetching Credentials - Profile: %s, Duration: %s",
                    short_term_name, args.duration)
        try:
            response = client.get_session_token(DurationSeconds=args.duration,
                                                SerialNumber=args.device,
                                                TokenCode=mfa_token)
        except ClientError as e:
            log_error_and_exit(
                logger,
                "An error occured while calling assume role: {}".format(e))
        except ParamValidationError:
            log_error_and_exit(logger, getattr(e, 'message', repr(e)))

        config.set(
            short_term_name,
            'assumed_role',
            'False',
        )
        config.remove_option(short_term_name, 'assumed_role_arn')

    # aws_session_token and aws_security_token are both added
    # to support boto and boto3
    options = [
        ('aws_access_key_id', 'AccessKeyId'),
        ('aws_secret_access_key', 'SecretAccessKey'),
        ('aws_session_token', 'SessionToken'),
        ('aws_security_token', 'SessionToken'),
    ]

    for option, value in options:
        config.set(short_term_name, option, response['Credentials'][value])
    # Save expiration individiually, so it can be manipulated
    config.set(
        short_term_name, 'expiration',
        response['Credentials']['Expiration'].strftime('%Y-%m-%d %H:%M:%S'))

    # Copy over other aws config options
    # List taken from - https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html
    # Excluding those to do with authentication, which we have already handled
    copy_options = [
        'region', 's3', 'api_versions', 'ca_bundle', 'cli_follow_urlparam',
        'cli_timestamp_format', 'output', 'parameter_validation',
        'tcp_keepalive'
    ]
    for copy_option in copy_options:
        if config.has_option(long_term_name, copy_option):
            config.set(short_term_name, copy_option,
                       config.get(long_term_name, copy_option))

    with open(AWS_CREDS_PATH, 'w') as configfile:
        config.write(configfile)
    logger.info("Success! Your credentials will expire in %s seconds at: %s" %
                (args.duration, response['Credentials']['Expiration']))

    warn_on_existing_aws_env()

    sys.exit(0)