mirror of
https://github.com/Rayzggz/server_torii.git
synced 2025-06-23 15:31:31 +08:00
feat: External Migration
This commit is contained in:
@ -1,9 +1,16 @@
|
|||||||
package check
|
package check
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/hmac"
|
||||||
|
"crypto/sha512"
|
||||||
|
"fmt"
|
||||||
"server_torii/internal/action"
|
"server_torii/internal/action"
|
||||||
"server_torii/internal/config"
|
"server_torii/internal/config"
|
||||||
"server_torii/internal/dataType"
|
"server_torii/internal/dataType"
|
||||||
|
"server_torii/internal/utils"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func ExternalMigration(reqData dataType.UserRequest, ruleSet *config.RuleSet, decision *action.Decision, sharedMem *dataType.SharedMemory) {
|
func ExternalMigration(reqData dataType.UserRequest, ruleSet *config.RuleSet, decision *action.Decision, sharedMem *dataType.SharedMemory) {
|
||||||
@ -12,10 +19,79 @@ func ExternalMigration(reqData dataType.UserRequest, ruleSet *config.RuleSet, de
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if !verifyClearanceCookie(reqData, *ruleSet) {
|
if !verifyExternalMigrationClearanceCookie(reqData, *ruleSet) {
|
||||||
decision.SetResponse(action.Done, []byte("EXTERNAL"), genSessionID(reqData, *ruleSet))
|
decision.SetResponse(action.Done, []byte("EXTERNAL"), genExternalMigrationSessionID(reqData, *ruleSet))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
decision.Set(action.Continue)
|
decision.Set(action.Continue)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GenExternalMigrationClearance(reqData dataType.UserRequest, ruleSet config.RuleSet) []byte {
|
||||||
|
timeNow := time.Now().Unix()
|
||||||
|
mac := hmac.New(sha512.New, []byte(ruleSet.ExternalMigrationRule.SecretKey))
|
||||||
|
mac.Write([]byte(fmt.Sprintf("%d%s%sEXTERNAL-CLEARANCE", timeNow, reqData.Host, utils.GetClearanceUserAgent(reqData.UserAgent))))
|
||||||
|
return []byte(fmt.Sprintf("%s:%s", fmt.Sprintf("%d", time.Now().Unix()), fmt.Sprintf("%x", mac.Sum(nil))))
|
||||||
|
}
|
||||||
|
|
||||||
|
func verifyExternalMigrationClearanceCookie(reqData dataType.UserRequest, ruleSet config.RuleSet) bool {
|
||||||
|
if reqData.ToriiClearance == "" {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
parts := strings.Split(reqData.ToriiClearance, ":")
|
||||||
|
if len(parts) != 2 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
timestamp := parts[0]
|
||||||
|
expectedHash := parts[1]
|
||||||
|
|
||||||
|
timeNow := time.Now().Unix()
|
||||||
|
parsedTimestamp, err := strconv.ParseInt(timestamp, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
utils.LogError(reqData, "", fmt.Sprintf("Error parsing timestamp: %v", err))
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if timeNow-parsedTimestamp > ruleSet.ExternalMigrationRule.SessionTimeout {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
mac := hmac.New(sha512.New, []byte(ruleSet.ExternalMigrationRule.SecretKey))
|
||||||
|
mac.Write([]byte(fmt.Sprintf("%d%s%sEXTERNAL-CLEARANCE", parsedTimestamp, reqData.Host, utils.GetClearanceUserAgent(reqData.UserAgent))))
|
||||||
|
computedHash := fmt.Sprintf("%x", mac.Sum(nil))
|
||||||
|
|
||||||
|
return hmac.Equal([]byte(computedHash), []byte(expectedHash))
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func genExternalMigrationSessionID(reqData dataType.UserRequest, ruleSet config.RuleSet) []byte {
|
||||||
|
timeNow := time.Now().Unix()
|
||||||
|
mac := hmac.New(sha512.New, []byte(ruleSet.ExternalMigrationRule.SecretKey))
|
||||||
|
mac.Write([]byte(fmt.Sprintf("%d%s%sEXTERNAL-SESSION", timeNow, reqData.Host, utils.GetClearanceUserAgent(reqData.UserAgent))))
|
||||||
|
return []byte(fmt.Sprintf("%s:%s", fmt.Sprintf("%d", time.Now().Unix()), fmt.Sprintf("%x", mac.Sum(nil))))
|
||||||
|
}
|
||||||
|
|
||||||
|
func verifyExternalMigrationSessionIDCookie(reqData dataType.UserRequest, ruleSet config.RuleSet) bool {
|
||||||
|
if reqData.ToriiSessionID == "" {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
parts := strings.Split(reqData.ToriiSessionID, ":")
|
||||||
|
if len(parts) != 2 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
timestamp := parts[0]
|
||||||
|
expectedHash := parts[1]
|
||||||
|
|
||||||
|
parsedTimestamp, err := strconv.ParseInt(timestamp, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
utils.LogError(reqData, "", fmt.Sprintf("Error parsing timestamp: %v", err))
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
mac := hmac.New(sha512.New, []byte(ruleSet.ExternalMigrationRule.SecretKey))
|
||||||
|
mac.Write([]byte(fmt.Sprintf("%d%s%sEXTERNAL-SESSION", parsedTimestamp, reqData.Host, utils.GetClearanceUserAgent(reqData.UserAgent))))
|
||||||
|
computedHash := fmt.Sprintf("%x", mac.Sum(nil))
|
||||||
|
|
||||||
|
return hmac.Equal([]byte(computedHash), []byte(expectedHash))
|
||||||
|
|
||||||
|
}
|
||||||
|
@ -107,6 +107,11 @@ func CheckMain(w http.ResponseWriter, userRequestData dataType.UserRequest, rule
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} else if bytes.Compare(decision.HTTPCode, []byte("EXTERNAL")) == 0 {
|
||||||
|
w.Header().Set("Set-Cookie", "__torii_sessionid="+string(decision.ResponseData)+"; Path=/; Max-Age=86400; Priority=High; HttpOnly; SameSite=Lax")
|
||||||
|
w.Header().Set("Location", ruleSet.ExternalMigrationRule.RedirectUrl+"?domain="+userRequestData.Host+"&session_id="+string(decision.ResponseData)+"&original_url="+userRequestData.Uri)
|
||||||
|
w.WriteHeader(http.StatusFound)
|
||||||
|
return
|
||||||
} else {
|
} else {
|
||||||
//should never happen
|
//should never happen
|
||||||
utils.LogError(userRequestData, fmt.Sprintf("Error access in wrong state: %v", decision), "CheckMain")
|
utils.LogError(userRequestData, fmt.Sprintf("Error access in wrong state: %v", decision), "CheckMain")
|
||||||
|
Reference in New Issue
Block a user