Documentation ¶
Overview ¶
TODO refactor?
Index ¶
- type DuoClient
- func (d *DuoClient) ChallengeU2f(verificationHost string) (err error)
- func (d *DuoClient) DoAuth(tx string, inputSid string, inputCertsURL string) (sid string, err error)
- func (d *DuoClient) DoCallback(auth string) (err error)
- func (d *DuoClient) DoPrompt(sid string) (txid string, err error)
- func (d *DuoClient) DoRedirect(url string, sid string) (string, error)
- func (d *DuoClient) DoStatus(txid, sid string) (auth string, status StatusResp, err error)
- func (d *DuoClient) DoU2FPromptFinish(sid string, sessionID string, resp *u2fhost.AuthenticateResponse) (txid string, err error)
- type FacetResponse
- type PromptResp
- type ResponseData
- type StatusResp
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type DuoClient ¶
type DuoClient struct { Host string Signature string Callback string Device string StateToken string }
func (*DuoClient) ChallengeU2f ¶
ChallengeU2F performs multiple call against an obscure Duo API.
Normally you use an iframe to perform those calls but here the main idea is to fake Duo is order to use the CLI without any browser.
The function perform three successive calls to retry the challenge data. Wait for the user to perform the verification (Duo Push or Yubikey). And then call the callback url.
TODO: Use a Context to gracefully shutdown the thing and have a nice timeout
func (*DuoClient) DoAuth ¶
func (d *DuoClient) DoAuth(tx string, inputSid string, inputCertsURL string) (sid string, err error)
DoAuth sends a POST request to the Duo /frame/web/v1/auth endpoint. The request will not follow the redirect and retrieve the location from the HTTP header. From the Location we get the Duo Session ID (sid) required for the rest of the communication. In some integrations of Duo, an empty POST to the Duo /frame/web/v1/auth endpoint will return StatusOK with a form of hidden inputs. In that case, we redo the POST with data from the hidden inputs, which triggers the usual redirect/location flow and allows for a successful authentication.
The function will return the sid
func (*DuoClient) DoCallback ¶
DoCallback send a POST request to the Okta callback url defined in the DuoClient
The callback request requires the stateToken from Okta and a sig_response built from the precedent requests.
func (*DuoClient) DoPrompt ¶
DoPrompt sends a POST request to the Duo /frame/promt endpoint
The functions returns the Duo transaction ID which is different from the Okta transaction ID
func (*DuoClient) DoRedirect ¶
func (*DuoClient) DoStatus ¶
func (d *DuoClient) DoStatus(txid, sid string) (auth string, status StatusResp, err error)
DoStatus sends a POST request against the Duo /frame/status endpoint
The function returns the auth string required for the Okta Callback if the request succeeded.
func (*DuoClient) DoU2FPromptFinish ¶
func (d *DuoClient) DoU2FPromptFinish(sid string, sessionID string, resp *u2fhost.AuthenticateResponse) (txid string, err error)
DoPrompt sends a POST request to the Duo /frame/promt endpoint
The functions returns the Duo transaction ID which is different from the Okta transaction ID
type FacetResponse ¶
type PromptResp ¶
type ResponseData ¶
type ResponseData struct { ClientData string `json:"clientData"` KeyHandle string `json:"keyHandle"` SessionID string `json:"sessionId"` SignatureData string `json:"signatureData"` }
It's same as u2fhost.AuthenticateResponse but needs SessionID for Duo/Okta
type StatusResp ¶
type StatusResp struct { Response struct { U2FSignRequest []struct { Version string `json:"version"` Challenge string `json:"challenge"` AppID string `json:"appId"` KeyHandle string `json:"keyHandle"` SessionID string `json:"sessionId"` } `json:"u2f_sign_request"` Status string `json:"status"` StatusCode string `json:"status_code"` Reason string `json:"reason"` Parent string `json:"parent"` Cookie string `json:"cookie"` Result string `json:"result"` ResultURL string `json:"result_url"` } `json:"response"` Stat string `json:"stat"` }