|
|
|
|
@ -541,6 +541,22 @@ func (srv *server) expandDelegateURL(ci *sshConnInfo, lu *user.User, actionURL s |
|
|
|
|
).Replace(actionURL) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (ci *sshConnInfo) expandPublicKeyURL(pubKeyURL string) string { |
|
|
|
|
if !strings.Contains(pubKeyURL, "$") { |
|
|
|
|
return pubKeyURL |
|
|
|
|
} |
|
|
|
|
var localPart string |
|
|
|
|
var loginName string |
|
|
|
|
if ci.uprof != nil { |
|
|
|
|
loginName = ci.uprof.LoginName |
|
|
|
|
localPart, _, _ = strings.Cut(loginName, "@") |
|
|
|
|
} |
|
|
|
|
return strings.NewReplacer( |
|
|
|
|
"$LOGINNAME_EMAIL", loginName, |
|
|
|
|
"$LOGINNAME_LOCALPART", localPart, |
|
|
|
|
).Replace(pubKeyURL) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// sshSession is an accepted Tailscale SSH session.
|
|
|
|
|
type sshSession struct { |
|
|
|
|
ssh.Session |
|
|
|
|
@ -1011,7 +1027,7 @@ func principalMatchesPubKey(p *tailcfg.SSHPrincipal, ci *sshConnInfo, clientPubK |
|
|
|
|
return false, fmt.Errorf("no public key fetcher") |
|
|
|
|
} |
|
|
|
|
var err error |
|
|
|
|
knownKeys, err = ci.fetchPublicKeysURL(knownKeys[0]) |
|
|
|
|
knownKeys, err = ci.fetchPublicKeysURL(ci.expandPublicKeyURL(knownKeys[0])) |
|
|
|
|
if err != nil { |
|
|
|
|
return false, err |
|
|
|
|
} |
|
|
|
|
|