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
27 changes: 21 additions & 6 deletions api/utils/keys/hardwarekey/cliprompt.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,18 +58,33 @@ func NewCLIPrompt(w io.Writer, r prompt.StdinReader) *cliPrompt {

// AskPIN prompts the user for a PIN. If the requirement is [PINOptional],
// the prompt will offer the default PIN as a default value.
func (c *cliPrompt) AskPIN(ctx context.Context, requirement PINPromptRequirement, _ ContextualKeyInfo) (string, error) {
message := "Enter your YubiKey PIV PIN"
func (c *cliPrompt) AskPIN(ctx context.Context, requirement PINPromptRequirement, keyInfo ContextualKeyInfo) (string, error) {
msg := "Enter your YubiKey PIV PIN"

// The user may need to set their PIN for the first time during login,
// give them a hint to continue to setting the PIN.
if requirement == PINOptional {
message = "Enter your YubiKey PIV PIN [blank to use default PIN]"
msg += " [blank to use default PIN]"
}

// If this is a hardware key agent request with command context info,
// include the command in the prompt.
if keyInfo.Command != "" {
msg = fmt.Sprintf("%v to continue with command %q", msg, keyInfo.Command)
}
password, err := prompt.Password(ctx, c.writer, c.reader, message)

password, err := prompt.Password(ctx, c.writer, c.reader, msg)
return password, trace.Wrap(err)
}

// Touch prompts the user to touch the hardware key.
func (c *cliPrompt) Touch(_ context.Context, _ ContextualKeyInfo) error {
_, err := fmt.Fprintln(c.writer, "Tap your YubiKey")
func (c *cliPrompt) Touch(_ context.Context, keyInfo ContextualKeyInfo) error {
msg := "Tap your YubiKey"
if keyInfo.Command != "" {
msg = fmt.Sprintf("%v to continue with command %q", msg, keyInfo.Command)
}

_, err := fmt.Fprintln(c.writer, msg)
return trace.Wrap(err)
}

Expand Down
2 changes: 2 additions & 0 deletions api/utils/keys/hardwarekey/hardwarekey.go
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,8 @@ type ContextualKeyInfo struct {
// metadata certificate format, to ensure the agent doesn't provide access to
// non teleport client PIV keys.
AgentKey bool
// Command is the running command utilizing this key.
Command string
}

// SignatureAlgorithm is a signature key algorithm option.
Expand Down
1 change: 1 addition & 0 deletions api/utils/keys/hardwarekeyagent/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ func (s *agentService) Sign(ctx context.Context, req *hardwarekeyagentv1.SignReq
Username: req.KeyInfo.Username,
ClusterName: req.KeyInfo.ClusterName,
AgentKey: true,
Command: req.Command,
}

var signerOpts crypto.SignerOpts
Expand Down
12 changes: 11 additions & 1 deletion api/utils/keys/hardwarekeyagent/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,11 @@ import (
"crypto"
"crypto/rsa"
"crypto/x509"
"fmt"
"io"
"log/slog"
"os"
"strings"

"github.com/gravitational/trace"

Expand Down Expand Up @@ -120,6 +123,13 @@ func (s *Service) agentSign(ctx context.Context, ref *hardwarekey.PrivateKeyRef,
}
}

// Trim leading path (/ or \ on windows) from command for user readability.
command := os.Args[0]
if i := strings.LastIndexAny(command, "/\\"); i != -1 {
command = command[i+1:]
}
commandString := fmt.Sprintf("%v %v", command, strings.Join(os.Args[1:], " "))

req := &hardwarekeyagentv1.SignRequest{
Digest: digest,
Hash: hash,
Expand All @@ -136,7 +146,7 @@ func (s *Service) agentSign(ctx context.Context, ref *hardwarekey.PrivateKeyRef,
Username: keyInfo.Username,
ClusterName: keyInfo.ClusterName,
},
// TODO: Add command to sign request for prompt context.
Command: commandString,
}

resp, err := s.agentClient.Sign(ctx, req)
Expand Down
108 changes: 66 additions & 42 deletions gen/proto/go/teleport/lib/teleterm/v1/tshd_events_service.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading