Created
July 24, 2019 21:55
-
-
Save wilsonjackson/2ec2a6f5c5330bf1207daef3306fbd74 to your computer and use it in GitHub Desktop.
aws-okta wrapper with GUI prompt for code
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
# Detect known terminals and map them to their process name for use with AppleScript. | |
if [[ ${TERM_PROGRAM} == "Apple_Terminal" ]]; then | |
terminal="Terminal" | |
elif [[ ${TERM_PROGRAM} == "iTerm.app" ]]; then | |
terminal="iTerm2" | |
fi | |
function aws_okta() { | |
aws-okta exec okta-saml -- sh -c 'echo "{\"Version\":1,\"AccessKeyId\":\"$AWS_ACCESS_KEY_ID\",\"SecretAccessKey\":\"$AWS_SECRET_ACCESS_KEY\",\"SessionToken\":\"$AWS_SESSION_TOKEN\",\"Expiration\":\"`date -u -v+15M +"%Y-%m-%dT%H:%M:%SZ"`\"}"' | |
} | |
# If the terminal is unrecognized or osascript isn't found, just execute aws-okta. | |
# Same if the wrapper has been explicitly disabled. | |
if [[ ${AWS_OKTA_WRAPPER_DISABLE} -eq 1 || ${terminal:-unknown} == "unknown" ]] || ! type osascript >/dev/null 2>/dev/null; then | |
aws_okta | |
exit $? | |
fi | |
# A bit of AppleScript is used to send a GUI prompt to the user for their MFA code | |
# so that it doesn't interrupt and break the process originating the request (aws | |
# or kubernetes cli). | |
function gimme() { | |
code=$(osascript <<APPLESCRIPTYAY | |
tell app "${terminal}" | |
set code to text returned of (display dialog "Enter an Okta MFA code" buttons {"OK"} default answer "" default button 1 with icon caution with title "Okta MFA Challenge") | |
end tell | |
APPLESCRIPTYAY | |
) | |
echo ${code} | |
} | |
pipe=/tmp/aws-okta-mfa.pipe | |
mfa_required_string="Requesting MFA" | |
if [[ ! -e ${pipe} ]]; then | |
mkfifo ${pipe} | |
fi | |
# Read each line sent by aws-okta to stdout or stderr. On the first line, check for a | |
# match against the expected substring to indicate an MFA challenge, and prompt the | |
# user for the code. A named pipe is used as input to aws-okta so the entered code can | |
# be sent to the interactive prompt. | |
# | |
# An extra trick is needed to capture the process substitution's exit code: the exit | |
# code is printed as a final, non-newline-terminated line in the subshell, and specially | |
# handled in the while condition so it can be assigned to a variable. | |
first_line=1 | |
while read -r line || { exit_code=${line} && break; }; do | |
if [[ ${first_line} -eq 1 ]]; then | |
if [[ ${line} =~ $mfa_required_string ]]; then | |
gimme > ${pipe} | |
else | |
echo "" > ${pipe} | |
fi | |
fi | |
first_line=0 | |
result=${line} | |
done < <(cat ${pipe} | aws_okta 2>&1; printf $?) | |
echo "$result" | |
exit ${exit_code} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment