Browse Source

Add salt for every single user

tags/v1.2.0-rc1
Unknown 12 years ago
parent
commit
e7c8a3cb8d
8 changed files with 64 additions and 30 deletions
  1. +0
    -1
      .gopmfile
  2. +2
    -2
      README.md
  3. +1
    -1
      README_ZH.md
  4. +1
    -1
      gogs.go
  5. +16
    -15
      models/user.go
  6. +40
    -0
      modules/base/tool.go
  7. +2
    -5
      routers/user/setting.go
  8. +2
    -5
      routers/user/user.go

+ 0
- 1
.gopmfile View File

@@ -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 =


+ 2
- 2
README.md View File

@@ -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




+ 1
- 1
README_ZH.md View File

@@ -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


## 开发目的 ## 开发目的




+ 1
- 1
gogs.go View File

@@ -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


+ 16
- 15
models/user.go View File

@@ -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 {
newPasswd, err := scrypt.Key([]byte(user.Passwd), []byte(base.SecretKey), 16384, 8, 1, 64)
func (user *User) EncodePasswd() {
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 {
return nil, err
} else if _, err = orm.Insert(user); err != nil {
user.Salt = GetUserSalt()
user.EncodePasswd()
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}
if err := user.EncodePasswd(); err != nil {
return nil, err
}

user := User{LowerName: strings.ToLower(name)}
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
}

newUser := &User{Passwd: passwd, Salt: user.Salt}
newUser.EncodePasswd()
if user.Passwd != newUser.Passwd {
return nil, ErrUserNotExist
} }
return &user, err
return &user, nil
} }


// Follow is connection request for receiving user notifycation. // Follow is connection request for receiving user notifycation.


+ 40
- 0
modules/base/tool.go View File

@@ -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 {


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

@@ -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 {
ctx.Handle(200, "setting.SettingPassword", err)
return
}

newUser.EncodePasswd()
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)


+ 2
- 5
routers/user/user.go View File

@@ -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…
Cancel
Save