Skip to content

Commit

Permalink
Merge pull request #777 from nickvollmar/google-prompt-extra-number
Browse files Browse the repository at this point in the history
feat(googleapps): add support for 'extra number' in device push challenges
  • Loading branch information
mapkon authored Mar 30, 2023
2 parents 3f84884 + 5dd380e commit a67ba9c
Show file tree
Hide file tree
Showing 3 changed files with 128 additions and 1 deletion.
96 changes: 96 additions & 0 deletions pkg/provider/googleapps/example/challenge-extra-number.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
<!doctype html>
<html lang="en" dir="ltr">

<head>
<base href="https://accounts.google.com/">
<title>Google Accounts</title>
</head>

<body id="yDmH0d">
<div class="s2h6df">
<div class="JYXKFb IA6off">
<div class="ql1pVb ZnXjYc EaNIqc">
<div class="omTHz" aria-label="Google"></div>
</div>
</div>
<div class="RgEUV ZnXjYc EaNIqc JhUD8d">
<div>
<div class="glT6eb">
<div jsname="IDL96d"><h1>2-Step Verification</h1></div>
<div jsname="jqgtP"><h2>This extra step shows it’s really you trying to sign in</h2></div>
</div>
</div>
<div class="LJtPoc" jsname="Ki8mld">
<form method="POST" id="challenge" action="/signin/challenge/dp/6" jsname="rzWj5"
jscontroller="HNBfvc" jsaction="submit:zbvklb" jsshadow=""><span jsslot=""><input
name="challengeId" type="hidden" id="challengeId" value="6"/><input name="challengeType"
type="hidden"
id="challengeType"
value="39"/><input
name="checkConnection" type="hidden" value="youtube:930:1"/><input name="continue"
type="hidden"
value="https://accounts.google.com/o/saml2/initsso?idpid=XXXXXX&amp;spid=YYYYYY&amp;forceauthn=false&amp;from_login=1&amp;as=123123-w"/><input
name="flowName" type="hidden" value="WEB_SETUP_GLIF"/><input name="faa" type="hidden"
value="1"/><input name="hl"
type="hidden"
value="en"/><input
name="oauth" type="hidden" value="1"/><input name="sarp" type="hidden" value="1"/><input
name="scc" type="hidden" value="1"/><input name="TL" type="hidden"
value="XXXXXX"/><input
type="hidden" name="gxf" id="gxf"
value="XXXXXX:1529303586210"/><div jsname="KrwUDc"><div
jsname="wsPcPe"><img jsname="TqVmm" class="JC07Dd"
src="//ssl.gstatic.com/accounts/marc/open_notification_android.gif"
alt=""/><div class="EGmPD" jsname="BCqkPb">Open the Gmail app on Nicholas’s iPhone</div><div
class="VnJmLc" jsname="NhJ5Dd">Google sent a notification to your Nicholas’s iPhone. Open the Gmail app, tap <strong>Yes</strong> on the prompt, then tap <strong>89</strong> on your phone to verify it’s you.<div
class="PrDSKc"></div><div jsname="feLNVc" class="NOZDsb">89</div></div><p>After you’ve finished on your phone, press the button below.</p><button
type="submit" class="MK9CEd MVpUfe" jsname="M2UYVd" jscontroller="rrJN5c"
jsaction="aJAbCd:zbvklb" formnovalidate="" value="submit" id="submit">I have responded from my phone</button><div
style="display: none;"><a href="null" target="_blank">null</a></div><div
class="ARshqb"><input type="checkbox" name="TrustDevice" id="trustDevice" class="aCOJmf"
checked=""/><span>Don’t ask again on this device</span><div
class="Bfmfyc" role="tooltip"><div class="x7qQqf"></div><div class="hzC8Lb">For your convenience, keep this checked. On shared devices, additional precautions are recommended. <a
href="https://support.google.com/accounts/?p=securesignin&amp;hl=en" target="_blank">Learn more</a></div></div></div></div></div></span>
</form>
</div>
<div class=" KSYbxc ">
<form method="POST" action="/signin/challenge/skip"><input name="challengeId" type="hidden"
value="6"/><input
name="checkConnection" type="hidden" value="youtube:930:1"/><input name="continue"
type="hidden"
value="https://accounts.google.com/o/saml2/initsso?idpid=XXXXXX&amp;spid=YYYYYY&amp;forceauthn=false&amp;hl=en&amp;loc=US&amp;from_login=1&amp;as=123123-w"/><input
name="flowName" type="hidden" value="WEB_SETUP_GLIF"/><input name="faa" type="hidden"
value="1"/><input name="hl"
type="hidden"
value="en"/><input
name="oauth" type="hidden" value="1"/><input name="sarp" type="hidden" value="1"/><input
name="scc" type="hidden" value="1"/><input name="TL" type="hidden"
value="XXXXXX-XXXXXX-XXXXXX-XXXXXX-XXXXXX"/><input
type="hidden" name="gxf" id="gxf"
value="XXXXXX:1529303586210"/><input id="skipChallenge"
type="submit"
jsname="rwR6T"
class="g1C42c"
value="Try another way to sign in"/>
</form>
</div>
<div class="M0leCe"><span jsname="tODuDc">[email protected]</span><a
href="https://accounts.google.com/AccountChooser?continue=https%3A%2F%2Faccounts.google.com%2Fo%2Fsaml2%2Finitsso%3Fidpid%3DXXXXXX%26spid%3DYYYYYY%26forceauthn%3Dfalse%26hl%3Den%26loc%3DUS%26from_login%3D1%26as%3D123123-w&amp;hl=en&amp;oauth=1&amp;sarp=1&amp;faa=1"
class="vHOx3b">Use a different account</a></div>
</div>
<div class="zOB73">
<div class="SEK88d ZnXjYc EaNIqc">
<ul id="footer-list">
<li>Google</li>
<li><a href="https://accounts.google.com/TOS?loc=US&amp;hl=en&amp;privacy=true"
target="_blank">Privacy</a></li>
<li><a href="https://accounts.google.com/TOS?loc=US&amp;hl=en" target="_blank">Terms</a>
</li>
</ul>
<div id="lang-vis-control" jscontroller="nCyKU" jsaction="change:iktSbe"></div>
</div>
</div>
</div>
<div class="lDwpOe"></div>
</body>
</html>
17 changes: 16 additions & 1 deletion pkg/provider/googleapps/googleapps.go
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,14 @@ func (kc *Client) loadChallengePage(submitURL string, referer string, authForm u
return kc.loadResponsePage(secondActionURL, submitURL, responseForm)

case strings.Contains(secondActionURL, "challenge/dp/"): // handle device push challenge
log.Print("Check your phone - after you have confirmed response press ENTER to continue.")
if extraNumber := extractDevicePushExtraNumber(doc); extraNumber != "" {
log.Println("Check your phone and tap 'Yes' on the prompt, then tap the number:")
log.Printf("\t%v\n", extraNumber)
log.Println("Then press ENTER to continue.")
} else {
log.Print("Check your phone and tap 'Yes' on the prompt. Then press ENTER to continue.")
}

_, err := bufio.NewReader(os.Stdin).ReadBytes('\n')
if err != nil {
return nil, errors.Wrap(err, "error reading new line \\n")
Expand Down Expand Up @@ -737,3 +744,11 @@ func isAppId(val string) string {
}
return appId
}

func extractDevicePushExtraNumber(doc *goquery.Document) string {
extraNumber := ""
doc.Find("div[jsname=feLNVc]").Each(func(_ int, s *goquery.Selection) {
extraNumber = s.Text()
})
return extraNumber
}
16 changes: 16 additions & 0 deletions pkg/provider/googleapps/googleapps_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -171,3 +171,19 @@ func TestWrongPassword(t *testing.T) {
txt := doc.Selection.Find("#" + passwordErrorId).Text()
require.NotEqual(t, "", txt)
}

func TestExtractDevicePushExtraNumber(t *testing.T) {
data1, err := os.ReadFile("example/challenge-extra-number.html")
require.Nil(t, err)
doc1, err := goquery.NewDocumentFromReader(bytes.NewReader(data1))
require.Nil(t, err)
require.Equal(t, "89", extractDevicePushExtraNumber(doc1))

for _, filename := range []string{"example/challenge-prompt.html", "example/challenge-totp.html"} {
data2, err := os.ReadFile(filename)
require.Nil(t, err)
doc2, err := goquery.NewDocumentFromReader(bytes.NewReader(data2))
require.Nil(t, err)
require.Equal(t, "", extractDevicePushExtraNumber(doc2))
}
}

0 comments on commit a67ba9c

Please sign in to comment.