Ejemplo n.º 1
0
    def token(self):
        global region
        global role
        global access_key
        global session_key
        global session_token

        # Welcome
        if args.verbose:
            print()
            print("Awsauth Amazon Account Access " + version)
            print()

        else:
            print()
            print("Awsauth Amazon Account Access " + version)
            print()

        # Set values from parser
        if args.role:
            role = args.role
        else:
            role = 'developer'

        if args.region:
            region = args.region
        else:
            region = 'eu-west-1'

        if args.project:
            project = args.project
            project = project.lower()
            verbose("Project: " + project)

        if args.env:
            env = args.env
            env = env.lower()
            verbose("Environment: " + env)

        token_expiration = 3600

        iam_connection = IAMConnection()

        # role_session_name=iam_connection.get_user()['get_user_response']['get_user_result']['user']['user_name']
        try:
            role_session_name = iam_connection.get_user().get_user_response.get_user_result.user.user_name
        except Exception as e:
            colormsg("There was an error retrieving your session_name. Check your credentials", "error")
            verbose(e)
            exit(1)

        # account_id=iam_connection.get_user()['get_user_response']['get_user_result']['user']['arn'].split(':')[4]
        try:
            account_id = iam_connection.get_user().get_user_response.get_user_result.user.arn.split(':')[4]
        except Exception as e:
            colormsg("There was an error retrieving your account id. Check your credentials", "error")
            verbose(e)
            exit(1)

        # Regexp for groups and policies. Set the policy name used by your organization

        if args.project and args.env:
            group_name = 'corp-' + project + '-master-' + role
            policy_name = 'Delegated_Roles'
            role_filter = env + '-' + project + '-delegated-' + role

        # Step 1: Prompt user for target account ID and name of role to assume

        # IAM groups
        verbose("Getting IAM group info:")
        delegated_policy = []
        group_policy = []
        delegated_arn = []

        try:
            policy = iam_connection.get_group_policy(group_name, policy_name)
        except Exception as e:
            colormsg(
                "There was an error retrieving your group policy. Check your credentials, group_name and policy_name",
                "error")
            verbose(e)
            exit(1)

        policy = policy.get_group_policy_response.get_group_policy_result.policy_document
        policy = unquote(policy)
        group_policy.append(config_line_policy("iam:grouppolicy", group_name, policy_name, policy))

        output_lines(group_policy)

        # Format policy and search by role_filter

        policy = re.split('"', policy)

        for i in policy:
            result_filter = re.search(role_filter, i)
            if result_filter:
                delegated_arn.append(i)

        if len(delegated_arn) == 0:
            if args.role and args.project:
                colormsg("Sorry, you are not authorized to use the role " + role + " for project " + project, "error")
                exit(1)
            else:
                colormsg("Sorry, you are not authorized to use the role " + role_filter, "error")
                exit(1)

        elif len(delegated_arn) == 1:
            account_id_from_user = delegated_arn[0].split(':')[4]
            role_name_from_user = delegated_arn[0].split('/')[1]

        else:
            colormsg("There are two or more policies matching your input", "error")
            exit(1)

        colormsg("You are authenticated as " + role_session_name, "ok")

        # MFA
        if not args.nomfa:
            mfa_devices_r = iam_connection.get_all_mfa_devices(role_session_name)
            if mfa_devices_r.list_mfa_devices_response.list_mfa_devices_result.mfa_devices:
                mfa_serial_number = mfa_devices_r.list_mfa_devices_response.list_mfa_devices_result.mfa_devices[
                    0].serial_number
            else:
                colormsg("You don't have MFA devices associated with our user", "error")
                exit(1)
        else:
            mfa_serial_number = "arn:aws:iam::" + account_id + ":mfa/" + role_session_name

        # Create an ARN out of the information provided by the user.
        role_arn = "arn:aws:iam::" + account_id_from_user + ":role/"
        role_arn += role_name_from_user

        # Connect to AWS STS and then call AssumeRole. This returns temporary security credentials.
        sts_connection = STSConnection()

        # Assume the role
        if not args.nomfa:
            verbose("Assuming role " + role_arn + " using MFA device " + mfa_serial_number + "...")
            if args.project:
                colormsg(
                    "Assuming role " + role + " from project " + project + " using MFA device from user " + role_session_name + "...",
                    "normal")
            elif args.iam_delegated_role:
                colormsg("Assuming role " + role + " using MFA device from user " + role_session_name + "...", "normal")
        else:
            verbose("Assuming role " + role_arn + "...")
            if args.project:
                colormsg(
                    "Assuming role " + role + " from project " + project + " from user " + role_session_name + "...",
                    "normal")
            elif args.iam_delegated_role:
                colormsg("Assuming role " + role + " from user " + role_session_name + "...", "normal")

        if os.path.isfile(os.path.expanduser('~/.awsauth')):

            with open(os.path.expanduser('~/.awsauth')) as json_file:
                root_json_data = json.load(json_file)
                json_file.close()

                if project in root_json_data and env in root_json_data[project] and role in root_json_data[project][
                    env]:
                    json_data = root_json_data[project][env][role]
                    awsauth_last_timestamp = json_data["awsauth_last_timestamp"]

                    # check if the token has expired
                    if int(time.time()) - int(awsauth_last_timestamp) > token_expiration or args.refresh:

                        verbose("token has expired")
                        sts_token = get_sts_token(sts_connection, role_arn, mfa_serial_number, role_session_name,
                                                  project, env, role, token_expiration)

                    else:
                        verbose("token has not expired, trying to login...")
                    login_to_fedaccount(json_data["access_key"], json_data["session_key"], json_data["session_token"],
                                        json_data["role_session_name"])
                    sts_token = {'access_key': json_data["access_key"], 'session_key': json_data["session_key"],
                                 'session_token': json_data["session_token"],
                                 'role_session_name': json_data["role_session_name"]}

                else:
                    sts_token = get_sts_token(sts_connection, role_arn, mfa_serial_number, role_session_name, project,
                                              env, role, token_expiration)
        else:
            verbose("role is " + role)
            sts_token = get_sts_token(sts_connection, role_arn, mfa_serial_number, role_session_name, project, env,
                                      role, token_expiration)
        return sts_token
