| 
									
										
										
										
											2015-01-08 16:00:00 +08:00
										 |  |  | package util | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"crypto/hmac" | 
					
						
							| 
									
										
										
										
											2015-01-27 19:05:23 +08:00
										 |  |  | 	"crypto/md5" | 
					
						
							| 
									
										
										
										
											2015-01-08 16:00:00 +08:00
										 |  |  | 	"crypto/rand" | 
					
						
							|  |  |  | 	"crypto/sha256" | 
					
						
							| 
									
										
										
										
											2015-03-02 16:58:35 +08:00
										 |  |  | 	"encoding/base64" | 
					
						
							| 
									
										
										
										
											2015-01-27 19:05:23 +08:00
										 |  |  | 	"encoding/hex" | 
					
						
							| 
									
										
										
										
											2015-06-30 15:37:52 +08:00
										 |  |  | 	"errors" | 
					
						
							| 
									
										
										
										
											2015-01-08 16:00:00 +08:00
										 |  |  | 	"hash" | 
					
						
							| 
									
										
										
										
											2015-06-30 15:37:52 +08:00
										 |  |  | 	"strings" | 
					
						
							| 
									
										
										
										
											2015-01-08 16:00:00 +08:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // source: https://github.com/gogits/gogs/blob/9ee80e3e5426821f03a4e99fad34418f5c736413/modules/base/tool.go#L58
 | 
					
						
							|  |  |  | func GetRandomString(n int, alphabets ...byte) string { | 
					
						
							|  |  |  | 	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))] | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return string(bytes) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func EncodePassword(password string, salt string) string { | 
					
						
							|  |  |  | 	newPasswd := PBKDF2([]byte(password), []byte(salt), 10000, 50, sha256.New) | 
					
						
							| 
									
										
										
										
											2017-11-09 01:10:11 +08:00
										 |  |  | 	return hex.EncodeToString(newPasswd) | 
					
						
							| 
									
										
										
										
											2015-01-08 16:00:00 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-27 19:05:23 +08:00
										 |  |  | // Encode string to md5 hex value.
 | 
					
						
							|  |  |  | func EncodeMd5(str string) string { | 
					
						
							|  |  |  | 	m := md5.New() | 
					
						
							|  |  |  | 	m.Write([]byte(str)) | 
					
						
							|  |  |  | 	return hex.EncodeToString(m.Sum(nil)) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-08 16:00:00 +08:00
										 |  |  | // 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] | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2015-03-02 16:58:35 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | func GetBasicAuthHeader(user string, password string) string { | 
					
						
							|  |  |  | 	var userAndPass = user + ":" + password | 
					
						
							|  |  |  | 	return "Basic " + base64.StdEncoding.EncodeToString([]byte(userAndPass)) | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2015-06-30 15:37:52 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | func DecodeBasicAuthHeader(header string) (string, string, error) { | 
					
						
							|  |  |  | 	var code string | 
					
						
							|  |  |  | 	parts := strings.SplitN(header, " ", 2) | 
					
						
							|  |  |  | 	if len(parts) == 2 && parts[0] == "Basic" { | 
					
						
							|  |  |  | 		code = parts[1] | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	decoded, err := base64.StdEncoding.DecodeString(code) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return "", "", err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	userAndPass := strings.SplitN(string(decoded), ":", 2) | 
					
						
							|  |  |  | 	if len(userAndPass) != 2 { | 
					
						
							|  |  |  | 		return "", "", errors.New("Invalid basic auth header") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return userAndPass[0], userAndPass[1], nil | 
					
						
							|  |  |  | } |