]> source.dussan.org Git - gitea.git/commitdiff
Make command in authorized keys a template (#16003)
authorzeripath <art27@cantab.net>
Tue, 15 Jun 2021 01:15:12 +0000 (02:15 +0100)
committerGitHub <noreply@github.com>
Tue, 15 Jun 2021 01:15:12 +0000 (21:15 -0400)
Fix #15595
Replaces #15978

Signed-off-by: Andrew Thornton <art27@cantab.net>
Co-authored-by: techknowlogick <techknowlogick@gitea.io>
docs/content/doc/advanced/config-cheat-sheet.en-us.md
models/ssh_key.go
modules/setting/setting.go

index 54ef780bcac1ac298a3a216a36bef1992c7d0f86..1fb05a4253d708f6bb0025316bea81d6c78a8fcd 100644 (file)
@@ -270,6 +270,7 @@ The following configuration set `Content-Type: application/vnd.android.package-a
 - `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.
 - `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`.
 - `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`.
+- `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.
 - `SSH_SERVER_CIPHERS`: **aes128-ctr, aes192-ctr, aes256-ctr, aes128-gcm@openssh.com, arcfour256, arcfour128**: For the built-in SSH server, choose the ciphers to support for SSH connections, for system SSH this setting has no effect.
 - `SSH_SERVER_KEY_EXCHANGES`: **diffie-hellman-group1-sha1, diffie-hellman-group14-sha1, ecdh-sha2-nistp256, ecdh-sha2-nistp384, ecdh-sha2-nistp521, curve25519-sha256@libssh.org**: For the built-in SSH server, choose the key exchange algorithms to support for SSH connections, for system SSH this setting has no effect.
 - `SSH_SERVER_MACS`: **hmac-sha2-256-etm@openssh.com, 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
index 9f9c33e848f5f5769a559f5cc11196a1d9c3cd87..e35fc12e080a28549cb650245dc476e397bdb0b9 100644 (file)
@@ -38,7 +38,6 @@ import (
 
 const (
        tplCommentPrefix = `# gitea public key`
-       tplCommand       = "%s --config=%s serv key-%d"
        tplPublicKey     = tplCommentPrefix + "\n" + `command=%s,no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty %s` + "\n"
 
        authorizedPrincipalsFile = "authorized_principals"
@@ -88,7 +87,16 @@ func (key *PublicKey) OmitEmail() string {
 
 // AuthorizedString returns formatted public key string for authorized_keys file.
 func (key *PublicKey) AuthorizedString() string {
-       return fmt.Sprintf(tplPublicKey, util.ShellEscape(fmt.Sprintf(tplCommand, util.ShellEscape(setting.AppPath), util.ShellEscape(setting.CustomConf), key.ID)), key.Content)
+       sb := &strings.Builder{}
+       _ = setting.SSH.AuthorizedKeysCommandTemplateTemplate.Execute(sb, map[string]interface{}{
+               "AppPath":     util.ShellEscape(setting.AppPath),
+               "AppWorkPath": util.ShellEscape(setting.AppWorkPath),
+               "CustomConf":  util.ShellEscape(setting.CustomConf),
+               "CustomPath":  util.ShellEscape(setting.CustomPath),
+               "Key":         key,
+       })
+
+       return fmt.Sprintf(tplPublicKey, util.ShellEscape(sb.String()), key.Content)
 }
 
 func extractTypeFromBase64Key(key string) (string, error) {
index 355d1d36d10ca1ae64e8e24b67800256a53ecf9f..6e05df1ad99f2f011e03efed95d3f1b796b74645 100644 (file)
@@ -20,6 +20,7 @@ import (
        "runtime"
        "strconv"
        "strings"
+       "text/template"
        "time"
 
        "code.gitea.io/gitea/modules/generate"
@@ -123,48 +124,51 @@ var (
        AbsoluteAssetURL     string
 
        SSH = struct {
-               Disabled                       bool              `ini:"DISABLE_SSH"`
-               StartBuiltinServer             bool              `ini:"START_SSH_SERVER"`
-               BuiltinServerUser              string            `ini:"BUILTIN_SSH_SERVER_USER"`
-               Domain                         string            `ini:"SSH_DOMAIN"`
-               Port                           int               `ini:"SSH_PORT"`
-               ListenHost                     string            `ini:"SSH_LISTEN_HOST"`
-               ListenPort                     int               `ini:"SSH_LISTEN_PORT"`
-               RootPath                       string            `ini:"SSH_ROOT_PATH"`
-               ServerCiphers                  []string          `ini:"SSH_SERVER_CIPHERS"`
-               ServerKeyExchanges             []string          `ini:"SSH_SERVER_KEY_EXCHANGES"`
-               ServerMACs                     []string          `ini:"SSH_SERVER_MACS"`
-               ServerHostKeys                 []string          `ini:"SSH_SERVER_HOST_KEYS"`
-               KeyTestPath                    string            `ini:"SSH_KEY_TEST_PATH"`
-               KeygenPath                     string            `ini:"SSH_KEYGEN_PATH"`
-               AuthorizedKeysBackup           bool              `ini:"SSH_AUTHORIZED_KEYS_BACKUP"`
-               AuthorizedPrincipalsBackup     bool              `ini:"SSH_AUTHORIZED_PRINCIPALS_BACKUP"`
-               MinimumKeySizeCheck            bool              `ini:"-"`
-               MinimumKeySizes                map[string]int    `ini:"-"`
-               CreateAuthorizedKeysFile       bool              `ini:"SSH_CREATE_AUTHORIZED_KEYS_FILE"`
-               CreateAuthorizedPrincipalsFile bool              `ini:"SSH_CREATE_AUTHORIZED_PRINCIPALS_FILE"`
-               ExposeAnonymous                bool              `ini:"SSH_EXPOSE_ANONYMOUS"`
-               AuthorizedPrincipalsAllow      []string          `ini:"SSH_AUTHORIZED_PRINCIPALS_ALLOW"`
-               AuthorizedPrincipalsEnabled    bool              `ini:"-"`
-               TrustedUserCAKeys              []string          `ini:"SSH_TRUSTED_USER_CA_KEYS"`
-               TrustedUserCAKeysFile          string            `ini:"SSH_TRUSTED_USER_CA_KEYS_FILENAME"`
-               TrustedUserCAKeysParsed        []gossh.PublicKey `ini:"-"`
-               PerWriteTimeout                time.Duration     `ini:"SSH_PER_WRITE_TIMEOUT"`
-               PerWritePerKbTimeout           time.Duration     `ini:"SSH_PER_WRITE_PER_KB_TIMEOUT"`
+               Disabled                              bool               `ini:"DISABLE_SSH"`
+               StartBuiltinServer                    bool               `ini:"START_SSH_SERVER"`
+               BuiltinServerUser                     string             `ini:"BUILTIN_SSH_SERVER_USER"`
+               Domain                                string             `ini:"SSH_DOMAIN"`
+               Port                                  int                `ini:"SSH_PORT"`
+               ListenHost                            string             `ini:"SSH_LISTEN_HOST"`
+               ListenPort                            int                `ini:"SSH_LISTEN_PORT"`
+               RootPath                              string             `ini:"SSH_ROOT_PATH"`
+               ServerCiphers                         []string           `ini:"SSH_SERVER_CIPHERS"`
+               ServerKeyExchanges                    []string           `ini:"SSH_SERVER_KEY_EXCHANGES"`
+               ServerMACs                            []string           `ini:"SSH_SERVER_MACS"`
+               ServerHostKeys                        []string           `ini:"SSH_SERVER_HOST_KEYS"`
+               KeyTestPath                           string             `ini:"SSH_KEY_TEST_PATH"`
+               KeygenPath                            string             `ini:"SSH_KEYGEN_PATH"`
+               AuthorizedKeysBackup                  bool               `ini:"SSH_AUTHORIZED_KEYS_BACKUP"`
+               AuthorizedPrincipalsBackup            bool               `ini:"SSH_AUTHORIZED_PRINCIPALS_BACKUP"`
+               AuthorizedKeysCommandTemplate         string             `ini:"SSH_AUTHORIZED_KEYS_COMMAND_TEMPLATE"`
+               AuthorizedKeysCommandTemplateTemplate *template.Template `ini:"-"`
+               MinimumKeySizeCheck                   bool               `ini:"-"`
+               MinimumKeySizes                       map[string]int     `ini:"-"`
+               CreateAuthorizedKeysFile              bool               `ini:"SSH_CREATE_AUTHORIZED_KEYS_FILE"`
+               CreateAuthorizedPrincipalsFile        bool               `ini:"SSH_CREATE_AUTHORIZED_PRINCIPALS_FILE"`
+               ExposeAnonymous                       bool               `ini:"SSH_EXPOSE_ANONYMOUS"`
+               AuthorizedPrincipalsAllow             []string           `ini:"SSH_AUTHORIZED_PRINCIPALS_ALLOW"`
+               AuthorizedPrincipalsEnabled           bool               `ini:"-"`
+               TrustedUserCAKeys                     []string           `ini:"SSH_TRUSTED_USER_CA_KEYS"`
+               TrustedUserCAKeysFile                 string             `ini:"SSH_TRUSTED_USER_CA_KEYS_FILENAME"`
+               TrustedUserCAKeysParsed               []gossh.PublicKey  `ini:"-"`
+               PerWriteTimeout                       time.Duration      `ini:"SSH_PER_WRITE_TIMEOUT"`
+               PerWritePerKbTimeout                  time.Duration      `ini:"SSH_PER_WRITE_PER_KB_TIMEOUT"`
        }{
-               Disabled:             false,
-               StartBuiltinServer:   false,
-               Domain:               "",
-               Port:                 22,
-               ServerCiphers:        []string{"aes128-ctr", "aes192-ctr", "aes256-ctr", "aes128-gcm@openssh.com", "arcfour256", "arcfour128"},
-               ServerKeyExchanges:   []string{"diffie-hellman-group1-sha1", "diffie-hellman-group14-sha1", "ecdh-sha2-nistp256", "ecdh-sha2-nistp384", "ecdh-sha2-nistp521", "curve25519-sha256@libssh.org"},
-               ServerMACs:           []string{"hmac-sha2-256-etm@openssh.com", "hmac-sha2-256", "hmac-sha1", "hmac-sha1-96"},
-               KeygenPath:           "ssh-keygen",
-               MinimumKeySizeCheck:  true,
-               MinimumKeySizes:      map[string]int{"ed25519": 256, "ed25519-sk": 256, "ecdsa": 256, "ecdsa-sk": 256, "rsa": 2048},
-               ServerHostKeys:       []string{"ssh/gitea.rsa", "ssh/gogs.rsa"},
-               PerWriteTimeout:      PerWriteTimeout,
-               PerWritePerKbTimeout: PerWritePerKbTimeout,
+               Disabled:                      false,
+               StartBuiltinServer:            false,
+               Domain:                        "",
+               Port:                          22,
+               ServerCiphers:                 []string{"aes128-ctr", "aes192-ctr", "aes256-ctr", "aes128-gcm@openssh.com", "arcfour256", "arcfour128"},
+               ServerKeyExchanges:            []string{"diffie-hellman-group1-sha1", "diffie-hellman-group14-sha1", "ecdh-sha2-nistp256", "ecdh-sha2-nistp384", "ecdh-sha2-nistp521", "curve25519-sha256@libssh.org"},
+               ServerMACs:                    []string{"hmac-sha2-256-etm@openssh.com", "hmac-sha2-256", "hmac-sha1", "hmac-sha1-96"},
+               KeygenPath:                    "ssh-keygen",
+               MinimumKeySizeCheck:           true,
+               MinimumKeySizes:               map[string]int{"ed25519": 256, "ed25519-sk": 256, "ecdsa": 256, "ecdsa-sk": 256, "rsa": 2048},
+               ServerHostKeys:                []string{"ssh/gitea.rsa", "ssh/gogs.rsa"},
+               AuthorizedKeysCommandTemplate: "{{.AppPath}} --config={{.CustomConf}} serv key-{{.Key.ID}}",
+               PerWriteTimeout:               PerWriteTimeout,
+               PerWritePerKbTimeout:          PerWritePerKbTimeout,
        }
 
        // Security settings
@@ -785,6 +789,10 @@ func NewContext() {
        }
 
        SSH.ExposeAnonymous = sec.Key("SSH_EXPOSE_ANONYMOUS").MustBool(false)
+       SSH.AuthorizedKeysCommandTemplate = sec.Key("SSH_AUTHORIZED_KEYS_COMMAND_TEMPLATE").MustString(SSH.AuthorizedKeysCommandTemplate)
+
+       SSH.AuthorizedKeysCommandTemplateTemplate = template.Must(template.New("").Parse(SSH.AuthorizedKeysCommandTemplate))
+
        SSH.PerWriteTimeout = sec.Key("SSH_PER_WRITE_TIMEOUT").MustDuration(PerWriteTimeout)
        SSH.PerWritePerKbTimeout = sec.Key("SSH_PER_WRITE_PER_KB_TIMEOUT").MustDuration(PerWritePerKbTimeout)