feat: add support for encrypted query parameters
All checks were successful
CI / build (push) Successful in 1m18s
All checks were successful
CI / build (push) Successful in 1m18s
This commit is contained in:
parent
81aa259a31
commit
6bd0f28d77
4 changed files with 65 additions and 21 deletions
|
@ -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)")
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue