github.com/bingoohuang/gg@v0.0.0-20240325092523-45da7dee9335/pkg/sqlparse/tidbparser/dependency/util/auth/auth.go (about) 1 // Copyright 2015 PingCAP, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package auth 15 16 import ( 17 "bytes" 18 "crypto/sha1" 19 "encoding/hex" 20 "fmt" 21 22 "github.com/bingoohuang/gg/pkg/sqlparse/tidbparser/dependency/terror" 23 "github.com/juju/errors" 24 ) 25 26 // UserIdentity represents username and hostname. 27 type UserIdentity struct { 28 Username string 29 Hostname string 30 } 31 32 // String converts UserIdentity to the format user@host. 33 func (user *UserIdentity) String() string { 34 // TODO: Escape username and hostname. 35 return fmt.Sprintf("%s@%s", user.Username, user.Hostname) 36 } 37 38 // CheckScrambledPassword check scrambled password received from client. 39 // The new authentication is performed in following manner: 40 // 41 // SERVER: public_seed=create_random_string() 42 // send(public_seed) 43 // CLIENT: recv(public_seed) 44 // hash_stage1=sha1("password") 45 // hash_stage2=sha1(hash_stage1) 46 // reply=xor(hash_stage1, sha1(public_seed,hash_stage2) 47 // // this three steps are done in scramble() 48 // send(reply) 49 // SERVER: recv(reply) 50 // hash_stage1=xor(reply, sha1(public_seed,hash_stage2)) 51 // candidate_hash2=sha1(hash_stage1) 52 // check(candidate_hash2==hash_stage2) 53 // // this three steps are done in check_scramble() 54 func CheckScrambledPassword(salt, hpwd, auth []byte) bool { 55 crypt := sha1.New() 56 _, err := crypt.Write(salt) 57 terror.Log(errors.Trace(err)) 58 _, err = crypt.Write(hpwd) 59 terror.Log(errors.Trace(err)) 60 hash := crypt.Sum(nil) 61 // token = scrambleHash XOR stage1Hash 62 for i := range hash { 63 hash[i] ^= auth[i] 64 } 65 66 return bytes.Equal(hpwd, Sha1Hash(hash)) 67 } 68 69 // Sha1Hash is an util function to calculate sha1 hash. 70 func Sha1Hash(bs []byte) []byte { 71 crypt := sha1.New() 72 _, err := crypt.Write(bs) 73 terror.Log(errors.Trace(err)) 74 return crypt.Sum(nil) 75 } 76 77 // EncodePassword converts plaintext password to hashed hex string. 78 func EncodePassword(pwd string) string { 79 if len(pwd) == 0 { 80 return "" 81 } 82 hash1 := Sha1Hash([]byte(pwd)) 83 hash2 := Sha1Hash(hash1) 84 85 return fmt.Sprintf("*%X", hash2) 86 } 87 88 // DecodePassword converts hex string password without prefix '*' to byte array. 89 func DecodePassword(pwd string) ([]byte, error) { 90 x, err := hex.DecodeString(pwd[1:]) 91 if err != nil { 92 return nil, errors.Trace(err) 93 } 94 return x, nil 95 }