From f05e41c9aad83f3d45aff620a739a116c32b4c47 Mon Sep 17 00:00:00 2001 From: Simon Beck Date: Tue, 8 Feb 2022 17:59:59 +0100 Subject: Improve password hash handling This adds support for more hash algorithms. Also a stored password will be updated to SSHA512 upon a successful bind. It will also automatically hash a cleartext password if the `userpassword` field is modified with a cleartext one. Hashes supported: * SSHA * SSHA256 * SSHA512 --- main.go | 39 +++++++++++++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 6 deletions(-) (limited to 'main.go') diff --git a/main.go b/main.go index 4e5abce..2b37803 100644 --- a/main.go +++ b/main.go @@ -12,8 +12,8 @@ import ( "os/signal" "syscall" - ldap "bottin/ldapserver" message "bottin/goldap" + ldap "bottin/ldapserver" consul "github.com/hashicorp/consul/api" log "github.com/sirupsen/logrus" @@ -320,7 +320,6 @@ func (server *Server) init() error { return err } - admin_pass_str, environnement_variable_exist := os.LookupEnv("BOTTIN_DEFAULT_ADMIN_PW") if !environnement_variable_exist { admin_pass := make([]byte, 8) @@ -329,11 +328,15 @@ func (server *Server) init() error { return err } admin_pass_str = base64.RawURLEncoding.EncodeToString(admin_pass) - } else { + } else { server.logger.Debug("BOTTIN_DEFAULT_ADMIN_PW environment variable is set, using it for admin's password") } - admin_pass_hash := SSHAEncode([]byte(admin_pass_str)) + admin_pass_hash, err := SSHAEncode(admin_pass_str) + if err != nil { + server.logger.Error("can't create admin password") + panic(err) + } admin_dn := "cn=admin," + server.config.Suffix admin_attributes := Entry{ @@ -434,8 +437,8 @@ func (server *Server) handleBindInternal(state *State, r *message.BindRequest) ( } for _, hash := range passwd { - valid := SSHAMatches(hash, []byte(r.AuthenticationSimple())) - if valid { + valid, err := SSHAMatches(hash, string(r.AuthenticationSimple())) + if valid && err == nil { groups, err := server.getAttribute(string(r.Name()), ATTR_MEMBEROF) if err != nil { return ldap.LDAPResultOperationsError, err @@ -444,8 +447,32 @@ func (server *Server) handleBindInternal(state *State, r *message.BindRequest) ( user: string(r.Name()), groups: groups, } + + updatePasswordHash(string(r.AuthenticationSimple()), hash, server, string(r.Name())) + return ldap.LDAPResultSuccess, nil + } else { + return ldap.LDAPResultInvalidCredentials, fmt.Errorf("can't authenticate: %w", err) } } return ldap.LDAPResultInvalidCredentials, fmt.Errorf("No password match") } + +// Update the hash if it's not already SSHA512 +func updatePasswordHash(password string, currentHash string, server *Server, dn string) { + hashType, err := determineHashType(currentHash) + if err != nil { + server.logger.Errorf("can't determine hash type of password") + return + } + if hashType != SSHA512 { + reencodedPassword, err := SSHAEncode(password) + if err != nil { + server.logger.Errorf("can't encode password") + return + } + server.putAttributes(dn, Entry{ + ATTR_USERPASSWORD: []string{reencodedPassword}, + }) + } +} -- cgit v1.2.3