Ejemplo n.º 2
0
    def token(self):
        global region
        global role
        global externalid
        global browser
        global access_key
        global session_key
        global session_token
        global filter_name

        # Welcome
        if self.args.verbose:
            print("")
            print("             __          ___     _  _____ ")
            print("     /\      \ \        / / |   (_)/ ____|")
            print("    /  \   _ _\ \  /\  / /| |__  _| (___  ")
            print("   / /\ \ | '_ \ \/  \/ / | '_ \| |\___ \ ")
            print("  / ____ \| | | \  /\  /  | |_) | |____) |")
            print(" /_/    \_\_| |_|\/  \/   |_.__/|_|_____/ ")
            print("")
            print("       Amazon Account Access "+ version)
            print("")

        else:
            print("")
            print("AnWbiS Amazon Account Access "+ version)
            print("")

        # Set values from parser

        if not self.args.project or not self.args.env:
            if not self.args.iam_master_group or not self.args.iam_policy or not self.args.iam_delegated_role and not self.args.from_ec2_role:
                colormsg("You must provide either -p and -e flags or --iam_master_group, --iam_policy and --iam_delegated_role to use Anwbis", "error")
                exit(1)
            elif self.args.from_ec2_role and not self.args.iam_delegated_role:
                colormsg("When using credentials stored in EC2 roles you must use either -p and -e flags or --iam_delegated_role to use Anwbis", "error")
                exit(1)
        if self.args.role:
            if self.args.role == 'contractor' and not self.args.contractor:
                colormsg ("When using role contractor you must provide --contractor (-c) flag with the contractor policy to asume", "error")
                exit(1)
            elif self.args.role == 'contractor' and self.args.contractor and not self.args.externalid:
                colormsg ("When using role contractor you must provide --externalid (-ext) code with the ExternalID to use", "error")
                exit(1)
            elif self.args.role == 'contractor' and self.args.contractor and self.args.externalid:
                role = self.args.role+'-'+self.args.contractor
                verbose("Asuming contractor role: "+ self.args.role+'-'+self.args.contractor)
            else:
                role = self.args.role
        elif self.args.iam_delegated_role:
            role = self.args.iam_delegated_role
        else:
            role = 'developer'

        if self.args.profile:
            profile_name = self.args.profile

        if self.args.region:
            region = self.args.region
        else:
            region = 'eu-west-1'

        if self.args.project:
            project = self.args.project
            #project = project.lower()
            verbose("Proyect: "+project)

        if self.args.env:
            env = self.args.env
            #env = env.lower()
            verbose("Environment: "+env)

        if self.args.browser:
            browser = self.args.browser
        else:
            browser = 'none'

        # Max token duration = 1h, session token = 8h

        if self.args.duration > 3600:
            token_expiration = 3600
            if self.args.get_session:
                if self.args.duration > 28800:
                    session_token_expiration = 28800
        elif self.args.duration < 900:
            token_expiration = 900
            if self.args.get_session:
                session_token_expiration = token_expiration
        else:
            token_expiration = self.args.duration
            if self.args.get_session and not self.args.duration:
                session_token_expiration = token_expiration
            else:
                session_token_expiration = 28800

        if self.args.externalid:
            externalid = self.args.externalid

        # Get Corp Account ID and set session name

        if self.args.profile:
            iam_connection = IAMConnection(profile_name=self.args.profile)
        else:
            iam_connection = IAMConnection()

        # role_session_name=iam_connection.get_user()['get_user_response']['get_user_result']['user']['user_name']
        try:
            if self.args.from_ec2_role:
                request_url = "http://169.254.169.254/latest/meta-data/iam/info/"
                r = requests.get(request_url)
                profilearn = json.loads(r.text)["InstanceProfileArn"]
                profileid = json.loads(r.text)["InstanceProfileId"]
                profilename = json.loads(r.text)["InstanceProfileArn"].split('/')[1]
                role_session_name = profilename
            else:
                role_session_name=iam_connection.get_user().get_user_response.get_user_result.user.user_name
        except Exception as e:
            colormsg("There was an error retrieving your session_name. Check your credentials", "error")
            verbose(str(e))
            exit(1)

        # account_id=iam_connection.get_user()['get_user_response']['get_user_result']['user']['arn'].split(':')[4]
        try:
            if self.args.from_ec2_role:
                account_id = profilearn = json.loads(r.text)["InstanceProfileArn"].split(':')[4]
                account_id_from_user = account_id
                role_name_from_user = profilename
            else:
                account_id=iam_connection.get_user().get_user_response.get_user_result.user.arn.split(':')[4]
        except Exception as e:
            colormsg ("There was an error retrieving your account id. Check your credentials", "error")
            verbose(str(e))
            exit(1)

        # Regexp for groups and policies. Set the policy name used by your organization
        group_name = None
        if self.args.project and self.args.env:
            if not self.args.from_ec2_role:
                group_name = 'corp-'+project+'-master-'+role
                policy_name = 'Delegated_Roles'
                role_filter = env+'-'+project+'-delegated-'+role
            else:
                group_name = 'IAM EC2 ROLE'
                policy_name = 'Delegated_Roles'
                role_filter = env+'-'+project+'-delegated-'+role

        # Get rid of the standard for using another policies or group names
        elif self.args.from_ec2_role and self.args.iam_delegated_role:
            role_filter = self.args.iam_delegated_role
            # Fix references to project, env and role in .anwbis file for non-standard use
            role = role_filter
            project = group_name
            env = "ec2-role"
        elif self.args.iam_master_group and self.args.iam_policy and self.args.iam_delegated_role:
            group_name = self.args.iam_master_group
            policy_name = self.args.iam_policy
            role_filter = self.args.iam_delegated_role
            # Fix references to project, env and role in .anwbis file for non-standard use
            role = role_filter
            project = group_name
            env = policy_name

        # Step 1: Prompt user for target account ID and name of role to assume

        # IAM groups
        verbose("Getting IAM group info:")
        delegated_policy = []
        group_policy = []
        delegated_arn = []

        try:
            if not self.args.from_ec2_role:
                policy = iam_connection.get_group_policy(group_name, policy_name)
            else:
                # policy = iam_connection.get_instance_profile(profilename)
                policy = iam_connection.get_role_policy(profilename, policy_name)
        except Exception as e:
            colormsg("There was an error retrieving your group policy. Check your credentials, group_name and policy_name",
                     "error")
            verbose(e)
            exit(1)

        if not self.args.from_ec2_role:
            policy = policy.get_group_policy_response.get_group_policy_result.policy_document
            policy = urllib.parse.unquote(policy)
            group_policy.append(config_line_policy("iam:grouppolicy", group_name, policy_name, policy))

        else:
            policy = policy.get_role_policy_response.get_role_policy_result.policy_document
            policy = urllib.parse.unquote(policy)
            group_policy.append(config_line_policy("iam:grouppolicy", group_name, policy_name, policy))

        output_lines(group_policy)

        # Format policy and search by role_filter

        policy = re.split('"', policy)

        for i in policy:
            result_filter = re.search(role_filter, i)
            if result_filter:
                delegated_arn.append(i)

        if len(delegated_arn) == 0:
            if self.args.role and self.args.project:
                colormsg("Sorry, you are not authorized to use the role " + role + " for project "+ project, "error")
                exit(1)
            else:
                colormsg("Sorry, you are not authorized to use the role "+ role_filter, "error")
                exit(1)

        elif len(delegated_arn) == 1:
            account_id_from_user = delegated_arn[0].split(':')[4]
            role_name_from_user = delegated_arn[0].split('/')[1]

        else:
            colormsg("There are two or more policies matching your input", "error")
            exit(1)

        colormsg("You are authenticated as " + role_session_name, "ok")

        # MFA
        if not self.args.nomfa:
            mfa_devices_r = iam_connection.get_all_mfa_devices(role_session_name)
            if mfa_devices_r.list_mfa_devices_response.list_mfa_devices_result.mfa_devices:
                mfa_serial_number =  mfa_devices_r.list_mfa_devices_response.list_mfa_devices_result.mfa_devices[0].serial_number
            else:
                colormsg("You don't have MFA devices associated with our user", "error")
                exit(1)
        else:
            mfa_serial_number = "arn:aws:iam::"+ account_id +":mfa/"+role_session_name

        # Create an ARN out of the information provided by the user.
        role_arn = "arn:aws:iam::" + account_id_from_user + ":role/"
        role_arn += role_name_from_user

        # Connect to AWS STS and then call AssumeRole. This returns temporary security credentials.
        if self.args.profile:
            sts_connection = STSConnection(profile_name=self.args.profile)
        else:
            sts_connection = STSConnection()

        # Assume the role
        if not self.args.nomfa:
            verbose("Assuming role " + role_arn + " using MFA device " + mfa_serial_number + "...")
            if self.args.project:
                colormsg("Assuming role " + role + " from project " + project + " using MFA device from user " + role_session_name + "...", "normal")
            elif self.args.iam_delegated_role:
                colormsg("Assuming role " + role + " using MFA device from user " + role_session_name+ "...", "normal")
        else:
            verbose("Assuming role " + role_arn + "...")
            if self.args.project:
                colormsg("Assuming role " + role + " from project "+ project+ " from user " + role_session_name + "...", "normal")
            elif self.args.iam_delegated_role:
                colormsg("Assuming role " + role + " from user "+ role_session_name + "...", "normal")
        if self.args.get_session:
                sts_token = get_session_token(sts_connection, role_arn, mfa_serial_number, role_session_name, project, env, role, token_expiration, session_token_expiration, self.args)
        else:
            if os.path.isfile(os.path.expanduser('~/.anwbis')):

                with open(os.path.expanduser('~/.anwbis')) as json_file:
                    root_json_data = json.load(json_file)
                    json_file.close()

                    if project in root_json_data and env in root_json_data[project] and role in root_json_data[project][env]:
                        json_data = root_json_data[project][env][role]
                        anwbis_last_timestamp = json_data["anwbis_last_timestamp"]

                        # check if the token has expired
                        # TODO: Check if token is written in credentials
                        if int(time.time()) - int(anwbis_last_timestamp) > token_expiration or self.args.refresh:

                            verbose("token has expired")
                            sts_token = get_sts_token(sts_connection,
                                                      role_arn,
                                                      mfa_serial_number,
                                                      role_session_name,
                                                      project,
                                                      env,
                                                      role,
                                                      token_expiration,
                                                      self.args)

                        else:
                            verbose("token has not expired, trying to login...")
                        login_to_fedaccount(json_data["access_key"],
                                            json_data["session_key"],
                                            json_data["session_token"],
                                            json_data["role_session_name"],
                                            args=self.args)
                        sts_token = {'access_key': json_data["access_key"],
                                     'session_key':json_data["session_key"],
                                     'session_token': json_data["session_token"],
                                     'role_session_name': json_data["role_session_name"]}

                    else:
                        sts_token = get_sts_token(sts_connection, role_arn, mfa_serial_number, role_session_name, project, env, role, token_expiration, self.args)
            else:
                # print ".anwbis configuration file doesn't exists"
                verbose("role is " + role)
                sts_token = get_sts_token(sts_connection, role_arn, mfa_serial_number, role_session_name, project, env, role, token_expiration, self.args)
        return sts_token