mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-27 00:23:41 +09:00 
			
		
		
		
	
							
								
								
									
										214
									
								
								vendor/github.com/go-sql-driver/mysql/utils.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										214
									
								
								vendor/github.com/go-sql-driver/mysql/utils.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -9,23 +9,29 @@ | ||||
| package mysql | ||||
|  | ||||
| import ( | ||||
| 	"crypto/sha1" | ||||
| 	"crypto/tls" | ||||
| 	"database/sql/driver" | ||||
| 	"encoding/binary" | ||||
| 	"fmt" | ||||
| 	"io" | ||||
| 	"strings" | ||||
| 	"sync" | ||||
| 	"sync/atomic" | ||||
| 	"time" | ||||
| ) | ||||
|  | ||||
| // Registry for custom tls.Configs | ||||
| var ( | ||||
| 	tlsConfigRegister map[string]*tls.Config // Register for custom tls.Configs | ||||
| 	tlsConfigLock     sync.RWMutex | ||||
| 	tlsConfigRegistry map[string]*tls.Config | ||||
| ) | ||||
|  | ||||
| // RegisterTLSConfig registers a custom tls.Config to be used with sql.Open. | ||||
| // Use the key as a value in the DSN where tls=value. | ||||
| // | ||||
| // Note: The provided tls.Config is exclusively owned by the driver after | ||||
| // registering it. | ||||
| // | ||||
| //  rootCertPool := x509.NewCertPool() | ||||
| //  pem, err := ioutil.ReadFile("/path/ca-cert.pem") | ||||
| //  if err != nil { | ||||
| @@ -51,19 +57,32 @@ func RegisterTLSConfig(key string, config *tls.Config) error { | ||||
| 		return fmt.Errorf("key '%s' is reserved", key) | ||||
| 	} | ||||
|  | ||||
| 	if tlsConfigRegister == nil { | ||||
| 		tlsConfigRegister = make(map[string]*tls.Config) | ||||
| 	tlsConfigLock.Lock() | ||||
| 	if tlsConfigRegistry == nil { | ||||
| 		tlsConfigRegistry = make(map[string]*tls.Config) | ||||
| 	} | ||||
|  | ||||
| 	tlsConfigRegister[key] = config | ||||
| 	tlsConfigRegistry[key] = config | ||||
| 	tlsConfigLock.Unlock() | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // DeregisterTLSConfig removes the tls.Config associated with key. | ||||
| func DeregisterTLSConfig(key string) { | ||||
| 	if tlsConfigRegister != nil { | ||||
| 		delete(tlsConfigRegister, key) | ||||
| 	tlsConfigLock.Lock() | ||||
| 	if tlsConfigRegistry != nil { | ||||
| 		delete(tlsConfigRegistry, key) | ||||
| 	} | ||||
| 	tlsConfigLock.Unlock() | ||||
| } | ||||
|  | ||||
| func getTLSConfigClone(key string) (config *tls.Config) { | ||||
| 	tlsConfigLock.RLock() | ||||
| 	if v, ok := tlsConfigRegistry[key]; ok { | ||||
| 		config = cloneTLSConfig(v) | ||||
| 	} | ||||
| 	tlsConfigLock.RUnlock() | ||||
| 	return | ||||
| } | ||||
|  | ||||
| // Returns the bool value of the input. | ||||
| @@ -80,119 +99,6 @@ func readBool(input string) (value bool, valid bool) { | ||||
| 	return | ||||
| } | ||||
|  | ||||
| /****************************************************************************** | ||||
| *                             Authentication                                  * | ||||
| ******************************************************************************/ | ||||
|  | ||||
| // Encrypt password using 4.1+ method | ||||
| func scramblePassword(scramble, password []byte) []byte { | ||||
| 	if len(password) == 0 { | ||||
| 		return nil | ||||
| 	} | ||||
|  | ||||
| 	// stage1Hash = SHA1(password) | ||||
| 	crypt := sha1.New() | ||||
| 	crypt.Write(password) | ||||
| 	stage1 := crypt.Sum(nil) | ||||
|  | ||||
| 	// scrambleHash = SHA1(scramble + SHA1(stage1Hash)) | ||||
| 	// inner Hash | ||||
| 	crypt.Reset() | ||||
| 	crypt.Write(stage1) | ||||
| 	hash := crypt.Sum(nil) | ||||
|  | ||||
| 	// outer Hash | ||||
| 	crypt.Reset() | ||||
| 	crypt.Write(scramble) | ||||
| 	crypt.Write(hash) | ||||
| 	scramble = crypt.Sum(nil) | ||||
|  | ||||
| 	// token = scrambleHash XOR stage1Hash | ||||
| 	for i := range scramble { | ||||
| 		scramble[i] ^= stage1[i] | ||||
| 	} | ||||
| 	return scramble | ||||
| } | ||||
|  | ||||
| // Encrypt password using pre 4.1 (old password) method | ||||
| // https://github.com/atcurtis/mariadb/blob/master/mysys/my_rnd.c | ||||
| type myRnd struct { | ||||
| 	seed1, seed2 uint32 | ||||
| } | ||||
|  | ||||
| const myRndMaxVal = 0x3FFFFFFF | ||||
|  | ||||
| // Pseudo random number generator | ||||
| func newMyRnd(seed1, seed2 uint32) *myRnd { | ||||
| 	return &myRnd{ | ||||
| 		seed1: seed1 % myRndMaxVal, | ||||
| 		seed2: seed2 % myRndMaxVal, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Tested to be equivalent to MariaDB's floating point variant | ||||
| // http://play.golang.org/p/QHvhd4qved | ||||
| // http://play.golang.org/p/RG0q4ElWDx | ||||
| func (r *myRnd) NextByte() byte { | ||||
| 	r.seed1 = (r.seed1*3 + r.seed2) % myRndMaxVal | ||||
| 	r.seed2 = (r.seed1 + r.seed2 + 33) % myRndMaxVal | ||||
|  | ||||
| 	return byte(uint64(r.seed1) * 31 / myRndMaxVal) | ||||
| } | ||||
|  | ||||
| // Generate binary hash from byte string using insecure pre 4.1 method | ||||
| func pwHash(password []byte) (result [2]uint32) { | ||||
| 	var add uint32 = 7 | ||||
| 	var tmp uint32 | ||||
|  | ||||
| 	result[0] = 1345345333 | ||||
| 	result[1] = 0x12345671 | ||||
|  | ||||
| 	for _, c := range password { | ||||
| 		// skip spaces and tabs in password | ||||
| 		if c == ' ' || c == '\t' { | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		tmp = uint32(c) | ||||
| 		result[0] ^= (((result[0] & 63) + add) * tmp) + (result[0] << 8) | ||||
| 		result[1] += (result[1] << 8) ^ result[0] | ||||
| 		add += tmp | ||||
| 	} | ||||
|  | ||||
| 	// Remove sign bit (1<<31)-1) | ||||
| 	result[0] &= 0x7FFFFFFF | ||||
| 	result[1] &= 0x7FFFFFFF | ||||
|  | ||||
| 	return | ||||
| } | ||||
|  | ||||
| // Encrypt password using insecure pre 4.1 method | ||||
| func scrambleOldPassword(scramble, password []byte) []byte { | ||||
| 	if len(password) == 0 { | ||||
| 		return nil | ||||
| 	} | ||||
|  | ||||
| 	scramble = scramble[:8] | ||||
|  | ||||
| 	hashPw := pwHash(password) | ||||
| 	hashSc := pwHash(scramble) | ||||
|  | ||||
| 	r := newMyRnd(hashPw[0]^hashSc[0], hashPw[1]^hashSc[1]) | ||||
|  | ||||
| 	var out [8]byte | ||||
| 	for i := range out { | ||||
| 		out[i] = r.NextByte() + 64 | ||||
| 	} | ||||
|  | ||||
| 	mask := r.NextByte() | ||||
| 	for i := range out { | ||||
| 		out[i] ^= mask | ||||
| 	} | ||||
|  | ||||
| 	return out[:] | ||||
| } | ||||
|  | ||||
| /****************************************************************************** | ||||
| *                           Time related utils                                * | ||||
| ******************************************************************************/ | ||||
| @@ -519,7 +425,7 @@ func readLengthEncodedString(b []byte) ([]byte, bool, int, error) { | ||||
|  | ||||
| 	// Check data length | ||||
| 	if len(b) >= n { | ||||
| 		return b[n-int(num) : n], false, n, nil | ||||
| 		return b[n-int(num) : n : n], false, n, nil | ||||
| 	} | ||||
| 	return nil, false, n, io.EOF | ||||
| } | ||||
| @@ -548,8 +454,8 @@ func readLengthEncodedInteger(b []byte) (uint64, bool, int) { | ||||
| 	if len(b) == 0 { | ||||
| 		return 0, true, 1 | ||||
| 	} | ||||
| 	switch b[0] { | ||||
|  | ||||
| 	switch b[0] { | ||||
| 	// 251: NULL | ||||
| 	case 0xfb: | ||||
| 		return 0, true, 1 | ||||
| @@ -738,3 +644,67 @@ func escapeStringQuotes(buf []byte, v string) []byte { | ||||
|  | ||||
| 	return buf[:pos] | ||||
| } | ||||
|  | ||||
| /****************************************************************************** | ||||
| *                               Sync utils                                    * | ||||
| ******************************************************************************/ | ||||
|  | ||||
| // noCopy may be embedded into structs which must not be copied | ||||
| // after the first use. | ||||
| // | ||||
| // See https://github.com/golang/go/issues/8005#issuecomment-190753527 | ||||
| // for details. | ||||
| type noCopy struct{} | ||||
|  | ||||
| // Lock is a no-op used by -copylocks checker from `go vet`. | ||||
| func (*noCopy) Lock() {} | ||||
|  | ||||
| // atomicBool is a wrapper around uint32 for usage as a boolean value with | ||||
| // atomic access. | ||||
| type atomicBool struct { | ||||
| 	_noCopy noCopy | ||||
| 	value   uint32 | ||||
| } | ||||
|  | ||||
| // IsSet returns wether the current boolean value is true | ||||
| func (ab *atomicBool) IsSet() bool { | ||||
| 	return atomic.LoadUint32(&ab.value) > 0 | ||||
| } | ||||
|  | ||||
| // Set sets the value of the bool regardless of the previous value | ||||
| func (ab *atomicBool) Set(value bool) { | ||||
| 	if value { | ||||
| 		atomic.StoreUint32(&ab.value, 1) | ||||
| 	} else { | ||||
| 		atomic.StoreUint32(&ab.value, 0) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // TrySet sets the value of the bool and returns wether the value changed | ||||
| func (ab *atomicBool) TrySet(value bool) bool { | ||||
| 	if value { | ||||
| 		return atomic.SwapUint32(&ab.value, 1) == 0 | ||||
| 	} | ||||
| 	return atomic.SwapUint32(&ab.value, 0) > 0 | ||||
| } | ||||
|  | ||||
| // atomicError is a wrapper for atomically accessed error values | ||||
| type atomicError struct { | ||||
| 	_noCopy noCopy | ||||
| 	value   atomic.Value | ||||
| } | ||||
|  | ||||
| // Set sets the error value regardless of the previous value. | ||||
| // The value must not be nil | ||||
| func (ae *atomicError) Set(value error) { | ||||
| 	ae.value.Store(value) | ||||
| } | ||||
|  | ||||
| // Value returns the current error value | ||||
| func (ae *atomicError) Value() error { | ||||
| 	if v := ae.value.Load(); v != nil { | ||||
| 		// this will panic if the value doesn't implement the error interface | ||||
| 		return v.(error) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user