mirror of
https://github.com/drakkan/sftpgo.git
synced 2024-11-21 23:20:24 +00:00
add support for checking sha256crypt passwords
they will be converted to the configured password hashing algorithm after the first user login Fixes #1000 Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
This commit is contained in:
parent
f9eadd7f04
commit
1e21aa9453
4 changed files with 9 additions and 3 deletions
|
@ -14,7 +14,7 @@ the dump is a JSON with all SFTPGo data including users, folders, admins.
|
|||
|
||||
These properties are stored inside the configured data provider.
|
||||
|
||||
SFTPGo supports checking passwords stored with bcrypt, pbkdf2, md5crypt and sha512crypt too. For pbkdf2 the supported format is `$<algo>$<iterations>$<salt>$<hashed pwd base64 encoded>`, where algo is `pbkdf2-sha1` or `pbkdf2-sha256` or `pbkdf2-sha512` or `$pbkdf2-b64salt-sha256$`. For example the pbkdf2-sha256 of the word password using 150000 iterations and E86a9YMX3zC7 as salt must be stored as `$pbkdf2-sha256$150000$E86a9YMX3zC7$R5J62hsSq+pYw00hLLPKBbcGXmq7fj5+/M0IFoYtZbo=`. In pbkdf2 variant with b64salt the salt is base64 encoded. For bcrypt the format must be the one supported by golang's crypto/bcrypt package, for example the password secret with cost 14 must be stored as `$2a$14$ajq8Q7fbtFRQvXpdCq7Jcuy.Rx1h/L4J60Otx.gyNLbAYctGMJ9tK`. For md5crypt and sha512crypt we support the format used in `/etc/shadow` with the `$1$` and `$6$` prefix, this is useful if you are migrating from Unix system user accounts. We support Apache md5crypt (`$apr1$` prefix) too. Using the REST API you can send a password hashed as bcrypt, pbkdf2, md5crypt or sha512crypt and it will be stored as is.
|
||||
SFTPGo supports checking passwords stored with argon2id, bcrypt, pbkdf2, md5cryptm sha256crypt and sha512crypt too. For pbkdf2 the supported format is `$<algo>$<iterations>$<salt>$<hashed pwd base64 encoded>`, where algo is `pbkdf2-sha1` or `pbkdf2-sha256` or `pbkdf2-sha512` or `$pbkdf2-b64salt-sha256$`. For example the pbkdf2-sha256 of the word password using 150000 iterations and E86a9YMX3zC7 as salt must be stored as `$pbkdf2-sha256$150000$E86a9YMX3zC7$R5J62hsSq+pYw00hLLPKBbcGXmq7fj5+/M0IFoYtZbo=`. In pbkdf2 variant with b64salt the salt is base64 encoded. For bcrypt the format must be the one supported by golang's crypto/bcrypt package, for example the password secret with cost 14 must be stored as `$2a$14$ajq8Q7fbtFRQvXpdCq7Jcuy.Rx1h/L4J60Otx.gyNLbAYctGMJ9tK`. For md5crypt, sha256crypt and sha512crypt we support the format used in `/etc/shadow` with the `$1$`, `$5$` and `$6$` prefix, this is useful if you are migrating from Unix system user accounts. We support Apache md5crypt (`$apr1$` prefix) too. Using the REST API you can send a password hashed as argon2id, bcrypt, pbkdf2, md5crypt, sha256crypt or sha512crypt and it will be stored as is.
|
||||
|
||||
If you want to use your existing accounts, you have these options:
|
||||
|
||||
|
|
|
@ -502,6 +502,7 @@ Supported hash algorithms:
|
|||
- PBKDF2 sha256 with base64 salt, prefix `$pbkdf2-b64salt-sha256$`
|
||||
- MD5 crypt, prefix `$1$`
|
||||
- MD5 crypt APR1, prefix `$apr1$`
|
||||
- SHA256 crypt, prefix `$5$`
|
||||
- SHA512 crypt, prefix `$6$`
|
||||
- LDAP MD5, prefix `{MD5}`
|
||||
|
||||
|
|
|
@ -51,6 +51,7 @@ import (
|
|||
"github.com/GehirnInc/crypt"
|
||||
"github.com/GehirnInc/crypt/apr1_crypt"
|
||||
"github.com/GehirnInc/crypt/md5_crypt"
|
||||
"github.com/GehirnInc/crypt/sha256_crypt"
|
||||
"github.com/GehirnInc/crypt/sha512_crypt"
|
||||
"github.com/alexedwards/argon2id"
|
||||
"github.com/go-chi/render"
|
||||
|
@ -96,6 +97,7 @@ const (
|
|||
pbkdf2SHA256B64SaltPrefix = "$pbkdf2-b64salt-sha256$"
|
||||
md5cryptPwdPrefix = "$1$"
|
||||
md5cryptApr1PwdPrefix = "$apr1$"
|
||||
sha256cryptPwdPrefix = "$5$"
|
||||
sha512cryptPwdPrefix = "$6$"
|
||||
md5LDAPPwdPrefix = "{MD5}"
|
||||
trackQuotaDisabledError = "please enable track_quota in your configuration to use this method"
|
||||
|
@ -163,10 +165,10 @@ var (
|
|||
internalHashPwdPrefixes = []string{argonPwdPrefix, bcryptPwdPrefix}
|
||||
hashPwdPrefixes = []string{argonPwdPrefix, bcryptPwdPrefix, pbkdf2SHA1Prefix, pbkdf2SHA256Prefix,
|
||||
pbkdf2SHA512Prefix, pbkdf2SHA256B64SaltPrefix, md5cryptPwdPrefix, md5cryptApr1PwdPrefix, md5LDAPPwdPrefix,
|
||||
sha512cryptPwdPrefix}
|
||||
sha256cryptPwdPrefix, sha512cryptPwdPrefix}
|
||||
pbkdfPwdPrefixes = []string{pbkdf2SHA1Prefix, pbkdf2SHA256Prefix, pbkdf2SHA512Prefix, pbkdf2SHA256B64SaltPrefix}
|
||||
pbkdfPwdB64SaltPrefixes = []string{pbkdf2SHA256B64SaltPrefix}
|
||||
unixPwdPrefixes = []string{md5cryptPwdPrefix, md5cryptApr1PwdPrefix, sha512cryptPwdPrefix}
|
||||
unixPwdPrefixes = []string{md5cryptPwdPrefix, md5cryptApr1PwdPrefix, sha256cryptPwdPrefix, sha512cryptPwdPrefix}
|
||||
sharedProviders = []string{PGSQLDataProviderName, MySQLDataProviderName, CockroachDataProviderName}
|
||||
logSender = "dataprovider"
|
||||
sqlTableUsers string
|
||||
|
@ -3067,6 +3069,8 @@ func compareUnixPasswordAndHash(user *User, password string) (bool, error) {
|
|||
var crypter crypt.Crypter
|
||||
if strings.HasPrefix(user.Password, sha512cryptPwdPrefix) {
|
||||
crypter = sha512_crypt.New()
|
||||
} else if strings.HasPrefix(user.Password, sha256cryptPwdPrefix) {
|
||||
crypter = sha256_crypt.New()
|
||||
} else if strings.HasPrefix(user.Password, md5cryptPwdPrefix) {
|
||||
crypter = md5_crypt.New()
|
||||
} else if strings.HasPrefix(user.Password, md5cryptApr1PwdPrefix) {
|
||||
|
|
|
@ -7231,6 +7231,7 @@ func TestHashedPasswords(t *testing.T) {
|
|||
pwdMapping["$1$b5caebda$VODr/nyhGWgZaY8sJ4x05."] = plainPwd
|
||||
pwdMapping["$2a$14$ajq8Q7fbtFRQvXpdCq7Jcuy.Rx1h/L4J60Otx.gyNLbAYctGMJ9tK"] = "secret"
|
||||
pwdMapping["$6$459ead56b72e44bc$uog86fUxscjt28BZxqFBE2pp2QD8P/1e98MNF75Z9xJfQvOckZnQ/1YJqiq1XeytPuDieHZvDAMoP7352ELkO1"] = "secret"
|
||||
pwdMapping["$5$h4Aalt0fJdGX8sgv$Rd2ew0fvgzUN.DzAVlKa9QL4q/DZWo4SsKpB9.3AyZ/"] = plainPwd
|
||||
pwdMapping["$apr1$OBWLeSme$WoJbB736e7kKxMBIAqilb1"] = plainPwd
|
||||
pwdMapping["{MD5}5f4dcc3b5aa765d61d8327deb882cf99"] = plainPwd
|
||||
|
||||
|
|
Loading…
Reference in a new issue