Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions lib/client/mfa/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -184,8 +184,8 @@ func (c *CLIPrompt) filterMFAMethods(state mfaPromptState, isPerSessionMFA bool,
if len(availableMethods) > len(chosenMethods) && len(chosenMethods) > 0 && !userSpecifiedMethod {
availableMethodsString := strings.ToLower(strings.Join(availableMethods, ","))
const msg = "" +
"Available MFA methods [%v]. Continuing with %v.\n" +
"If you wish to perform MFA with another method, specify with flag --mfa-mode=<%v> or environment variable TELEPORT_MFA_MODE=<%v>.\n\n"
"Available MFA methods [%v]. Continuing with %v.\r\n" +
"If you wish to perform MFA with another method, specify with flag --mfa-mode=<%v> or environment variable TELEPORT_MFA_MODE=<%v>.\r\n\r\n"
fmt.Fprintf(c.writer(), msg, strings.Join(availableMethods, ", "), strings.Join(chosenMethods, " and "), availableMethodsString, availableMethodsString)
}

Expand All @@ -195,7 +195,7 @@ func (c *CLIPrompt) filterMFAMethods(state mfaPromptState, isPerSessionMFA bool,
// Run prompts the user to complete an MFA authentication challenge.
func (c *CLIPrompt) Run(ctx context.Context, chal *proto.MFAAuthenticateChallenge) (*proto.MFAAuthenticateResponse, error) {
if c.cfg.PromptReason != "" {
fmt.Fprintln(c.writer(), c.cfg.PromptReason)
fmt.Fprintf(c.writer(), "%s\r\n", c.cfg.PromptReason)
}

// Initialize prompt state from the challenge.
Expand Down Expand Up @@ -303,7 +303,7 @@ func (c *CLIPrompt) promptWithFallback(ctx context.Context, chal *proto.MFAAuthe

// If we're retrying after a failure, inform the user.
if lastErr != nil {
fmt.Fprintf(c.writer(), "Attempting MFA authentication with %s\n", currentMethod)
fmt.Fprintf(c.writer(), "Attempting MFA authentication with %s\r\n", currentMethod)
}

// Perform the chosen ceremony based on the filtered state.
Expand Down Expand Up @@ -346,7 +346,7 @@ func (c *CLIPrompt) promptWithFallback(ctx context.Context, chal *proto.MFAAuthe
}

// Print error message about the failure.
fmt.Fprintf(c.writer(), "MFA authentication with %s failed, check logs for details\n", currentMethod)
fmt.Fprintf(c.writer(), "MFA authentication with %s failed, check logs for details\r\n", currentMethod)

// Don't fall back if the context is done (e.g. user canceled or request timed out).
if ctx.Err() != nil {
Expand Down Expand Up @@ -426,7 +426,7 @@ func (c *CLIPrompt) promptWebauthnAndOTP(ctx context.Context, chal *proto.MFAAut
} else {
message = fmt.Sprintf("Tap any %ssecurity key or enter a code from a %sOTP device", c.promptDevicePrefix(), c.promptDevicePrefix())
}
fmt.Fprintln(c.writer(), message)
fmt.Fprintf(c.writer(), "%s\r\n", message)

// Prepare to fire OTP goroutine.
otpCtx, otpCancel := context.WithCancel(ctx)
Expand Down
59 changes: 29 additions & 30 deletions lib/client/mfa/cli_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,8 +186,8 @@ func TestCLIPrompt(t *testing.T) {
{
name: "OK prefer webauthn over sso",
expectStdOut: "" +
"Available MFA methods [WEBAUTHN, SSO]. Continuing with WEBAUTHN.\n" +
"If you wish to perform MFA with another method, specify with flag --mfa-mode=<webauthn,sso> or environment variable TELEPORT_MFA_MODE=<webauthn,sso>.\n\n" +
"Available MFA methods [WEBAUTHN, SSO]. Continuing with WEBAUTHN.\r\n" +
"If you wish to perform MFA with another method, specify with flag --mfa-mode=<webauthn,sso> or environment variable TELEPORT_MFA_MODE=<webauthn,sso>.\r\n\r\n" +
"Tap any security key\n",
challenge: &proto.MFAAuthenticateChallenge{
WebauthnChallenge: &webauthnpb.CredentialAssertion{},
Expand All @@ -202,9 +202,9 @@ func TestCLIPrompt(t *testing.T) {
{
name: "OK prefer webauthn+otp over sso",
expectStdOut: "" +
"Available MFA methods [WEBAUTHN, SSO, OTP]. Continuing with WEBAUTHN and OTP.\n" +
"If you wish to perform MFA with another method, specify with flag --mfa-mode=<webauthn,sso,otp> or environment variable TELEPORT_MFA_MODE=<webauthn,sso,otp>.\n\n" +
"Tap any security key or enter a code from a OTP device\n",
"Available MFA methods [WEBAUTHN, SSO, OTP]. Continuing with WEBAUTHN and OTP.\r\n" +
"If you wish to perform MFA with another method, specify with flag --mfa-mode=<webauthn,sso,otp> or environment variable TELEPORT_MFA_MODE=<webauthn,sso,otp>.\r\n\r\n" +
"Tap any security key or enter a code from a OTP device\r\n",
challenge: &proto.MFAAuthenticateChallenge{
WebauthnChallenge: &webauthnpb.CredentialAssertion{},
Comment thread
danielashare marked this conversation as resolved.
TOTP: &proto.TOTPChallenge{},
Expand All @@ -222,8 +222,8 @@ func TestCLIPrompt(t *testing.T) {
{
name: "OK prefer sso over otp",
expectStdOut: "" +
"Available MFA methods [SSO, OTP]. Continuing with SSO.\n" +
"If you wish to perform MFA with another method, specify with flag --mfa-mode=<sso,otp> or environment variable TELEPORT_MFA_MODE=<sso,otp>.\n\n",
"Available MFA methods [SSO, OTP]. Continuing with SSO.\r\n" +
"If you wish to perform MFA with another method, specify with flag --mfa-mode=<sso,otp> or environment variable TELEPORT_MFA_MODE=<sso,otp>.\r\n\r\n",
challenge: &proto.MFAAuthenticateChallenge{
TOTP: &proto.TOTPChallenge{},
SSOChallenge: &proto.SSOChallenge{},
Expand All @@ -240,8 +240,8 @@ func TestCLIPrompt(t *testing.T) {
{
name: "OK prefer webauthn over otp when stdin hijack disallowed",
expectStdOut: "" +
"Available MFA methods [WEBAUTHN, OTP]. Continuing with WEBAUTHN.\n" +
"If you wish to perform MFA with another method, specify with flag --mfa-mode=<webauthn,otp> or environment variable TELEPORT_MFA_MODE=<webauthn,otp>.\n\n" +
"Available MFA methods [WEBAUTHN, OTP]. Continuing with WEBAUTHN.\r\n" +
"If you wish to perform MFA with another method, specify with flag --mfa-mode=<webauthn,otp> or environment variable TELEPORT_MFA_MODE=<webauthn,otp>.\r\n\r\n" +
"Tap any security key\n",
challenge: &proto.MFAAuthenticateChallenge{
WebauthnChallenge: &webauthnpb.CredentialAssertion{},
Expand All @@ -256,9 +256,9 @@ func TestCLIPrompt(t *testing.T) {
{
name: "OK webauthn or otp with stdin hijack allowed, choose webauthn",
expectStdOut: "" +
"Available MFA methods [WEBAUTHN, SSO, OTP]. Continuing with WEBAUTHN and OTP.\n" +
"If you wish to perform MFA with another method, specify with flag --mfa-mode=<webauthn,sso,otp> or environment variable TELEPORT_MFA_MODE=<webauthn,sso,otp>.\n\n" +
"Tap any security key or enter a code from a OTP device\n",
"Available MFA methods [WEBAUTHN, SSO, OTP]. Continuing with WEBAUTHN and OTP.\r\n" +
"If you wish to perform MFA with another method, specify with flag --mfa-mode=<webauthn,sso,otp> or environment variable TELEPORT_MFA_MODE=<webauthn,sso,otp>.\r\n\r\n" +
"Tap any security key or enter a code from a OTP device\r\n",
challenge: &proto.MFAAuthenticateChallenge{
WebauthnChallenge: &webauthnpb.CredentialAssertion{},
TOTP: &proto.TOTPChallenge{},
Expand All @@ -276,9 +276,9 @@ func TestCLIPrompt(t *testing.T) {
{
name: "OK webauthn or otp with stdin hijack allowed, choose otp",
expectStdOut: "" +
"Available MFA methods [WEBAUTHN, SSO, OTP]. Continuing with WEBAUTHN and OTP.\n" +
"If you wish to perform MFA with another method, specify with flag --mfa-mode=<webauthn,sso,otp> or environment variable TELEPORT_MFA_MODE=<webauthn,sso,otp>.\n\n" +
"Tap any security key or enter a code from a OTP device\n",
"Available MFA methods [WEBAUTHN, SSO, OTP]. Continuing with WEBAUTHN and OTP.\r\n" +
"If you wish to perform MFA with another method, specify with flag --mfa-mode=<webauthn,sso,otp> or environment variable TELEPORT_MFA_MODE=<webauthn,sso,otp>.\r\n\r\n" +
"Tap any security key or enter a code from a OTP device\r\n",
stdin: "123456",
challenge: &proto.MFAAuthenticateChallenge{
WebauthnChallenge: &webauthnpb.CredentialAssertion{},
Expand All @@ -298,31 +298,31 @@ func TestCLIPrompt(t *testing.T) {
},
{
name: "NOK no webauthn response",
expectStdOut: "Tap any security key\nMFA authentication with WEBAUTHN failed, check logs for details\n",
expectStdOut: "Tap any security key\nMFA authentication with WEBAUTHN failed, check logs for details\r\n",
challenge: &proto.MFAAuthenticateChallenge{
WebauthnChallenge: &webauthnpb.CredentialAssertion{},
},
expectErr: context.DeadlineExceeded,
},
{
name: "NOK no sso response",
expectStdOut: "MFA authentication with SSO failed, check logs for details\n",
expectStdOut: "MFA authentication with SSO failed, check logs for details\r\n",
challenge: &proto.MFAAuthenticateChallenge{
SSOChallenge: &proto.SSOChallenge{},
},
expectErr: context.DeadlineExceeded,
},
{
name: "NOK no otp response",
expectStdOut: "Enter an OTP code from a device:\nMFA authentication with OTP failed, check logs for details\n",
expectStdOut: "Enter an OTP code from a device:\nMFA authentication with OTP failed, check logs for details\r\n",
challenge: &proto.MFAAuthenticateChallenge{
TOTP: &proto.TOTPChallenge{},
},
expectErr: context.DeadlineExceeded,
},
{
name: "NOK no webauthn or otp response",
expectStdOut: "Tap any security key or enter a code from a OTP device\nMFA authentication with WEBAUTHN failed, check logs for details\n",
expectStdOut: "Tap any security key or enter a code from a OTP device\r\nMFA authentication with WEBAUTHN failed, check logs for details\r\n",
challenge: &proto.MFAAuthenticateChallenge{
WebauthnChallenge: &webauthnpb.CredentialAssertion{},
TOTP: &proto.TOTPChallenge{},
Expand All @@ -341,10 +341,9 @@ func TestCLIPrompt(t *testing.T) {
modifyPromptConfig: func(cfg *mfa.CLIPromptConfig) {
cfg.AllowStdinHijack = true
},
expectStdOut: `Tap any security key or enter a code from a OTP device
Detected security key tap
Enter your security key PIN:
`,
expectStdOut: "Tap any security key or enter a code from a OTP device\r\n" +
"Detected security key tap\n" +
"Enter your security key PIN:\n",
expectResp: &proto.MFAAuthenticateResponse{
Response: &proto.MFAAuthenticateResponse_Webauthn{
Webauthn: &webauthnpb.CredentialAssertionResponse{
Expand Down Expand Up @@ -531,10 +530,10 @@ Enter your security key PIN:
{
name: "NOK browser fallback skipped on windows when not preferred",
expectStdOut: "" +
"Available MFA methods [WEBAUTHN, BROWSER]. Continuing with WEBAUTHN.\n" +
"If you wish to perform MFA with another method, specify with flag --mfa-mode=<webauthn,browser> or environment variable TELEPORT_MFA_MODE=<webauthn,browser>.\n\n" +
"Available MFA methods [WEBAUTHN, BROWSER]. Continuing with WEBAUTHN.\r\n" +
"If you wish to perform MFA with another method, specify with flag --mfa-mode=<webauthn,browser> or environment variable TELEPORT_MFA_MODE=<webauthn,browser>.\r\n\r\n" +
"Tap any security key\n" +
"MFA authentication with WEBAUTHN failed, check logs for details\n",
"MFA authentication with WEBAUTHN failed, check logs for details\r\n",
challenge: &proto.MFAAuthenticateChallenge{
WebauthnChallenge: &webauthnpb.CredentialAssertion{},
BrowserMFAChallenge: &proto.BrowserMFAChallenge{},
Expand Down Expand Up @@ -564,11 +563,11 @@ Enter your security key PIN:
{
name: "OK prompt fallback webauthn > SSO > browser MFA",
expectStdOut: "" +
"Available MFA methods [WEBAUTHN, BROWSER]. Continuing with WEBAUTHN.\n" +
"If you wish to perform MFA with another method, specify with flag --mfa-mode=<webauthn,browser> or environment variable TELEPORT_MFA_MODE=<webauthn,browser>.\n\n" +
"Available MFA methods [WEBAUTHN, BROWSER]. Continuing with WEBAUTHN.\r\n" +
"If you wish to perform MFA with another method, specify with flag --mfa-mode=<webauthn,browser> or environment variable TELEPORT_MFA_MODE=<webauthn,browser>.\r\n\r\n" +
"Tap any security key\n" +
"MFA authentication with WEBAUTHN failed, check logs for details\n" +
"Attempting MFA authentication with BROWSER\n",
"MFA authentication with WEBAUTHN failed, check logs for details\r\n" +
"Attempting MFA authentication with BROWSER\r\n",
challenge: &proto.MFAAuthenticateChallenge{
WebauthnChallenge: &webauthnpb.CredentialAssertion{},
BrowserMFAChallenge: &proto.BrowserMFAChallenge{},
Expand Down
6 changes: 3 additions & 3 deletions lib/client/sso/redirector.go
Original file line number Diff line number Diff line change
Expand Up @@ -271,16 +271,16 @@ func (rd *Redirector) processLoginURL(redirectURL, postForm string) error {

// If a command was found to launch the browser, create and start it.
if err := OpenURLInBrowser(rd.Browser, clickableURL); err != nil {
fmt.Fprintf(rd.Stderr, "Failed to open a browser window for login: %v\n", err)
fmt.Fprintf(rd.Stderr, "Failed to open a browser window for login: %v\r\n", err)
}

// Print the URL to the screen, in case the command that launches the browser did not run.
// If Browser is set to the special string teleport.BrowserNone, no browser will be opened.
if rd.Browser == teleport.BrowserNone {
fmt.Fprintf(rd.Stderr, "Use the following URL to authenticate:\n %v\n", clickableURL)
fmt.Fprintf(rd.Stderr, "Use the following URL to authenticate:\r\n %v\r\n", clickableURL)
} else {
fmt.Fprintf(rd.Stderr, "If browser window does not open automatically, open it by ")
fmt.Fprintf(rd.Stderr, "clicking on the link:\n %v\n", clickableURL)
fmt.Fprintf(rd.Stderr, "clicking on the link:\r\n %v\r\n", clickableURL)
}

return nil
Expand Down
Loading