github.com/minio/minio@v0.0.0-20240328213742-3f72439b8a27/internal/event/target/kafka_scram_client_contrib.go (about)

     1  /*
     2   * MinIO Object Storage (c) 2021-2023 MinIO, Inc.
     3   *
     4   * Licensed under the Apache License, Version 2.0 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   *
     8   *      http://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16  
    17  package target
    18  
    19  import (
    20  	"crypto/sha512"
    21  	"strings"
    22  
    23  	"github.com/IBM/sarama"
    24  	"github.com/xdg/scram"
    25  
    26  	"github.com/minio/minio/internal/hash/sha256"
    27  )
    28  
    29  func initScramClient(args KafkaArgs, config *sarama.Config) {
    30  	switch strings.ToLower(args.SASL.Mechanism) {
    31  	case "sha512":
    32  		config.Net.SASL.SCRAMClientGeneratorFunc = func() sarama.SCRAMClient { return &XDGSCRAMClient{HashGeneratorFcn: KafkaSHA512} }
    33  		config.Net.SASL.Mechanism = sarama.SASLMechanism(sarama.SASLTypeSCRAMSHA512)
    34  	case "sha256":
    35  		config.Net.SASL.SCRAMClientGeneratorFunc = func() sarama.SCRAMClient { return &XDGSCRAMClient{HashGeneratorFcn: KafkaSHA256} }
    36  		config.Net.SASL.Mechanism = sarama.SASLMechanism(sarama.SASLTypeSCRAMSHA256)
    37  	default:
    38  		// default to PLAIN
    39  		config.Net.SASL.Mechanism = sarama.SASLMechanism(sarama.SASLTypePlaintext)
    40  	}
    41  }
    42  
    43  // KafkaSHA256 is a function that returns a crypto/sha256 hasher and should be used
    44  // to create Client objects configured for SHA-256 hashing.
    45  var KafkaSHA256 scram.HashGeneratorFcn = sha256.New
    46  
    47  // KafkaSHA512 is a function that returns a crypto/sha512 hasher and should be used
    48  // to create Client objects configured for SHA-512 hashing.
    49  var KafkaSHA512 scram.HashGeneratorFcn = sha512.New
    50  
    51  // XDGSCRAMClient implements the client-side of an authentication
    52  // conversation with a server.  A new conversation must be created for
    53  // each authentication attempt.
    54  type XDGSCRAMClient struct {
    55  	*scram.Client
    56  	*scram.ClientConversation
    57  	scram.HashGeneratorFcn
    58  }
    59  
    60  // Begin constructs a SCRAM client component based on a given hash.Hash
    61  // factory receiver.  This constructor will normalize the username, password
    62  // and authzID via the SASLprep algorithm, as recommended by RFC-5802.  If
    63  // SASLprep fails, the method returns an error.
    64  func (x *XDGSCRAMClient) Begin(userName, password, authzID string) (err error) {
    65  	x.Client, err = x.HashGeneratorFcn.NewClient(userName, password, authzID)
    66  	if err != nil {
    67  		return err
    68  	}
    69  	x.ClientConversation = x.Client.NewConversation()
    70  	return nil
    71  }
    72  
    73  // Step takes a string provided from a server (or just an empty string for the
    74  // very first conversation step) and attempts to move the authentication
    75  // conversation forward.  It returns a string to be sent to the server or an
    76  // error if the server message is invalid.  Calling Step after a conversation
    77  // completes is also an error.
    78  func (x *XDGSCRAMClient) Step(challenge string) (response string, err error) {
    79  	response, err = x.ClientConversation.Step(challenge)
    80  	return
    81  }
    82  
    83  // Done returns true if the conversation is completed or has errored.
    84  func (x *XDGSCRAMClient) Done() bool {
    85  	return x.ClientConversation.Done()
    86  }