Skip to content

Commit 94142e8

Browse files
committed
Make command in authorized keys a template
Fix go-gitea#15595 Replaces go-gitea#15978 Signed-off-by: Andrew Thornton <[email protected]>
1 parent 6d6a65c commit 94142e8

File tree

3 files changed

+55
-39
lines changed

3 files changed

+55
-39
lines changed

docs/content/doc/advanced/config-cheat-sheet.en-us.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,7 @@ The following configuration set `Content-Type: application/vnd.android.package-a
267267
- `SSH_AUTHORIZED_PRINCIPALS_ALLOW`: **off** or **username, email**: \[off, username, email, anything\]: Specify the principals values that users are allowed to use as principal. When set to `anything` no checks are done on the principal string. When set to `off` authorized principal are not allowed to be set.
268268
- `SSH_CREATE_AUTHORIZED_PRINCIPALS_FILE`: **false/true**: Gitea will create a authorized_principals file by default when it is not using the internal ssh server and `SSH_AUTHORIZED_PRINCIPALS_ALLOW` is not `off`.
269269
- `SSH_AUTHORIZED_PRINCIPALS_BACKUP`: **false/true**: Enable SSH Authorized Principals Backup when rewriting all keys, default is true if `SSH_AUTHORIZED_PRINCIPALS_ALLOW` is not `off`.
270+
- `SSH_AUTHORIZED_KEYS_COMMAND_TEMPLATE`: **{{.AppPath}} --config={{.CustomConf}} serv key-{{.Key.ID}}**: Set the template for the command to passed on authorized keys. Possible keys are: AppPath, AppWorkPath, CustomConf, CustomPath, Key - where Key is a `models.PublicKey` and the others are strings which are shellquoted.
270271
- `SSH_SERVER_CIPHERS`: **aes128-ctr, aes192-ctr, aes256-ctr, [email protected], arcfour256, arcfour128**: For the built-in SSH server, choose the ciphers to support for SSH connections, for system SSH this setting has no effect.
271272
- `SSH_SERVER_KEY_EXCHANGES`: **diffie-hellman-group1-sha1, diffie-hellman-group14-sha1, ecdh-sha2-nistp256, ecdh-sha2-nistp384, ecdh-sha2-nistp521, [email protected]**: For the built-in SSH server, choose the key exchange algorithms to support for SSH connections, for system SSH this setting has no effect.
272273
- `SSH_SERVER_MACS`: **[email protected], hmac-sha2-256, hmac-sha1, hmac-sha1-96**: For the built-in SSH server, choose the MACs to support for SSH connections, for system SSH this setting has no effect

models/ssh_key.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ import (
3838

3939
const (
4040
tplCommentPrefix = `# gitea public key`
41-
tplCommand = "%s --config=%s serv key-%d"
4241
tplPublicKey = tplCommentPrefix + "\n" + `command=%s,no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty %s` + "\n"
4342

