Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

cloaks.go 1.9KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. // Copyright (c) 2019 Shivaram Lingamneni
  2. package cloaks
  3. import (
  4. "fmt"
  5. "net"
  6. "os"
  7. "golang.org/x/crypto/sha3"
  8. "github.com/oragono/oragono/irc/utils"
  9. )
  10. type CloakConfig struct {
  11. Enabled bool
  12. Netname string
  13. Secret string
  14. SecretEnvVar string `yaml:"secret-environment-variable"`
  15. CidrLenIPv4 int `yaml:"cidr-len-ipv4"`
  16. CidrLenIPv6 int `yaml:"cidr-len-ipv6"`
  17. NumBits int `yaml:"num-bits"`
  18. numBytes int
  19. ipv4Mask net.IPMask
  20. ipv6Mask net.IPMask
  21. }
  22. func (cloakConfig *CloakConfig) Initialize() {
  23. if cloakConfig.SecretEnvVar != "" {
  24. envSecret := os.Getenv(cloakConfig.SecretEnvVar)
  25. if envSecret != "" {
  26. cloakConfig.Secret = envSecret
  27. }
  28. }
  29. // sanity checks:
  30. numBits := cloakConfig.NumBits
  31. if 0 == numBits {
  32. numBits = 80
  33. } else if 256 < numBits {
  34. numBits = 256
  35. }
  36. // derived values:
  37. cloakConfig.numBytes = numBits / 8
  38. // round up to the nearest byte
  39. if numBits%8 != 0 {
  40. cloakConfig.numBytes += 1
  41. }
  42. cloakConfig.ipv4Mask = net.CIDRMask(cloakConfig.CidrLenIPv4, 32)
  43. cloakConfig.ipv6Mask = net.CIDRMask(cloakConfig.CidrLenIPv6, 128)
  44. }
  45. // simple cloaking algorithm: normalize the IP to its CIDR,
  46. // then hash the resulting bytes with a secret key,
  47. // then truncate to the desired length, b32encode, and append the fake TLD.
  48. func (config *CloakConfig) ComputeCloak(ip net.IP) string {
  49. if !config.Enabled {
  50. return ""
  51. } else if config.NumBits == 0 {
  52. return config.Netname
  53. }
  54. var masked net.IP
  55. v4ip := ip.To4()
  56. if v4ip != nil {
  57. masked = v4ip.Mask(config.ipv4Mask)
  58. } else {
  59. masked = ip.Mask(config.ipv6Mask)
  60. }
  61. // SHA3(K || M):
  62. // https://crypto.stackexchange.com/questions/17735/is-hmac-needed-for-a-sha-3-based-mac
  63. input := make([]byte, len(config.Secret)+len(masked))
  64. copy(input, config.Secret[:])
  65. copy(input[len(config.Secret):], masked)
  66. digest := sha3.Sum512(input)
  67. b32digest := utils.B32Encoder.EncodeToString(digest[:config.numBytes])
  68. return fmt.Sprintf("%s.%s", b32digest, config.Netname)
  69. }