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  }