]> source.dussan.org Git - gitea.git/commitdiff
Synchronize SSH keys on login with LDAP + Fix SQLite deadlock on ldap ssh key deletio...
authorzeripath <art27@cantab.net>
Thu, 27 Dec 2018 17:28:48 +0000 (17:28 +0000)
committertechknowlogick <hello@techknowlogick.com>
Thu, 27 Dec 2018 17:28:48 +0000 (12:28 -0500)
* Synchronize SSH keys on login with LDAP

* BUG: Fix hang on sqlite during LDAP key deletion

models/login_source.go
models/ssh_key.go
models/user.go
modules/auth/ldap/ldap.go

index 2c0b4fb5f9e472d162b857b0945fc4b43c2a305d..25c7aa31205d53ac730a11f6644467c036e0aed9 100644 (file)
@@ -393,7 +393,13 @@ func LoginViaLDAP(user *User, login, password string, source *LoginSource, autoR
                return nil, ErrUserNotExist{0, login, 0}
        }
 
+       var isAttributeSSHPublicKeySet = len(strings.TrimSpace(source.LDAP().AttributeSSHPublicKey)) > 0
+
        if !autoRegister {
+               if isAttributeSSHPublicKeySet && synchronizeLdapSSHPublicKeys(user, source, sr.SSHPublicKey) {
+                       RewriteAllPublicKeys()
+               }
+
                return user, nil
        }
 
@@ -421,7 +427,14 @@ func LoginViaLDAP(user *User, login, password string, source *LoginSource, autoR
                IsActive:    true,
                IsAdmin:     sr.IsAdmin,
        }
-       return user, CreateUser(user)
+
+       err := CreateUser(user)
+
+       if err == nil && isAttributeSSHPublicKeySet && addLdapSSHPublicKeys(user, source, sr.SSHPublicKey) {
+               RewriteAllPublicKeys()
+       }
+
+       return user, err
 }
 
 //   _________   __________________________
index 0f8e5225bb8dff41c8d7d7571c6cb0edc86714ce..27c5bf080858616085616f5a803c9b8a84d1d463 100644 (file)
@@ -451,11 +451,9 @@ func GetPublicKeyByID(keyID int64) (*PublicKey, error) {
        return key, nil
 }
 
