MCPcopy
hub / github.com/smallstep/cli / doLoginIfNeeded

Function doLoginIfNeeded

command/ssh/proxycommand.go:100–216  ·  view source on GitHub ↗

doLoginIfNeeded check if the user is logged in looking at the ssh agent, if it's not it will do the login flow.

(ctx *cli.Context, subject string)

Source from the content-addressed store, hash-verified

98// doLoginIfNeeded check if the user is logged in looking at the ssh agent, if
99// it's not it will do the login flow.
100func doLoginIfNeeded(ctx *cli.Context, subject string) error {
101 templateData, err := flags.ParseTemplateData(ctx)
102 if err != nil {
103 return err
104 }
105
106 agent, err := sshutil.DialAgent()
107 if err != nil {
108 return err
109 }
110
111 client, err := cautils.NewClient(ctx)
112 if err != nil {
113 return err
114 }
115
116 // Check if a user key exists
117 if roots, err := client.SSHRoots(); err == nil && len(roots.UserKeys) > 0 {
118 userKeys := make([]ssh.PublicKey, len(roots.UserKeys))
119 for i, uk := range roots.UserKeys {
120 userKeys[i] = uk.PublicKey
121 }
122 exists, err := agent.HasKeys(sshutil.WithSignatureKey(userKeys), sshutil.WithRemoveExpiredCerts(time.Now()))
123 if err != nil {
124 return err
125 }
126 if exists {
127 return nil
128 }
129 }
130
131 // Do login flow
132 flow, err := cautils.NewCertificateFlow(ctx)
133 if err != nil {
134 return err
135 }
136
137 // There's not need to sanitize the principal, it should come from ssh.
138 principals := []string{subject}
139
140 // Make sure the validAfter is in the past. It avoids `Certificate
141 // invalid: not yet valid` errors if the times are not in sync
142 // perfectly.
143 validAfter := provisioner.NewTimeDuration(time.Now().Add(-1 * time.Minute))
144 validBefore := provisioner.TimeDuration{}
145
146 token, err := flow.GenerateSSHToken(ctx, subject, cautils.SSHUserSignType, principals, validAfter, validBefore)
147 if err != nil {
148 return err
149 }
150
151 // NOTE: For OIDC tokens the subject should always be the email. The
152 // provisioner is responsible for loading and setting the principals with
153 // the application of an Identity function.
154 if email, ok := tokenEmail(token); ok {
155 subject = email
156 }
157

Callers 1

proxycommandActionFunction · 0.85

Calls 14

GenerateSSHTokenMethod · 0.95
GetClientMethod · 0.95
ParseTemplateDataFunction · 0.92
DialAgentFunction · 0.92
NewClientFunction · 0.92
WithSignatureKeyFunction · 0.92
WithRemoveExpiredCertsFunction · 0.92
NewCertificateFlowFunction · 0.92
tokenEmailFunction · 0.85
HasKeysMethod · 0.80
AddCertificateMethod · 0.80
SSHRootsMethod · 0.65

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…