diff --git a/cmd/http3-ytproxy/main.go b/cmd/http3-ytproxy/main.go index e9a28bf..d00d1ed 100644 --- a/cmd/http3-ytproxy/main.go +++ b/cmd/http3-ytproxy/main.go @@ -137,12 +137,6 @@ func beforeProxy(next http.HandlerFunc) http.HandlerFunc { } } -func getenv(key string) string { - // `YTPROXY_` as a prefix - v, _ := syscall.Getenv("YTPROXY_" + key) - return v -} - func main() { defaultHost := "0.0.0.0" defaultPort := "8080" @@ -157,58 +151,58 @@ func main() { var ipv6 bool = false var bc bool = true - if strings.ToLower(getenv("HTTP")) == "true" { + if strings.ToLower(utils.Getenv("HTTP")) == "true" { http_server = true } - if strings.ToLower(getenv("HTTPS")) == "true" { + if strings.ToLower(utils.Getenv("HTTPS")) == "true" { https = true } - if strings.ToLower(getenv("H2C")) == "true" { + if strings.ToLower(utils.Getenv("H2C")) == "true" { h2c = true } - if strings.ToLower(getenv("H3C")) == "true" { + if strings.ToLower(utils.Getenv("H3C")) == "true" { h3c = true } - if strings.ToLower(getenv("H3S")) == "true" { + if strings.ToLower(utils.Getenv("H3S")) == "true" { h3s = true } - if strings.ToLower(getenv("IPV6_ONLY")) == "true" { + if strings.ToLower(utils.Getenv("IPV6_ONLY")) == "true" { ipv6 = true } - if strings.ToLower(getenv("BLOCK_CHECKER")) == "false" { + if strings.ToLower(utils.Getenv("BLOCK_CHECKER")) == "false" { bc = false } - tls_cert := getenv("TLS_CERT") + tls_cert := utils.Getenv("TLS_CERT") if tls_cert == "" { tls_cert = defaultTLSCert } - tls_key := getenv("TLS_KEY") + tls_key := utils.Getenv("TLS_KEY") if tls_key == "" { tls_key = defaultTLSKey } - sock := getenv("SOCK_PATH") + sock := utils.Getenv("SOCK_PATH") if sock == "" { sock = defaultSock } - port := getenv("PORT") + port := utils.Getenv("PORT") if port == "" { port = defaultPort } - host := getenv("HOST") + host := utils.Getenv("HOST") if host == "" { host = defaultHost } // gh is where the gluetun api is located - gh := getenv("GLUETUN_HOSTNAME") + gh := utils.Getenv("GLUETUN_HOSTNAME") if gh == "" { gh = "127.0.0.1:8000" } - bc_cooldown := getenv("BLOCK_CHECKER_COOLDOWN") + bc_cooldown := utils.Getenv("BLOCK_CHECKER_COOLDOWN") if bc_cooldown == "" { bc_cooldown = "60" } - httpc.Proxy = getenv("PROXY") + httpc.Proxy = utils.Getenv("PROXY") flag.BoolVar(&https, "https", https, "Use built-in https server (recommended)") flag.BoolVar(&h3c, "h3c", h3c, "Use HTTP/3 for client requests (high CPU usage)") diff --git a/internal/paths/consts.go b/internal/paths/consts.go index 1da12ea..8ba44d9 100644 --- a/internal/paths/consts.go +++ b/internal/paths/consts.go @@ -3,6 +3,8 @@ package paths import ( "net/http" "regexp" + + "git.nadeko.net/Fijxu/http3-ytproxy/internal/utils" ) const ( @@ -31,3 +33,5 @@ var videoplayback_headers = &http.Header{ // https://github.com/FreeTubeApp/FreeTube/blob/5a4cd981cdf2c2a20ab68b001746658fd0c6484e/src/renderer/components/ft-shaka-video-player/ft-shaka-video-player.js#L1097 var protobuf_body = []byte{0x78, 0} // protobuf body + +var secret_key = utils.Getenv("SECRET_KEY") diff --git a/internal/paths/videoplayback.go b/internal/paths/videoplayback.go index c8920f2..7ec07ea 100644 --- a/internal/paths/videoplayback.go +++ b/internal/paths/videoplayback.go @@ -56,6 +56,19 @@ func checkRequest(w http.ResponseWriter, req *http.Request, params url.Values) { func Videoplayback(w http.ResponseWriter, req *http.Request) { q := req.URL.Query() + if q.Get("enc") == "yes" { + deencryptedQueryParams, err := utils.DecryptQueryParams(req.URL.Query().Get("data"), secret_key) + if err != nil { + http.Error(w, "Internal Server Error:\nFailed to decrypt query parameters", http.StatusInternalServerError) + return + } + q, err = url.ParseQuery(deencryptedQueryParams) + if err != nil { + http.Error(w, "Internal Server Error:\nFailed to parse query parameters from the decrypted query parameters", http.StatusInternalServerError) + return + } + } + checkRequest(w, req, q) expire, err := strconv.ParseInt(q.Get("expire"), 10, 64) diff --git a/internal/utils/utils.go b/internal/utils/utils.go index 5c05672..d4a1c37 100644 --- a/internal/utils/utils.go +++ b/internal/utils/utils.go @@ -1,10 +1,13 @@ package utils import ( + "crypto/aes" + "encoding/base64" "log" "net/http" "net/url" "strings" + "syscall" "git.nadeko.net/Fijxu/http3-ytproxy/internal/httpc" ) @@ -74,3 +77,33 @@ func PanicHandler(w http.ResponseWriter) { http.Error(w, "Internal Server Error", http.StatusInternalServerError) } } + +func Getenv(key string) string { + // `YTPROXY_` as a prefix + v, _ := syscall.Getenv("YTPROXY_" + key) + return v +} + +// https://stackoverflow.com/a/41652605 +func DecryptQueryParams(encryptedQuery string, key string) (string, error) { + se, err := base64.URLEncoding.DecodeString(encryptedQuery) + if err != nil { + log.Println("[ERROR] Error when decoding base64 string:", err) + return "", err + } + + cipher, err := aes.NewCipher([]byte(key)[0:16]) + if err != nil { + log.Println("[ERROR] Error initializating cipher.Block:", err) + return "", err + } + decrypted := make([]byte, len(se)) + size := 16 + + for bs, be := 0, size; bs < len(se); bs, be = bs+size, be+size { + cipher.Decrypt(decrypted[bs:be], se[bs:be]) + } + + paddingSize := int(decrypted[len(decrypted)-1]) + return string(decrypted[0 : len(decrypted)-paddingSize]), nil +}