Skip to content

Commit

Permalink
Merge pull request Versent#406 from v3rm0n/google-mfa-token
Browse files Browse the repository at this point in the history
Allow passing MFA token for GoogleApps
  • Loading branch information
Mark Wolfe authored Jan 23, 2020
2 parents 6187b37 + 3d7afef commit 940f6b6
Show file tree
Hide file tree
Showing 4 changed files with 15 additions and 11 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ Flags:
--password=PASSWORD The password used to login. (env:
SAML2AWS_PASSWORD)
--mfa-token=MFA-TOKEN The current MFA token (supported in Keycloak,
ADFS). (env: SAML2AWS_MFA_TOKEN)
ADFS, GoogleApps). (env: SAML2AWS_MFA_TOKEN)
--role=ROLE The ARN of the role to assume. (env:
SAML2AWS_ROLE)
--aws-urn=AWS-URN The URN used by SAML when you login. (env:
Expand Down
2 changes: 1 addition & 1 deletion cmd/saml2aws/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ func main() {
app.Flag("url", "The URL of the SAML IDP server used to login. (env: SAML2AWS_URL)").Envar("SAML2AWS_URL").StringVar(&commonFlags.URL)
app.Flag("username", "The username used to login. (env: SAML2AWS_USERNAME)").Envar("SAML2AWS_USERNAME").StringVar(&commonFlags.Username)
app.Flag("password", "The password used to login. (env: SAML2AWS_PASSWORD)").Envar("SAML2AWS_PASSWORD").StringVar(&commonFlags.Password)
app.Flag("mfa-token", "The current MFA token (supported in Keycloak, ADFS). (env: SAML2AWS_MFA_TOKEN)").Envar("SAML2AWS_MFA_TOKEN").StringVar(&commonFlags.MFAToken)
app.Flag("mfa-token", "The current MFA token (supported in Keycloak, ADFS, GoogleApps). (env: SAML2AWS_MFA_TOKEN)").Envar("SAML2AWS_MFA_TOKEN").StringVar(&commonFlags.MFAToken)
app.Flag("role", "The ARN of the role to assume. (env: SAML2AWS_ROLE)").Envar("SAML2AWS_ROLE").StringVar(&commonFlags.RoleArn)
app.Flag("aws-urn", "The URN used by SAML when you login. (env: SAML2AWS_AWS_URN)").Envar("SAML2AWS_AWS_URN").StringVar(&commonFlags.AmazonWebservicesURN)
app.Flag("skip-prompt", "Skip prompting for parameters during login.").BoolVar(&commonFlags.SkipPrompt)
Expand Down
17 changes: 10 additions & 7 deletions pkg/provider/googleapps/googleapps.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ func (kc *Client) Authenticate(loginDetails *creds.LoginDetails) (string, error)
authForm.Set("Passwd", loginDetails.Password)
authForm.Set("rawidentifier", loginDetails.Username)

responseDoc, err := kc.loadChallengePage(passwordURL+"?hl=en&loc=US", authURL, authForm)
responseDoc, err := kc.loadChallengePage(passwordURL+"?hl=en&loc=US", authURL, authForm, loginDetails)
if err != nil {
return "", errors.Wrap(err, "error loading challenge page")
}
Expand Down Expand Up @@ -91,7 +91,7 @@ func (kc *Client) Authenticate(loginDetails *creds.LoginDetails) (string, error)
captchaForm.Set("Passwd", loginDetails.Password)
captchaForm.Set("logincaptcha", captcha)

responseDoc, err = kc.loadChallengePage(captchaURL+"?hl=en&loc=US", captchaURL, captchaForm)
responseDoc, err = kc.loadChallengePage(captchaURL+"?hl=en&loc=US", captchaURL, captchaForm, loginDetails)
if err != nil {
return "", errors.Wrap(err, "error loading challenge page")
}
Expand Down Expand Up @@ -186,7 +186,7 @@ func (kc *Client) loadLoginPage(submitURL string, referer string, authForm url.V
return loginURL, loginForm, err
}

func (kc *Client) loadChallengePage(submitURL string, referer string, authForm url.Values) (*goquery.Document, error) {
func (kc *Client) loadChallengePage(submitURL string, referer string, authForm url.Values, loginDetails *creds.LoginDetails) (*goquery.Document, error) {

req, err := http.NewRequest("POST", submitURL, strings.NewReader(authForm.Encode()))
if err != nil {
Expand Down Expand Up @@ -236,7 +236,10 @@ func (kc *Client) loadChallengePage(submitURL string, referer string, authForm u
switch {
case strings.Contains(secondActionURL, "challenge/totp/"): // handle TOTP challenge

var token = prompter.RequestSecurityCode("000000")
var token = loginDetails.MFAToken
if token == "" {
token = prompter.RequestSecurityCode("000000")
}

responseForm.Set("Pin", token)
responseForm.Set("TrustDevice", "on") // Don't ask again on this computer
Expand Down Expand Up @@ -303,15 +306,15 @@ func (kc *Client) loadChallengePage(submitURL string, referer string, authForm u

u.Path = skipActionURL

return kc.loadAlternateChallengePage(u.String(), submitURL, skipResponseForm)
return kc.loadAlternateChallengePage(u.String(), submitURL, skipResponseForm, loginDetails)

}

return doc, nil

}

func (kc *Client) loadAlternateChallengePage(submitURL string, referer string, authForm url.Values) (*goquery.Document, error) {
func (kc *Client) loadAlternateChallengePage(submitURL string, referer string, authForm url.Values, loginDetails *creds.LoginDetails) (*goquery.Document, error) {

req, err := http.NewRequest("POST", submitURL, strings.NewReader(authForm.Encode()))
if err != nil {
Expand Down Expand Up @@ -365,7 +368,7 @@ func (kc *Client) loadAlternateChallengePage(submitURL string, referer string, a
u, _ := url.Parse(submitURL)
u.Path = newActionURL

return kc.loadChallengePage(u.String(), submitURL, responseForm)
return kc.loadChallengePage(u.String(), submitURL, responseForm, loginDetails)
}

func (kc *Client) postJSON(submitURL string, values map[string]string, referer string) (*http.Response, error) {
Expand Down
5 changes: 3 additions & 2 deletions pkg/provider/googleapps/googleapps_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (

"github.com/PuerkitoBio/goquery"
"github.com/stretchr/testify/require"
"github.com/versent/saml2aws/pkg/creds"
"github.com/versent/saml2aws/pkg/provider"
)

Expand Down Expand Up @@ -81,10 +82,10 @@ func TestChallengePage(t *testing.T) {
defer ts.Close()

kc := Client{client: &provider.HTTPClient{Client: http.Client{}}}
// loginDetails := &creds.LoginDetails{URL: ts.URL, Username: "test", Password: "test123"}
loginDetails := &creds.LoginDetails{URL: ts.URL, Username: "test", Password: "test123"}
authForm := url.Values{}

challengeDoc, err := kc.loadChallengePage(ts.URL, "https://accounts.google.com/signin/challenge/sl/password", authForm)
challengeDoc, err := kc.loadChallengePage(ts.URL, "https://accounts.google.com/signin/challenge/sl/password", authForm, loginDetails)
require.Nil(t, err)
require.NotNil(t, challengeDoc)
}
Expand Down

0 comments on commit 940f6b6

Please sign in to comment.