Browse Source

Fix random string generator (#384)

* Remove unused custom-alphabet feature of random string generator

Fix random string generator

Random string generator should return error if it fails to read random data via crypto/rand

* Fixes variable (un)initialization mixed assign
Update test GetRandomString
tags/v1.0.0
Denis Denisov 7 years ago
parent
commit
380e32e129

+ 6
- 2
models/migrations/migrations.go View File

} }


for _, org := range orgs { for _, org := range orgs {
org.Rands = base.GetRandomString(10)
org.Salt = base.GetRandomString(10)
if org.Rands, err = base.GetRandomString(10); err != nil {
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
} }

+ 6
- 2
models/org.go View File

} }


org.LowerName = strings.ToLower(org.Name) org.LowerName = strings.ToLower(org.Name)
org.Rands = GetUserSalt()
org.Salt = GetUserSalt()
if org.Rands, err = GetUserSalt(); err != nil {
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

+ 7
- 3
models/user.go View File

} }


// 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)
} }


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()
u.Salt = GetUserSalt()
if u.Rands, err = GetUserSalt(); err != nil {
return err
}
if u.Salt, err = GetUserSalt(); err != nil {
return err
}
u.EncodePasswd() u.EncodePasswd()
u.MaxRepoCreation = -1 u.MaxRepoCreation = -1



+ 3
- 1
models/user_mail.go View File

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)

+ 23
- 9
modules/base/tool.go View File

"fmt" "fmt"
"html/template" "html/template"
"math" "math"
"math/big"
"net/http" "net/http"
"strconv" "strconv"
"strings" "strings"
} }


// 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)
for i, b := range bytes {
if len(alphabets) == 0 {
bytes[i] = alphanum[b%byte(len(alphanum))]
} else {
bytes[i] = alphabets[b%byte(len(alphabets))]

buffer := make([]byte, n)
max := big.NewInt(int64(len(alphanum)))

for i := 0; i < n; i++ {
index, err := randomInt(max)
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
} }


// VerifyTimeLimitCode verify time limit code // VerifyTimeLimitCode verify time limit code

+ 3
- 1
modules/base/tool_test.go View File

} }


func TestGetRandomString(t *testing.T) { func TestGetRandomString(t *testing.T) {
assert.Len(t, GetRandomString(4), 4)
randomString, err := GetRandomString(4)
assert.NoError(t, err)
assert.Len(t, randomString, 4)
} }


// TODO: Test PBKDF2() // TODO: Test PBKDF2()

+ 5
- 1
routers/admin/users.go View File



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()
} }



+ 5
- 1
routers/api/v1/admin/user.go View File



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()
} }



+ 17
- 11
routers/install.go View File



