683ff82b |
(in-package :mfa-tool)
(defvar *accounts* ())
(defun session-name ()
(format nil "bootstrap~d" (+ 5000 (random 5000))))
(defparameter *user_management_account_id* 597974043991)
|
40c2d5d8 |
(defun read-new-mfa-token ()
(format *query-io* "~&New MFA token: ")
(finish-output *query-io*)
(list (read-line *query-io*)))
|
683ff82b |
|
72718ef5 |
(defun do-auth (user role token)
(with-retry (let ((mfa-serial-number (arn-for :mfa *user_management_account_id* user))
(role-arn (cj-organization-role-arn role)))
(aws/sts:assume-role :role-arn role-arn
:role-session-name (session-name)
:serial-number mfa-serial-number
|
edb09ea2 |
:duration-seconds (if (eql (mfa-tool.aws-utils:session-duration role)
:max)
#.(* 12 60 60)
(mfa-tool.aws-utils:session-duration role))
|
72718ef5 |
:token-code token))
(change-mfa-token (new-token)
:interactive read-new-mfa-token
(setf token new-token))))
|
40c2d5d8 |
(defun change-mfa-token (new-value)
(when (find-restart 'change-mfa-token)
(invoke-restart 'change-mfa-token new-value)))
|
683ff82b |
(defun get-url (params)
(format nil "https://signin.aws.amazon.com/federation?Action=getSigninToken&Session=~a"
(quri.encode:url-encode (with-output-to-string (s)
(yason:encode params s))
:space-to-plus t)))
|
5aa9ad6e |
(cells:defmodel sts-result-handler ()
((credentials :accessor credentials :initarg :credentials
:initform (cells:c-in nil))
|
683ff82b |
(session-id :reader session-id
|
5aa9ad6e |
:initform (cells:c? (typecase (^credentials)
|
76ad2e41 |
(aws:credentials
(aws-sdk/credentials/base:credentials-access-key-id
(^credentials)))
|
5aa9ad6e |
(cons (serapeum:assocadr "AccessKeyId" (^credentials)
:test 'equal)))))
|
76ad2e41 |
(session-key :reader session-key
|
5aa9ad6e |
:initform (cells:c? (typecase (^credentials)
|
76ad2e41 |
(aws:credentials
(aws-sdk/credentials/base:credentials-secret-access-key
(^credentials)))
|
5aa9ad6e |
(cons (serapeum:assocadr "SecretAccessKey" (^credentials)
:test 'equal)))))
|
76ad2e41 |
(session-token :reader session-token
|
5aa9ad6e |
:initform (cells:c? (typecase (^credentials)
|
76ad2e41 |
(aws:credentials
(aws-sdk/credentials/base:credentials-session-token
(^credentials)))
|
5aa9ad6e |
(cons (serapeum:assocadr "SessionToken" (^credentials)
:test 'equal)))))
|
76ad2e41 |
(url-params :reader url-params
|
683ff82b |
:initform (cells:c? (fw.lu:alist-string-hash-table
`(("sessionId" . ,(^session-id))
("sessionKey" . ,(^session-key))
("sessionToken" . ,(^session-token)))) ))
(url :reader url
:initform (cells:c? (get-url (^url-params))))))
|
0d44e5e6 |
(defgeneric session-credentials (source)
(:method ((source sts-result-handler))
|
72718ef5 |
(aws-sdk:make-credentials
:access-key-id (session-id source)
:secret-access-key (session-key source)
:session-token (session-token source))))
|
0d44e5e6 |
|
76ad2e41 |
(defun url-from-signin-token (signin-token &optional (region "us-west-2"))
(format nil #.(concatenate 'string
"https://signin.aws.amazon.com/federation?"
"Action=login&"
"Destination=https%3A%2F%2F~a.console.aws.amazon.com&"
"SigninToken=~a")
region
|
683ff82b |
signin-token))
|
32ddc779 |
(defun read-new-aws-credentials ()
(serapeum:collecting
(fresh-line *query-io*)
(format *query-io* "Access Key?")
(finish-output *query-io*)
(collect (read-line *query-io*))
(format *query-io* "Secret Access Key?")
(finish-output *query-io*)
(collect (read-line *query-io*))))
|
72718ef5 |
(defun run-process (user role token)
(with-retry* ((set-aws-credentials (lambda (access-key-id secret-access-key)
(setf aws:*session*
(aws:make-session
:credentials (aws:make-credentials
:access-key-id access-key-id
:secret-access-key secret-access-key
:session-token nil
:provider-name "restart-provider")))
(continue))
:interactive-function 'read-new-aws-credentials
:report-function (lambda (s)
(princ "Supply new AWS credentials" s))
:test-function (lambda (c)
(and (find-restart 'continue)
(typep c 'aws:no-credentials)))))
|
5aa9ad6e |
(let* ((api-result (do-auth user role token))
(parser (make-instance 'sts-result-handler
:credentials (serapeum:assocdr "Credentials" api-result
:test 'equal)))
|
72718ef5 |
(federation-url (url parser))
|
76ad2e41 |
(signin-token (gethash "SigninToken"
|
72718ef5 |
(yason:parse
(dexador:get federation-url)))))
(values signin-token
parser))))
|
683ff82b |
|
2b35742e |
(defun set-aws-credentials (access-key-id secret-access-key &optional condition)
|
72718ef5 |
(safely-invoke-restart 'set-aws-credentials condition access-key-id secret-access-key))
|
40c2d5d8 |
(defun sts-error-value (sts-response)
(let ((parsed-error (dom:first-child
(cxml:parse sts-response
(cxml-dom:make-dom-builder)))))
(flet ((get-node (path)
(dom:node-value
(dom:first-child
(xpath:first-node
(xpath:with-namespaces (("" "https://sts.amazonaws.com/doc/2011-06-15/"))
(xpath:evaluate path parsed-error)))))))
(values (get-node "//Error/Type")
(get-node "//Error/Code")
(get-node "//Error/Message")))))
|