diff options
Diffstat (limited to 'modules/ssh')
-rw-r--r-- | modules/ssh/ssh.go | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/modules/ssh/ssh.go b/modules/ssh/ssh.go index e7a694683a..7a449dd41b 100644 --- a/modules/ssh/ssh.go +++ b/modules/ssh/ssh.go @@ -5,6 +5,7 @@ package ssh import ( + "bytes" "crypto/rand" "crypto/rsa" "crypto/x509" @@ -136,6 +137,52 @@ func publicKeyHandler(ctx ssh.Context, key ssh.PublicKey) bool { return false } + // check if we have a certificate + if cert, ok := key.(*gossh.Certificate); ok { + if len(setting.SSH.TrustedUserCAKeys) == 0 { + return false + } + + // look for the exact principal + for _, principal := range cert.ValidPrincipals { + pkey, err := models.SearchPublicKeyByContentExact(principal) + if err != nil { + log.Error("SearchPublicKeyByContentExact: %v", err) + return false + } + + if models.IsErrKeyNotExist(err) { + continue + } + + c := &gossh.CertChecker{ + IsUserAuthority: func(auth gossh.PublicKey) bool { + for _, k := range setting.SSH.TrustedUserCAKeysParsed { + if bytes.Equal(auth.Marshal(), k.Marshal()) { + return true + } + } + + return false + }, + } + + // check the CA of the cert + if !c.IsUserAuthority(cert.SignatureKey) { + return false + } + + // validate the cert for this principal + if err := c.CheckCert(principal, cert); err != nil { + return false + } + + ctx.SetValue(giteaKeyID, pkey.ID) + + return true + } + } + pkey, err := models.SearchPublicKeyByContent(strings.TrimSpace(string(gossh.MarshalAuthorizedKey(key)))) if err != nil { log.Error("SearchPublicKeyByContent: %v", err) |