mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2024-12-22 12:54:53 -05:00
Add salt for every single user
This commit is contained in:
parent
db1fe3483e
commit
e7c8a3cb8d
8 changed files with 64 additions and 30 deletions
|
@ -7,7 +7,6 @@ github.com/go-martini/martini =
|
||||||
github.com/Unknwon/com =
|
github.com/Unknwon/com =
|
||||||
github.com/Unknwon/cae =
|
github.com/Unknwon/cae =
|
||||||
github.com/Unknwon/goconfig =
|
github.com/Unknwon/goconfig =
|
||||||
github.com/dchest/scrypt =
|
|
||||||
github.com/nfnt/resize =
|
github.com/nfnt/resize =
|
||||||
github.com/lunny/xorm =
|
github.com/lunny/xorm =
|
||||||
github.com/go-sql-driver/mysql =
|
github.com/go-sql-driver/mysql =
|
||||||
|
|
|
@ -5,9 +5,9 @@ Gogs(Go Git Service) is a Self Hosted Git Service in the Go Programming Language
|
||||||
|
|
||||||
![Demo](http://gowalker.org/public/gogs_demo.gif)
|
![Demo](http://gowalker.org/public/gogs_demo.gif)
|
||||||
|
|
||||||
##### Current version: 0.2.1 Alpha
|
##### Current version: 0.2.2 Alpha
|
||||||
|
|
||||||
#### Due to testing purpose, data of [try.gogits.org](http://try.gogits.org) has been reset in March 29, 2014 and will reset multiple times after. Please do NOT put your important data on the site.
|
#### Due to testing purpose, data of [try.gogits.org](http://try.gogits.org) has been reset in April 6, 2014 and will reset multiple times after. Please do NOT put your important data on the site.
|
||||||
|
|
||||||
#### Other language version
|
#### Other language version
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ Gogs(Go Git Service) 是一个由 Go 语言编写的自助 Git 托管服务。
|
||||||
|
|
||||||
![Demo](http://gowalker.org/public/gogs_demo.gif)
|
![Demo](http://gowalker.org/public/gogs_demo.gif)
|
||||||
|
|
||||||
##### 当前版本:0.2.1 Alpha
|
##### 当前版本:0.2.2 Alpha
|
||||||
|
|
||||||
## 开发目的
|
## 开发目的
|
||||||
|
|
||||||
|
|
2
gogs.go
2
gogs.go
|
@ -19,7 +19,7 @@ import (
|
||||||
// Test that go1.2 tag above is included in builds. main.go refers to this definition.
|
// Test that go1.2 tag above is included in builds. main.go refers to this definition.
|
||||||
const go12tag = true
|
const go12tag = true
|
||||||
|
|
||||||
const APP_VER = "0.2.1.0406 Alpha"
|
const APP_VER = "0.2.2.0406 Alpha"
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
base.AppVer = APP_VER
|
base.AppVer = APP_VER
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
package models
|
package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/sha256"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
@ -13,8 +14,6 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/dchest/scrypt"
|
|
||||||
|
|
||||||
"github.com/gogits/git"
|
"github.com/gogits/git"
|
||||||
|
|
||||||
"github.com/gogits/gogs/modules/base"
|
"github.com/gogits/gogs/modules/base"
|
||||||
|
@ -62,6 +61,7 @@ type User struct {
|
||||||
IsActive bool
|
IsActive bool
|
||||||
IsAdmin bool
|
IsAdmin bool
|
||||||
Rands string `xorm:"VARCHAR(10)"`
|
Rands string `xorm:"VARCHAR(10)"`
|
||||||
|
Salt string `xorm:"VARCHAR(10)"`
|
||||||
Created time.Time `xorm:"created"`
|
Created time.Time `xorm:"created"`
|
||||||
Updated time.Time `xorm:"updated"`
|
Updated time.Time `xorm:"updated"`
|
||||||
}
|
}
|
||||||
|
@ -89,10 +89,9 @@ func (user *User) NewGitSig() *git.Signature {
|
||||||
}
|
}
|
||||||
|
|
||||||
// EncodePasswd encodes password to safe format.
|
// EncodePasswd encodes password to safe format.
|
||||||
func (user *User) EncodePasswd() error {
|
func (user *User) EncodePasswd() {
|
||||||
newPasswd, err := scrypt.Key([]byte(user.Passwd), []byte(base.SecretKey), 16384, 8, 1, 64)
|
newPasswd := base.PBKDF2([]byte(user.Passwd), []byte(user.Salt), 10000, 50, sha256.New)
|
||||||
user.Passwd = fmt.Sprintf("%x", newPasswd)
|
user.Passwd = fmt.Sprintf("%x", newPasswd)
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Member represents user is member of organization.
|
// Member represents user is member of organization.
|
||||||
|
@ -148,9 +147,9 @@ func RegisterUser(user *User) (*User, error) {
|
||||||
user.Avatar = base.EncodeMd5(user.Email)
|
user.Avatar = base.EncodeMd5(user.Email)
|
||||||
user.AvatarEmail = user.Email
|
user.AvatarEmail = user.Email
|
||||||
user.Rands = GetUserSalt()
|
user.Rands = GetUserSalt()
|
||||||
if err = user.EncodePasswd(); err != nil {
|
user.Salt = GetUserSalt()
|
||||||
return nil, err
|
user.EncodePasswd()
|
||||||
} else if _, err = orm.Insert(user); err != nil {
|
if _, err = orm.Insert(user); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
} else if err = os.MkdirAll(UserPath(user.Name), os.ModePerm); err != nil {
|
} else if err = os.MkdirAll(UserPath(user.Name), os.ModePerm); err != nil {
|
||||||
if _, err := orm.Id(user.Id).Delete(&User{}); err != nil {
|
if _, err := orm.Id(user.Id).Delete(&User{}); err != nil {
|
||||||
|
@ -384,18 +383,20 @@ func GetUserByEmail(email string) (*User, error) {
|
||||||
|
|
||||||
// LoginUserPlain validates user by raw user name and password.
|
// LoginUserPlain validates user by raw user name and password.
|
||||||
func LoginUserPlain(name, passwd string) (*User, error) {
|
func LoginUserPlain(name, passwd string) (*User, error) {
|
||||||
user := User{LowerName: strings.ToLower(name), Passwd: passwd}
|
user := User{LowerName: strings.ToLower(name)}
|
||||||
if err := user.EncodePasswd(); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
has, err := orm.Get(&user)
|
has, err := orm.Get(&user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
} else if !has {
|
} else if !has {
|
||||||
err = ErrUserNotExist
|
return nil, ErrUserNotExist
|
||||||
}
|
}
|
||||||
return &user, err
|
|
||||||
|
newUser := &User{Passwd: passwd, Salt: user.Salt}
|
||||||
|
newUser.EncodePasswd()
|
||||||
|
if user.Passwd != newUser.Passwd {
|
||||||
|
return nil, ErrUserNotExist
|
||||||
|
}
|
||||||
|
return &user, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Follow is connection request for receiving user notifycation.
|
// Follow is connection request for receiving user notifycation.
|
||||||
|
|
|
@ -6,12 +6,14 @@ package base
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"crypto/hmac"
|
||||||
"crypto/md5"
|
"crypto/md5"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"crypto/sha1"
|
"crypto/sha1"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"hash"
|
||||||
"math"
|
"math"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -40,6 +42,44 @@ func GetRandomString(n int, alphabets ...byte) string {
|
||||||
return string(bytes)
|
return string(bytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// http://code.google.com/p/go/source/browse/pbkdf2/pbkdf2.go?repo=crypto
|
||||||
|
func PBKDF2(password, salt []byte, iter, keyLen int, h func() hash.Hash) []byte {
|
||||||
|
prf := hmac.New(h, password)
|
||||||
|
hashLen := prf.Size()
|
||||||
|
numBlocks := (keyLen + hashLen - 1) / hashLen
|
||||||
|
|
||||||
|
var buf [4]byte
|
||||||
|
dk := make([]byte, 0, numBlocks*hashLen)
|
||||||
|
U := make([]byte, hashLen)
|
||||||
|
for block := 1; block <= numBlocks; block++ {
|
||||||
|
// N.B.: || means concatenation, ^ means XOR
|
||||||
|
// for each block T_i = U_1 ^ U_2 ^ ... ^ U_iter
|
||||||
|
// U_1 = PRF(password, salt || uint(i))
|
||||||
|
prf.Reset()
|
||||||
|
prf.Write(salt)
|
||||||
|
buf[0] = byte(block >> 24)
|
||||||
|
buf[1] = byte(block >> 16)
|
||||||
|
buf[2] = byte(block >> 8)
|
||||||
|
buf[3] = byte(block)
|
||||||
|
prf.Write(buf[:4])
|
||||||
|
dk = prf.Sum(dk)
|
||||||
|
T := dk[len(dk)-hashLen:]
|
||||||
|
copy(U, T)
|
||||||
|
|
||||||
|
// U_n = PRF(password, U_(n-1))
|
||||||
|
for n := 2; n <= iter; n++ {
|
||||||
|
prf.Reset()
|
||||||
|
prf.Write(U)
|
||||||
|
U = U[:0]
|
||||||
|
U = prf.Sum(U)
|
||||||
|
for x := range U {
|
||||||
|
T[x] ^= U[x]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dk[:keyLen]
|
||||||
|
}
|
||||||
|
|
||||||
// verify time limit code
|
// verify time limit code
|
||||||
func VerifyTimeLimitCode(data string, minutes int, code string) bool {
|
func VerifyTimeLimitCode(data string, minutes int, code string) bool {
|
||||||
if len(code) <= 18 {
|
if len(code) <= 18 {
|
||||||
|
|
|
@ -73,11 +73,7 @@ func SettingPassword(ctx *middleware.Context, form auth.UpdatePasswdForm) {
|
||||||
|
|
||||||
user := ctx.User
|
user := ctx.User
|
||||||
newUser := &models.User{Passwd: form.NewPasswd}
|
newUser := &models.User{Passwd: form.NewPasswd}
|
||||||
if err := newUser.EncodePasswd(); err != nil {
|
newUser.EncodePasswd()
|
||||||
ctx.Handle(200, "setting.SettingPassword", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if user.Passwd != newUser.Passwd {
|
if user.Passwd != newUser.Passwd {
|
||||||
ctx.Data["HasError"] = true
|
ctx.Data["HasError"] = true
|
||||||
ctx.Data["ErrorMsg"] = "Old password is not correct"
|
ctx.Data["ErrorMsg"] = "Old password is not correct"
|
||||||
|
@ -85,6 +81,7 @@ func SettingPassword(ctx *middleware.Context, form auth.UpdatePasswdForm) {
|
||||||
ctx.Data["HasError"] = true
|
ctx.Data["HasError"] = true
|
||||||
ctx.Data["ErrorMsg"] = "New password and re-type password are not same"
|
ctx.Data["ErrorMsg"] = "New password and re-type password are not same"
|
||||||
} else {
|
} else {
|
||||||
|
newUser.Salt = models.GetUserSalt()
|
||||||
user.Passwd = newUser.Passwd
|
user.Passwd = newUser.Passwd
|
||||||
if err := models.UpdateUser(user); err != nil {
|
if err := models.UpdateUser(user); err != nil {
|
||||||
ctx.Handle(200, "setting.SettingPassword", err)
|
ctx.Handle(200, "setting.SettingPassword", err)
|
||||||
|
|
|
@ -477,12 +477,9 @@ func ResetPasswd(ctx *middleware.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
u.Passwd = passwd
|
u.Passwd = passwd
|
||||||
if err := u.EncodePasswd(); err != nil {
|
|
||||||
ctx.Handle(404, "user.ResetPasswd(EncodePasswd)", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
u.Rands = models.GetUserSalt()
|
u.Rands = models.GetUserSalt()
|
||||||
|
u.Salt = models.GetUserSalt()
|
||||||
|
u.EncodePasswd()
|
||||||
if err := models.UpdateUser(u); err != nil {
|
if err := models.UpdateUser(u); err != nil {
|
||||||
ctx.Handle(404, "user.ResetPasswd(UpdateUser)", err)
|
ctx.Handle(404, "user.ResetPasswd(UpdateUser)", err)
|
||||||
return
|
return
|
||||||
|
|
Loading…
Reference in a new issue