Ejemplo n.º 1
0
    def run(self):
        """ Pulling it all together to make the CLI """
        config = Config()
        config.get_args()
        # Create/Update config when configure arg set
        if config.configure is True:
            config.update_config_file()
            exit()

        # get the config dict
        conf_dict = config.get_config_dict()

        if not conf_dict.get('okta_org_url'):
            print(
                'No Okta organization URL in configuration.  Try running --config again.'
            )
            exit(1)

        if not conf_dict.get('gimme_creds_server'):
            print(
                'No Gimme-Creds server URL in configuration.  Try running --config again.'
            )
            exit(1)

        okta = OktaClient(conf_dict['okta_org_url'], config.verify_ssl_certs)
        if config.resolve == True:
            self.resolver = AwsResolver(config.verify_ssl_certs)
        else:
            if conf_dict.get('resolve_aws_alias') and str(
                    conf_dict['resolve_aws_alias']) == 'True':
                self.resolver = AwsResolver(config.verify_ssl_certs)

        if config.username is not None:
            okta.set_username(config.username)
        else:
            if conf_dict.get('okta_username'):
                okta.set_username(conf_dict['okta_username'])

        if conf_dict.get('preferred_mfa_type'):
            okta.set_preferred_mfa_type(conf_dict['preferred_mfa_type'])

        if config.mfa_code is not None:
            okta.set_mfa_code(config.mfa_code)

        # AWS Default session duration ....
        if conf_dict.get('aws_default_duration'):
            config.aws_default_duration = int(
                conf_dict['aws_default_duration'])
        else:
            config.aws_default_duration = 3600

        # Call the Okta APIs and proces data locally
        if conf_dict.get('gimme_creds_server') == 'internal':
            # Okta API key is required when calling Okta APIs internally
            if config.api_key is None:
                print('OKTA_API_KEY environment variable not found!')
                exit(1)
            # Authenticate with Okta
            auth_result = okta.auth_session()

            print("Authentication Success! Getting AWS Accounts")
            aws_results = self._get_aws_account_info(conf_dict['okta_org_url'],
                                                     config.api_key,
                                                     auth_result['username'])

        elif conf_dict.get('gimme_creds_server') == 'appurl':
            # bypass lambda & API call
            # Apps url is required when calling with appurl
            if conf_dict.get('app_url'):
                config.app_url = conf_dict['app_url']
            if config.app_url is None:
                print('app_url is not defined in your config !')
                exit(1)

            # Authenticate with Okta
            auth_result = okta.auth_session()
            print("Authentication Success! Getting AWS Accounts")

            # build app list
            aws_results = []
            newAppEntry = {}
            newAppEntry['id'] = "fakeid"  # not used anyway
            newAppEntry['name'] = "fakelabel"  #not used anyway
            newAppEntry['links'] = {}
            newAppEntry['links']['appLink'] = config.app_url
            aws_results.append(newAppEntry)

        # Use the gimme_creds_lambda service
        else:
            if not conf_dict.get('client_id'):
                print(
                    'No OAuth Client ID in configuration.  Try running --config again.'
                )
            if not conf_dict.get('okta_auth_server'):
                print(
                    'No OAuth Authorization server in configuration.  Try running --config again.'
                )

            # Authenticate with Okta and get an OAuth access token
            okta.auth_oauth(conf_dict['client_id'],
                            authorization_server=conf_dict['okta_auth_server'],
                            access_token=True,
                            id_token=False,
                            scopes=['openid'])

            # Add Access Tokens to Okta-protected requests
            okta.use_oauth_access_token(True)

            print("Authentication Success! Calling Gimme-Creds Server...")
            aws_results = self._call_gimme_creds_server(
                okta, conf_dict['gimme_creds_server'])

        aws_app = self._get_selected_app(conf_dict.get('aws_appname'),
                                         aws_results)
        saml_data = okta.get_saml_response(aws_app['links']['appLink'])
        # aws_signin_page = aws_signin.get_signinpage(saml_data['SAMLResponse'])
        roles = self.resolver._enumerate_saml_roles(saml_data['SAMLResponse'],
                                                    saml_data['TargetUrl'])
        aws_role = self._get_selected_role(conf_dict.get('aws_rolename'),
                                           roles)
        aws_partition = self._get_partition_from_saml_acs(
            saml_data['TargetUrl'])

        for _, role in enumerate(roles):
            # Skip irrelevant roles
            if aws_role != 'all' and aws_role not in role.role:
                continue

            try:
                aws_creds = self._get_sts_creds(aws_partition,
                                                saml_data['SAMLResponse'],
                                                role.idp, role.role,
                                                config.aws_default_duration)
            except ClientError as ex:
                if ex.response['Error'][
                        'Message'] == 'The requested DurationSeconds exceeds the MaxSessionDuration set for this role.':
                    print(
                        "The requested session duration was too long for this role.  Falling back to 1 hour."
                    )
                    aws_creds = self._get_sts_creds(aws_partition,
                                                    saml_data['SAMLResponse'],
                                                    role.idp, role.role, 3600)

            deriv_profname = re.sub('arn:aws:iam:.*/', '', role.role)

            # check if write_aws_creds is true if so
            # get the profile name and write out the file
            if str(conf_dict['write_aws_creds']) == 'True':
                # set the profile name
                # Note if there are multiple roles, and 'default' is
                # selected it will be overwritten multiple times and last role
                # wins.
                if conf_dict['cred_profile'].lower() == 'default':
                    profile_name = 'default'
                elif conf_dict['cred_profile'].lower() == 'role':
                    profile_name = deriv_profname
                else:
                    profile_name = conf_dict['cred_profile']

                # Write out the AWS Config file
                print('writing role {} to {}'.format(role.role,
                                                     self.AWS_CONFIG))
                self._write_aws_creds(profile_name, aws_creds['AccessKeyId'],
                                      aws_creds['SecretAccessKey'],
                                      aws_creds['SessionToken'])
            else:
                #Print out temporary AWS credentials.  Credentials are printed to stderr to simplify
                #redirection for use in automated scripts
                print("export AWS_ACCESS_KEY_ID=" + aws_creds['AccessKeyId'],
                      file=sys.stderr)
                print("export AWS_SECRET_ACCESS_KEY=" +
                      aws_creds['SecretAccessKey'],
                      file=sys.stderr)
                print("export AWS_SESSION_TOKEN=" + aws_creds['SessionToken'],
                      file=sys.stderr)
                print("export AWS_SECURITY_TOKEN=" + aws_creds['SessionToken'],
                      file=sys.stderr)

        config.clean_up()
