package main import ( "encoding/base64" "fmt" "io" "os" "path/filepath" "strings" ) const mediaLockMagic = "CMVD" func decryptMediaFile(encPath, keyB64, playName string) (string, func(), error) { key, err := base64.StdEncoding.DecodeString(keyB64) if err != nil || len(key) == 0 { return "", nil, fmt.Errorf("invalid media key") } in, err := os.Open(encPath) if err != nil { return "", nil, err } defer in.Close() head := make([]byte, len(mediaLockMagic)) if _, err := io.ReadFull(in, head); err != nil || string(head) != mediaLockMagic { return "", nil, fmt.Errorf("not a locked media file") } dir, err := os.MkdirTemp("", "cm-fusion-play-*") if err != nil { return "", nil, err } outName := filepath.Base(playName) if outName == "" || outName == "." { outName = "movie.mkv" } outPath := filepath.Join(dir, outName) out, err := os.Create(outPath) if err != nil { os.RemoveAll(dir) return "", nil, err } buf := make([]byte, 256*1024) ki := 0 for { n, readErr := in.Read(buf) if n > 0 { plain := make([]byte, n) for i := 0; i < n; i++ { plain[i] = buf[i] ^ key[ki%len(key)] ki++ } if _, err := out.Write(plain); err != nil { out.Close() os.RemoveAll(dir) return "", nil, err } } if readErr == io.EOF { break } if readErr != nil { out.Close() os.RemoveAll(dir) return "", nil, readErr } } out.Close() return outPath, func() { _ = os.RemoveAll(dir) }, nil } func encryptedMediaBesideRunner(mediaEncFile, keyB64, playName string) (string, func(), error) { exe, err := os.Executable() if err != nil { return "", nil, err } name := strings.TrimSpace(mediaEncFile) if name == "" { return "", nil, fmt.Errorf("missing encrypted media name") } encPath := filepath.Join(filepath.Dir(exe), filepath.Base(name)) if st, err := os.Stat(encPath); err != nil || st.IsDir() { return "", nil, fmt.Errorf("encrypted media not found") } return decryptMediaFile(encPath, keyB64, playName) }