github.com/minio/minio@v0.0.0-20240328213742-3f72439b8a27/internal/logger/target/kafka/kafka_scram_client_contrib.go (about) 1 // Copyright (c) 2015-2021 MinIO, Inc. 2 // 3 // This file is part of MinIO Object Storage stack 4 // 5 // This program is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU Affero General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // This program is distributed in the hope that it will be useful 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU Affero General Public License for more details. 14 // 15 // You should have received a copy of the GNU Affero General Public License 16 // along with this program. If not, see <http://www.gnu.org/licenses/>. 17 18 package kafka 19 20 import ( 21 "crypto/sha512" 22 "strings" 23 24 "github.com/IBM/sarama" 25 "github.com/xdg/scram" 26 27 "github.com/minio/minio/internal/hash/sha256" 28 ) 29 30 func initScramClient(cfg Config, config *sarama.Config) { 31 switch strings.ToLower(cfg.SASL.Mechanism) { 32 case "sha512": 33 config.Net.SASL.SCRAMClientGeneratorFunc = func() sarama.SCRAMClient { return &XDGSCRAMClient{HashGeneratorFcn: KafkaSHA512} } 34 config.Net.SASL.Mechanism = sarama.SASLMechanism(sarama.SASLTypeSCRAMSHA512) 35 case "sha256": 36 config.Net.SASL.SCRAMClientGeneratorFunc = func() sarama.SCRAMClient { return &XDGSCRAMClient{HashGeneratorFcn: KafkaSHA256} } 37 config.Net.SASL.Mechanism = sarama.SASLMechanism(sarama.SASLTypeSCRAMSHA256) 38 default: 39 // default to PLAIN 40 config.Net.SASL.Mechanism = sarama.SASLMechanism(sarama.SASLTypePlaintext) 41 } 42 } 43 44 // KafkaSHA256 is a function that returns a crypto/sha256 hasher and should be used 45 // to create Client objects configured for SHA-256 hashing. 46 var KafkaSHA256 scram.HashGeneratorFcn = sha256.New 47 48 // KafkaSHA512 is a function that returns a crypto/sha512 hasher and should be used 49 // to create Client objects configured for SHA-512 hashing. 50 var KafkaSHA512 scram.HashGeneratorFcn = sha512.New 51 52 // XDGSCRAMClient implements the client-side of an authentication 53 // conversation with a server. A new conversation must be created for 54 // each authentication attempt. 55 type XDGSCRAMClient struct { 56 *scram.Client 57 *scram.ClientConversation 58 scram.HashGeneratorFcn 59 } 60 61 // Begin constructs a SCRAM client component based on a given hash.Hash 62 // factory receiver. This constructor will normalize the username, password 63 // and authzID via the SASLprep algorithm, as recommended by RFC-5802. If 64 // SASLprep fails, the method returns an error. 65 func (x *XDGSCRAMClient) Begin(userName, password, authzID string) (err error) { 66 x.Client, err = x.HashGeneratorFcn.NewClient(userName, password, authzID) 67 if err != nil { 68 return err 69 } 70 x.ClientConversation = x.Client.NewConversation() 71 return nil 72 } 73 74 // Step takes a string provided from a server (or just an empty string for the 75 // very first conversation step) and attempts to move the authentication 76 // conversation forward. It returns a string to be sent to the server or an 77 // error if the server message is invalid. Calling Step after a conversation 78 // completes is also an error. 79 func (x *XDGSCRAMClient) Step(challenge string) (response string, err error) { 80 response, err = x.ClientConversation.Step(challenge) 81 return 82 } 83 84 // Done returns true if the conversation is completed or has errored. 85 func (x *XDGSCRAMClient) Done() bool { 86 return x.ClientConversation.Done() 87 }