summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gopmfile1
-rw-r--r--README.md4
-rw-r--r--README_ZH.md2
-rw-r--r--gogs.go2
-rw-r--r--models/user.go31
-rw-r--r--modules/base/tool.go40
-rw-r--r--routers/user/setting.go7
-rw-r--r--routers/user/user.go7
8 files changed, 64 insertions, 30 deletions
diff --git a/.gopmfile b/.gopmfile
index 9bdca49fc8..c9fad8a036 100644
--- a/.gopmfile
+++ b/.gopmfile
@@ -7,7 +7,6 @@ github.com/go-martini/martini =
github.com/Unknwon/com =
github.com/Unknwon/cae =
github.com/Unknwon/goconfig =
-github.com/dchest/scrypt =
github.com/nfnt/resize =
github.com/lunny/xorm =
github.com/go-sql-driver/mysql =
diff --git a/README.md b/README.md
index ede1894ad0..fe15328b1b 100644
--- a/README.md
+++ b/README.md
@@ -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)
-##### 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
diff --git a/README_ZH.md b/README_ZH.md
index 9b5e46413e..015ee0af99 100644
--- a/README_ZH.md
+++ b/README_ZH.md
@@ -5,7 +5,7 @@ Gogs(Go Git Service) 是一个由 Go 语言编写的自助 Git 托管服务。
![Demo](http://gowalker.org/public/gogs_demo.gif)
-##### 当前版本:0.2.1 Alpha
+##### 当前版本:0.2.2 Alpha
## 开发目的
diff --git a/gogs.go b/gogs.go
index 0e48ff7b11..e719748200 100644
--- a/gogs.go
+++ b/gogs.go
@@ -19,7 +19,7 @@ import (
// Test that go1.2 tag above is included in builds. main.go refers to this definition.
const go12tag = true
-const APP_VER = "0.2.1.0406 Alpha"
+const APP_VER = "0.2.2.0406 Alpha"
func init() {
base.AppVer = APP_VER
diff --git a/models/user.go b/models/user.go
index 2196eae84f..a5a6de097f 100644
--- a/models/user.go
+++ b/models/user.go
@@ -5,6 +5,7 @@
package models
import (
+ "crypto/sha256"
"encoding/hex"
"errors"
"fmt"
@@ -13,8 +14,6 @@ import (
"strings"
"time"
- "github.com/dchest/scrypt"
-
"github.com/gogits/git"
"github.com/gogits/gogs/modules/base"
@@ -62,6 +61,7 @@ type User struct {
IsActive bool
IsAdmin bool
Rands string `xorm:"VARCHAR(10)"`
+ Salt string `xorm:"VARCHAR(10)"`
Created time.Time `xorm:"created"`
Updated time.Time `xorm:"updated"`
}
@@ -89,10 +89,9 @@ func (user *User) NewGitSig() *git.Signature {
}
// 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)
- return err
}
// Member represents user is member of organization.
@@ -148,9 +147,9 @@ func RegisterUser(user *User) (*User, error) {
user.Avatar = base.EncodeMd5(user.Email)
user.AvatarEmail = user.Email
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
} else if err = os.MkdirAll(UserPath(user.Name), os.ModePerm); 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.
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)
if err != nil {
return nil, err
} 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.
diff --git a/modules/base/tool.go b/modules/base/tool.go
index 3946c4b56b..f7d1bc2c55 100644
--- a/modules/base/tool.go
+++ b/modules/base/tool.go
@@ -6,12 +6,14 @@ package base
import (
"bytes"
+ "crypto/hmac"
"crypto/md5"
"crypto/rand"
"crypto/sha1"
"encoding/hex"
"encoding/json"
"fmt"
+ "hash"
"math"
"strconv"
"strings"
@@ -40,6 +42,44 @@ func GetRandomString(n int, alphabets ...byte) string {
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
func VerifyTimeLimitCode(data string, minutes int, code string) bool {
if len(code) <= 18 {
diff --git a/routers/user/setting.go b/routers/user/setting.go
index 4b6d88a362..ea779e8549 100644
--- a/routers/user/setting.go
+++ b/routers/user/setting.go
@@ -73,11 +73,7 @@ func SettingPassword(ctx *middleware.Context, form auth.UpdatePasswdForm) {
user := ctx.User
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 {
ctx.Data["HasError"] = true
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["ErrorMsg"] = "New password and re-type password are not same"
} else {
+ newUser.Salt = models.GetUserSalt()
user.Passwd = newUser.Passwd
if err := models.UpdateUser(user); err != nil {
ctx.Handle(200, "setting.SettingPassword", err)
diff --git a/routers/user/user.go b/routers/user/user.go
index 872ed0d600..12f2bd8c51 100644
--- a/routers/user/user.go
+++ b/routers/user/user.go
@@ -477,12 +477,9 @@ func ResetPasswd(ctx *middleware.Context) {
}
u.Passwd = passwd
- if err := u.EncodePasswd(); err != nil {
- ctx.Handle(404, "user.ResetPasswd(EncodePasswd)", err)
- return
- }
-
u.Rands = models.GetUserSalt()
+ u.Salt = models.GetUserSalt()
+ u.EncodePasswd()
if err := models.UpdateUser(u); err != nil {
ctx.Handle(404, "user.ResetPasswd(UpdateUser)", err)
return