mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-11-04 01:34:27 +00:00 
			
		
		
		
	Make command in authorized keys a template (#16003)
Fix #15595 Replaces #15978 Signed-off-by: Andrew Thornton <art27@cantab.net> Co-authored-by: techknowlogick <techknowlogick@gitea.io>
This commit is contained in:
		@@ -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_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_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_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_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_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
 | 
					- `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
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -38,7 +38,6 @@ import (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
	tplCommentPrefix = `# gitea public key`
 | 
						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"
 | 
						tplPublicKey     = tplCommentPrefix + "\n" + `command=%s,no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty %s` + "\n"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	authorizedPrincipalsFile = "authorized_principals"
 | 
						authorizedPrincipalsFile = "authorized_principals"
 | 
				
			||||||
@@ -88,7 +87,16 @@ func (key *PublicKey) OmitEmail() string {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// AuthorizedString returns formatted public key string for authorized_keys file.
 | 
					// AuthorizedString returns formatted public key string for authorized_keys file.
 | 
				
			||||||
func (key *PublicKey) AuthorizedString() string {
 | 
					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) {
 | 
					func extractTypeFromBase64Key(key string) (string, error) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -20,6 +20,7 @@ import (
 | 
				
			|||||||
	"runtime"
 | 
						"runtime"
 | 
				
			||||||
	"strconv"
 | 
						"strconv"
 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
 | 
						"text/template"
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"code.gitea.io/gitea/modules/generate"
 | 
						"code.gitea.io/gitea/modules/generate"
 | 
				
			||||||
@@ -123,48 +124,51 @@ var (
 | 
				
			|||||||
	AbsoluteAssetURL     string
 | 
						AbsoluteAssetURL     string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	SSH = struct {
 | 
						SSH = struct {
 | 
				
			||||||
		Disabled                       bool              `ini:"DISABLE_SSH"`
 | 
							Disabled                              bool               `ini:"DISABLE_SSH"`
 | 
				
			||||||
		StartBuiltinServer             bool              `ini:"START_SSH_SERVER"`
 | 
							StartBuiltinServer                    bool               `ini:"START_SSH_SERVER"`
 | 
				
			||||||
		BuiltinServerUser              string            `ini:"BUILTIN_SSH_SERVER_USER"`
 | 
							BuiltinServerUser                     string             `ini:"BUILTIN_SSH_SERVER_USER"`
 | 
				
			||||||
		Domain                         string            `ini:"SSH_DOMAIN"`
 | 
							Domain                                string             `ini:"SSH_DOMAIN"`
 | 
				
			||||||
		Port                           int               `ini:"SSH_PORT"`
 | 
							Port                                  int                `ini:"SSH_PORT"`
 | 
				
			||||||
		ListenHost                     string            `ini:"SSH_LISTEN_HOST"`
 | 
							ListenHost                            string             `ini:"SSH_LISTEN_HOST"`
 | 
				
			||||||
		ListenPort                     int               `ini:"SSH_LISTEN_PORT"`
 | 
							ListenPort                            int                `ini:"SSH_LISTEN_PORT"`
 | 
				
			||||||
		RootPath                       string            `ini:"SSH_ROOT_PATH"`
 | 
							RootPath                              string             `ini:"SSH_ROOT_PATH"`
 | 
				
			||||||
		ServerCiphers                  []string          `ini:"SSH_SERVER_CIPHERS"`
 | 
							ServerCiphers                         []string           `ini:"SSH_SERVER_CIPHERS"`
 | 
				
			||||||
		ServerKeyExchanges             []string          `ini:"SSH_SERVER_KEY_EXCHANGES"`
 | 
							ServerKeyExchanges                    []string           `ini:"SSH_SERVER_KEY_EXCHANGES"`
 | 
				
			||||||
		ServerMACs                     []string          `ini:"SSH_SERVER_MACS"`
 | 
							ServerMACs                            []string           `ini:"SSH_SERVER_MACS"`
 | 
				
			||||||
		ServerHostKeys                 []string          `ini:"SSH_SERVER_HOST_KEYS"`
 | 
							ServerHostKeys                        []string           `ini:"SSH_SERVER_HOST_KEYS"`
 | 
				
			||||||
		KeyTestPath                    string            `ini:"SSH_KEY_TEST_PATH"`
 | 
							KeyTestPath                           string             `ini:"SSH_KEY_TEST_PATH"`
 | 
				
			||||||
		KeygenPath                     string            `ini:"SSH_KEYGEN_PATH"`
 | 
							KeygenPath                            string             `ini:"SSH_KEYGEN_PATH"`
 | 
				
			||||||
		AuthorizedKeysBackup           bool              `ini:"SSH_AUTHORIZED_KEYS_BACKUP"`
 | 
							AuthorizedKeysBackup                  bool               `ini:"SSH_AUTHORIZED_KEYS_BACKUP"`
 | 
				
			||||||
		AuthorizedPrincipalsBackup     bool              `ini:"SSH_AUTHORIZED_PRINCIPALS_BACKUP"`
 | 
							AuthorizedPrincipalsBackup            bool               `ini:"SSH_AUTHORIZED_PRINCIPALS_BACKUP"`
 | 
				
			||||||
		MinimumKeySizeCheck            bool              `ini:"-"`
 | 
							AuthorizedKeysCommandTemplate         string             `ini:"SSH_AUTHORIZED_KEYS_COMMAND_TEMPLATE"`
 | 
				
			||||||
		MinimumKeySizes                map[string]int    `ini:"-"`
 | 
							AuthorizedKeysCommandTemplateTemplate *template.Template `ini:"-"`
 | 
				
			||||||
		CreateAuthorizedKeysFile       bool              `ini:"SSH_CREATE_AUTHORIZED_KEYS_FILE"`
 | 
							MinimumKeySizeCheck                   bool               `ini:"-"`
 | 
				
			||||||
		CreateAuthorizedPrincipalsFile bool              `ini:"SSH_CREATE_AUTHORIZED_PRINCIPALS_FILE"`
 | 
							MinimumKeySizes                       map[string]int     `ini:"-"`
 | 
				
			||||||
		ExposeAnonymous                bool              `ini:"SSH_EXPOSE_ANONYMOUS"`
 | 
							CreateAuthorizedKeysFile              bool               `ini:"SSH_CREATE_AUTHORIZED_KEYS_FILE"`
 | 
				
			||||||
		AuthorizedPrincipalsAllow      []string          `ini:"SSH_AUTHORIZED_PRINCIPALS_ALLOW"`
 | 
							CreateAuthorizedPrincipalsFile        bool               `ini:"SSH_CREATE_AUTHORIZED_PRINCIPALS_FILE"`
 | 
				
			||||||
		AuthorizedPrincipalsEnabled    bool              `ini:"-"`
 | 
							ExposeAnonymous                       bool               `ini:"SSH_EXPOSE_ANONYMOUS"`
 | 
				
			||||||
		TrustedUserCAKeys              []string          `ini:"SSH_TRUSTED_USER_CA_KEYS"`
 | 
							AuthorizedPrincipalsAllow             []string           `ini:"SSH_AUTHORIZED_PRINCIPALS_ALLOW"`
 | 
				
			||||||
		TrustedUserCAKeysFile          string            `ini:"SSH_TRUSTED_USER_CA_KEYS_FILENAME"`
 | 
							AuthorizedPrincipalsEnabled           bool               `ini:"-"`
 | 
				
			||||||
		TrustedUserCAKeysParsed        []gossh.PublicKey `ini:"-"`
 | 
							TrustedUserCAKeys                     []string           `ini:"SSH_TRUSTED_USER_CA_KEYS"`
 | 
				
			||||||
		PerWriteTimeout                time.Duration     `ini:"SSH_PER_WRITE_TIMEOUT"`
 | 
							TrustedUserCAKeysFile                 string             `ini:"SSH_TRUSTED_USER_CA_KEYS_FILENAME"`
 | 
				
			||||||
		PerWritePerKbTimeout           time.Duration     `ini:"SSH_PER_WRITE_PER_KB_TIMEOUT"`
 | 
							TrustedUserCAKeysParsed               []gossh.PublicKey  `ini:"-"`
 | 
				
			||||||
 | 
							PerWriteTimeout                       time.Duration      `ini:"SSH_PER_WRITE_TIMEOUT"`
 | 
				
			||||||
 | 
							PerWritePerKbTimeout                  time.Duration      `ini:"SSH_PER_WRITE_PER_KB_TIMEOUT"`
 | 
				
			||||||
	}{
 | 
						}{
 | 
				
			||||||
		Disabled:             false,
 | 
							Disabled:                      false,
 | 
				
			||||||
		StartBuiltinServer:   false,
 | 
							StartBuiltinServer:            false,
 | 
				
			||||||
		Domain:               "",
 | 
							Domain:                        "",
 | 
				
			||||||
		Port:                 22,
 | 
							Port:                          22,
 | 
				
			||||||
		ServerCiphers:        []string{"aes128-ctr", "aes192-ctr", "aes256-ctr", "aes128-gcm@openssh.com", "arcfour256", "arcfour128"},
 | 
							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"},
 | 
							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"},
 | 
							ServerMACs:                    []string{"hmac-sha2-256-etm@openssh.com", "hmac-sha2-256", "hmac-sha1", "hmac-sha1-96"},
 | 
				
			||||||
		KeygenPath:           "ssh-keygen",
 | 
							KeygenPath:                    "ssh-keygen",
 | 
				
			||||||
		MinimumKeySizeCheck:  true,
 | 
							MinimumKeySizeCheck:           true,
 | 
				
			||||||
		MinimumKeySizes:      map[string]int{"ed25519": 256, "ed25519-sk": 256, "ecdsa": 256, "ecdsa-sk": 256, "rsa": 2048},
 | 
							MinimumKeySizes:               map[string]int{"ed25519": 256, "ed25519-sk": 256, "ecdsa": 256, "ecdsa-sk": 256, "rsa": 2048},
 | 
				
			||||||
		ServerHostKeys:       []string{"ssh/gitea.rsa", "ssh/gogs.rsa"},
 | 
							ServerHostKeys:                []string{"ssh/gitea.rsa", "ssh/gogs.rsa"},
 | 
				
			||||||
		PerWriteTimeout:      PerWriteTimeout,
 | 
							AuthorizedKeysCommandTemplate: "{{.AppPath}} --config={{.CustomConf}} serv key-{{.Key.ID}}",
 | 
				
			||||||
		PerWritePerKbTimeout: PerWritePerKbTimeout,
 | 
							PerWriteTimeout:               PerWriteTimeout,
 | 
				
			||||||
 | 
							PerWritePerKbTimeout:          PerWritePerKbTimeout,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Security settings
 | 
						// Security settings
 | 
				
			||||||
@@ -785,6 +789,10 @@ func NewContext() {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	SSH.ExposeAnonymous = sec.Key("SSH_EXPOSE_ANONYMOUS").MustBool(false)
 | 
						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.PerWriteTimeout = sec.Key("SSH_PER_WRITE_TIMEOUT").MustDuration(PerWriteTimeout)
 | 
				
			||||||
	SSH.PerWritePerKbTimeout = sec.Key("SSH_PER_WRITE_PER_KB_TIMEOUT").MustDuration(PerWritePerKbTimeout)
 | 
						SSH.PerWritePerKbTimeout = sec.Key("SSH_PER_WRITE_PER_KB_TIMEOUT").MustDuration(PerWritePerKbTimeout)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user