-// SearchPublicKeyByContent searches content as prefix (leak e-mail part)
-// and returns public key found.
-func SearchPublicKeyByContent(content string) (*PublicKey, error) {
+func searchPublicKeyByContentWithEngine(e Engine, content string) (*PublicKey, error) {
        key := new(PublicKey)
-       has, err := x.
+       has, err := e.
                Where("content like ?", content+"%").
                Get(key)
        if err != nil {
@@ -466,6 +464,12 @@ func SearchPublicKeyByContent(content string) (*PublicKey, error) {
        return key, nil
 }
 
+// SearchPublicKeyByContent searches content as prefix (leak e-mail part)
+// and returns public key found.
+func SearchPublicKeyByContent(content string) (*PublicKey, error) {
+       return searchPublicKeyByContentWithEngine(x, content)
+}
+
 // SearchPublicKey returns a list of public keys matching the provided arguments.
 func SearchPublicKey(uid int64, fingerprint string) ([]*PublicKey, error) {
        keys := make([]*PublicKey, 0, 5)
index a30e0d8e5261dcb605bf8adad9dd04d0421cb335..3a47346e34d56cfc8b7640386bc03473ed773138 100644 (file)
@@ -1402,7 +1402,7 @@ func deleteKeysMarkedForDeletion(keys []string) (bool, error) {
        // Delete keys marked for deletion
        var sshKeysNeedUpdate bool
        for _, KeyToDelete := range keys {
-               key, err := SearchPublicKeyByContent(KeyToDelete)
+               key, err := searchPublicKeyByContentWithEngine(sess, KeyToDelete)
                if err != nil {
                        log.Error(4, "SearchPublicKeyByContent: %v", err)
                        continue
@@ -1421,7 +1421,8 @@ func deleteKeysMarkedForDeletion(keys []string) (bool, error) {
        return sshKeysNeedUpdate, nil
 }
 
-func addLdapSSHPublicKeys(s *LoginSource, usr *User, SSHPublicKeys []string) bool {
+// addLdapSSHPublicKeys add a users public keys. Returns true if there are changes.
+func addLdapSSHPublicKeys(usr *User, s *LoginSource, SSHPublicKeys []string) bool {
        var sshKeysNeedUpdate bool
        for _, sshKey := range SSHPublicKeys {
                _, _, _, _, err := ssh.ParseAuthorizedKey([]byte(sshKey))
@@ -1440,7 +1441,8 @@ func addLdapSSHPublicKeys(s *LoginSource, usr *User, SSHPublicKeys []string) boo
        return sshKeysNeedUpdate
 }
 
-func synchronizeLdapSSHPublicKeys(s *LoginSource, SSHPublicKeys []string, usr *User) bool {
+// synchronizeLdapSSHPublicKeys updates a users public keys. Returns true if there are changes.
+func synchronizeLdapSSHPublicKeys(usr *User, s *LoginSource, SSHPublicKeys []string) bool {
        var sshKeysNeedUpdate bool
 
        log.Trace("synchronizeLdapSSHPublicKeys[%s]: Handling LDAP Public SSH Key synchronization for user %s", s.Name, usr.Name)
@@ -1479,7 +1481,7 @@ func synchronizeLdapSSHPublicKeys(s *LoginSource, SSHPublicKeys []string, usr *U
                        newLdapSSHKeys = append(newLdapSSHKeys, LDAPPublicSSHKey)
                }
        }
-       if addLdapSSHPublicKeys(s, usr, newLdapSSHKeys) {
+       if addLdapSSHPublicKeys(usr, s, newLdapSSHKeys) {
                sshKeysNeedUpdate = true
        }
 
@@ -1581,7 +1583,7 @@ func SyncExternalUsers() {
                                                log.Error(4, "SyncExternalUsers[%s]: Error creating user %s: %v", s.Name, su.Username, err)
                                        } else if isAttributeSSHPublicKeySet {
                                                log.Trace("SyncExternalUsers[%s]: Adding LDAP Public SSH Keys for user %s", s.Name, usr.Name)
-                                               if addLdapSSHPublicKeys(s, usr, su.SSHPublicKey) {
+                                               if addLdapSSHPublicKeys(usr, s, su.SSHPublicKey) {
                                                        sshKeysNeedUpdate = true
                                                }
                                        }
@@ -1589,7 +1591,7 @@ func SyncExternalUsers() {
                                        existingUsers = append(existingUsers, usr.ID)
 
                                        // Synchronize SSH Public Key if that attribute is set
-                                       if isAttributeSSHPublicKeySet && synchronizeLdapSSHPublicKeys(s, su.SSHPublicKey, usr) {
+                                       if isAttributeSSHPublicKeySet && synchronizeLdapSSHPublicKeys(usr, s, su.SSHPublicKey) {
                                                sshKeysNeedUpdate = true
                                        }
 
index f4c55d0bd675b9245d39cf8249cdea9999f0856a..c33dbea11be885e014f3cdd2c98f0a0e2df266fb 100644 (file)
@@ -247,10 +247,10 @@ func (ls *Source) SearchEntry(name, passwd string, directBind bool) *SearchResul
                return nil
        }
 
-       log.Trace("Fetching attributes '%v', '%v', '%v', '%v' with filter %s and base %s", ls.AttributeUsername, ls.AttributeName, ls.AttributeSurname, ls.AttributeMail, userFilter, userDN)
+       log.Trace("Fetching attributes '%v', '%v', '%v', '%v', '%v' with filter %s and base %s", ls.AttributeUsername, ls.AttributeName, ls.AttributeSurname, ls.AttributeMail, ls.AttributeSSHPublicKey, userFilter, userDN)
        search := ldap.NewSearchRequest(
                userDN, ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false, userFilter,
-               []string{ls.AttributeUsername, ls.AttributeName, ls.AttributeSurname, ls.AttributeMail},
+               []string{ls.AttributeUsername, ls.AttributeName, ls.AttributeSurname, ls.AttributeMail, ls.AttributeSSHPublicKey},
                nil)
 
        sr, err := l.Search(search)
@@ -271,6 +271,7 @@ func (ls *Source) SearchEntry(name, passwd string, directBind bool) *SearchResul
        firstname := sr.Entries[0].GetAttributeValue(ls.AttributeName)
        surname := sr.Entries[0].GetAttributeValue(ls.AttributeSurname)
        mail := sr.Entries[0].GetAttributeValue(ls.AttributeMail)
+       sshPublicKey := sr.Entries[0].GetAttributeValues(ls.AttributeSSHPublicKey)
        isAdmin := checkAdmin(l, ls, userDN)
 
        if !directBind && ls.AttributesInBind {
@@ -282,11 +283,12 @@ func (ls *Source) SearchEntry(name, passwd string, directBind bool) *SearchResul
        }
 
        return &SearchResult{
-               Username: username,
-               Name:     firstname,
-               Surname:  surname,
-               Mail:     mail,
-               IsAdmin:  isAdmin,
+               Username:     username,
+               Name:         firstname,
+               Surname:      surname,
+               Mail:         mail,
+               SSHPublicKey: sshPublicKey,
+               IsAdmin:      isAdmin,
        }
 }