mirror of https://github.com/grafana/grafana.git
				
				
				
			
		
			
				
	
	
		
			105 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			105 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			Go
		
	
	
	
| package util
 | |
| 
 | |
| import (
 | |
| 	"crypto/hmac"
 | |
| 	"crypto/md5"
 | |
| 	"crypto/rand"
 | |
| 	"crypto/sha256"
 | |
| 	"encoding/base64"
 | |
| 	"encoding/hex"
 | |
| 	"errors"
 | |
| 	"fmt"
 | |
| 	"hash"
 | |
| 	"strings"
 | |
| )
 | |
| 
 | |
| // 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)
 | |
| 	return fmt.Sprintf("%x", newPasswd)
 | |
| }
 | |
| 
 | |
| // Encode string to md5 hex value.
 | |
| func EncodeMd5(str string) string {
 | |
| 	m := md5.New()
 | |
| 	m.Write([]byte(str))
 | |
| 	return hex.EncodeToString(m.Sum(nil))
 | |
| }
 | |
| 
 | |
| // 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]
 | |
| }
 | |
| 
 | |
| func GetBasicAuthHeader(user string, password string) string {
 | |
| 	var userAndPass = user + ":" + password
 | |
| 	return "Basic " + base64.StdEncoding.EncodeToString([]byte(userAndPass))
 | |
| }
 | |
| 
 | |
| 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
 | |
| }
 |