cubefs
1// Copyright 2022 The CubeFS Authors.
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// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
12// implied. See the License for the specific language governing
13// permissions and limitations under the License.
14
15package auth16
17import (18"bytes"19"crypto/md5"20"encoding/base64"21"encoding/binary"22"errors"23"net/http"24)
25
26const (27// md5 need 16 byte28TokenKeyLenth = 1629
30// #nosec G10131TokenHeaderKey = "BLOB-STORE-AUTH-TOKEN"32)
33
34var errMismatchToken = errors.New("mismatch token")35
36type Config struct {37EnableAuth bool `json:"enable_auth"`38Secret string `json:"secret"`39}
40
41// simply: use timestamp as a token calculate param
42type authInfo struct {43timestamp int6444token []byte45// other auth content46others []byte47}
48
49func encodeAuthInfo(info *authInfo) (ret string, err error) {50w := bytes.NewBuffer([]byte{})51if err = binary.Write(w, binary.LittleEndian, &info.timestamp); err != nil {52return53}54if err = binary.Write(w, binary.LittleEndian, &info.token); err != nil {55return56}57return base64.URLEncoding.EncodeToString(w.Bytes()), nil58}
59
60func decodeAuthInfo(encodeStr string) (info *authInfo, err error) {61info = new(authInfo)62b, err := base64.URLEncoding.DecodeString(encodeStr)63if err != nil {64return65}66
67info.token = make([]byte, TokenKeyLenth)68r := bytes.NewBuffer(b)69if err = binary.Read(r, binary.LittleEndian, &info.timestamp); err != nil {70return71}72if err = binary.Read(r, binary.LittleEndian, &info.token); err != nil {73return74}75return76}
77
78// calculate auth token with params and secret
79func calculate(info *authInfo, secret []byte) (err error) {80hash := md5.New()81b := make([]byte, 8)82binary.LittleEndian.PutUint64(b, uint64(info.timestamp))83hash.Write(info.others)84hash.Write(b)85hash.Write(secret)86info.token = hash.Sum(nil)87return88}
89
90// verify auth token with params and secret
91func verify(info *authInfo, secret []byte) (err error) {92checkAuthInfo := &authInfo{timestamp: info.timestamp, others: info.others}93calculate(checkAuthInfo, secret)94if !bytes.Equal(checkAuthInfo.token, info.token) {95return errMismatchToken96}97return98}
99
100func genEncodeStr(req *http.Request) []byte {101calStr := req.URL.Path + req.URL.RawQuery102return []byte(calStr)103}
104