4443
authorizedPrincipalsFile = "authorized_principals"
@@ -88,7 +87,16 @@ func (key *PublicKey) OmitEmail() string {
8887

8988
// AuthorizedString returns formatted public key string for authorized_keys file.
9089
func (key *PublicKey) AuthorizedString() string {
91-
return fmt.Sprintf(tplPublicKey, util.ShellEscape(fmt.Sprintf(tplCommand, util.ShellEscape(setting.AppPath), util.ShellEscape(setting.CustomConf), key.ID)), key.Content)
90+
sb := &strings.Builder{}
91+
_ = setting.SSH.AuthorizedKeysCommandTemplateTemplate.Execute(sb, map[string]interface{}{
92+
"AppPath": util.ShellEscape(setting.AppPath),
93+
"AppWorkPath": util.ShellEscape(setting.AppWorkPath),
94+
"CustomConf": util.ShellEscape(setting.CustomConf),
95+
"CustomPath": util.ShellEscape(setting.CustomPath),
96+
"Key": key,
97+
})
98+
99+
return fmt.Sprintf(tplPublicKey, util.ShellEscape(sb.String()), key.Content)
92100
}
93101

94102
func extractTypeFromBase64Key(key string) (string, error) {

modules/setting/setting.go

Lines changed: 44 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"runtime"
2121
"strconv"
2222
"strings"
23+
"text/template"
2324
"time"
2425

2526
"code.gitea.io/gitea/modules/generate"
@@ -121,44 +122,47 @@ var (
121122
AbsoluteAssetURL string
122123

123124
SSH = struct {
124-
Disabled bool `ini:"DISABLE_SSH"`
125-
StartBuiltinServer bool `ini:"START_SSH_SERVER"`
126-
BuiltinServerUser string `ini:"BUILTIN_SSH_SERVER_USER"`
127-
Domain string `ini:"SSH_DOMAIN"`
128-
Port int `ini:"SSH_PORT"`
129-
ListenHost string `ini:"SSH_LISTEN_HOST"`
130-
ListenPort int `ini:"SSH_LISTEN_PORT"`
131-
RootPath string `ini:"SSH_ROOT_PATH"`
132-
ServerCiphers []string `ini:"SSH_SERVER_CIPHERS"`
133-
ServerKeyExchanges []string `ini:"SSH_SERVER_KEY_EXCHANGES"`
134-
ServerMACs []string `ini:"SSH_SERVER_MACS"`
135-
ServerHostKeys []string `ini:"SSH_SERVER_HOST_KEYS"`
136-
KeyTestPath string `ini:"SSH_KEY_TEST_PATH"`
137-
KeygenPath string `ini:"SSH_KEYGEN_PATH"`
138-
AuthorizedKeysBackup bool `ini:"SSH_AUTHORIZED_KEYS_BACKUP"`
139-
AuthorizedPrincipalsBackup bool `ini:"SSH_AUTHORIZED_PRINCIPALS_BACKUP"`
140-
MinimumKeySizeCheck bool `ini:"-"`
141-
MinimumKeySizes map[string]int `ini:"-"`
142-
CreateAuthorizedKeysFile bool `ini:"SSH_CREATE_AUTHORIZED_KEYS_FILE"`
143-
CreateAuthorizedPrincipalsFile bool `ini:"SSH_CREATE_AUTHORIZED_PRINCIPALS_FILE"`
144-
ExposeAnonymous bool `ini:"SSH_EXPOSE_ANONYMOUS"`
145-
AuthorizedPrincipalsAllow []string `ini:"SSH_AUTHORIZED_PRINCIPALS_ALLOW"`
146-
AuthorizedPrincipalsEnabled bool `ini:"-"`
147-
TrustedUserCAKeys []string `ini:"SSH_TRUSTED_USER_CA_KEYS"`
148-
TrustedUserCAKeysFile string `ini:"SSH_TRUSTED_USER_CA_KEYS_FILENAME"`
149-
TrustedUserCAKeysParsed []gossh.PublicKey `ini:"-"`
125+
Disabled bool `ini:"DISABLE_SSH"`
126+
StartBuiltinServer bool `ini:"START_SSH_SERVER"`
127+
BuiltinServerUser string `ini:"BUILTIN_SSH_SERVER_USER"`
128+
Domain string `ini:"SSH_DOMAIN"`
129+
Port int `ini:"SSH_PORT"`
130+
ListenHost string `ini:"SSH_LISTEN_HOST"`
131+
ListenPort int `ini:"SSH_LISTEN_PORT"`
132+
RootPath string `ini:"SSH_ROOT_PATH"`
133+
ServerCiphers []string `ini:"SSH_SERVER_CIPHERS"`
134+
ServerKeyExchanges []string `ini:"SSH_SERVER_KEY_EXCHANGES"`
135+
ServerMACs []string `ini:"SSH_SERVER_MACS"`
136+
ServerHostKeys []string `ini:"SSH_SERVER_HOST_KEYS"`
137+
KeyTestPath string `ini:"SSH_KEY_TEST_PATH"`
138+
KeygenPath string `ini:"SSH_KEYGEN_PATH"`
139+
AuthorizedKeysBackup bool `ini:"SSH_AUTHORIZED_KEYS_BACKUP"`
140+
AuthorizedPrincipalsBackup bool `ini:"SSH_AUTHORIZED_PRINCIPALS_BACKUP"`
141+
AuthorizedKeysCommandTemplate string `ini:"SSH_AUTHORIZED_KEYS_COMMAND_TEMPLATE"`
142+
AuthorizedKeysCommandTemplateTemplate *template.Template `ini:"-"`
143+
MinimumKeySizeCheck bool `ini:"-"`
144+
MinimumKeySizes map[string]int `ini:"-"`
145+
CreateAuthorizedKeysFile bool `ini:"SSH_CREATE_AUTHORIZED_KEYS_FILE"`
146+
CreateAuthorizedPrincipalsFile bool `ini:"SSH_CREATE_AUTHORIZED_PRINCIPALS_FILE"`
147+
ExposeAnonymous bool `ini:"SSH_EXPOSE_ANONYMOUS"`
148+
AuthorizedPrincipalsAllow []string `ini:"SSH_AUTHORIZED_PRINCIPALS_ALLOW"`
149+
AuthorizedPrincipalsEnabled bool `ini:"-"`
150+
TrustedUserCAKeys []string `ini:"SSH_TRUSTED_USER_CA_KEYS"`
151+
TrustedUserCAKeysFile string `ini:"SSH_TRUSTED_USER_CA_KEYS_FILENAME"`
152+
TrustedUserCAKeysParsed []gossh.PublicKey `ini:"-"`
150153
}{
151-
Disabled: false,
152-
StartBuiltinServer: false,
153-
Domain: "",
154-
Port: 22,
155-
ServerCiphers: []string{"aes128-ctr", "aes192-ctr", "aes256-ctr", "[email protected]", "arcfour256", "arcfour128"},
156-
ServerKeyExchanges: []string{"diffie-hellman-group1-sha1", "diffie-hellman-group14-sha1", "ecdh-sha2-nistp256", "ecdh-sha2-nistp384", "ecdh-sha2-nistp521", "[email protected]"},
157-
ServerMACs: []string{"[email protected]", "hmac-sha2-256", "hmac-sha1", "hmac-sha1-96"},
158-
KeygenPath: "ssh-keygen",
159-
MinimumKeySizeCheck: true,
160-
MinimumKeySizes: map[string]int{"ed25519": 256, "ed25519-sk": 256, "ecdsa": 256, "ecdsa-sk": 256, "rsa": 2048},
161-
ServerHostKeys: []string{"ssh/gitea.rsa", "ssh/gogs.rsa"},
154+
Disabled: false,
155+
StartBuiltinServer: false,
156+
Domain: "",
157+
Port: 22,
158+
ServerCiphers: []string{"aes128-ctr", "aes192-ctr", "aes256-ctr", "[email protected]", "arcfour256", "arcfour128"},
159+
ServerKeyExchanges: []string{"diffie-hellman-group1-sha1", "diffie-hellman-group14-sha1", "ecdh-sha2-nistp256", "ecdh-sha2-nistp384", "ecdh-sha2-nistp521", "[email protected]"},
160+
ServerMACs: []string{"[email protected]", "hmac-sha2-256", "hmac-sha1", "hmac-sha1-96"},
161+
KeygenPath: "ssh-keygen",
162+
MinimumKeySizeCheck: true,
163+
MinimumKeySizes: map[string]int{"ed25519": 256, "ed25519-sk": 256, "ecdsa": 256, "ecdsa-sk": 256, "rsa": 2048},
164+
ServerHostKeys: []string{"ssh/gitea.rsa", "ssh/gogs.rsa"},
165+
AuthorizedKeysCommandTemplate: "{{.AppPath}} --config={{.CustomConf}} serv key-{{.Key.ID}}",
162166
}
163167

164168
// Security settings
@@ -777,6 +781,9 @@ func NewContext() {
777781
}
778782

779783
SSH.ExposeAnonymous = sec.Key("SSH_EXPOSE_ANONYMOUS").MustBool(false)
784+
SSH.AuthorizedKeysCommandTemplate = sec.Key("SSH_AUTHORIZED_KEYS_COMMAND_TEMPLATE").MustString(SSH.AuthorizedKeysCommandTemplate)
785+
786+
SSH.AuthorizedKeysCommandTemplateTemplate = template.Must(template.New("").Parse(SSH.AuthorizedKeysCommandTemplate))
780787

781788
if err = Cfg.Section("oauth2").MapTo(&OAuth2); err != nil {
782789
log.Fatal("Failed to OAuth2 settings: %v", err)

0 commit comments

Comments
 (0)