From e4b740b5bcce81a9e9765752878e05e508e0fbfd Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Mon, 16 Dec 2019 13:04:52 +0100 Subject: [PATCH] admin: Use SSHA password instead of APR1 --- admin/api/certificate.go | 38 +++++++++++++++++++++++++++++++------- 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/admin/api/certificate.go b/admin/api/certificate.go index b962be6f..6d22d299 100644 --- a/admin/api/certificate.go +++ b/admin/api/certificate.go @@ -2,9 +2,11 @@ package api import ( "crypto/rand" + "crypto/sha1" "crypto/x509" "crypto/x509/pkix" "encoding/base32" + "encoding/base64" "encoding/json" "errors" "fmt" @@ -28,7 +30,11 @@ var TeamsDir string func init() { router.GET("/api/htpasswd", apiHandler( func(httprouter.Params, []byte) (interface{}, error) { - return genHtpasswd() + return genHtpasswd(true) + })) + router.GET("/api/htpasswd.apr1", apiHandler( + func(httprouter.Params, []byte) (interface{}, error) { + return genHtpasswd(false) })) router.GET("/api/ca/", apiHandler(infoCA)) router.GET("/api/ca.pem", apiHandler(getCAPEM)) @@ -88,7 +94,7 @@ func init() { func(cert fic.Certificate, _ []byte) (interface{}, error) { return cert.Revoke() }))) } -func genHtpasswd() (ret string, err error) { +func genHtpasswd(ssha bool) (ret string, err error) { var teams []fic.Team teams, err = fic.GetTeams() if err != nil { @@ -111,20 +117,38 @@ func genHtpasswd() (ret string, err error) { var cert fic.Certificate cert, err = fic.GetCertificate(serial) if err != nil { - return + // Ignore invalid/incorrect/non-existant certificates + continue } if cert.Revoked != nil { continue } - b := make([]byte, 5) - if _, err = rand.Read(b); err != nil { + salt := make([]byte, 5) + if _, err = rand.Read(salt); err != nil { return } - salt := base32.StdEncoding.EncodeToString(b) - ret += fmt.Sprintf("%s:$apr1$%s$%s\n", strings.ToLower(team.Name), salt, fic.Apr1Md5(cert.Password, salt)) + if ssha { + hash := sha1.New() + hash.Write([]byte(cert.Password)) + hash.Write([]byte(salt)) + + ret += fmt.Sprintf( + "%s:{SSHA}%s\n", + strings.ToLower(team.Name), + base64.StdEncoding.EncodeToString(append(hash.Sum(nil), salt...)), + ) + } else { + salt32 := base32.StdEncoding.EncodeToString(salt) + ret += fmt.Sprintf( + "%s:$apr1$%s$%s\n", + strings.ToLower(team.Name), + salt32, + fic.Apr1Md5(cert.Password, salt32), + ) + } } }