Browse Source

Fix random string generator (#3953)

* Remove unused custom-alphabet feature of random string generator

* Fix modulo-biased random string generator

* Random string generator should return error if it fails to read random data via crypto/rand
pull/3781/merge
leonklingele 8 years ago committed by 无闻
parent
commit
d96f2a7184
  1. 8
      models/migrations/migrations.go
  2. 8
      models/org.go
  3. 10
      models/user.go
  4. 4
      models/user_mail.go
  5. 32
      modules/base/tool.go
  6. 6
      routers/admin/users.go
  7. 6
      routers/api/v1/admin/user.go
  8. 7
      routers/install.go
  9. 17
      routers/user/auth.go
  10. 6
      routers/user/setting.go

8
models/migrations/migrations.go

@ -451,8 +451,12 @@ func generateOrgRandsAndSalt(x *xorm.Engine) (err error) {
} }
for _, org := range orgs { for _, org := range orgs {
org.Rands = base.GetRandomString(10) if org.Rands, err = base.GetRandomString(10); err != nil {
org.Salt = base.GetRandomString(10) return err
}
if org.Salt, err = base.GetRandomString(10); err != nil {
return err
}
if _, err = sess.Id(org.ID).Update(org); err != nil { if _, err = sess.Id(org.ID).Update(org); err != nil {
return err return err
} }

8
models/org.go

@ -108,8 +108,12 @@ func CreateOrganization(org, owner *User) (err error) {
} }
org.LowerName = strings.ToLower(org.Name) org.LowerName = strings.ToLower(org.Name)
org.Rands = GetUserSalt() if org.Rands, err = GetUserSalt(); err != nil {
org.Salt = GetUserSalt() return err
}
if org.Salt, err = GetUserSalt(); err != nil {
return err
}
org.UseCustomAvatar = true org.UseCustomAvatar = true
org.MaxRepoCreation = -1 org.MaxRepoCreation = -1
org.NumTeams = 1 org.NumTeams = 1

10
models/user.go

@ -474,7 +474,7 @@ func IsUserExist(uid int64, name string) (bool, error) {
} }
// GetUserSalt returns a ramdom user salt token. // GetUserSalt returns a ramdom user salt token.
func GetUserSalt() string { func GetUserSalt() (string, error) {
return base.GetRandomString(10) return base.GetRandomString(10)
} }
@ -545,8 +545,12 @@ func CreateUser(u *User) (err error) {
u.LowerName = strings.ToLower(u.Name) u.LowerName = strings.ToLower(u.Name)
u.AvatarEmail = u.Email u.AvatarEmail = u.Email
u.Avatar = base.HashEmail(u.AvatarEmail) u.Avatar = base.HashEmail(u.AvatarEmail)
u.Rands = GetUserSalt() if u.Rands, err = GetUserSalt(); err != nil {
u.Salt = GetUserSalt() return err
}
if u.Salt, err = GetUserSalt(); err != nil {
return err
}
u.EncodePasswd() u.EncodePasswd()
u.MaxRepoCreation = -1 u.MaxRepoCreation = -1

4
models/user_mail.go

@ -111,7 +111,9 @@ func (email *EmailAddress) Activate() error {
if err != nil { if err != nil {
return err return err
} }
user.Rands = GetUserSalt() if user.Rands, err = GetUserSalt(); err != nil {
return err
}
sess := x.NewSession() sess := x.NewSession()
defer sessionRelease(sess) defer sessionRelease(sess)

32
modules/base/tool.go

@ -15,6 +15,7 @@ import (
"hash" "hash"
"html/template" "html/template"
"math" "math"
"math/big"
"net/http" "net/http"
"strings" "strings"
"time" "time"
@ -82,18 +83,31 @@ func BasicAuthEncode(username, password string) string {
} }
// GetRandomString generate random string by specify chars. // GetRandomString generate random string by specify chars.
func GetRandomString(n int, alphabets ...byte) string { func GetRandomString(n int) (string, error) {
const alphanum = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" const alphanum = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
var bytes = make([]byte, n)
rand.Read(bytes) buffer := make([]byte, n)
for i, b := range bytes { max := big.NewInt(int64(len(alphanum)))
if len(alphabets) == 0 {
bytes[i] = alphanum[b%byte(len(alphanum))] for i := 0; i < n; i++ {
} else { index, err := randomInt(max)
bytes[i] = alphabets[b%byte(len(alphabets))] if err != nil {
return "", err
} }
buffer[i] = alphanum[index]
} }
return string(bytes)
return string(buffer), nil
}
func randomInt(max *big.Int) (int, error) {
rand, err := rand.Int(rand.Reader, max)
if err != nil {
return 0, err
}
return int(rand.Int64()), nil
} }
// http://code.google.com/p/go/source/browse/pbkdf2/pbkdf2.go?repo=crypto // http://code.google.com/p/go/source/browse/pbkdf2/pbkdf2.go?repo=crypto

6
routers/admin/users.go

@ -192,7 +192,11 @@ func EditUserPost(ctx *context.Context, form auth.AdminEditUserForm) {
if len(form.Password) > 0 { if len(form.Password) > 0 {
u.Passwd = form.Password u.Passwd = form.Password
u.Salt = models.GetUserSalt() var err error
if u.Salt, err = models.GetUserSalt(); err != nil {
ctx.Handle(500, "UpdateUser", err)
return
}
u.EncodePasswd() u.EncodePasswd()
} }

6
routers/api/v1/admin/user.go

@ -85,7 +85,11 @@ func EditUser(ctx *context.APIContext, form api.EditUserOption) {
if len(form.Password) > 0 { if len(form.Password) > 0 {
u.Passwd = form.Password u.Passwd = form.Password
u.Salt = models.GetUserSalt() var err error
if u.Salt, err = models.GetUserSalt(); err != nil {
ctx.Error(500, "UpdateUser", err)
return
}
u.EncodePasswd() u.EncodePasswd()
} }

7
routers/install.go

@ -343,7 +343,12 @@ func InstallPost(ctx *context.Context, form auth.InstallForm) {
cfg.Section("log").Key("ROOT_PATH").SetValue(form.LogRootPath) cfg.Section("log").Key("ROOT_PATH").SetValue(form.LogRootPath)
cfg.Section("security").Key("INSTALL_LOCK").SetValue("true") cfg.Section("security").Key("INSTALL_LOCK").SetValue("true")
cfg.Section("security").Key("SECRET_KEY").SetValue(base.GetRandomString(15)) secretKey, err := base.GetRandomString(15)
if err != nil {
ctx.RenderWithErr(ctx.Tr("install.secret_key_failed", err), INSTALL, &form)
return
}
cfg.Section("security").Key("SECRET_KEY").SetValue(secretKey)
os.MkdirAll(filepath.Dir(setting.CustomConf), os.ModePerm) os.MkdirAll(filepath.Dir(setting.CustomConf), os.ModePerm)
if err := cfg.SaveTo(setting.CustomConf); err != nil { if err := cfg.SaveTo(setting.CustomConf); err != nil {

17
routers/user/auth.go

@ -273,7 +273,11 @@ func Activate(ctx *context.Context) {
// Verify code. // Verify code.
if user := models.VerifyUserActiveCode(code); user != nil { if user := models.VerifyUserActiveCode(code); user != nil {
user.IsActive = true user.IsActive = true
user.Rands = models.GetUserSalt() var err error
if user.Rands, err = models.GetUserSalt(); err != nil {
ctx.Handle(500, "UpdateUser", err)
return
}
if err := models.UpdateUser(user); err != nil { if err := models.UpdateUser(user); err != nil {
if models.IsErrUserNotExist(err) { if models.IsErrUserNotExist(err) {
ctx.Error(404) ctx.Error(404)
@ -407,8 +411,15 @@ func ResetPasswdPost(ctx *context.Context) {
} }
u.Passwd = passwd u.Passwd = passwd
u.Rands = models.GetUserSalt() var err error
u.Salt = models.GetUserSalt() if u.Rands, err = models.GetUserSalt(); err != nil {
ctx.Handle(500, "UpdateUser", err)
return
}
if u.Salt, err = models.GetUserSalt(); err != nil {
ctx.Handle(500, "UpdateUser", err)
return
}
u.EncodePasswd() u.EncodePasswd()
if err := models.UpdateUser(u); err != nil { if err := models.UpdateUser(u); err != nil {
ctx.Handle(500, "UpdateUser", err) ctx.Handle(500, "UpdateUser", err)

6
routers/user/setting.go

@ -189,7 +189,11 @@ func SettingsPasswordPost(ctx *context.Context, form auth.ChangePasswordForm) {
ctx.Flash.Error(ctx.Tr("form.password_not_match")) ctx.Flash.Error(ctx.Tr("form.password_not_match"))
} else { } else {
ctx.User.Passwd = form.Password ctx.User.Passwd = form.Password
ctx.User.Salt = models.GetUserSalt() var err error
if ctx.User.Salt, err = models.GetUserSalt(); err != nil {
ctx.Handle(500, "UpdateUser", err)
return
}
ctx.User.EncodePasswd() ctx.User.EncodePasswd()
if err := models.UpdateUser(ctx.User); err != nil { if err := models.UpdateUser(ctx.User); err != nil {
ctx.Handle(500, "UpdateUser", err) ctx.Handle(500, "UpdateUser", err)

Loading…
Cancel
Save