certificates/templates/values.go
Mariano Cano 5d87201abc
Ignore principals validations with OIDC
This commit will ignore principals validation when an OIDC provisioner
is used. When the principals in the server does not match the principals
given the validation was failing, even if the proper principals were set
by templates or webhooks. With this change OIDC will not validate the
principals and just set the default ones (name, name@example.org) plus
the ones in the templates.

This commit also includes a change in the templates to allow to pass
a provisioner to the $(step path)/ssh/config template

Related to #807
2022-12-14 17:51:50 -08:00

154 lines
5 KiB
Go

package templates
import (
"golang.org/x/crypto/ssh"
)
// SSHTemplateVersionKey is a key that can be submitted by a client to select
// the template version that will be returned by the server.
var SSHTemplateVersionKey = "StepSSHTemplateVersion"
// Step represents the default variables available in the CA.
type Step struct {
SSH StepSSH
}
// StepSSH holds SSH-related values for the CA.
type StepSSH struct {
HostKey ssh.PublicKey
UserKey ssh.PublicKey
HostFederatedKeys []ssh.PublicKey
UserFederatedKeys []ssh.PublicKey
}
// DefaultSSHTemplates contains the configuration of default templates used on ssh.
// Relative paths are relative to the StepPath.
var DefaultSSHTemplates = SSHTemplates{
User: []Template{
{
Name: "config.tpl",
Type: Snippet,
TemplatePath: "templates/ssh/config.tpl",
Path: "~/.ssh/config",
Comment: "#",
},
{
Name: "step_includes.tpl",
Type: PrependLine,
TemplatePath: "templates/ssh/step_includes.tpl",
Path: "${STEPPATH}/ssh/includes",
Comment: "#",
},
{
Name: "step_config.tpl",
Type: File,
TemplatePath: "templates/ssh/step_config.tpl",
Path: "ssh/config",
Comment: "#",
},
{
Name: "known_hosts.tpl",
Type: File,
TemplatePath: "templates/ssh/known_hosts.tpl",
Path: "ssh/known_hosts",
Comment: "#",
},
},
Host: []Template{
{
Name: "sshd_config.tpl",
Type: Snippet,
TemplatePath: "templates/ssh/sshd_config.tpl",
Path: "/etc/ssh/sshd_config",
Comment: "#",
RequiredData: []string{"Certificate", "Key"},
},
{
Name: "ca.tpl",
Type: Snippet,
TemplatePath: "templates/ssh/ca.tpl",
Path: "/etc/ssh/ca.pub",
Comment: "#",
},
},
}
// DefaultSSHTemplateData contains the data of the default templates used on ssh.
var DefaultSSHTemplateData = map[string]string{
// config.tpl adds the step ssh config file.
//
// Note: on windows `Include C:\...` is treated as a relative path.
"config.tpl": `Host *
{{- if or .User.GOOS "none" | eq "windows" }}
{{- if .User.StepBasePath }}
Include "{{ .User.StepBasePath | replace "\\" "/" | trimPrefix "C:" }}/ssh/includes"
{{- else }}
Include "{{ .User.StepPath | replace "\\" "/" | trimPrefix "C:" }}/ssh/includes"
{{- end }}
{{- else }}
{{- if .User.StepBasePath }}
Include "{{.User.StepBasePath}}/ssh/includes"
{{- else }}
Include "{{.User.StepPath}}/ssh/includes"
{{- end }}
{{- end }}`,
// step_includes.tpl adds the step ssh config file.
//
// Note: on windows `Include C:\...` is treated as a relative path.
"step_includes.tpl": `{{- if or .User.GOOS "none" | eq "windows" }}Include "{{ .User.StepPath | replace "\\" "/" | trimPrefix "C:" }}/ssh/config"{{- else }}Include "{{.User.StepPath}}/ssh/config"{{- end }}`,
// step_config.tpl is the step ssh config file, it includes the Match rule and
// references the step known_hosts file.
//
// Note: on windows ProxyCommand requires the full path
"step_config.tpl": `Match exec "step ssh check-host{{- if .User.Context }} --context {{ .User.Context }}{{- end }} %h"
{{- if .User.User }}
User {{.User.User}}
{{- end }}
{{- if or .User.GOOS "none" | eq "windows" }}
UserKnownHostsFile "{{.User.StepPath}}\ssh\known_hosts"
ProxyCommand C:\Windows\System32\cmd.exe /c step ssh proxycommand{{- if .User.Context }} --context {{ .User.Context }}{{- end }}{{- if .User.Provisioner }} --provisioner {{ .User.Provisioner }}{{- end }} %r %h %p
{{- else }}
UserKnownHostsFile "{{.User.StepPath}}/ssh/known_hosts"
ProxyCommand step ssh proxycommand{{- if .User.Context }} --context {{ .User.Context }}{{- end }}{{- if .User.Provisioner }} --provisioner {{ .User.Provisioner }}{{- end }} %r %h %p
{{- end }}
`,
// known_hosts.tpl authorizes the ssh hosts key
"known_hosts.tpl": `@cert-authority * {{.Step.SSH.HostKey.Type}} {{.Step.SSH.HostKey.Marshal | toString | b64enc}}
{{- range .Step.SSH.HostFederatedKeys}}
@cert-authority * {{.Type}} {{.Marshal | toString | b64enc}}
{{- end }}
`,
// sshd_config.tpl adds the configuration to support certificates
"sshd_config.tpl": `Match all
TrustedUserCAKeys /etc/ssh/ca.pub
HostCertificate /etc/ssh/{{.User.Certificate}}
HostKey /etc/ssh/{{.User.Key}}`,
// ca.tpl contains the public key used to authorized clients
"ca.tpl": `{{.Step.SSH.UserKey.Type}} {{.Step.SSH.UserKey.Marshal | toString | b64enc}}
{{- range .Step.SSH.UserFederatedKeys}}
{{.Type}} {{.Marshal | toString | b64enc}}
{{- end }}
`,
}
// DefaultTemplates returns the default templates.
func DefaultTemplates() *Templates {
sshTemplates := DefaultSSHTemplates
for i, t := range sshTemplates.User {
sshTemplates.User[i].TemplatePath = ""
sshTemplates.User[i].Content = []byte(DefaultSSHTemplateData[t.Name])
}
for i, t := range sshTemplates.Host {
sshTemplates.Host[i].TemplatePath = ""
sshTemplates.Host[i].Content = []byte(DefaultSSHTemplateData[t.Name])
}
return &Templates{
SSH: &sshTemplates,
Data: map[string]interface{}{},
}
}