Ejemplo n.º 2
0
    def run(self):
        """ Pulling it all together to make the CLI """
        config = Config()
        config.get_args()
        # Create/Update config when configure arg set
        if config.configure is True:
            config.update_config_file()
            exit()

        # get the config dict
        conf_dict = config.get_config_dict()

        if not conf_dict.get('okta_org_url'):
            print(
                'No Okta organization URL in configuration.  Try running --config again.'
            )
            exit(1)

        if not conf_dict.get('gimme_creds_server'):
            print(
                'No Gimme-Creds server URL in configuration.  Try running --config again.'
            )
            exit(1)

        okta = OktaClient(conf_dict['okta_org_url'], config.verify_ssl_certs)

        if config.username is not None:
            okta.set_username(config.username)
        else:
            if conf_dict.get('okta_username'):
                okta.set_username(conf_dict['okta_username'])

        # Call the Okta APIs and proces data locally
        if conf_dict.get('gimme_creds_server') == 'internal':
            # Okta API key is required when calling Okta APIs internally
            if config.api_key is None:
                print('OKTA_API_KEY environment variable not found!')
                exit(1)
            # Authenticate with Okta
            auth_result = okta.auth_session()

            print("Authentication Success! Getting AWS Accounts")
            aws_results = self._get_aws_account_info(conf_dict['okta_org_url'],
                                                     config.api_key,
                                                     auth_result['username'])

        # Use the gimme_creds_lambda service
        else:
            if not conf_dict.get('client_id'):
                print(
                    'No OAuth Client ID in configuration.  Try running --config again.'
                )
            if not conf_dict.get('okta_auth_server'):
                print(
                    'No OAuth Authorization server in configuration.  Try running --config again.'
                )

            # Authenticate with Okta and get an OAuth access token
            okta.auth_oauth(conf_dict['client_id'],
                            authorization_server=conf_dict['okta_auth_server'],
                            access_token=True,
                            id_token=False,
                            scopes=['openid'])

            # Add Access Tokens to Okta-protected requests
            okta.use_oauth_access_token(True)

            print("Authentication Success! Calling Gimme-Creds Server...")
            aws_results = self._call_gimme_creds_server(
                okta, conf_dict['gimme_creds_server'])

        aws_app = self._get_selected_app(conf_dict.get('aws_appname'),
                                         aws_results)
        saml_data = okta.get_saml_response(aws_app['links']['appLink'])
        roles = self._enumerate_saml_roles(saml_data['SAMLResponse'])
        aws_role = self._get_selected_role(conf_dict.get('aws_rolename'),
                                           roles)
        aws_partition = self._get_partition_from_saml_acs(
            saml_data['TargetUrl'])

        for _, role in enumerate(roles):
            # Skip irrelevant roles
            if aws_role != 'all' and aws_role not in role.role:
                continue

            aws_creds = self._get_sts_creds(aws_partition,
                                            saml_data['SAMLResponse'],
                                            role.idp, role.role)
            deriv_profname = re.sub('arn:aws:iam:.*/', '', role.role)

            # check if write_aws_creds is true if so
            # get the profile name and write out the file
            if str(conf_dict['write_aws_creds']) == 'True':
                # set the profile name
                # Note if there are multiple roles, and 'default' is
                # selected it will be overwritten multiple times and last role
                # wins.
                if conf_dict['cred_profile'].lower() == 'default':
                    profile_name = 'default'
                elif conf_dict['cred_profile'].lower() == 'role':
                    profile_name = deriv_profname
                else:
                    profile_name = conf_dict['cred_profile']

                # Write out the AWS Config file
                print('writing role {} to {}'.format(role.role,
                                                     self.AWS_CONFIG))
                self._write_aws_creds(profile_name, aws_creds['AccessKeyId'],
                                      aws_creds['SecretAccessKey'],
                                      aws_creds['SessionToken'])
            else:
                #Print out temporary AWS credentials.  Credentials are printed to stderr to simplify
                #redirection for use in automated scripts
                print("export AWS_ACCESS_KEY_ID=" + aws_creds['AccessKeyId'],
                      file=sys.stderr)
                print("export AWS_SECRET_ACCESS_KEY=" +
                      aws_creds['SecretAccessKey'],
                      file=sys.stderr)
                print("export AWS_SESSION_TOKEN=" + aws_creds['SessionToken'],
                      file=sys.stderr)

        config.clean_up()