auth.go 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. package main
  2. import (
  3. "crypto/rand"
  4. "crypto/sha256"
  5. "encoding/base64"
  6. "encoding/hex"
  7. "encoding/json"
  8. "goseg/config"
  9. "fmt"
  10. "time"
  11. "golang.org/x/crypto/nacl/secretbox"
  12. )
  13. // CheckToken checks the validity of the token.
  14. func CheckToken(token string, websocket interface{}, setup bool) (bool, string, error) {
  15. if token == "" {
  16. authStatus := false
  17. if setup {
  18. authStatus = true
  19. }
  20. newToken, err := CreateToken(websocket, setup)
  21. if err != nil {
  22. return false, "", err
  23. }
  24. return authStatus, newToken["token"], nil
  25. }
  26. // Token verification logic here...
  27. // ...
  28. return false, "", nil
  29. }
  30. // CreateToken creates a new session token.
  31. func CreateToken(websocket interface{}, setup bool) (map[string]string, error) {
  32. // placeholder logic for IP and UserAgent
  33. ip := "localhost"
  34. userAgent := "lick"
  35. // if more properties are needed from websocket, you can extract them here
  36. conf := config.Conf()
  37. key := conf.KeyFile
  38. // generate random strings for id, secret, and padding
  39. id := NewSecretString(32)
  40. secret := NewSecretString(128)
  41. padding := NewSecretString(32)
  42. contents := map[string]string{
  43. "id": id,
  44. "ip": ip,
  45. "user_agent": userAgent,
  46. "secret": secret,
  47. "padding": padding,
  48. "authorized": fmt.Sprintf("%v", setup),
  49. "created": time.Now().Format("2006-01-02_15:04:05"),
  50. }
  51. // encrypt the contents
  52. encryptedText, err := KeyfileEncrypt(contents, key)
  53. if err != nil {
  54. return nil, fmt.Errorf("failed to encrypt token: %v", err)
  55. }
  56. // and hash
  57. hashed := sha256.Sum256([]byte(encryptedText))
  58. // Update sessions in the system's configuration
  59. now := time.Now().Format("2006-01-02_15:04:05")
  60. if setup {
  61. updates := map[string]interface{}{
  62. "Sessions": map[string]interface{}{
  63. "Authorized": map[string]string{
  64. "Hash": hex.EncodeToString(hashed[:]),
  65. "Created": now,
  66. },
  67. },
  68. }
  69. config.UpdateConf(updates)
  70. } else {
  71. updates := map[string]interface{}{
  72. "Sessions": map[string]interface{}{
  73. "Unauthorized": map[string]string{
  74. "Hash": hex.EncodeToString(hashed[:]),
  75. "Created": now,
  76. },
  77. },
  78. }
  79. config.UpdateConf(updates)
  80. }
  81. return map[string]string{
  82. "id": id,
  83. "token": encryptedText,
  84. }, nil
  85. }
  86. // encrypt the contents using stored keyfile val
  87. func KeyfileEncrypt(contents map[string]string, key string) (string, error) {
  88. contentBytes, err := json.Marshal(contents)
  89. if err != nil {
  90. return "", err
  91. }
  92. // convert key to bytes
  93. keyBytes := []byte(key)
  94. if len(keyBytes) != 32 {
  95. return "", fmt.Errorf("key must be 32 bytes in length")
  96. }
  97. var keyArray [32]byte
  98. copy(keyArray[:], keyBytes)
  99. // generate nonce
  100. var nonce [24]byte
  101. if _, err := rand.Read(nonce[:]); err != nil {
  102. return "", err
  103. }
  104. // encrypt contents
  105. encrypted := secretbox.Seal(nonce[:], contentBytes, &nonce, &keyArray)
  106. return base64.URLEncoding.EncodeToString(encrypted), nil
  107. }
  108. // decrypt routine
  109. func KeyfileDecrypt(encryptedText string, key string) (map[string]string, error) {
  110. // get bytes
  111. keyBytes := []byte(key)
  112. var keyArray [32]byte
  113. copy(keyArray[:], keyBytes)
  114. encryptedBytes, err := base64.URLEncoding.DecodeString(encryptedText)
  115. if err != nil {
  116. return nil, err
  117. }
  118. // get nonce
  119. var nonce [24]byte
  120. copy(nonce[:], encryptedBytes[:24])
  121. // attempt decrypt
  122. decrypted, ok := secretbox.Open(nil, encryptedBytes[24:], &nonce, &keyArray)
  123. if !ok {
  124. return nil, fmt.Errorf("Decryption failed")
  125. }
  126. var contents map[string]string
  127. if err := json.Unmarshal(decrypted, &contents); err != nil {
  128. return nil, err
  129. }
  130. return contents, nil
  131. }
  132. // NewSecretString generates a random secret string of the given length.
  133. func NewSecretString(length int) string {
  134. randBytes := make([]byte, length)
  135. _, err := rand.Read(randBytes)
  136. if err != nil {
  137. return ""
  138. }
  139. return base64.URLEncoding.EncodeToString(randBytes)
  140. }
  141. func main() {
  142. fmt.Println("Compiled")
  143. }