mirror of
https://github.com/netbirdio/netbird.git
synced 2026-04-22 18:26:41 +00:00
[management, reverse proxy] Add reverse proxy feature (#5291)
* implement reverse proxy --------- Co-authored-by: Alisdair MacLeod <git@alisdairmacleod.co.uk> Co-authored-by: mlsmaycon <mlsmaycon@gmail.com> Co-authored-by: Eduard Gert <kontakt@eduardgert.de> Co-authored-by: Viktor Liu <viktor@netbird.io> Co-authored-by: Diego Noguês <diego.sure@gmail.com> Co-authored-by: Diego Noguês <49420+diegocn@users.noreply.github.com> Co-authored-by: Bethuel Mmbaga <bethuelmbaga12@gmail.com> Co-authored-by: Zoltan Papp <zoltan.pmail@gmail.com> Co-authored-by: Ashley Mensah <ashleyamo982@gmail.com>
This commit is contained in:
136
shared/hash/argon2id/argon2id.go
Normal file
136
shared/hash/argon2id/argon2id.go
Normal file
@@ -0,0 +1,136 @@
|
||||
package argon2id
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"crypto/subtle"
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/crypto/argon2"
|
||||
)
|
||||
|
||||
const (
|
||||
argon2Memory = 19456
|
||||
argon2Iterations = 2
|
||||
argon2Parallelism = 1
|
||||
argon2SaltLength = 16
|
||||
argon2KeyLength = 32
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrInvalidHash is returned when the hash string format is invalid
|
||||
ErrInvalidHash = errors.New("invalid hash format")
|
||||
|
||||
// ErrIncompatibleVersion is returned when the Argon2 version is not supported
|
||||
ErrIncompatibleVersion = errors.New("incompatible argon2 version")
|
||||
|
||||
// ErrMismatchedHashAndPassword is returned when password verification fails
|
||||
ErrMismatchedHashAndPassword = errors.New("password does not match hash")
|
||||
)
|
||||
|
||||
func Hash(secret string) (string, error) {
|
||||
salt := make([]byte, argon2SaltLength)
|
||||
if _, err := rand.Read(salt); err != nil {
|
||||
return "", fmt.Errorf("failed to generate salt: %w", err)
|
||||
}
|
||||
|
||||
hash := argon2.IDKey(
|
||||
[]byte(secret),
|
||||
salt,
|
||||
argon2Iterations,
|
||||
argon2Memory,
|
||||
argon2Parallelism,
|
||||
argon2KeyLength,
|
||||
)
|
||||
|
||||
encodedSalt := base64.RawStdEncoding.EncodeToString(salt)
|
||||
encodedHash := base64.RawStdEncoding.EncodeToString(hash)
|
||||
|
||||
return fmt.Sprintf(
|
||||
"$argon2id$v=%d$m=%d,t=%d,p=%d$%s$%s",
|
||||
argon2.Version,
|
||||
argon2Memory,
|
||||
argon2Iterations,
|
||||
argon2Parallelism,
|
||||
encodedSalt,
|
||||
encodedHash,
|
||||
), nil
|
||||
}
|
||||
|
||||
func Verify(secret, encodedHash string) error {
|
||||
params, salt, hash, err := decodeHash(encodedHash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
computedHash := argon2.IDKey(
|
||||
[]byte(secret),
|
||||
salt,
|
||||
params.iterations,
|
||||
params.memory,
|
||||
params.parallelism,
|
||||
params.keyLength,
|
||||
)
|
||||
|
||||
if subtle.ConstantTimeCompare(hash, computedHash) == 1 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return ErrMismatchedHashAndPassword
|
||||
}
|
||||
|
||||
type hashParams struct {
|
||||
memory uint32
|
||||
iterations uint32
|
||||
parallelism uint8
|
||||
keyLength uint32
|
||||
version int
|
||||
}
|
||||
|
||||
func decodeHash(encodedHash string) (*hashParams, []byte, []byte, error) {
|
||||
parts := strings.Split(encodedHash, "$")
|
||||
|
||||
if len(parts) != 6 {
|
||||
return nil, nil, nil, ErrInvalidHash
|
||||
}
|
||||
|
||||
if parts[1] != "argon2id" {
|
||||
return nil, nil, nil, ErrInvalidHash
|
||||
}
|
||||
|
||||
var version int
|
||||
if _, err := fmt.Sscanf(parts[2], "v=%d", &version); err != nil {
|
||||
return nil, nil, nil, fmt.Errorf("%w: invalid version: %v", ErrInvalidHash, err)
|
||||
}
|
||||
if version != argon2.Version {
|
||||
return nil, nil, nil, ErrIncompatibleVersion
|
||||
}
|
||||
|
||||
var memory, iterations uint32
|
||||
var parallelism uint8
|
||||
if _, err := fmt.Sscanf(parts[3], "m=%d,t=%d,p=%d", &memory, &iterations, ¶llelism); err != nil {
|
||||
return nil, nil, nil, fmt.Errorf("%w: invalid parameters: %v", ErrInvalidHash, err)
|
||||
}
|
||||
|
||||
salt, err := base64.RawStdEncoding.DecodeString(parts[4])
|
||||
if err != nil {
|
||||
return nil, nil, nil, fmt.Errorf("%w: invalid salt encoding: %v", ErrInvalidHash, err)
|
||||
}
|
||||
|
||||
hash, err := base64.RawStdEncoding.DecodeString(parts[5])
|
||||
if err != nil {
|
||||
return nil, nil, nil, fmt.Errorf("%w: invalid hash encoding: %v", ErrInvalidHash, err)
|
||||
}
|
||||
|
||||
params := &hashParams{
|
||||
memory: memory,
|
||||
iterations: iterations,
|
||||
parallelism: parallelism,
|
||||
keyLength: uint32(len(hash)),
|
||||
version: version,
|
||||
}
|
||||
|
||||
return params, salt, hash, nil
|
||||
}
|
||||
Reference in New Issue
Block a user