// InstallPost response for submit install items // InstallPost response for submit install items
func InstallPost(ctx *context.Context, form auth.InstallForm) { func InstallPost(ctx *context.Context, form auth.InstallForm) {
var err error
ctx.Data["CurDbOption"] = form.DbType ctx.Data["CurDbOption"] = form.DbType


if ctx.HasError() { if ctx.HasError() {
return return
} }


if _, err := exec.LookPath("git"); err != nil {
if _, err = exec.LookPath("git"); err != nil {
ctx.RenderWithErr(ctx.Tr("install.test_git_failed", err), tplInstall, &form) ctx.RenderWithErr(ctx.Tr("install.test_git_failed", err), tplInstall, &form)
return return
} }


// Set test engine. // Set test engine.
var x *xorm.Engine var x *xorm.Engine
if err := models.NewTestEngine(x); err != nil {
if err = models.NewTestEngine(x); err != nil {
if strings.Contains(err.Error(), `Unknown database type: sqlite3`) { if strings.Contains(err.Error(), `Unknown database type: sqlite3`) {
ctx.Data["Err_DbType"] = true ctx.Data["Err_DbType"] = true
ctx.RenderWithErr(ctx.Tr("install.sqlite3_not_available", "https://docs.gitea.io/installation/install_from_binary.html"), tplInstall, &form) ctx.RenderWithErr(ctx.Tr("install.sqlite3_not_available", "https://docs.gitea.io/installation/install_from_binary.html"), tplInstall, &form)


// Test repository root path. // Test repository root path.
form.RepoRootPath = strings.Replace(form.RepoRootPath, "\\", "/", -1) form.RepoRootPath = strings.Replace(form.RepoRootPath, "\\", "/", -1)
if err := os.MkdirAll(form.RepoRootPath, os.ModePerm); err != nil {
if err = os.MkdirAll(form.RepoRootPath, os.ModePerm); err != nil {
ctx.Data["Err_RepoRootPath"] = true ctx.Data["Err_RepoRootPath"] = true
ctx.RenderWithErr(ctx.Tr("install.invalid_repo_path", err), tplInstall, &form) ctx.RenderWithErr(ctx.Tr("install.invalid_repo_path", err), tplInstall, &form)
return return


// Test log root path. // Test log root path.
form.LogRootPath = strings.Replace(form.LogRootPath, "\\", "/", -1) form.LogRootPath = strings.Replace(form.LogRootPath, "\\", "/", -1)
if err := os.MkdirAll(form.LogRootPath, os.ModePerm); err != nil {
if err = os.MkdirAll(form.LogRootPath, os.ModePerm); err != nil {
ctx.Data["Err_LogRootPath"] = true ctx.Data["Err_LogRootPath"] = true
ctx.RenderWithErr(ctx.Tr("install.invalid_log_root_path", err), tplInstall, &form) ctx.RenderWithErr(ctx.Tr("install.invalid_log_root_path", err), tplInstall, &form)
return return
cfg := ini.Empty() cfg := ini.Empty()
if com.IsFile(setting.CustomConf) { if com.IsFile(setting.CustomConf) {
// Keeps custom settings if there is already something. // Keeps custom settings if there is already something.
if err := cfg.Append(setting.CustomConf); err != nil {
if err = cfg.Append(setting.CustomConf); err != nil {
log.Error(4, "Fail to load custom conf '%s': %v", setting.CustomConf, err) log.Error(4, "Fail to load custom conf '%s': %v", setting.CustomConf, err)
} }
} }
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))
var secretKey string
if secretKey, err = base.GetRandomString(10); err != nil {
ctx.RenderWithErr(ctx.Tr("install.secret_key_failed", err), tplInstall, &form)
return
}
cfg.Section("security").Key("SECRET_KEY").SetValue(secretKey)


err := os.MkdirAll(filepath.Dir(setting.CustomConf), os.ModePerm)
err = os.MkdirAll(filepath.Dir(setting.CustomConf), os.ModePerm)
if err != nil { if err != nil {
ctx.RenderWithErr(ctx.Tr("install.save_config_failed", err), tplInstall, &form) ctx.RenderWithErr(ctx.Tr("install.save_config_failed", err), tplInstall, &form)
return return
} }


if err := cfg.SaveTo(setting.CustomConf); err != nil {
if err = cfg.SaveTo(setting.CustomConf); err != nil {
ctx.RenderWithErr(ctx.Tr("install.save_config_failed", err), tplInstall, &form) ctx.RenderWithErr(ctx.Tr("install.save_config_failed", err), tplInstall, &form)
return return
} }
IsAdmin: true, IsAdmin: true,
IsActive: true, IsActive: true,
} }
if err := models.CreateUser(u); err != nil {
if err = models.CreateUser(u); err != nil {
if !models.IsErrUserAlreadyExist(err) { if !models.IsErrUserAlreadyExist(err) {
setting.InstallLock = false setting.InstallLock = false
ctx.Data["Err_AdminName"] = true ctx.Data["Err_AdminName"] = true
} }


// Auto-login for admin // Auto-login for admin
if err := ctx.Session.Set("uid", u.ID); err != nil {
if err = ctx.Session.Set("uid", u.ID); err != nil {
ctx.RenderWithErr(ctx.Tr("install.save_config_failed", err), tplInstall, &form) ctx.RenderWithErr(ctx.Tr("install.save_config_failed", err), tplInstall, &form)
return return
} }
if err := ctx.Session.Set("uname", u.Name); err != nil {
if err = ctx.Session.Set("uname", u.Name); err != nil {
ctx.RenderWithErr(ctx.Tr("install.save_config_failed", err), tplInstall, &form) ctx.RenderWithErr(ctx.Tr("install.save_config_failed", err), tplInstall, &form)
return return
} }

+ 14
- 3
routers/user/auth.go View File

// 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)
} }


u.Passwd = passwd u.Passwd = passwd
u.Rands = models.GetUserSalt()
u.Salt = models.GetUserSalt()
var err error
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)

+ 5
- 1
routers/user/setting.go View File

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