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
This commit is contained in:
		
							parent
							
								
									952587dbae
								
							
						
					
					
						commit
						380e32e129
					
				| @ -457,8 +457,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 | ||||||
| 		} | 		} | ||||||
|  | |||||||
| @ -109,8 +109,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 | ||||||
|  | |||||||
| @ -532,7 +532,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) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -604,8 +604,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 | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -122,7 +122,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) | ||||||
|  | |||||||
| @ -13,6 +13,7 @@ import ( | |||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"html/template" | 	"html/template" | ||||||
| 	"math" | 	"math" | ||||||
|  | 	"math/big" | ||||||
| 	"net/http" | 	"net/http" | ||||||
| 	"strconv" | 	"strconv" | ||||||
| 	"strings" | 	"strings" | ||||||
| @ -81,18 +82,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 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // VerifyTimeLimitCode verify time limit code
 | // VerifyTimeLimitCode verify time limit code
 | ||||||
|  | |||||||
| @ -43,7 +43,9 @@ func TestBasicAuthEncode(t *testing.T) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 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()
 | ||||||
|  | |||||||
| @ -197,7 +197,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() | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -87,7 +87,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() | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -115,6 +115,7 @@ func Install(ctx *context.Context) { | |||||||
| 
 | 
 | ||||||
| // 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() { | ||||||
| @ -131,7 +132,7 @@ func InstallPost(ctx *context.Context, form auth.InstallForm) { | |||||||
| 		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 | ||||||
| 	} | 	} | ||||||
| @ -161,7 +162,7 @@ func InstallPost(ctx *context.Context, form auth.InstallForm) { | |||||||
| 
 | 
 | ||||||
| 	// 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) | ||||||
| @ -174,7 +175,7 @@ func InstallPost(ctx *context.Context, form auth.InstallForm) { | |||||||
| 
 | 
 | ||||||
| 	// 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 | ||||||
| @ -182,7 +183,7 @@ func InstallPost(ctx *context.Context, form auth.InstallForm) { | |||||||
| 
 | 
 | ||||||
| 	// 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 | ||||||
| @ -225,7 +226,7 @@ func InstallPost(ctx *context.Context, form auth.InstallForm) { | |||||||
| 	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) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| @ -279,15 +280,20 @@ 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)) | 	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 | ||||||
| 	} | 	} | ||||||
| @ -303,7 +309,7 @@ func InstallPost(ctx *context.Context, form auth.InstallForm) { | |||||||
| 			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 | ||||||
| @ -316,11 +322,11 @@ func InstallPost(ctx *context.Context, form auth.InstallForm) { | |||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		// 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 | ||||||
| 		} | 		} | ||||||
|  | |||||||
| @ -289,7 +289,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) | ||||||
| @ -428,8 +432,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) | ||||||
|  | |||||||
| @ -197,7 +197,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…
	
		Reference in New Issue
	
	Block a user