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
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