From 8012948b26787b5480be09d697f4d0fc1a266c97 Mon Sep 17 00:00:00 2001 From: MeowOS Date: Mon, 31 Aug 2026 06:41:23 +0800 Subject: [PATCH] =?UTF-8?q?feat(ncm):=20=E7=BD=91=E6=98=93=E4=BA=91?= =?UTF-8?q?=E6=A0=B8=E5=BF=83=E5=BA=93=20core/=20(agent-203)=20=E2=80=94?= =?UTF-8?q?=20ncm=5Fhttp(mbedtls=20TLS1.2+chunked+=E6=B5=81=E5=BC=8F?= =?UTF-8?q?=E9=99=90=E5=B9=85)/ncm=5Fcrypto(eapi/weapi/linuxapi,=20RSA=20r?= =?UTF-8?q?aw=E9=80=90=E5=AD=97=E8=8A=82=E9=AA=8C=E8=AF=81)/ncm=5Flogin(un?= =?UTF-8?q?ikey=E2=86=92=E4=BA=8C=E7=BB=B4=E7=A0=81=E2=86=92=E8=BD=AE?= =?UTF-8?q?=E8=AF=A2=E7=8A=B6=E6=80=81=E6=9C=BA=E2=86=92cookie=E5=8A=A0?= =?UTF-8?q?=E5=AF=86=E8=90=BD=E7=9B=98)/ncm=5Fapi(=E6=AD=8C=E5=8D=95/?= =?UTF-8?q?=E8=AF=A6=E6=83=85/=E6=92=AD=E6=94=BE=E5=9C=B0=E5=9D=80Hi-res?= =?UTF-8?q?=E9=80=90=E6=A1=A3=E9=99=8D=E7=BA=A7/=E6=AD=8C=E8=AF=8D)/ncm=5F?= =?UTF-8?q?cache(LRU=20=E9=BB=98=E8=AE=A410G)/ncm=5Fstore(deviceId?= =?UTF-8?q?=E6=8C=81=E4=B9=85=E5=8C=96+=E6=9C=BA=E5=99=A8=E5=AF=86?= =?UTF-8?q?=E9=92=A5)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 宿主+qemu-mipsel 全链路 PASS(unikey实拿/801轮询/eapi往返/RSA对拍/缓存LRU); -Wall -Wextra 自有代码0warning 待联调: 803真扫码、真机 hw:0,0 播放链路 --- patch_v2/ncm_app/REPORT.md | 94 ++++ patch_v2/ncm_app/build_core.sh | 62 +++ patch_v2/ncm_app/core/jsmn_impl.c | 4 + patch_v2/ncm_app/core/ncm.h | 46 ++ patch_v2/ncm_app/core/ncm_api.c | 265 ++++++++++++ patch_v2/ncm_app/core/ncm_api.h | 82 ++++ patch_v2/ncm_app/core/ncm_cache.c | 202 +++++++++ patch_v2/ncm_app/core/ncm_cache.h | 62 +++ patch_v2/ncm_app/core/ncm_common.c | 193 +++++++++ patch_v2/ncm_app/core/ncm_common.h | 76 ++++ patch_v2/ncm_app/core/ncm_crypto.c | 140 ++++++ patch_v2/ncm_app/core/ncm_crypto.h | 49 +++ patch_v2/ncm_app/core/ncm_ctx.c | 57 +++ patch_v2/ncm_app/core/ncm_http.c | 527 +++++++++++++++++++++++ patch_v2/ncm_app/core/ncm_http.h | 74 ++++ patch_v2/ncm_app/core/ncm_json.c | 189 ++++++++ patch_v2/ncm_app/core/ncm_json.h | 58 +++ patch_v2/ncm_app/core/ncm_login.c | 197 +++++++++ patch_v2/ncm_app/core/ncm_login.h | 58 +++ patch_v2/ncm_app/core/ncm_req.c | 298 +++++++++++++ patch_v2/ncm_app/core/ncm_req.h | 50 +++ patch_v2/ncm_app/core/ncm_store.c | 329 ++++++++++++++ patch_v2/ncm_app/core/ncm_store.h | 62 +++ patch_v2/ncm_app/test/test_ncm_core.c | 242 +++++++++++ patch_v2/ncm_app/test/test_ncm_core_host | Bin 0 -> 553848 bytes 25 files changed, 3416 insertions(+) create mode 100755 patch_v2/ncm_app/build_core.sh create mode 100644 patch_v2/ncm_app/core/jsmn_impl.c create mode 100644 patch_v2/ncm_app/core/ncm.h create mode 100644 patch_v2/ncm_app/core/ncm_api.c create mode 100644 patch_v2/ncm_app/core/ncm_api.h create mode 100644 patch_v2/ncm_app/core/ncm_cache.c create mode 100644 patch_v2/ncm_app/core/ncm_cache.h create mode 100644 patch_v2/ncm_app/core/ncm_common.c create mode 100644 patch_v2/ncm_app/core/ncm_common.h create mode 100644 patch_v2/ncm_app/core/ncm_crypto.c create mode 100644 patch_v2/ncm_app/core/ncm_crypto.h create mode 100644 patch_v2/ncm_app/core/ncm_ctx.c create mode 100644 patch_v2/ncm_app/core/ncm_http.c create mode 100644 patch_v2/ncm_app/core/ncm_http.h create mode 100644 patch_v2/ncm_app/core/ncm_json.c create mode 100644 patch_v2/ncm_app/core/ncm_json.h create mode 100644 patch_v2/ncm_app/core/ncm_login.c create mode 100644 patch_v2/ncm_app/core/ncm_login.h create mode 100644 patch_v2/ncm_app/core/ncm_req.c create mode 100644 patch_v2/ncm_app/core/ncm_req.h create mode 100644 patch_v2/ncm_app/core/ncm_store.c create mode 100644 patch_v2/ncm_app/core/ncm_store.h create mode 100644 patch_v2/ncm_app/test/test_ncm_core.c create mode 100755 patch_v2/ncm_app/test/test_ncm_core_host diff --git a/patch_v2/ncm_app/REPORT.md b/patch_v2/ncm_app/REPORT.md index 3987c36..0188244 100644 --- a/patch_v2/ncm_app/REPORT.md +++ b/patch_v2/ncm_app/REPORT.md @@ -122,3 +122,97 @@ CA bundle 内置方案、音质档位映射实测。这些属设备/账号侧联 - **推荐 TLS/加密一体用 mbedtls**(单库一次解决 TLS + AES/MD5/RSA raw/Base64 + X509,规避 RNSS-raw 手写风险);BearSSL 为省 flash 备选。 - **v1 体积增量 ≈ 438 KB(库)/ 只做 mp3**,内存估计数百 KB 工作集,14MB 可行;主要优化点是 mbedtls 裁剪与封面限幅。 - **最关键风险(RSA raw)已验证**;其余风险集中在风控(deviceId/UA 稳定持久化)与无版权降级策略。 + +--- + +## 9. 核心库批次(core/,纯 C 静态库,无 UI) + +> 日期:2026-08-31。在 §1-8 预研(候选库/工具链已定型)基础上落地核心库:http/crypto/login/api/cache 五模块 +> + 公共/存储/JSON/请求构建支撑模块 + ncm_ctx 上下文。仅改动 `patch_v2/ncm_app/`。未 commit/push/刷机/动设备。 + +### 9.1 模块与公开 API(头文件签名) + +| 模块 | 文件 | 主要公开函数 | +|---|---|---| +| 公共工具 | `core/ncm_common.h/.c` | `ncm_hex_encode/decode` `ncm_b64_encode/decode` `ncm_md5_hex` `ncm_sha256_hex` `ncm_url_encode/decode` `ncm_random_bytes` `ncm_now_ms` 等 | +| JSON | `core/ncm_json.h/.c` | `ncm_json_parse` `ncm_json_obj_get` `ncm_json_arr_get/len` `ncm_json_path[_str/_int/_bool]` `ncm_json_get_str_at/get_int_at` | +| HTTP | `core/ncm_http.h/.c` | `ncm_http_request`(一次性 POST/GET,限幅)`ncm_http_download`(流式回调 + max_bytes)`ncm_http_parse_set_cookie` `ncm_http_set_verify_default` | +| 存储 | `core/ncm_store.h/.c` | `ncm_store_init` `ncm_store_get/set_device_id` `ncm_store_machine_key` `ncm_store_cookie_encrypt/decrypt` `ncm_store_save/load/clear_session` `ncm_store_write/read_file` `ncm_store_read_cfg_int` | +| 加密 | `core/ncm_crypto.h/.c` | `ncm_crypto_eapi` `ncm_crypto_weapi` `ncm_crypto_linuxapi` `ncm_crypto_rsa_raw_selfcheck` | +| 请求构建 | `core/ncm_req.h/.c` | `ncm_req_build`(eapi/weapi/linux,注入 header/csrf_token/UA/Cookie)`ncm_req_cookie_get` | +| 登录 | `core/ncm_login.h/.c` | `ncm_login_qr_url` `ncm_login_unikey` `ncm_login_qr_matrix`(qrcodegen)`ncm_login_poll` `ncm_login_status_check` `ncm_login_save/load/clear_cookie` | +| 歌单/播放 | `core/ncm_api.h/.c` | `ncm_api_user_playlist` `ncm_api_playlist_detail` `ncm_api_song_detail` `ncm_api_song_url` `ncm_api_song_url_auto` `ncm_api_lyric` `ncm_api_level_str` | +| 缓存 | `core/ncm_cache.h/.c` | `ncm_cache_init` `ncm_cache_set_limit_gb/limit_gb` `ncm_cache_load_setting` `ncm_cache_lookup` `ncm_cache_open/write/commit/abort` `ncm_cache_total_bytes` `ncm_cache_evict` `ncm_cache_path` | +| 上下文 | `core/ncm.h` + `ncm_ctx.c` | `ncm_ctx_t`(deviceId/cookie/CA/默认音质/cache)`ncm_ctx_init` `ncm_ctx_set/load/clear_cookie` `ncm_ctx_default_cache_dir` | + +关键常量:`NCM_EAPI_KEY`/`NCM_WEAPI_PRESET`/`NCM_WEAPI_IV`/`NCM_LINUXAPI_KEY`/`NCM_RSA_DER_B64`(`ncm_crypto.h`); +UA 按加密类型分流(eapi=iPhone `NeteaseMusic 9.0.90/5038`,weapi=Chrome/Edg 124),请求头注入对齐 CNMPlayer `request.rs`(deviceId/UA 稳定)。 + +### 9.2 关键实现取舍 +- **CA 方案**(`ncm_http.h` 注释):`verify_ca=1`(默认)加载系统 CA bundle(或 `ca_path`),失败即拒绝(防 MITM);`verify_ca=0` 跳过校验(仅调试/受限网)。全局默认由 `ncm_http_set_verify_default` 设定,`ncm_ctx_init` 以其 `verify_ca/ca_path` 设置。**设备侧需内置 CA 根**(VENDOR_NOTES §备注),否则接口 eapi/weapi 会被拒。 +- **RSA raw**:用 `mbedtls_rsa_public()` 无 padding 纯模幂,16 字节 secret 右对齐 128 字节(前导 0),输出 256 小写 hex——已与 Python `pow(m,e,n)` 逐字节一致(见 9.4)。 +- **weapi**:双层 AES-128-CBC(`params` base64,含 `+/=` 需 urlencode)+ RSA(raw) 加密随机 16 位 base62 密钥(RSA 前**反转**)。 +- **会话cookie**:加密落盘 `MeowData//data/session.enc`,密钥 = `sha256(MAC + 盐)`;无 MAC(qemu/无网卡)回退到设备私有 `.mkey` 派生。**仅为防裸读模糊,非真安全**(头文件已注明)。 +- **缓存**:目录默认 `MeowData/os.meow.ncm/cache/`;上限默认 10GB(1~100 可配),读设置键 `ncm.cache_limit_gb`(`/ncm.cache_limit_gb.cfg`,对齐 SDK meow_config);LRU 按文件 mtime,`ncm_cache_lookup/commit` 刷新;命中即离线可播。 +- **音质**:`ncm_api_song_url_auto` 从 desired(默认 Hi-res)往下降级 `hires→lossless→exhigh→higher→standard`,只返回可解码 mp3(url 非空且 type=mp3);无该档对当前歌曲降级。 + +### 9.3 构建 +`./build_core.sh` → `out/core-host/`、`core-mipsel/`(自有代码对象 + vendor qrcodegen + jsmn 唯一实现 TU),链接 `out/mbedtls/{host,mipsel}/*.a`,产出: +- `test/test_ncm_core_host`(宿主,可跑) +- `out/test_ncm_core_mipsel`(mipsel 静态)。`size`:`text 462662 / data 212 / bss 27688`(含测试 printf 基建 + mbedtls + qrcodegen;核心库本身链接更小)。 +- 自有代码 `-Wall -Wextra` **0 warning**;vendor 警告豁免。mipsel 用 `.tools/zig-mipsel-cc` 静态交叉。 + +### 9.4 验证记录(宿主 + qemu-mipsel 双向实测,响应已脱敏/截断) +- **unikey 实拿(eapi)**:`{"code":200,"unikey":""}`(宿主 `dc5bd090-…`,qemu-mipsel `ef9a5db2-…`);二维码 URL `https://music.163.com/login?codekey=`。 +- **轮询(未扫码)**:`{"code":801,"message":"等待扫码"}` → `state=等待扫码(801)`,两平台一致。 +- **login_status(伪造 cookie)**:返回 weapi 可解析 JSON(code 200 但 profile null)→ 库判 `NCM_ERR_AUTH(-13)`,证明 weapi 请求被服务端接受。 +- **RSA raw 交叉**:`ncm_crypto_rsa_raw_selfcheck` 输出 `55b33e7e…b2b83`,与 Python `pow(m,65537,n)`(§3 已交叉验证值)**逐字节一致**。weapi params 为合法 base64(RSA 封装的 16 字节随机密钥无法无私钥解密,其 AES-CBC 为标准用法)。 +- **eapi 往返**:`ncm_crypto_eapi` 产物可用 AES-ECB 解回含 `url` + `json` 的明文(`/api/login/qrcode/unikey` + `{"type":3}`)。 +- **cookie 加解密**:38 字节串 `MUSIC_U=…; __csrf=xyz; os=pc` 加密→解密完全一致(含一次 mbedtls `crypt_cbc` 就地改写 IV 的坑,已修)。 +- **缓存**:写入/命中/abort 不留档/强制小上限触发 LRU 淘汰(总字节降至 ≤ 上限)。 +- **二维码**:41×41 内矩阵生成,暗模块 >0。 +- **无凭据错误处理**:`user_playlist(uid=0,无cookie)` 优雅返回(公开数据或错误码,不崩溃);`song_url(id=0)` 返回无 url。 + +### 9.5 md5(自有源码) +``` +778847a8419325af2b95ad0ef7749781 core/ncm_api.h c07d246c9b64e4d3b9078b9e33d19fe4 core/ncm_cache.h +6e878566f6a4c4377c98e87e9967fdcc core/ncm_common.h 9056253bfb635d8224e7454c6b1796a2 core/ncm_crypto.h +157807f07a96f43249f6aeb9707d053f core/ncm.h 477dd9f5eab61e2940cb432d1b215b3a core/ncm_http.h +398e62a0b641f13bc80c02d5e42a0401 core/ncm_json.h 05fb336d3b65b041095bd8fb3c64bc3c core/ncm_login.h +96f423ef1a36bda7b5cb3961fbe22028 core/ncm_req.h 02c7ff38dd856455f32a4cc7bbc5edd5 core/ncm_store.h +f8f8e96464d3c4ebcf1898eb4212c55a core/jsmn_impl.c a00e9b9b1adf7c6cf924eb9ecfc90a67 core/ncm_common.c +e75c29217ef5dd3f0e23c740b79210c1 core/ncm_crypto.c 9ebfa83e31a530b4dc8fd7877c2f5fb9 core/ncm_ctx.c +319df449ecd7727f328e01adb518ba57 core/ncm_http.c d69ff302ec111a74f621571818da4622 core/ncm_json.c +a53e55f9cab828fd59b694330ec7371e core/ncm_login.c d81eda09640ff748b0a1c14607447d1b core/ncm_req.c +1ceda66d30d44a3d8850df2e876c0195 core/ncm_store.c 7cdb84fcf87384eb5125e5aae01eac84 test/test_ncm_core.c +94a4dd07fba98a6e7b70021aaeb8cb19 build_core.sh +``` +产物:`test/test_ncm_core_host` md5 `0e41d3d413819768d65d2e9ca9e082ed`;`out/test_ncm_core_mipsel` md5 `e05f1937e5fc49a2590b830c28ee6372`。 + +### 9.6 出入清单(只改 `patch_v2/ncm_app/`) +``` +新增: + core/ncm.h ncm_ctx.c // 伞头 + 上下文 + core/ncm_common.h/.c // hex/base64/md5/sha256/urlencode/errcode + core/ncm_json.h/.c // jsmn 路径导航 + core/ncm_crypto.h/.c // eapi/weapi/linuxapi + RSA raw + core/ncm_http.h/.c // mbedtls HTTPS POST/GET + CA取舍 + 超时 + chunked + core/ncm_store.h/.c // deviceId/MAC机器密钥/cookie加解密/配置读取 + core/ncm_req.h/.c // 加密请求构建(md5/UA/cookie 注入) + core/ncm_login.h/.c // unikey/二维码矩阵/轮询状态机/cookie捕获/login_status + core/ncm_api.h/.c // 歌单/详情/歌曲/播放地址/歌词 + core/ncm_cache.h/.c // LRU 缓存 + 离线可播 + core/jsmn_impl.c // jsmn 唯一实现 TU(防多 TU 重复定义) + test/test_ncm_core.c // 宿主 + mipsel 综合实测 + build_core.sh // 宿主 + mipsel 编译链接 +修改: + REPORT.md // 追加本批记录 +(未动 vendor/,未动其余目录) +``` + +### 9.7 未做/诚实出入 +- **803 真登录**未实测(需真实扫码):code 803 分支的 set-cookie 捕获/合并逻辑按 document 实现,但未真跑;联调时建议真扫码验证一次 `MUSIC_U` 内容与 `login_status` 校验链路。 +- **weapi params 无法无 RSA 私钥解密**核验其内部 AES 双层,但 RSA 封路径已逐字节交叉,AES-CBC 为标准用法(可用 CNMPlayer 同源实现比对)。 +- **播放地址/缓存仅验证到“请求-解析-无版权返回 null”**;未做真实音频下载落盘(缓存 open/write/commit 已由单元测试覆盖;真实 mp3 下载留给带 UI 的播放层用 `ncm_http_download`+`ncm_cache_*` 串联)。 +- **栈用量**:单次 http 调用涉及 mbedtls ssl/净栈,峰值栈估几十 KB(与预研 demo 同级);App 线程栈需 ≥64KB,联调时以真机线程栈为准。 +- **JSON 响应限幅**:歌单/歌曲详情走 1MB~2MB 堆缓冲 + token 计数后精确分配,不算常驻;封面/大 JSON 不整体驻留,封面下载另有 `max_bytes` 限幅(建议 ~256KB,未在本次接线)。 diff --git a/patch_v2/ncm_app/build_core.sh b/patch_v2/ncm_app/build_core.sh new file mode 100755 index 0000000..dd23063 --- /dev/null +++ b/patch_v2/ncm_app/build_core.sh @@ -0,0 +1,62 @@ +#!/bin/bash +# build_core.sh — 编译/链接 ncm_app 核心库与宿主测试(宿主 + mipsel 静态)。 +# 依赖:先运行 build_mbedtls.sh(产出 out/mbedtls/{host,mipsel}/*.a)。 +. ./libs_common.sh + +INC_CORE="-Icore" +INC_VENDOR="-I$VENDOR/mbedtls/include -I$VENDOR/jsmn -I$VENDOR/qrcodegen/c" +CORE="core/ncm_common.c core/ncm_json.c core/ncm_store.c core/ncm_http.c \ + core/ncm_crypto.c core/ncm_req.c core/ncm_login.c core/ncm_api.c \ + core/ncm_cache.c core/ncm_ctx.c" +VENDOR_C="vendor/qrcodegen/c/qrcodegen.c" # qrcodegen 单独编译 +JSMN_IMPL="core/jsmn_impl.c" # jsmn 唯一实现 TU + +STRICT="-Wall -Wextra" +HOST_LIBS="-L$OUT/mbedtls/host -lmbedtls -lmbedx509 -lmbedcrypto" +MIPS_LIBS="$OUT/mbedtls/mipsel/libmbedtls.a $OUT/mbedtls/mipsel/libmbedx509.a $OUT/mbedtls/mipsel/libmbedcrypto.a" + +echo "==> host 核心库对象" +mkdir -p out/core-host out/core-mipsel +ok=1 +for f in $CORE; do + b=$(basename "$f" .c) + if ! $CC_HOST -O2 -c $STRICT -DJSMN_HEADER -Icore $INC_VENDOR "$f" -o "out/core-host/$b.o"; then ok=0; break; fi +done +[ $ok -ne 1 ] && { echo "host core build FAILED"; exit 1; } + +echo "==> host vendor/jsmn 对象(豁免警告)" +$CC_HOST -O2 -c -I$VENDOR/jsmn $JSMN_IMPL -o out/core-host/jsmn_impl.o 2>/dev/null || { echo "jsmn_impl FAILED"; exit 1; } +for f in $VENDOR_C; do + b=$(basename "$f" .c) + $CC_HOST -O2 -c -I$VENDOR "$f" -o "out/core-host/v_$b.o" 2>/dev/null || { echo "vendor $f FAILED"; exit 1; } +done + +echo "==> host 测试可执行" +$CC_HOST -O2 $STRICT -DJSMN_HEADER -Icore $INC_VENDOR test/test_ncm_core.c \ + out/core-host/*.o $HOST_LIBS -o test/test_ncm_core_host -lpthread -lm || { echo "host test link FAILED"; exit 1; } +echo " 运行: ./test/test_ncm_core_host" + +echo +echo "==> mipsel 核心库对象(交叉)" +ok=1 +for f in $CORE; do + b=$(basename "$f" .c) + if ! $CC_MIPS -O2 -static -c $STRICT -DJSMN_HEADER -Icore $INC_VENDOR "$f" -o "out/core-mipsel/$b.o"; then ok=0; break; fi +done +[ $ok -ne 1 ] && { echo "mipsel core build FAILED"; exit 1; } + +echo "==> mipsel vendor/jsmn 对象(豁免警告)" +$CC_MIPS -O2 -static -c -I$VENDOR/jsmn $JSMN_IMPL -o out/core-mipsel/jsmn_impl.o 2>/dev/null || { echo "jsmn_impl FAILED"; exit 1; } +for f in $VENDOR_C; do + b=$(basename "$f" .c) + $CC_MIPS -O2 -static -c -I$VENDOR "$f" -o "out/core-mipsel/v_$b.o" 2>/dev/null || { echo "vendor $f FAILED"; exit 1; } +done + +echo "==> mipsel 测试可执行(静态)" +$CC_MIPS -O2 -static -Wl,--gc-sections $STRICT -DJSMN_HEADER -Icore $INC_VENDOR test/test_ncm_core.c \ + out/core-mipsel/*.o $MIPS_LIBS -o out/test_ncm_core_mipsel -lpthread -lm \ + || { echo "mipsel test link FAILED"; exit 1; } +size out/test_ncm_core_mipsel +echo " 运行: timeout 120 qemu-mipsel ./out/test_ncm_core_mipsel" +echo +echo "build_core OK" diff --git a/patch_v2/ncm_app/core/jsmn_impl.c b/patch_v2/ncm_app/core/jsmn_impl.c new file mode 100644 index 0000000..5bdad47 --- /dev/null +++ b/patch_v2/ncm_app/core/jsmn_impl.c @@ -0,0 +1,4 @@ +/* jsmn_impl.c — jsmn 唯一实现 TU。 + * jsmn.h 默认把实现(extern 函数)写进每个包含它的 TU, + * 因此全工程只允许这一个 TU 不带 JSMN_HEADER 编译,其余 TU 用 -DJSMN_HEADER 取声明。 */ +#include "jsmn.h" diff --git a/patch_v2/ncm_app/core/ncm.h b/patch_v2/ncm_app/core/ncm.h new file mode 100644 index 0000000..9985650 --- /dev/null +++ b/patch_v2/ncm_app/core/ncm.h @@ -0,0 +1,46 @@ +/* ncm.h — 网易云核心库伞头 + * + * 汇总各模块,并提供 ncm_ctx_t 上下文(deviceId/会话 cookie/缓存/默认音质)。 + * 全部静态链接 mbedtls/jsmn/qrcodegen;纯 C,无 UI。 + */ +#ifndef NCM_H +#define NCM_H + +#include "ncm_common.h" +#include "ncm_crypto.h" +#include "ncm_http.h" +#include "ncm_json.h" +#include "ncm_store.h" +#include "ncm_req.h" +#include "ncm_login.h" +#include "ncm_api.h" +#include "ncm_cache.h" + +#define NCM_CTX_CA_PATH_MAX 256 + +typedef struct ncm_ctx { + ncm_store_t store; + ncm_cache_t cache; + char device_id[NCM_STORE_ID_MAX]; /* 52hex 已持久化 */ + char cookie[NCM_COOKIE_MAX]; /* 会话 cookie,可为空 */ + int verify_ca; /* 1=校验CA(默认) */ + int timeout_ms; /* HTTP 超时 */ + char ca_path[NCM_CTX_CA_PATH_MAX]; /* 可选 CA bundle */ + int default_level; /* NCM_LEVEL_* 默认音质(Hi-res) */ +} ncm_ctx_t; + +/* 默认缓存目录(/../cache,即 MeowData/os.meow.ncm/cache)。 */ +int ncm_ctx_default_cache_dir(const char *data_dir, char *out, size_t out_sz); + +/* 初始化上下文:store(数据目录) + deviceId 载入/生成 + cookie 载入 + cache 目录 + 缓存上限配置。 */ +void ncm_ctx_init(ncm_ctx_t *ctx, const char *data_dir); + +/* 会话 cookie 便捷存取(经 ncm_ctx 的 store)。 */ +int ncm_ctx_set_cookie(ncm_ctx_t *ctx, const char *cookie); /* 更新内存 + 加密落盘 */ +int ncm_ctx_load_cookie(ncm_ctx_t *ctx); /* 从盘载入到 ctx->cookie */ +int ncm_ctx_clear_cookie(ncm_ctx_t *ctx); + +#ifdef __cplusplus +} +#endif +#endif /* NCM_H */ diff --git a/patch_v2/ncm_app/core/ncm_api.c b/patch_v2/ncm_app/core/ncm_api.c new file mode 100644 index 0000000..6877e29 --- /dev/null +++ b/patch_v2/ncm_app/core/ncm_api.c @@ -0,0 +1,265 @@ +/* ncm_api.c — 歌单/播放数据接口实现(响应/token 走堆,避免大缓冲驻栈) */ +#include "ncm_api.h" +#include "ncm_common.h" +#include "ncm_http.h" +#include "ncm_json.h" +#include "ncm_req.h" + +#include +#include +#include + +const char *ncm_api_level_str(int level) { + switch (level) { + case NCM_LEVEL_HIRES: return "hires"; + case NCM_LEVEL_LOSSLESS: return "lossless"; + case NCM_LEVEL_EXHIGH: return "exhigh"; + case NCM_LEVEL_HIGHER: return "higher"; + default: return "standard"; + } +} + +/* 堆上建立一次接口调用 + 解析上下文;用完必须 api_free */ +typedef struct api_json { + char *rbuf; /* 响应体缓冲(含 body) */ + jsmntok_t *toks; + int *parent; + int ntoks; + ncm_json_t j; + ncm_http_resp_t resp; +} api_json_t; + +static void api_free(api_json_t *c); + +static int api_post(const char *device_id, const char *cookie, const char *path, + const char *json, int kind, size_t resp_cap, api_json_t *c) { + char body[NCM_REQ_BODY_MAX], hdrs[NCM_REQ_HDRS_MAX], url[NCM_REQ_URL_MAX]; + int rc = ncm_req_build(device_id, cookie, path, json, kind, + body, sizeof body, hdrs, sizeof hdrs, url, sizeof url); + if (rc != NCM_OK) return rc; + + ncm_http_req_t req; + memset(&req, 0, sizeof req); + req.url = url; req.method = "POST"; req.body = body; req.body_len = strlen(body); + req.extra_hdrs = hdrs; req.verify_ca = NCM_HTTP_VERIFY_DEFAULT; req.timeout_ms = 15000; + + c->rbuf = (char *)malloc(resp_cap); + if (!c->rbuf) return NCM_ERR_OOM; + rc = ncm_http_request(&req, c->rbuf, resp_cap, &c->resp); + if (rc != NCM_OK) { free(c->rbuf); c->rbuf = NULL; return rc; } + + jsmn_parser p; + jsmn_init(&p); + int n = jsmn_parse(&p, c->resp.body, c->resp.body_len, NULL, 0); + if (n <= 0) { free(c->rbuf); c->rbuf = NULL; return NCM_ERR_JSON; } + c->toks = (jsmntok_t *)malloc(sizeof(jsmntok_t) * (size_t)n); + c->parent = (int *)malloc(sizeof(int) * (size_t)n); + if (!c->toks || !c->parent) { + free(c->rbuf); free(c->toks); free(c->parent); + c->rbuf = NULL; c->toks = NULL; c->parent = NULL; + return NCM_ERR_OOM; + } + rc = ncm_json_parse(&c->j, c->resp.body, c->resp.body_len, c->toks, n, c->parent); + if (rc < 0) { api_free(c); return NCM_ERR_JSON; } + c->ntoks = n; + + long code; + if (ncm_json_path_int(&c->j, "code", &code) == NCM_OK && code != 200) { + int ec = NCM_ERR_HTTP; + if (code == 301 || code == -460 || code == 2000 || code == 201) ec = NCM_ERR_AUTH; + api_free(c); + return ec; + } + return NCM_OK; +} + +static void api_free(api_json_t *c) { + free(c->rbuf); c->rbuf = NULL; + free(c->toks); c->toks = NULL; + free(c->parent); c->parent = NULL; +} + +static int obj_str(const ncm_json_t *j, int tok, const char *key, char *out, size_t out_sz) { + if (!out || out_sz == 0) return 0; + int vt = ncm_json_obj_get(j, tok, key); + if (vt < 0) { out[0] = 0; return 0; } + if (!ncm_json_get_str_at(j, vt, out, out_sz)) out[0] = 0; + return 0; +} +static long obj_int(const ncm_json_t *j, int tok, const char *key) { + int vt = ncm_json_obj_get(j, tok, key); + int rc; + return ncm_json_get_int_at(j, vt, &rc); +} + +int ncm_api_user_playlist(const char *device_id, const char *cookie, const char *uid, + int limit, int offset, ncm_playlist_t *out, int max, int *out_n) { + if (!out_n) return NCM_ERR_ARG; + *out_n = 0; + if (!uid) return NCM_ERR_ARG; + char json[256]; + snprintf(json, sizeof json, "{\"uid\":\"%s\",\"limit\":%d,\"offset\":%d,\"includeVideo\":true}", + uid, limit > 0 ? limit : 30, offset > 0 ? offset : 0); + + api_json_t c; memset(&c, 0, sizeof c); + int rc = api_post(device_id, cookie, "/api/user/playlist", json, NCM_CRYPT_WEAPI, + NCM_RESP_MAX, &c); + if (rc != NCM_OK) return rc; + + int arr = ncm_json_path(&c.j, "playlist"); + if (arr < 0 || ncm_json_type(&c.j, arr) != JSMN_ARRAY) { api_free(&c); return NCM_ERR_NOTFOUND; } + int n = ncm_json_arr_len(&c.j, arr); + if (n > max) n = max; + memset(out, 0, sizeof(*out) * (size_t)(n > 0 ? n : 0)); + for (int i = 0; i < n; i++) { + int e = ncm_json_arr_get(&c.j, arr, i); + if (e < 0) break; + obj_str(&c.j, e, "id", out[i].id, sizeof out[i].id); + obj_str(&c.j, e, "name", out[i].name, sizeof out[i].name); + obj_str(&c.j, e, "coverImgUrl", out[i].cover, sizeof out[i].cover); + out[i].track_count = (int)obj_int(&c.j, e, "trackCount"); + } + *out_n = n; + api_free(&c); + return NCM_OK; +} + +int ncm_api_playlist_detail(const char *device_id, const char *cookie, const char *playlist_id, + char *name, size_t name_sz, char *cover, size_t cover_sz, + long *ids, int id_cap, int *out_id_n) { + if (!out_id_n) return NCM_ERR_ARG; + *out_id_n = 0; + char json[256]; + snprintf(json, sizeof json, "{\"id\":\"%s\",\"n\":100000,\"s\":8}", playlist_id); + + api_json_t c; memset(&c, 0, sizeof c); + int rc = api_post(device_id, cookie, "/api/v6/playlist/detail", json, NCM_CRYPT_EAPI, + NCM_RESP_MAX, &c); + if (rc != NCM_OK) return rc; + + int pl = ncm_json_path(&c.j, "playlist"); + if (pl < 0 || ncm_json_type(&c.j, pl) != JSMN_OBJECT) { api_free(&c); return NCM_ERR_NOTFOUND; } + if (name) obj_str(&c.j, pl, "name", name, name_sz); + if (cover) obj_str(&c.j, pl, "coverImgUrl", cover, cover_sz); + + int tid = ncm_json_obj_get(&c.j, pl, "trackIds"); + if (tid < 0 || ncm_json_type(&c.j, tid) != JSMN_ARRAY) { + tid = ncm_json_obj_get(&c.j, pl, "tracks"); + if (tid < 0) { api_free(&c); return NCM_OK; } + } + int n = ncm_json_arr_len(&c.j, tid); + int take = n < id_cap ? n : id_cap; + for (int i = 0; i < take; i++) { + int e = ncm_json_arr_get(&c.j, tid, i); + int vt = ncm_json_obj_get(&c.j, e, "id"); + int rc2; + ids[i] = ncm_json_get_int_at(&c.j, vt, &rc2); + } + *out_id_n = take; + api_free(&c); + return NCM_OK; +} + +int ncm_api_song_detail(const char *device_id, const char *cookie, const long *ids, int n, + ncm_song_t *out, int max, int *out_n) { + if (!out_n) return NCM_ERR_ARG; + *out_n = 0; + char clist[4096] = "[", tmp[64]; + for (int i = 0; i < n && strlen(clist) < sizeof clist - 80; i++) { + snprintf(tmp, sizeof tmp, "%s{\"id\":%ld}", i ? "," : "", ids[i]); + ncm_strlcat(clist, tmp, sizeof clist); + } + ncm_strlcat(clist, "]", sizeof clist); + char json[4500]; + snprintf(json, sizeof json, "{\"c\":\"%s\"}", clist); + + api_json_t c; memset(&c, 0, sizeof c); + int rc = api_post(device_id, cookie, "/api/v3/song/detail", json, NCM_CRYPT_EAPI, + 2 * 1024 * 1024, &c); + if (rc != NCM_OK) return rc; + + int arr = ncm_json_path(&c.j, "songs"); + if (arr < 0 || ncm_json_type(&c.j, arr) != JSMN_ARRAY) { api_free(&c); return NCM_ERR_NOTFOUND; } + int cnt = ncm_json_arr_len(&c.j, arr); + if (cnt > max) cnt = max; + memset(out, 0, sizeof(*out) * (size_t)(cnt > 0 ? cnt : 0)); + for (int i = 0; i < cnt; i++) { + int e = ncm_json_arr_get(&c.j, arr, i); + if (e < 0) break; + obj_str(&c.j, e, "id", out[i].id, sizeof out[i].id); + obj_str(&c.j, e, "name", out[i].name, sizeof out[i].name); + out[i].duration_ms = obj_int(&c.j, e, "dt"); + out[i].fee = (int)obj_int(&c.j, e, "fee"); + int ar = ncm_json_obj_get(&c.j, e, "ar"); + if (ar >= 0 && ncm_json_type(&c.j, ar) == JSMN_ARRAY) { + int a0 = ncm_json_arr_get(&c.j, ar, 0); + if (a0 >= 0) obj_str(&c.j, a0, "name", out[i].art_name, sizeof out[i].art_name); + } + int al = ncm_json_obj_get(&c.j, e, "al"); + if (al >= 0) obj_str(&c.j, al, "name", out[i].album_name, sizeof out[i].album_name); + } + *out_n = cnt; + api_free(&c); + return NCM_OK; +} + +int ncm_api_song_url(const char *device_id, const char *cookie, const char *id, + int level, ncm_play_url_t *out) { + if (!out) return NCM_ERR_ARG; + memset(out, 0, sizeof *out); + char json[256]; + snprintf(json, sizeof json, + "{\"ids\":\"[%s]\",\"level\":\"%s\",\"encodeType\":\"flac\"}", + id, ncm_api_level_str(level)); + + api_json_t c; memset(&c, 0, sizeof c); + int rc = api_post(device_id, cookie, "/api/song/enhance/player/url/v1", json, NCM_CRYPT_EAPI, + NCM_RESP_MAX, &c); + if (rc != NCM_OK) return rc; + + int d0 = ncm_json_path(&c.j, "data[0]"); + if (d0 < 0) { api_free(&c); return NCM_ERR_NOTFOUND; } + obj_str(&c.j, d0, "url", out->url, sizeof out->url); + obj_str(&c.j, d0, "type", out->type, sizeof out->type); + obj_str(&c.j, d0, "level", out->level, sizeof out->level); + out->br = (int)obj_int(&c.j, d0, "br"); + out->size = obj_int(&c.j, d0, "size"); + api_free(&c); + return NCM_OK; +} + +int ncm_api_song_url_auto(const char *device_id, const char *cookie, const char *id, + int desired, ncm_play_url_t *out) { + int start = desired; + if (start < NCM_LEVEL_STANDARD) start = NCM_LEVEL_HIRES; + if (start > NCM_LEVEL_HIRES) start = NCM_LEVEL_HIRES; + /* 从 desired 往下降级:hires->lossless->exhigh->higher->standard */ + for (int lv = start; lv >= NCM_LEVEL_STANDARD; lv--) { + ncm_play_url_t p; + int rc = ncm_api_song_url(device_id, cookie, id, lv, &p); + if (rc != NCM_OK) continue; + /* 只接受有 url 且 type 为 mp3(v1 不解 flac) */ + if (p.url[0] && (ncm_streq(p.type, "mp3") || p.type[0] == 0)) { + *out = p; + return NCM_OK; + } + /* url 为 null 或 flac:继续降级 */ + } + return NCM_ERR_NOTFOUND; +} + +int ncm_api_lyric(const char *device_id, const char *cookie, const char *id, + char *lrc, size_t lrc_sz, char *tlrc, size_t tlrc_sz) { + char json[256]; + snprintf(json, sizeof json, "{\"id\":\"%s\",\"tv\":-1,\"lv\":-1,\"rv\":-1,\"kv\":-1,\"_nmclfl\":1}", + id); + + api_json_t c; memset(&c, 0, sizeof c); + int rc = api_post(device_id, cookie, "/api/song/lyric", json, NCM_CRYPT_EAPI, + NCM_RESP_MAX, &c); + if (rc != NCM_OK) return rc; + if (lrc && lrc_sz) { lrc[0] = 0; ncm_json_path_str(&c.j, "lrc.lyric", lrc, lrc_sz); } + if (tlrc && tlrc_sz) { tlrc[0] = 0; ncm_json_path_str(&c.j, "tlyric.lyric", tlrc, tlrc_sz); } + api_free(&c); + return NCM_OK; +} diff --git a/patch_v2/ncm_app/core/ncm_api.h b/patch_v2/ncm_app/core/ncm_api.h new file mode 100644 index 0000000..e6d9802 --- /dev/null +++ b/patch_v2/ncm_app/core/ncm_api.h @@ -0,0 +1,82 @@ +/* ncm_api.h — 歌单 / 播放数据接口 + * + * 覆盖 NCM_API_NOTES §2.1 的 5 个数据端点: + * user_playlist(weapi) / playlist_detail(eapi,v6) / song_detail(eapi,v3) + * song_url_v1(eapi) / lyric(eapi) + * 解析用 jsmn 路径导航,响应体限幅(NCM_RESP_MAX)。封面/大 JSON 不整体驻留。 + */ +#ifndef NCM_API_H +#define NCM_API_H + +#include "ncm_store.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* 音质档位(song_url_v1 level)。v1 可解码 mp3:standard/higher/exhigh。 */ +enum { + NCM_LEVEL_STANDARD = 0, + NCM_LEVEL_HIGHER, + NCM_LEVEL_EXHIGH, + NCM_LEVEL_LOSSLESS, + NCM_LEVEL_HIRES, +}; +const char *ncm_api_level_str(int level); + +typedef struct ncm_playlist { + char id[32]; + char name[256]; + char cover[512]; + int track_count; +} ncm_playlist_t; + +typedef struct ncm_song { + char id[32]; + char name[256]; + char art_name[256]; /* 首个歌手名 */ + char album_name[256]; + long duration_ms; + int fee; +} ncm_song_t; + +typedef struct ncm_play_url { + char url[1024]; + char type[16]; + char level[16]; + int br; + long size; +} ncm_play_url_t; + +/* 用户歌单列表(weapi /user/playlist)。uid 必填;limit/offset 翻页。 + * 返回 NCM_OK;songs/out_n 为列表。 */ +int ncm_api_user_playlist(const char *device_id, const char *cookie, const char *uid, + int limit, int offset, ncm_playlist_t *out, int max, int *out_n); + +/* 歌单详情(eapi /v6/playlist/detail):取名字/封面 + trackIds 数组(填 ids, cap)。 */ +int ncm_api_playlist_detail(const char *device_id, const char *cookie, const char *playlist_id, + char *name, size_t name_sz, char *cover, size_t cover_sz, + long *ids, int id_cap, int *out_id_n); + +/* 批量歌曲详情(eapi /v3/song/detail)。ids 传入曲目 id 数组。 */ +int ncm_api_song_detail(const char *device_id, const char *cookie, const long *ids, int n, + ncm_song_t *out, int max, int *out_n); + +/* 播放地址(eapi /song/enhance/player/url/v1)。level 指定档位;url 可能为 null(无版权/VIP)。 */ +int ncm_api_song_url(const char *device_id, const char *cookie, const char *id, + int level, ncm_play_url_t *out); + +/* 播放地址自动降级:从 desired 档开始,遇 url 为 null 或非 mp3(本机不可解码)则逐步降档, + * 只返回 mp3。desired 默认 hires。 */ +int ncm_api_song_url_auto(const char *device_id, const char *cookie, const char *id, + int desired, ncm_play_url_t *out); + +/* 歌词(eapi /song/lyric):lrc 原文 + 翻译。 */ +int ncm_api_lyric(const char *device_id, const char *cookie, const char *id, + char *lrc, size_t lrc_sz, char *tlrc, size_t tlrc_sz); + +#ifdef __cplusplus +} +#endif +#endif /* NCM_API_H */ diff --git a/patch_v2/ncm_app/core/ncm_cache.c b/patch_v2/ncm_app/core/ncm_cache.c new file mode 100644 index 0000000..441baaa --- /dev/null +++ b/patch_v2/ncm_app/core/ncm_cache.c @@ -0,0 +1,202 @@ +/* ncm_cache.c — 缓存实现 */ +#include "ncm_cache.h" +#include "ncm_common.h" +#include "ncm_store.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DEFAULT_LIMIT_GB 10 +#define MIN_LIMIT_GB 1 +#define MAX_LIMIT_GB 100 +#define MAX_ENTRIES 4096 + +typedef struct entry { + char name[256]; + uint64_t size; + int64_t mtime; +} entry_t; + +static int gb_to_bytes(int gb) { + if (gb < MIN_LIMIT_GB) gb = MIN_LIMIT_GB; + if (gb > MAX_LIMIT_GB) gb = MAX_LIMIT_GB; + return (int)((uint64_t)gb * 1024ULL * 1024ULL * 1024ULL); +} + +int ncm_cache_init(ncm_cache_t *c, const char *dir) { + if (!c) return NCM_ERR_ARG; + memset(c, 0, sizeof *c); + if (dir && *dir) ncm_strlcpy(c->dir, dir, sizeof c->dir); + else ncm_strlcpy(c->dir, "cache", sizeof c->dir); + size_t n = strlen(c->dir); + while (n > 1 && c->dir[n-1]=='/') c->dir[--n] = 0; + ncm_store_mkdir_p(c->dir); + c->limit_gb = DEFAULT_LIMIT_GB; + c->limit_bytes = (uint64_t)gb_to_bytes(DEFAULT_LIMIT_GB); + return NCM_OK; +} + +void ncm_cache_set_limit_gb(ncm_cache_t *c, int gb) { + if (!c) return; + c->limit_gb = gb < MIN_LIMIT_GB ? MIN_LIMIT_GB : (gb > MAX_LIMIT_GB ? MAX_LIMIT_GB : gb); + c->limit_bytes = (uint64_t)gb_to_bytes(c->limit_gb); +} + +int ncm_cache_limit_gb(const ncm_cache_t *c) { + return c ? c->limit_gb : DEFAULT_LIMIT_GB; +} + +void ncm_cache_load_setting(ncm_cache_t *c, const char *data_dir) { + if (!c || !data_dir) return; + int gb = ncm_store_read_cfg_int(data_dir, "ncm.cache_limit_gb", DEFAULT_LIMIT_GB); + ncm_cache_set_limit_gb(c, gb); +} + +const char *ncm_cache_dir(const ncm_cache_t *c) { + return c ? c->dir : ""; +} + +int ncm_cache_path(const ncm_cache_t *c, const char *id, const char *ext, + char *out, size_t out_sz) { + if (!c || !id || !out) return NCM_ERR_ARG; + int n = snprintf(out, out_sz, "%s/song_%s.%s", c->dir, id, ext ? ext : "bin"); + return (n >= 0 && (size_t)n < out_sz) ? NCM_OK : NCM_ERR_FULL; +} + +int ncm_cache_lookup(const ncm_cache_t *c, const char *id, const char *ext, + char *out, size_t out_sz) { + char path[NCM_CACHE_DIR_MAX + 32]; + if (ncm_cache_path(c, id, ext, path, sizeof path) != 0) return NCM_ERR_FULL; + struct stat st; + if (stat(path, &st) != 0) return NCM_ERR_NOENT; + if (!S_ISREG(st.st_mode)) return NCM_ERR_NOENT; + utime(path, NULL); /* 刷新最后访问(按 mtime LRU) */ + ncm_strlcpy(out, path, out_sz); + return NCM_OK; +} + +struct ncm_cache_writer { + char final_path[NCM_CACHE_DIR_MAX + 64]; + char tmp_path[NCM_CACHE_DIR_MAX + 80]; + FILE *fp; + uint64_t nwritten; + int failed; +}; + +int ncm_cache_open(const ncm_cache_t *c, const char *id, const char *ext, + ncm_cache_writer_t **w_out) { + if (!c || !id || !w_out) return NCM_ERR_ARG; + ncm_cache_writer_t *w = (ncm_cache_writer_t *)calloc(1, sizeof *w); + if (!w) return NCM_ERR_OOM; + if (ncm_cache_path(c, id, ext, w->final_path, sizeof w->final_path) != 0) { + free(w); return NCM_ERR_FULL; + } + snprintf(w->tmp_path, sizeof w->tmp_path, "%s.tmp", w->final_path); + w->fp = fopen(w->tmp_path, "wb"); + if (!w->fp) { free(w); return NCM_ERR_IO; } + *w_out = w; + return NCM_OK; +} + +int ncm_cache_write(ncm_cache_writer_t *w, const unsigned char *data, size_t len) { + if (!w || !w->fp || w->failed) return NCM_ERR_ARG; + if (fwrite(data, 1, len, w->fp) != len) { w->failed = 1; return NCM_ERR_IO; } + w->nwritten += len; + return NCM_OK; +} + +static int cmp_mtime_asc(const void *a, const void *b) { + const entry_t *x = (const entry_t *)a, *y = (const entry_t *)b; + if (x->mtime < y->mtime) return -1; + if (x->mtime > y->mtime) return 1; + return 0; +} + +int ncm_cache_evict(const ncm_cache_t *c) { + if (!c) return NCM_ERR_ARG; + DIR *d = opendir(c->dir); + if (!d) return NCM_ERR_IO; + entry_t *ents = (entry_t *)malloc(sizeof(entry_t) * MAX_ENTRIES); + if (!ents) { closedir(d); return NCM_ERR_OOM; } + int n = 0; + uint64_t total = 0; + struct dirent *e; + while ((e = readdir(d)) && n < MAX_ENTRIES) { + if (strncmp(e->d_name, "song_", 5) != 0) continue; + char p[NCM_CACHE_DIR_MAX + NAME_MAX + 8]; + snprintf(p, sizeof p, "%s/%s", c->dir, e->d_name); + struct stat st; + if (stat(p, &st) != 0 || !S_ISREG(st.st_mode)) continue; + ncm_strlcpy(ents[n].name, e->d_name, sizeof ents[n].name); + ents[n].size = (uint64_t)st.st_size; + ents[n].mtime = (int64_t)st.st_mtim.tv_sec; + total += ents[n].size; + n++; + } + closedir(d); + + if (total > c->limit_bytes && n > 0) { + qsort(ents, (size_t)n, sizeof(entry_t), cmp_mtime_asc); + /* 从最旧删起,直到 <= 上限 */ + for (int i = 0; i < n; i++) { + if (total <= c->limit_bytes) break; + char p[NCM_CACHE_DIR_MAX + NAME_MAX + 8]; + snprintf(p, sizeof p, "%s/%s", c->dir, ents[i].name); + if (unlink(p) == 0 && ents[i].size < total) total -= ents[i].size; + } + } + free(ents); + return NCM_OK; +} + +int ncm_cache_commit(ncm_cache_writer_t *w) { + if (!w) return NCM_ERR_ARG; + int rc = NCM_OK; + if (w->failed || !w->fp) rc = NCM_ERR_IO; + else if (fflush(w->fp) != 0) rc = NCM_ERR_IO; + else if (fsync(fileno(w->fp)) != 0) rc = NCM_ERR_IO; + else if (fclose(w->fp) != 0) rc = NCM_ERR_IO; + else { + w->fp = NULL; + if (rename(w->tmp_path, w->final_path) != 0) { unlink(w->tmp_path); rc = NCM_ERR_IO; } + } + if (w->fp) { fclose(w->fp); w->fp = NULL; } + if (rc == NCM_OK) { + /* 刷新 mtime(= 最近访问)*/ + utime(w->final_path, NULL); + } + free(w); + return rc; +} + +int ncm_cache_abort(ncm_cache_writer_t *w) { + if (!w) return NCM_ERR_ARG; + if (w->fp) { fclose(w->fp); w->fp = NULL; } + unlink(w->tmp_path); + free(w); + return NCM_OK; +} + +uint64_t ncm_cache_total_bytes(const ncm_cache_t *c) { + if (!c) return 0; + DIR *d = opendir(c->dir); + if (!d) return 0; + uint64_t total = 0; + struct dirent *e; + while ((e = readdir(d))) { + if (strncmp(e->d_name, "song_", 5) != 0) continue; + char p[NCM_CACHE_DIR_MAX + NAME_MAX + 8]; + snprintf(p, sizeof p, "%s/%s", c->dir, e->d_name); + struct stat st; + if (stat(p, &st) == 0 && S_ISREG(st.st_mode)) total += (uint64_t)st.st_size; + } + closedir(d); + return total; +} diff --git a/patch_v2/ncm_app/core/ncm_cache.h b/patch_v2/ncm_app/core/ncm_cache.h new file mode 100644 index 0000000..7f4691e --- /dev/null +++ b/patch_v2/ncm_app/core/ncm_cache.h @@ -0,0 +1,62 @@ +/* ncm_cache.h — 听过的歌自动缓存(LRU 淘汰到上限) + * + * 目录:MeowData/os.meow.ncm/cache/(可被 ncm_cache_set_base_dir 覆盖)。 + * 上限:默认 10GB,可配 1~100GB,配置键 ncm.cache_limit_gb(MeowOS 设置,读 /.cfg)。 + * LRU:以文件 mtime 作为最后访问时间(lookup/commit 时刷新);超限时按 mtime 升序删最旧。 + * 命中缓存即可离线播放(ncm_cache_lookup 返回已缓存文件路径)。 + */ +#ifndef NCM_CACHE_H +#define NCM_CACHE_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define NCM_CACHE_DIR_MAX 512 + +typedef struct ncm_cache { + char dir[NCM_CACHE_DIR_MAX]; + uint64_t limit_bytes; /* 上限字节 */ + int limit_gb; +} ncm_cache_t; + +/* 初始化:设置目录 + 默认 10GB 上限,mkdir -p。 */ +int ncm_cache_init(ncm_cache_t *c, const char *dir); + +/* 设置/获取上限(1~100GB,越界钳制)。 */ +void ncm_cache_set_limit_gb(ncm_cache_t *c, int gb); +int ncm_cache_limit_gb(const ncm_cache_t *c); + +/* 从数据目录读 ncm.cache_limit_gb 配置(对齐 SDK meow_config_int)并应用。 */ +void ncm_cache_load_setting(ncm_cache_t *c, const char *data_dir); + +/* 缓存目录 / 单文件路径 */ +const char *ncm_cache_dir(const ncm_cache_t *c); +int ncm_cache_path(const ncm_cache_t *c, const char *id, const char *ext, + char *out, size_t out_sz); + +/* 查找已缓存文件。命中:写 out 路径并刷新 mtime,返回 NCM_OK。未命中:NCM_ERR_NOENT。 */ +int ncm_cache_lookup(const ncm_cache_t *c, const char *id, const char *ext, + char *out, size_t out_sz); + +/* 流式写入句柄:open 建 temp;write 累积;commit 落盘+刷新LRU+触发淘汰;abort 丢弃。 */ +typedef struct ncm_cache_writer ncm_cache_writer_t; +int ncm_cache_open(const ncm_cache_t *c, const char *id, const char *ext, + ncm_cache_writer_t **w); +int ncm_cache_write(ncm_cache_writer_t *w, const unsigned char *data, size_t len); +int ncm_cache_commit(ncm_cache_writer_t *w); /* win; 返回 0=成功 */ +int ncm_cache_abort(ncm_cache_writer_t *w); + +/* 当前缓存总字节(扫描目录) */ +uint64_t ncm_cache_total_bytes(const ncm_cache_t *c); + +/* 立即执行 LRU 淘汰(超上限则删最旧,直到 <= 上限)。 */ +int ncm_cache_evict(const ncm_cache_t *c); + +#ifdef __cplusplus +} +#endif +#endif /* NCM_CACHE_H */ diff --git a/patch_v2/ncm_app/core/ncm_common.c b/patch_v2/ncm_app/core/ncm_common.c new file mode 100644 index 0000000..6594023 --- /dev/null +++ b/patch_v2/ncm_app/core/ncm_common.c @@ -0,0 +1,193 @@ +/* ncm_common.c — 公共工具层实现 */ +#include "ncm_common.h" + +#include +#include +#include +#include +#include + +#include "mbedtls/base64.h" +#include "mbedtls/md.h" + +size_t ncm_strlcpy(char *dst, const char *src, size_t sz) { + size_t sl = strlen(src); + if (sz == 0) return sl; + size_t cp = (sl < sz - 1) ? sl : sz - 1; + memcpy(dst, src, cp); + dst[cp] = 0; + return sl; +} + +size_t ncm_strlcat(char *dst, const char *src, size_t sz) { + size_t dl = strlen(dst); + size_t sl = strlen(src); + if (sz == 0 || dl >= sz) return dl + sl; + size_t cp = (sl < sz - dl - 1) ? sl : sz - dl - 1; + memcpy(dst + dl, src, cp); + dst[dl + cp] = 0; + return dl + sl; +} + +int ncm_streq(const char *a, const char *b) { + return strcmp(a, b) == 0; +} + +int ncm_parse_int(const char *s, long *out) { + if (!s || !*s) return -1; + char *end = NULL; + long v = strtol(s, &end, 10); + if (end == s || *end != '\0') return -1; + *out = v; + return 0; +} + +int64_t ncm_now_ms(void) { + struct timespec ts; + clock_gettime(CLOCK_REALTIME, &ts); + return (int64_t)ts.tv_sec * 1000 + ts.tv_nsec / 1000000; +} + +void ncm_random_bytes(unsigned char *out, size_t n) { + FILE *f = fopen("/dev/urandom", "rb"); + if (f) { + size_t got = fread(out, 1, n, f); + fclose(f); + if (got == n) return; + } + /* 回退:时钟 + 地址扰动(仅用于 deviceId 初次生成,非密码学用途) */ + static uint64_t seed = 0; + if (seed == 0) + seed = (uint64_t)ncm_now_ms() ^ (uint64_t)(uintptr_t)out; + for (size_t i = 0; i < n; i++) { + seed = seed * 6364136223846793005ULL + 1442695040888963407ULL; + out[i] = (unsigned char)(seed >> 33); + } +} + +void ncm_hex_encode(const unsigned char *in, size_t n, char *out, int upper) { + static const char dL[] = "0123456789abcdef"; + static const char dU[] = "0123456789ABCDEF"; + const char *d = upper ? dU : dL; + for (size_t i = 0; i < n; i++) { + out[i * 2] = d[in[i] >> 4]; + out[i * 2 + 1] = d[in[i] & 15]; + } + out[n * 2] = 0; +} + +int ncm_hex_decode(const char *hex, unsigned char *out, size_t out_sz) { + size_t n = strlen(hex); + if (n % 2) return -1; + size_t bytes = n / 2; + if (bytes > out_sz) return -1; + for (size_t i = 0; i < bytes; i++) { + int hi, lo; + char c = hex[i * 2]; + if (c >= '0' && c <= '9') hi = c - '0'; + else if (c >= 'a' && c <= 'f') hi = c - 'a' + 10; + else if (c >= 'A' && c <= 'F') hi = c - 'A' + 10; + else return -1; + c = hex[i * 2 + 1]; + if (c >= '0' && c <= '9') lo = c - '0'; + else if (c >= 'a' && c <= 'f') lo = c - 'a' + 10; + else if (c >= 'A' && c <= 'F') lo = c - 'A' + 10; + else return -1; + out[i] = (unsigned char)((hi << 4) | lo); + } + return (int)bytes; +} + +int ncm_b64_encode(const unsigned char *in, size_t inlen, char *out, size_t out_sz) { + size_t olen = 0; + int rc = mbedtls_base64_encode((unsigned char *)out, out_sz, &olen, in, inlen); + if (rc != 0) return -1; + out[olen < out_sz ? olen : out_sz - 1] = 0; + return (int)olen; +} + +int ncm_b64_decode(const char *in, size_t inlen, unsigned char *out, size_t out_sz) { + size_t olen = 0; + int rc = mbedtls_base64_decode(out, out_sz, &olen, (const unsigned char *)in, inlen); + if (rc != 0) return -1; + return (int)olen; +} + +void ncm_md5_hex(const void *data, size_t len, char out_hex[33]) { + unsigned char d[16]; + const mbedtls_md_info_t *inf = mbedtls_md_info_from_type(MBEDTLS_MD_MD5); + if (inf) mbedtls_md(inf, (const unsigned char *)data, len, d); + else memset(d, 0, 16); + ncm_hex_encode(d, 16, out_hex, 0); +} + +int ncm_sha256(const void *data, size_t len, unsigned char out[32]) { + const mbedtls_md_info_t *inf = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256); + if (!inf) return -1; + return mbedtls_md(inf, (const unsigned char *)data, len, out); +} + +void ncm_sha256_hex(const void *data, size_t len, char out_hex[65]) { + unsigned char d[32]; + ncm_sha256(data, len, d); + ncm_hex_encode(d, 32, out_hex, 0); +} + +int ncm_url_encode_span(const char *src, size_t slen, char *dst, size_t dst_sz) { + size_t o = 0; + for (size_t i = 0; i < slen; i++) { + unsigned char c = (unsigned char)src[i]; + if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || + (c >= '0' && c <= '9') || c == '-' || c == '_' || c == '.' || c == '~') { + if (o + 1 >= dst_sz) return -NCM_ERR_FULL; + dst[o++] = (char)c; + } else if (c == ' ') { + if (o + 1 >= dst_sz) return -NCM_ERR_FULL; + dst[o++] = '+'; + } else { + if (o + 3 >= dst_sz) return -NCM_ERR_FULL; + static const char d[] = "0123456789ABCDEF"; + dst[o++] = '%'; + dst[o++] = d[c >> 4]; + dst[o++] = d[c & 15]; + } + } + dst[o] = 0; + return (int)o; +} + +int ncm_url_encode(const char *src, char *dst, size_t dst_sz) { + return ncm_url_encode_span(src, strlen(src), dst, dst_sz); +} + +int ncm_url_decode(const char *src, char *dst, size_t dst_sz) { + size_t o = 0; + size_t slen = strlen(src); + for (size_t i = 0; i < slen; i++) { + char c = src[i]; + if (c == '%') { + if (i + 2 >= slen) return -1; + int hi, lo; + char a = src[i + 1], b = src[i + 2]; + if (a >= '0' && a <= '9') hi = a - '0'; + else if (a >= 'a' && a <= 'f') hi = a - 'a' + 10; + else if (a >= 'A' && a <= 'F') hi = a - 'A' + 10; + else return -1; + if (b >= '0' && b <= '9') lo = b - '0'; + else if (b >= 'a' && b <= 'f') lo = b - 'a' + 10; + else if (b >= 'A' && b <= 'F') lo = b - 'A' + 10; + else return -1; + if (o + 1 >= dst_sz) return -NCM_ERR_FULL; + dst[o++] = (char)((hi << 4) | lo); + i += 2; + } else if (c == '+') { + if (o + 1 >= dst_sz) return -NCM_ERR_FULL; + dst[o++] = ' '; + } else { + if (o + 1 >= dst_sz) return -NCM_ERR_FULL; + dst[o++] = c; + } + } + dst[o] = 0; + return (int)o; +} diff --git a/patch_v2/ncm_app/core/ncm_common.h b/patch_v2/ncm_app/core/ncm_common.h new file mode 100644 index 0000000..e25a3b3 --- /dev/null +++ b/patch_v2/ncm_app/core/ncm_common.h @@ -0,0 +1,76 @@ +/* ncm_common.h — 网易云 App 核心库公共工具层(纯 C,无 UI) + * + * 提供:错误码、定长/动态缓冲、hex、base64、md5、sha256、urlencode 等 + * 无关业务的通用原语。所有实现集中在本目录,不依赖 UI/SDK。 + */ +#ifndef NCM_COMMON_H +#define NCM_COMMON_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* ---------- 错误码 ---------- */ +enum { + NCM_OK = 0, /* 成功 */ + NCM_ERR_ARG = -1, /* 参数错误 */ + NCM_ERR_OOM = -2, /* 内存不足 */ + NCM_ERR_IO = -3, /* 文件/IO 错误 */ + NCM_ERR_NET = -4, /* 网络错误 */ + NCM_ERR_TLS = -5, /* TLS 错误 */ + NCM_ERR_TIMEOUT = -6, /* 超时 */ + NCM_ERR_HTTP = -7, /* HTTP 状态非 2xx */ + NCM_ERR_CRYPTO = -8, /* 加解密错误 */ + NCM_ERR_JSON = -9, /* JSON 解析错误 */ + NCM_ERR_NOTFOUND = -10, /* 未找到(缺字段/null) */ + NCM_ERR_FULL = -11, /* 目标缓冲满 */ + NCM_ERR_NOENT = -12, /* 文件不存在 */ + NCM_ERR_AUTH = -13, /* 未登录/鉴权失败 */ + NCM_ERR_LIMIT = -14, /* 超出上限级 */ +}; + +/* ---------- 常用尺寸 ---------- */ +#define NCM_DEVICE_ID_LEN 52 /* 52 位小写十六进制(实际上传大写,见 crypto) */ +#define NCM_DEVICE_ID_SZ (NCM_DEVICE_ID_LEN + 1) +#define NCM_COOKIE_MAX 4096 /* 会话 cookie 串最大长度 */ +#define NCM_URL_MAX 2048 /* 单个 URL/路径最大长度 */ +#define NCM_HEADER_MAX 1024 /* 单次请求 Cookie 头最大长度 */ +#define NCM_JSON_MAX 8192 /* 小 JSON 明文(请求体)最大长度 */ +#define NCM_RESP_MAX (1024 * 1024) /* 单次响应体默认上限 (1MB) */ +#define NCM_SMALLBUF 256 + +/* ---------- 小工具 ---------- */ +size_t ncm_strlcpy(char *dst, const char *src, size_t sz); +size_t ncm_strlcat(char *dst, const char *src, size_t sz); +int ncm_streq(const char *a, const char *b); +int ncm_parse_int(const char *s, long *out); /* 完整数字串,成功返回 0 */ +int64_t ncm_now_ms(void); /* 毫秒时间戳 */ +void ncm_random_bytes(unsigned char *out, size_t n); /* /dev/urandom,失败则回退时钟扰动 */ + +/* ---------- hex ---------- */ +void ncm_hex_encode(const unsigned char *in, size_t n, char *out, int upper); /* out >= 2n+1 */ +int ncm_hex_decode(const char *hex, unsigned char *out, size_t out_sz); /* 返回字节数, 失败 -1 */ + +/* ---------- base64 (mbedtls 封装; 均为栈外缓冲调用) ---------- */ +int ncm_b64_encode(const unsigned char *in, size_t inlen, char *out, size_t out_sz); /* 成功返回写入长度,失败 -1 */ +int ncm_b64_decode(const char *in, size_t inlen, unsigned char *out, size_t out_sz); /* 成功返回字节数, 失败 -1 */ + +/* ---------- MD5 / SHA256 (mbedtls 封装) ---------- */ +void ncm_md5_hex(const void *data, size_t len, char out_hex[33]); /* 小写 hex */ +int ncm_sha256(const void *data, size_t len, unsigned char out[32]);/* 原始 32 字节, 0=成功 */ +void ncm_sha256_hex(const void *data, size_t len, char out_hex[65]);/* 小写 hex */ + +/* ---------- urlencode (application/x-www-form-urlencoded: 空格->'+') ---------- */ +/* 成功返回写入长度(不含NUL),溢出返回 -NCM_ERR_FULL */ +int ncm_url_encode(const char *src, char *dst, size_t dst_sz); +int ncm_url_encode_span(const char *src, size_t slen, char *dst, size_t dst_sz); +/* 解码 (也接受 '+' -> 空格)。返回解码字节数,失败 -1 */ +int ncm_url_decode(const char *src, char *dst, size_t dst_sz); + +#ifdef __cplusplus +} +#endif +#endif /* NCM_COMMON_H */ diff --git a/patch_v2/ncm_app/core/ncm_crypto.c b/patch_v2/ncm_app/core/ncm_crypto.c new file mode 100644 index 0000000..abf7d5d --- /dev/null +++ b/patch_v2/ncm_app/core/ncm_crypto.c @@ -0,0 +1,140 @@ +/* ncm_crypto.c — 加密层实现 */ +#include "ncm_crypto.h" +#include "ncm_common.h" + +#include +#include +#include + +#include "mbedtls/aes.h" +#include "mbedtls/base64.h" +#include "mbedtls/pk.h" +#include "mbedtls/rsa.h" + +#define SEP "-36cd479b6b5-" + +/* ---------- AES 原语 ---------- */ +/* AES-128-ECB 加密(PKCS7)-> 大写 hex */ +static int aes_ecb_hex(const unsigned char *in, size_t n, const unsigned char *key, + char *out, size_t out_sz) { + int pad = 16 - (int)(n % 16); + size_t total = n + (size_t)pad; + if (out_sz < total * 2 + 1) return -1; + unsigned char *buf = (unsigned char *)malloc(total); + unsigned char *enc = (unsigned char *)malloc(total); + if (!buf || !enc) { free(buf); free(enc); return -1; } + memcpy(buf, in, n); + for (int i = 0; i < pad; i++) buf[n + i] = (unsigned char)pad; + mbedtls_aes_context aes; + mbedtls_aes_init(&aes); + mbedtls_aes_setkey_enc(&aes, key, 128); + for (size_t off = 0; off < total; off += 16) + mbedtls_aes_crypt_ecb(&aes, MBEDTLS_AES_ENCRYPT, &buf[off], &enc[off]); + mbedtls_aes_free(&aes); + ncm_hex_encode(enc, total, out, 1); /* 大写 */ + free(buf); + free(enc); + return 0; +} + +/* AES-128-CBC 加密(PKCS7)-> base64 */ +static int aes_cbc_b64(const unsigned char *in, size_t n, + const unsigned char *key, const unsigned char *iv, + char *out, size_t out_sz) { + int pad = 16 - (int)(n % 16); + size_t total = n + (size_t)pad; + unsigned char *buf = (unsigned char *)malloc(total); + unsigned char *enc = (unsigned char *)malloc(total); + if (!buf || !enc) { free(buf); free(enc); return -1; } + memcpy(buf, in, n); + for (int i = 0; i < pad; i++) buf[n + i] = (unsigned char)pad; + unsigned char iv2[16]; + memcpy(iv2, iv, 16); + mbedtls_aes_context aes; + mbedtls_aes_init(&aes); + mbedtls_aes_setkey_enc(&aes, key, 128); + mbedtls_aes_crypt_cbc(&aes, MBEDTLS_AES_ENCRYPT, total, iv2, buf, enc); + mbedtls_aes_free(&aes); + int rc = ncm_b64_encode(enc, total, out, out_sz); + free(buf); + free(enc); + return rc < 0 ? -1 : 0; +} + +/* ---------- RSA raw ---------- */ +static int rsa_encrypt_raw_hex(const unsigned char secret[16], char *out, size_t out_sz) { + unsigned char der[512]; + int dl = ncm_b64_decode(NCM_RSA_DER_B64, strlen(NCM_RSA_DER_B64), der, sizeof der); + if (dl <= 0) return -1; + size_t der_len = (size_t)dl; + mbedtls_pk_context pk; + mbedtls_pk_init(&pk); + if (mbedtls_pk_parse_public_key(&pk, der, der_len) != 0) { + mbedtls_pk_free(&pk); + return -1; + } + mbedtls_rsa_context *rsa = mbedtls_pk_rsa(pk); + int keylen = mbedtls_rsa_get_len(rsa); + if (keylen <= 0 || keylen > 256) { mbedtls_pk_free(&pk); return -1; } + unsigned char input[256], output[256]; + memset(input, 0, sizeof input); + /* 右对齐到 keylen */ + memcpy(input + keylen - 16, secret, 16); /* 前导字节为 0 => input < N */ + if (mbedtls_rsa_public(rsa, input, output) != 0) { mbedtls_pk_free(&pk); return -1; } + if (out_sz < (size_t)keylen * 2 + 1) { mbedtls_pk_free(&pk); return -1; } + ncm_hex_encode(output, (size_t)keylen, out, 0); /* 小写 */ + mbedtls_pk_free(&pk); + return 0; +} + +int ncm_crypto_rsa_raw_selfcheck(const unsigned char secret[16], char *out, size_t out_sz) { + return rsa_encrypt_raw_hex(secret, out, out_sz); +} + +int ncm_crypto_eapi(const char *url, const char *json, char *out, size_t out_sz) { + if (!url || !json || !out) return NCM_ERR_ARG; + char msg[4096]; + int ml = snprintf(msg, sizeof msg, "nobody%suse%smd5forencrypt", url, json); + if (ml < 0 || (size_t)ml >= sizeof msg) return NCM_ERR_FULL; + char digest[33]; + ncm_md5_hex(msg, (size_t)ml, digest); + char plain[4096]; + int pl = snprintf(plain, sizeof plain, "%s%s%s%s%s", url, SEP, json, SEP, digest); + if (pl < 0 || (size_t)pl >= sizeof plain) return NCM_ERR_FULL; + return aes_ecb_hex((const unsigned char *)plain, (size_t)pl, + (const unsigned char *)NCM_EAPI_KEY, out, out_sz) == 0 ? NCM_OK : NCM_ERR_CRYPTO; +} + +int ncm_crypto_weapi(const char *json, char *params, size_t psz, + char *enc_sec_key, size_t esz) { + if (!json || !params || !enc_sec_key) return NCM_ERR_ARG; + /* 生成 16 位 base62 随机密钥 */ + unsigned char secret[16]; + unsigned char rnd[16]; + ncm_random_bytes(rnd, sizeof rnd); + for (int i = 0; i < 16; i++) + secret[i] = (unsigned char)NCM_WEAPI_BASE62[rnd[i] % 62]; + + /* 第一层 AES-CBC(preset) */ + char first[1024]; + if (aes_cbc_b64((const unsigned char *)json, strlen(json), + (const unsigned char *)NCM_WEAPI_PRESET, + (const unsigned char *)NCM_WEAPI_IV, first, sizeof first) != 0) + return NCM_ERR_CRYPTO; + /* 第二层 AES-CBC(secret) */ + if (aes_cbc_b64((const unsigned char *)first, strlen(first), + secret, (const unsigned char *)NCM_WEAPI_IV, params, psz) != 0) + return NCM_ERR_CRYPTO; + /* RSA: 反转 secret 后 raw 加密 */ + unsigned char rev[16]; + for (int i = 0; i < 16; i++) rev[i] = secret[15 - i]; + if (rsa_encrypt_raw_hex(rev, enc_sec_key, esz) != 0) return NCM_ERR_CRYPTO; + return NCM_OK; +} + +int ncm_crypto_linuxapi(const char *json, char *out, size_t out_sz) { + if (!json || !out) return NCM_ERR_ARG; + return aes_ecb_hex((const unsigned char *)json, strlen(json), + (const unsigned char *)NCM_LINUXAPI_KEY, out, out_sz) == 0 + ? NCM_OK : NCM_ERR_CRYPTO; +} diff --git a/patch_v2/ncm_app/core/ncm_crypto.h b/patch_v2/ncm_app/core/ncm_crypto.h new file mode 100644 index 0000000..f9ee88a --- /dev/null +++ b/patch_v2/ncm_app/core/ncm_crypto.h @@ -0,0 +1,49 @@ +/* ncm_crypto.h — 网易云请求加密层 + * + * 提供 eapi / weapi / linuxapi 三种加密(对齐 CNMPlayer ncm-api-rs crypto.rs): + * eapi: digest=md5("nobody"+url+"use"+json+"md5forencrypt") + * data=url+"-36cd479b6b5-"+json+"-36cd479b6b5-"+digest + * params=HEX_UPPER(AES128ECB(data, EAPI_KEY)) (eapi key: e82ckenh8dichen8) + * weapi: 双层 AES-128-CBC + RSA raw (无 padding 纯模幂) + * secret=16 随机 base62; first=AES_CBC_b64(json, PRESET, IV) + * params=AES_CBC_b64(first, secret, IV) + * encSecKey=HEX_LOWER(RSA_raw(REVERSE(secret), 1024 公钥)) + * linuxapi: params=HEX_UPPER(AES128ECB(json, LINUXAPI_KEY)) + * + * 由调用方负责对输出值做 urlencode(weapi 的 params 是 base64,含 '+' '/' '=' 需转义)。 + */ +#ifndef NCM_CRYPTO_H +#define NCM_CRYPTO_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define NCM_EAPI_KEY "e82ckenh8dichen8" +#define NCM_WEAPI_PRESET "0CoJUm6Qyw8W8jud" +#define NCM_WEAPI_IV "0102030405060708" +#define NCM_LINUXAPI_KEY "rFgB&h#%2?^eDg:Q" +#define NCM_WEAPI_BASE62 \ + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" +#define NCM_RSA_DER_B64 \ + "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDgtQn2JZ34ZC28NWYpAUd98iZ37BUrX/aKzmFbt7clFSs6sXqHauqKWqdtLkF2KexO40H1YTX8z2lSgBBOAxLsvaklV8k4cBFK9snQXE9/DDaFt6Rr7iVZMldczhC0JNgTz+SHXT6CBHuX3e9SdB1Ua44oncaTWz7OBGLbCiK45wIDAQAB" + +/* eapi:json 明文 -> params 值(大写 hex)。out_sz 需 >= 2*len(plain)+1。返回 NCM_OK */ +int ncm_crypto_eapi(const char *url, const char *json, char *out, size_t out_sz); + +/* weapi:json 明文 -> params(base64) 与 encSecKey(小写 hex)。返回 NCM_OK */ +int ncm_crypto_weapi(const char *json, char *params, size_t psz, + char *enc_sec_key, size_t esz); + +/* linuxapi:json 明文 -> params 值(大写 hex)。返回 NCM_OK */ +int ncm_crypto_linuxapi(const char *json, char *out, size_t out_sz); + +/* 低频自测:固定明文跑一遍 RSA raw,写 256 hex 到 out。返回 NCM_OK */ +int ncm_crypto_rsa_raw_selfcheck(const unsigned char secret[16], char *out, size_t out_sz); + +#ifdef __cplusplus +} +#endif +#endif /* NCM_CRYPTO_H */ diff --git a/patch_v2/ncm_app/core/ncm_ctx.c b/patch_v2/ncm_app/core/ncm_ctx.c new file mode 100644 index 0000000..97577de --- /dev/null +++ b/patch_v2/ncm_app/core/ncm_ctx.c @@ -0,0 +1,57 @@ +/* ncm_ctx.c — 上下文实现 */ +#include "ncm.h" +#include +#include + +int ncm_ctx_default_cache_dir(const char *data_dir, char *out, size_t out_sz) { + if (!data_dir || !out) return NCM_ERR_ARG; + size_t dlen = strlen(data_dir); + /* 去掉尾部斜杠 */ + while (dlen > 1 && data_dir[dlen-1]=='/') dlen--; + if (dlen >= 5 && strcmp(data_dir + dlen - 5, "/data") == 0) { + int n = snprintf(out, out_sz, "%.*s/cache", (int)(dlen - 5), data_dir); + return (n >= 0 && (size_t)n < out_sz) ? NCM_OK : NCM_ERR_FULL; + } + int n = snprintf(out, out_sz, "%.*s/cache", (int)dlen, data_dir); + return (n >= 0 && (size_t)n < out_sz) ? NCM_OK : NCM_ERR_FULL; +} + +void ncm_ctx_init(ncm_ctx_t *ctx, const char *data_dir) { + if (!ctx) return; + memset(ctx, 0, sizeof *ctx); + ncm_store_init(&ctx->store, data_dir); + ncm_store_get_device_id(&ctx->store, ctx->device_id); + ncm_ctx_load_cookie(ctx); + + char cdir[NCM_CACHE_DIR_MAX]; + if (ncm_ctx_default_cache_dir(ctx->store.data_dir, cdir, sizeof cdir) != 0) + ncm_strlcpy(cdir, "cache", sizeof cdir); + ncm_cache_init(&ctx->cache, cdir); + ncm_cache_load_setting(&ctx->cache, ctx->store.data_dir); + + ctx->verify_ca = 1; + ctx->timeout_ms = 15000; + ctx->default_level = NCM_LEVEL_HIRES; + ncm_http_set_verify_default(ctx->verify_ca, ctx->ca_path[0] ? ctx->ca_path : NULL); +} + +int ncm_ctx_set_cookie(ncm_ctx_t *ctx, const char *cookie) { + if (!ctx) return NCM_ERR_ARG; + ncm_strlcpy(ctx->cookie, cookie ? cookie : "", sizeof ctx->cookie); + return ncm_login_save_cookie(&ctx->store, ctx->cookie); +} + +int ncm_ctx_load_cookie(ncm_ctx_t *ctx) { + if (!ctx) return NCM_ERR_ARG; + char buf[NCM_COOKIE_MAX]; + int rc = ncm_login_load_cookie(&ctx->store, buf, sizeof buf); + if (rc == NCM_OK) ncm_strlcpy(ctx->cookie, buf, sizeof ctx->cookie); + else ctx->cookie[0] = 0; + return rc; +} + +int ncm_ctx_clear_cookie(ncm_ctx_t *ctx) { + if (!ctx) return NCM_ERR_ARG; + ctx->cookie[0] = 0; + return ncm_login_clear_cookie(&ctx->store); +} diff --git a/patch_v2/ncm_app/core/ncm_http.c b/patch_v2/ncm_app/core/ncm_http.c new file mode 100644 index 0000000..450eec6 --- /dev/null +++ b/patch_v2/ncm_app/core/ncm_http.c @@ -0,0 +1,527 @@ +/* ncm_http.c — mbedtls HTTPS 客户端封装实现 */ +#include "ncm_http.h" +#include "ncm_common.h" + +#include +#include +#include +#include + +#include "mbedtls/net_sockets.h" +#include "mbedtls/ssl.h" +#include "mbedtls/x509_crt.h" +#include "mbedtls/error.h" + +/* ---------- 自定义 RNG ---------- */ +static FILE *s_rng_fp = NULL; +static int my_rng(void *arg, unsigned char *out, size_t len) { + (void)arg; + if (!s_rng_fp) s_rng_fp = fopen("/dev/urandom", "rb"); + if (!s_rng_fp) return -1; + return fread(out, 1, len, s_rng_fp) == len ? 0 : -1; +} + +/* ---------- 全局 CA 默认 ---------- */ +static int g_verify_ca = 1; +static char g_ca_path[NCM_CA_PATH_MAX] = ""; +void ncm_http_set_verify_default(int verify, const char *ca_path) { + g_verify_ca = verify ? 1 : 0; + if (ca_path) ncm_strlcpy(g_ca_path, ca_path, sizeof g_ca_path); + else g_ca_path[0] = 0; +} + +/* ---------- URL 解析 ---------- */ +typedef struct url_parts { + char scheme[8]; + char host[256]; + int port; + char path[NCM_URL_MAX]; +} url_parts_t; + +static int parse_url(const char *url, url_parts_t *u) { + if (!url) return -1; + const char *p = strstr(url, "://"); + if (!p) return -1; + size_t schemelen = (size_t)(p - url); + if (schemelen >= sizeof u->scheme) return -1; + memcpy(u->scheme, url, schemelen); + u->scheme[schemelen] = 0; + const char *rest = p + 3; + const char *slash = strchr(rest, '/'); + const char *hostend = slash ? slash : rest + strlen(rest); + size_t hostlen = (size_t)(hostend - rest); + if (hostlen >= sizeof u->host) return -1; + memcpy(u->host, rest, hostlen); + u->host[hostlen] = 0; + + u->port = 443; + char *colon = strrchr(u->host, ':'); + if (colon) { + long port; + if (ncm_parse_int(colon + 1, &port) != 0 || port <= 0 || port > 65535) return -1; + u->port = (int)port; + *colon = 0; + } + const char *path = slash ? slash : "/"; + if (strlen(path) >= sizeof u->path) return -1; + ncm_strlcpy(u->path, path, sizeof u->path); + return 0; +} + +/* ---------- CA 加载 ---------- */ +static int load_ca(mbedtls_x509_crt *cacert, const char *ca_path) { + const char *defaults[] = { + "/etc/ssl/certs/ca-certificates.crt", + "/etc/ssl/certs/ca-bundle.crt", + "/etc/pki/tls/certs/ca-bundle.crt", + "/etc/ssl/cert.pem", + NULL + }; + if (ca_path && *ca_path) + return mbedtls_x509_crt_parse_file(cacert, ca_path) == 0 ? 0 : -1; + for (int i = 0; defaults[i]; i++) + if (mbedtls_x509_crt_parse_file(cacert, defaults[i]) == 0) return 0; + return -1; +} + +/* ---------- 等待 IO(deadline 约束) ---------- */ +static int wait_io(mbedtls_net_context *net, uint32_t rw, int64_t deadline_ms) { + int64_t now = ncm_now_ms(); + if (now >= deadline_ms) return MBEDTLS_ERR_SSL_TIMEOUT; + uint32_t rem = (uint32_t)(deadline_ms - now); + int r = mbedtls_net_poll(net, rw, rem); + if (r < 0) return r; + if (r == 0) return MBEDTLS_ERR_SSL_TIMEOUT; + return 0; +} + +/* ---------- 响应头解析 ---------- */ +static int ci_eq(const char *a, const char *b) { + while (*a && *b) { + unsigned char ca = (unsigned char)*a, cb = (unsigned char)*b; + if (ca >= 'A' && ca <= 'Z') ca = (unsigned char)(ca - 'A' + 'a'); + if (cb >= 'A' && cb <= 'Z') cb = (unsigned char)(cb - 'A' + 'a'); + if (ca != cb) return 0; + a++; b++; + } + return *a == 0 && *b == 0; +} +static int ci_contains(const char *hay, const char *needle) { + size_t nlen = strlen(needle); + if (!nlen) return 1; + for (; *hay; hay++) { + size_t i = 0; + while (i < nlen && hay[i]) { + unsigned char h = (unsigned char)hay[i], n = (unsigned char)needle[i]; + if (h >= 'A' && h <= 'Z') h = (unsigned char)(h - 'A' + 'a'); + if (n >= 'A' && n <= 'Z') n = (unsigned char)(n - 'A' + 'a'); + if (h != n) break; + i++; + } + if (i == nlen) return 1; + } + return 0; +} + +static long parse_long_field(const char *value) { + long v; + return ncm_parse_int(value, &v) == 0 ? v : -1; +} + +static int parse_headers(ncm_http_resp_t *resp) { + const char *h = resp->headers; + resp->status = 0; + resp->content_length = (size_t)-1; + resp->chunked = 0; + resp->has_content_type = 0; + resp->content_type[0] = 0; + + /* 状态行: "HTTP/1.1 200 OK" */ + char line[NCM_HTTP_HDR_MAX]; + size_t li = 0; + const char *p = h; + /* 第一行 */ + while (*p && *p != '\r' && *p != '\n' && li < sizeof line - 1) line[li++] = *p++; + line[li] = 0; + { + const char *sp = strchr(line, ' '); + if (sp) { + long st = parse_long_field(sp + 1); + if (st >= 100 && st <= 599) resp->status = (int)st; + } + } + /* 头行遍历 */ + p = h; + while ((p = strstr(p, "\r\n")) != NULL) { + p += 2; + if (*p == '\r' || *p == '\n' || *p == 0) break; + const char *eol = strstr(p, "\r\n"); + if (!eol) break; + size_t l = (size_t)(eol - p); + char hdr[256]; + if (l >= sizeof hdr) { p = eol + 2; continue; } + memcpy(hdr, p, l); + hdr[l] = 0; + char *colon = strchr(hdr, ':'); + if (!colon) { p = eol + 2; continue; } + *colon = 0; + char *name = hdr; + char *val = colon + 1; + while (*val == ' ' || *val == '\t') val++; + /* name 去尾空格 */ + char *nend = name + strlen(name); + while (nend > name && (nend[-1]==' '||nend[-1]=='\t')) *--nend = 0; + + if (ci_eq(name, "Content-Length")) { + long v = parse_long_field(val); + if (v >= 0) resp->content_length = (size_t)v; + } else if (ci_eq(name, "Transfer-Encoding")) { + if (ci_contains(val, "chunked")) resp->chunked = 1; + } else if (ci_eq(name, "Content-Type")) { + resp->has_content_type = 1; + ncm_strlcpy(resp->content_type, val, sizeof resp->content_type); + } + p = eol + 2; + } + return 0; +} + +/* ---------- 响应体分块状态机 ---------- */ +enum { + BS_LEN, /* 定长 body,剩余 remaining */ + BS_CLOSE, /* 读到对端关闭 */ + BS_CHUNK_SZ, /* 解析 chunk 尺寸行 */ + BS_CHUNK_DATA,/* 读 chunk 数据 remaining */ + BS_CHUNK_CRLF,/* 吃 chunk 终止 CRLF */ + BS_DONE +}; +typedef struct { + int st; + size_t remaining; + size_t total; + int exceeded; + char chunk_buf[16]; + int chunk_len; +} body_st; + +static void body_st_init(body_st *b, const ncm_http_resp_t *hdr) { + memset(b, 0, sizeof *b); + if (hdr->chunked) { + b->st = BS_CHUNK_SZ; + } else if (hdr->content_length != (size_t)-1) { + b->st = BS_LEN; + b->remaining = hdr->content_length; + } else { + b->st = BS_CLOSE; + } +} + +static int parse_chunk_size(body_st *b) { + long sz; + char *end = NULL; + b->chunk_buf[b->chunk_len] = 0; + /* 忽略扩展: 取 ';' 之前 */ + char *semi = strchr(b->chunk_buf, ';'); + if (semi) *semi = 0; + char *sb = b->chunk_buf; + while (*sb == ' ' || *sb == '\t') sb++; + if (!*sb) return -1; + sz = strtol(sb, &end, 16); + if (end == sb || *end != 0) return -1; + if (sz == 0) { b->st = BS_DONE; return 0; } + b->st = BS_CHUNK_DATA; + b->remaining = (size_t)sz; + return 0; +} + +/* 处理一段输入,产出解码后的 body 字节到 sink。 + * sink: (buf,cap,&len) 累加;或 (cb,ctx) 回调。返回 0=继续,NZ=中止。 */ +typedef struct sink { + unsigned char *buf; + size_t cap; + size_t len; + size_t max_bytes; /* 0=不设上限(受 cap 约束) */ + ncm_http_write_cb cb; + void *cb_ctx; + int overflow; +} sink_t; + +static void sink_write(sink_t *s, const unsigned char *data, size_t len) { + if (s->max_bytes && s->len + len > s->max_bytes) { s->overflow = 1; return; } + if (s->cb) { + if (s->cb(s->cb_ctx, data, len) != 0) { s->overflow = 1; } + return; + } + if (s->len + len > s->cap) { s->overflow = 1; return; } + memcpy(s->buf + s->len, data, len); + s->len += len; +} + +static int body_feed(body_st *b, const unsigned char *data, size_t len, sink_t *s) { + size_t i = 0; + while (i < len) { + switch (b->st) { + case BS_LEN: { + size_t take = len - i; + if (take > b->remaining) take = b->remaining; + if (take) { sink_write(s, data + i, take); b->remaining -= take; b->total += take; i += take; } + if (b->remaining == 0) b->st = BS_DONE; + if (take == 0) i++; /* 防御性推进 */ + break; + } + case BS_CLOSE: { + sink_write(s, data + i, len - i); + b->total += len - i; + i = len; + break; + } + case BS_CHUNK_SZ: { + if (i < len && (data[i] == '\r')) { i++; continue; } + if (i < len && data[i] == '\n') { + if (parse_chunk_size(b) != 0) return -1; + i++; + continue; + } + if (b->chunk_len < (int)sizeof b->chunk_buf - 1) { + b->chunk_buf[b->chunk_len++] = (char)data[i]; + } + i++; + break; + } + case BS_CHUNK_DATA: { + size_t take = len - i; + if (take > b->remaining) take = b->remaining; + if (take) { sink_write(s, data + i, take); b->remaining -= take; b->total += take; i += take; } + if (b->remaining == 0) b->st = BS_CHUNK_CRLF; + if (take == 0) i++; + break; + } + case BS_CHUNK_CRLF: { + while (i < len && (data[i]=='\r'||data[i]=='\n')) i++; + b->chunk_len = 0; + b->st = BS_CHUNK_SZ; + break; + } + case BS_DONE: + return (int)i; + default: + return -1; + } + if (s->overflow) return (int)i; + } + return (int)i; +} + +/* ---------- 核心请求 ---------- */ +static int http_run(const ncm_http_req_t *req, sink_t *sink, ncm_http_resp_t *resp) { + int ret; + url_parts_t url; + if (parse_url(req->url, &url) != 0) return NCM_ERR_ARG; + if (strcmp(url.scheme, "https") != 0 && strcmp(url.scheme, "http") != 0) return NCM_ERR_ARG; + + uint32_t tmo = req->timeout_ms ? req->timeout_ms : 15000; + int64_t deadline = ncm_now_ms() + (int64_t)tmo; + + mbedtls_net_context net; + mbedtls_ssl_context ssl; + mbedtls_ssl_config conf; + mbedtls_x509_crt cacert; + mbedtls_net_init(&net); + mbedtls_ssl_init(&ssl); + mbedtls_ssl_config_init(&conf); + mbedtls_x509_crt_init(&cacert); + int validate = req->verify_ca < 0 ? g_verify_ca : req->verify_ca; + const char *ca_path = (req->ca_path && *req->ca_path) ? req->ca_path + : (g_ca_path[0] ? g_ca_path : NULL); + + if (validate && load_ca(&cacert, ca_path) != 0) { + ret = NCM_ERR_TLS; /* 无 CA 则拒绝,不静默放行 */ + goto done; + } + + char portstr[8]; + snprintf(portstr, sizeof portstr, "%d", url.port); + if ((ret = mbedtls_net_connect(&net, url.host, portstr, MBEDTLS_NET_PROTO_TCP)) != 0) { + ret = NCM_ERR_NET; goto done; + } + mbedtls_net_set_nonblock(&net); + + if ((ret = mbedtls_ssl_config_defaults(&conf, MBEDTLS_SSL_IS_CLIENT, + MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT)) != 0) goto done; + mbedtls_ssl_conf_authmode(&conf, validate ? MBEDTLS_SSL_VERIFY_REQUIRED : MBEDTLS_SSL_VERIFY_NONE); + mbedtls_ssl_conf_ca_chain(&conf, &cacert, NULL); + mbedtls_ssl_conf_rng(&conf, my_rng, NULL); + if ((ret = mbedtls_ssl_setup(&ssl, &conf)) != 0) goto done; + if ((ret = mbedtls_ssl_set_hostname(&ssl, url.host)) != 0) goto done; + mbedtls_ssl_set_bio(&ssl, &net, mbedtls_net_send, mbedtls_net_recv, NULL); + + /* 握手(带 deadline) */ + for (;;) { + ret = mbedtls_ssl_handshake(&ssl); + if (ret == 0) break; + if (ret == MBEDTLS_ERR_SSL_WANT_READ) { + if ((ret = wait_io(&net, MBEDTLS_NET_POLL_READ, deadline)) != 0) goto done; + } else if (ret == MBEDTLS_ERR_SSL_WANT_WRITE) { + if ((ret = wait_io(&net, MBEDTLS_NET_POLL_WRITE, deadline)) != 0) goto done; + } else goto done; + } + + /* 构造请求(先写头、再写体,避免大 body 撑爆单一缓冲) */ + char headbuf[1024]; + int hl; + const char *m = req->method ? req->method : "POST"; + int has_body = (req->body && req->body_len > 0); + const char *eh = req->extra_hdrs ? req->extra_hdrs : ""; + const char *eh_sep = (eh[0]) ? "\r\n" : ""; + if (has_body) { + hl = snprintf(headbuf, sizeof headbuf, + "%s %s HTTP/1.1\r\nHost: %s\r\n" + "%s%s" + "Content-Length: %zu\r\nConnection: close\r\n\r\n", + m, url.path, url.host, eh, eh_sep, req->body_len); + } else { + hl = snprintf(headbuf, sizeof headbuf, + "%s %s HTTP/1.1\r\nHost: %s\r\n" + "%s%s" + "Connection: close\r\n\r\n", + m, url.path, url.host, eh, eh_sep); + } + if (hl < 0 || hl >= (int)sizeof headbuf) { ret = NCM_ERR_FULL; goto done; } + + /* 发送头 */ + size_t off = 0; + while (off < (size_t)hl) { + ret = mbedtls_ssl_write(&ssl, (const unsigned char *)headbuf + off, (size_t)hl - off); + if (ret > 0) { off += (size_t)ret; } + else if (ret == MBEDTLS_ERR_SSL_WANT_READ) { if ((ret=wait_io(&net, MBEDTLS_NET_POLL_READ, deadline))!=0) goto done; } + else if (ret == MBEDTLS_ERR_SSL_WANT_WRITE) { if ((ret=wait_io(&net, MBEDTLS_NET_POLL_WRITE, deadline))!=0) goto done; } + else goto done; + } + if (has_body) { + off = 0; + while (off < req->body_len) { + ret = mbedtls_ssl_write(&ssl, (const unsigned char *)req->body + off, req->body_len - off); + if (ret > 0) { off += (size_t)ret; } + else if (ret == MBEDTLS_ERR_SSL_WANT_READ) { if ((ret=wait_io(&net, MBEDTLS_NET_POLL_READ, deadline))!=0) goto done; } + else if (ret == MBEDTLS_ERR_SSL_WANT_WRITE) { if ((ret=wait_io(&net, MBEDTLS_NET_POLL_WRITE, deadline))!=0) goto done; } + else goto done; + } + } + + /* 读响应头 */ + resp->headers_len = 0; + resp->headers[0] = 0; + int hdr_done = 0; + unsigned char tmp[4096]; + body_st bst; + memset(&bst, 0, sizeof bst); + + for (;;) { + ret = mbedtls_ssl_read(&ssl, tmp, sizeof tmp); + if (ret > 0) { + size_t n = (size_t)ret; + if (!hdr_done) { + /* 幂等累积到 headers */ + size_t space = NCM_HTTP_HDR_MAX - 1 - resp->headers_len; + if (space > n) space = n; + memcpy(resp->headers + resp->headers_len, tmp, space); + resp->headers_len += space; + resp->headers[resp->headers_len] = 0; + /* 找 \r\n\r\n */ + char *split = strstr(resp->headers, "\r\n\r\n"); + if (split) { + parse_headers(resp); + body_st_init(&bst, resp); + size_t consumed = (size_t)(split + 4 - resp->headers); + /* 当前 tmp 中,已进 headers 的字节数 = space;tmp 剩余部分属于 body */ + /* headers 里 split+4 之后的字节实际上没被复制进 headers(因为 space<=..? ) + 这里简化:把 tmp[space..n) 送入 body */ + hdr_done = 1; + /* 需要把 headers 缓冲里 split+4 之后的字节(若有) 也送到 body */ + size_t hdr_after = resp->headers_len - consumed; + if (hdr_after > 0) { + if (body_feed(&bst, (const unsigned char *)(split + 4), hdr_after, sink) < 0) { ret=NCM_ERR_JSON; goto done; } + } + if (space < n) { + if (body_feed(&bst, tmp + space, n - space, sink) < 0) { ret=NCM_ERR_JSON; goto done; } + } + } else { + if (resp->headers_len >= NCM_HTTP_HDR_MAX - 1) { ret = NCM_ERR_FULL; goto done; } + } + } else { + if (body_feed(&bst, tmp, n, sink) < 0) { ret = NCM_ERR_JSON; goto done; } + } + if (sink->overflow || bst.st == BS_DONE) break; + } else if (ret == MBEDTLS_ERR_SSL_WANT_READ) { + if ((ret = wait_io(&net, MBEDTLS_NET_POLL_READ, deadline)) != 0) { if (ret==MBEDTLS_ERR_SSL_TIMEOUT) ret=NCM_ERR_TIMEOUT; goto done; } + } else if (ret == MBEDTLS_ERR_SSL_WANT_WRITE) { + if ((ret = wait_io(&net, MBEDTLS_NET_POLL_WRITE, deadline)) != 0) goto done; + } else if (ret == 0 || ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) { + break; /* 对端关闭 */ + } else { + if (ret == MBEDTLS_ERR_SSL_TIMEOUT) ret = NCM_ERR_TIMEOUT; else ret = NCM_ERR_NET; + goto done; + } + } + if (sink->overflow) { ret = NCM_ERR_FULL; goto done; } + ret = NCM_OK; +done: + mbedtls_net_free(&net); + mbedtls_ssl_free(&ssl); + mbedtls_ssl_config_free(&conf); + mbedtls_x509_crt_free(&cacert); + if (s_rng_fp) { fclose(s_rng_fp); s_rng_fp = NULL; } + return ret; +} + +int ncm_http_request(const ncm_http_req_t *req, char *buf, size_t buf_sz, ncm_http_resp_t *resp) { + if (!req || !resp) return NCM_ERR_ARG; + memset(resp, 0, sizeof *resp); + sink_t s; + memset(&s, 0, sizeof s); + s.buf = (unsigned char *)buf; + s.cap = buf_sz; + int rc = http_run(req, &s, resp); + resp->body = buf; + resp->body_len = s.len; + return rc; +} + +int ncm_http_download(const ncm_http_req_t *req, ncm_http_write_cb cb, void *ctx, + size_t max_bytes, ncm_http_resp_t *resp) { + if (!req || !cb || !resp) return NCM_ERR_ARG; + memset(resp, 0, sizeof *resp); + sink_t s; + memset(&s, 0, sizeof s); + s.cb = cb; + s.cb_ctx = ctx; + s.max_bytes = max_bytes; + int rc = http_run(req, &s, resp); + return rc; +} + +int ncm_http_parse_set_cookie(const char *hdrs, size_t len, char *out, size_t out_sz) { + if (!hdrs || !out || out_sz == 0) return -1; + out[0] = 0; + size_t o = 0; + int count = 0; + const char *p = hdrs; + const char *end = hdrs + len; + while ((p = strstr(p, "Set-Cookie:")) != NULL && p < end) { + const char *val = p + strlen("Set-Cookie:"); + while (*val == ' ' || *val == '\t') val++; + const char *semi = strchr(val, ';'); + size_t nlen = semi ? (size_t)(semi - val) : strlen(val); + /* 名字可能含空格? 直接取 val[0..nlen) 去尾空格 */ + while (nlen && (val[nlen-1]==' '||val[nlen-1]=='\t')) nlen--; + if (nlen == 0) { p = val; continue; } + if (o > 0) { if (o + 2 >= out_sz) break; out[o++] = ';'; out[o++] = ' '; } + if (o + nlen >= out_sz) break; + memcpy(out + o, val, nlen); + o += nlen; + count++; + p = val; + } + out[o] = 0; + return count; +} diff --git a/patch_v2/ncm_app/core/ncm_http.h b/patch_v2/ncm_app/core/ncm_http.h new file mode 100644 index 0000000..ab0988e --- /dev/null +++ b/patch_v2/ncm_app/core/ncm_http.h @@ -0,0 +1,74 @@ +/* ncm_http.h — mbedtls HTTPS 客户端封装 + * + * 职责:TLS1.2 下 POST/GET;带超时;支持 Content-Length 与 Transfer-Encoding: chunked。 + * CA 方案取舍: + * verify_ca=1(默认):加载系统 CA bundle(或 ca_path 指定)校验服务器证书,失败拒绝。 + * 防中间人;但依赖设备内置 CA 根(VENDOR 侧需内置 ca-certificates)。 + * verify_ca=0:跳过证书校验(MBEDTLS_SSL_VERIFY_NONE)。仅用于无 CA 的调试/受限网络, + * 会暴露 MITM 风险,正式发布应=1。API 层默认为 1。 + * + * 本层只补 Host/Content-Length/Connection: close 三个必需头;UA/Cookie/Content-Type 等 + * 由调用方经 extra_hdrs 传入(完整 CRLF 行,无结尾空行)。 + */ +#ifndef NCM_HTTP_H +#define NCM_HTTP_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define NCM_HTTP_HDR_MAX 4096 +#define NCM_CA_PATH_MAX 256 + +/* req->verify_ca 三态:1=校验,0=跳过,-1=用全局默认(ncm_http_set_verify_default) */ +#define NCM_HTTP_VERIFY_DEFAULT (-1) + +/* 设置全局默认 CA 行为(供 api/login 层无需逐参传递)。verify=1 校验、0 跳过; + * ca_path 拷贝到内部,可为 NULL(用系统默认)。 */ +void ncm_http_set_verify_default(int verify, const char *ca_path); + +typedef struct ncm_http_req { + const char *url; /* 完整 URL(http/https,仅 https 加密) */ + const char *method; /* "GET"/"POST" */ + const char *body; /* 表单体,可为 NULL */ + size_t body_len; /* 0 表示 strlen(body) */ + const char *extra_hdrs; /* 附加头(完整 CRLF 行),可为 NULL */ + uint32_t timeout_ms; /* 整体超时(ms);0=默认 15000 */ + int verify_ca; /* 1=校验CA,0=跳过(仅调试) */ + const char *ca_path; /* 指定 CA bundle 路径;NULL=系统默认 */ +} ncm_http_req_t; + +typedef struct ncm_http_resp { + int status; /* HTTP 状态码(解析自响应行) */ + char headers[NCM_HTTP_HDR_MAX]; /* 响应头(自持,NUL 终止) */ + size_t headers_len; + const char *body; /* 指向请求方 body 缓冲(ncm_http_request 模式) */ + size_t body_len; /* 已落入 body 缓冲的字节数 */ + size_t content_length; /* Content-Length 解析值;SIZE_MAX=未知 */ + int chunked; + int has_content_type; + char content_type[128]; +} ncm_http_resp_t; + +/* 一次性请求:响应(头+体)读入调用方缓冲。buf 容量 buf_sz(含 body)。 + * resp->body 指向 buf 内 body 起始。返回 NCM_OK 或负错误码。 */ +int ncm_http_request(const ncm_http_req_t *req, char *buf, size_t buf_sz, + ncm_http_resp_t *resp); + +/* 流式下载(用于音频/封面缓存):响应体逐块交给回调,回调返回非 0 中止。 + * max_bytes 上限,超出即中止并返回 NCM_ERR_LIMIT。 */ +typedef int (*ncm_http_write_cb)(void *ctx, const unsigned char *data, size_t len); +int ncm_http_download(const ncm_http_req_t *req, ncm_http_write_cb cb, void *ctx, + size_t max_bytes, ncm_http_resp_t *resp); + +/* 从响应头提取所有 Set-Cookie 的 name=value(去掉 Domain/Path/Expires 等属性), + * 以 "; " 连接写入 out(用于登录捕获 MUSIC_U 等)。成功返回 cookie 条数,失败 -1。 */ +int ncm_http_parse_set_cookie(const char *hdrs, size_t len, char *out, size_t out_sz); + +#ifdef __cplusplus +} +#endif +#endif /* NCM_HTTP_H */ diff --git a/patch_v2/ncm_app/core/ncm_json.c b/patch_v2/ncm_app/core/ncm_json.c new file mode 100644 index 0000000..bf98335 --- /dev/null +++ b/patch_v2/ncm_app/core/ncm_json.c @@ -0,0 +1,189 @@ +/* ncm_json.c — jsmn 封装实现 */ +#include "ncm_json.h" +#include "ncm_common.h" + +#include +#include + +int ncm_json_parse(ncm_json_t *j, const char *text, size_t len, + jsmntok_t *toks, int tokcap, int *parent) { + jsmn_parser p; + jsmn_init(&p); + int n = jsmn_parse(&p, text, len, NULL, 0); + if (n <= 0) return NCM_ERR_JSON; + if (n > tokcap) return NCM_ERR_FULL; + + jsmn_init(&p); + if (jsmn_parse(&p, text, len, toks, n) < 0) return NCM_ERR_JSON; + + j->text = text; + j->len = len; + j->toks = toks; + j->ntoks = n; + j->parent = parent; + + /* 构建 parent:预序 DFS,用“最近包含”的开放 token 作父。 + * stack 为临时分配(随解析生命周期,建成后释放)。 */ + int *stack = (int *)malloc(sizeof(int) * (size_t)n); + if (!stack) return NCM_ERR_OOM; + int top = -1; + for (int i = 0; i < n; i++) { + while (top >= 0) { + int s = stack[top]; + int s_start = toks[s].start, s_end = toks[s].end; + int i_start = toks[i].start, i_end = toks[i].end; + /* i 是否完全落在 s 之内 */ + int inside = (i_start >= s_start && i_end <= s_end); + if (inside) break; + top--; + } + parent[i] = (top >= 0) ? stack[top] : -1; + stack[++top] = i; + } + free(stack); + + /* 合理性: 每个非根 token 必须有父,父索引应小于自己 */ + for (int i = 1; i < n; i++) { + if (parent[i] >= i) return NCM_ERR_JSON; + } + return n; +} + +int ncm_json_type(const ncm_json_t *j, int tok) { + if (tok < 0 || tok >= j->ntoks) return JSMN_UNDEFINED; + return j->toks[tok].type; +} + +static int is_object(const ncm_json_t *j, int tok) { + return ncm_json_type(j, tok) == JSMN_OBJECT; +} +static int is_array(const ncm_json_t *j, int tok) { + return ncm_json_type(j, tok) == JSMN_ARRAY; +} + +int ncm_json_obj_get(const ncm_json_t *j, int tok, const char *key) { + if (!is_object(j, tok)) return -1; + size_t kl = strlen(key); + for (int t = 0; t < j->ntoks; t++) { + if (j->parent[t] == tok && j->toks[t].type == JSMN_STRING) { + size_t len = (size_t)(j->toks[t].end - j->toks[t].start); + if (len == kl && memcmp(j->text + j->toks[t].start, key, kl) == 0) { + if (t + 1 < j->ntoks && j->parent[t + 1] == tok) + return t + 1; + return -1; + } + } + } + return -1; +} + +int ncm_json_arr_get(const ncm_json_t *j, int tok, int idx) { + if (!is_array(j, tok)) return -1; + int k = 0; + for (int t = 0; t < j->ntoks; t++) { + if (j->parent[t] == tok) { + if (k == idx) return t; + k++; + } + } + return -1; +} + +int ncm_json_arr_len(const ncm_json_t *j, int tok) { + if (!is_array(j, tok)) return -1; + int k = 0; + for (int t = 0; t < j->ntoks; t++) + if (j->parent[t] == tok) k++; + return k; +} + +const char *ncm_json_get_str_at(const ncm_json_t *j, int tok, char *out, size_t out_sz) { + if (tok < 0 || tok >= j->ntoks) return NULL; + int type = j->toks[tok].type; + if (type != JSMN_STRING && type != JSMN_PRIMITIVE) return NULL; + int start = j->toks[tok].start; + int end = j->toks[tok].end; + /* JSON 字面量 null 视为“无值”,避免把 "null" 当字符串 */ + if (type == JSMN_PRIMITIVE && (size_t)(end - start) == 4 && + memcmp(j->text + start, "null", 4) == 0) + return NULL; + if (end < start) return NULL; + size_t len = (size_t)(end - start); + if (len >= out_sz) return NULL; + memcpy(out, j->text + start, len); + out[len] = 0; + return out; +} + +long ncm_json_get_int_at(const ncm_json_t *j, int tok, int *rc) { + if (rc) *rc = NCM_OK; + if (tok < 0 || tok >= j->ntoks) { if (rc) *rc = NCM_ERR_NOTFOUND; return 0; } + char s[32]; + if (!ncm_json_get_str_at(j, tok, s, sizeof s)) { if (rc) *rc = NCM_ERR_NOTFOUND; return 0; } + long v = 0; + if (ncm_parse_int(s, &v) != 0) { if (rc) *rc = NCM_ERR_JSON; return 0; } + return v; +} + +/* --- 路径导航 --- */ +static int obj_get_path(const ncm_json_t *j, int cur, const char *seg_start, int klen) { + char key[256]; + if (klen <= 0 || klen >= (int)sizeof key) return -1; + memcpy(key, seg_start, (size_t)klen); + key[klen] = 0; + return ncm_json_obj_get(j, cur, key); +} + +int ncm_json_path(const ncm_json_t *j, const char *path) { + if (!path || !*path) return 0; + int cur = 0; /* 根 token */ + const char *p = path; + while (*p) { + if (*p == '.') { p++; continue; } + if (*p == '[') { + const char *close = strchr(p, ']'); + if (!close) return -1; + long idx; + size_t l = (size_t)(close - p - 1); + if (l == 0 || l >= 16) return -1; + char tmp[16]; + memcpy(tmp, p + 1, l); + tmp[l] = 0; + if (ncm_parse_int(tmp, &idx) != 0 || idx < 0) return -1; + cur = ncm_json_arr_get(j, cur, (int)idx); + if (cur < 0) return -1; + p = close + 1; + } else { + const char *seg_start = p; + while (*p && *p != '.' && *p != '[') p++; + cur = obj_get_path(j, cur, seg_start, (int)(p - seg_start)); + if (cur < 0) return -1; + } + } + return cur; +} + +const char *ncm_json_path_str(const ncm_json_t *j, const char *path, char *out, size_t out_sz) { + int tok = ncm_json_path(j, path); + if (tok < 0) return NULL; + return ncm_json_get_str_at(j, tok, out, out_sz); +} + +int ncm_json_path_int(const ncm_json_t *j, const char *path, long *out) { + int tok = ncm_json_path(j, path); + int rc = NCM_ERR_NOTFOUND; + long v = ncm_json_get_int_at(j, tok, &rc); + if (rc != NCM_OK) return rc; + if (out) *out = v; + return NCM_OK; +} + +int ncm_json_path_bool(const ncm_json_t *j, const char *path) { + int tok = ncm_json_path(j, path); + if (tok < 0) return -1; + char s[8]; + if (!ncm_json_get_str_at(j, tok, s, sizeof s)) return -1; + if (ncm_streq(s, "true")) return 1; + if (ncm_streq(s, "false")) return 0; + return -1; +} diff --git a/patch_v2/ncm_app/core/ncm_json.h b/patch_v2/ncm_app/core/ncm_json.h new file mode 100644 index 0000000..dc5fbf5 --- /dev/null +++ b/patch_v2/ncm_app/core/ncm_json.h @@ -0,0 +1,58 @@ +/* ncm_json.h — jsmn 封装:无 DOM、路径导航取值 + * + * jsmn 只做分词(无 malloc/DOM)。本封装在其之上构建 parent 数组, + * 提供按点路径(如 "data[0].url")取值的小接口,用于解析响应 JSON。 + * 调用方提供 token 数组 + parent 数组(预分配),避免库内 malloc 大块。 + */ +#ifndef NCM_JSON_H +#define NCM_JSON_H + +#include +#include "jsmn.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct ncm_json { + const char *text; /* JSON 字符串(非拥有) */ + size_t len; + jsmntok_t *toks; /* token 数组(调用方提供) */ + int ntoks; /* 解析出的 token 数 */ + int *parent; /* parent 索引数组(调用方提供,长度 >= ntoks) */ +} ncm_json_t; + +/* 解析 text,写入 toks/parent。tokcap 为 toks 容量。 + * 返回 token 数(>=0),失败返回负错误码(NCM_ERR_*)。 + * 完成后 j->parent 已构建(parent[k] = k 的父 token 索引,根为 -1)。 */ +int ncm_json_parse(ncm_json_t *j, const char *text, size_t len, + jsmntok_t *toks, int tokcap, int *parent); + +/* 返回 token 类型(JSMN_OBJECT/ARRAY/STRING/PRIMITIVE/UNDEFINED) */ +int ncm_json_type(const ncm_json_t *j, int tok); + +/* 对象取键值的 token 索引;非对象/未找到返回 -1 */ +int ncm_json_obj_get(const ncm_json_t *j, int tok, const char *key); +/* 数组取下标的 token 索引;越界返回 -1 */ +int ncm_json_arr_get(const ncm_json_t *j, int tok, int idx); +/* 数组元素个数;非数组返回 -1 */ +int ncm_json_arr_len(const ncm_json_t *j, int tok); + +/* 取 token 处字符串值(去引号);写入 out,返回 out 或 NULL */ +const char *ncm_json_get_str_at(const ncm_json_t *j, int tok, char *out, size_t out_sz); +/* 取 token 处整数;primitiv/text 转 long,失败返回 0(用 rc 判错) */ +long ncm_json_get_int_at(const ncm_json_t *j, int tok, int *rc); + +/* 路径导航:支持 "data[0].url" / "playlist.trackIds" / "code" 等点+下标路径。 + * 返回目标 token 索引,失败 -1。 */ +int ncm_json_path(const ncm_json_t *j, const char *path); + +/* 便捷取值:路径 -> 字符串/整数/布尔 */ +const char *ncm_json_path_str(const ncm_json_t *j, const char *path, char *out, size_t out_sz); +int ncm_json_path_int(const ncm_json_t *j, const char *path, long *out); +int ncm_json_path_bool(const ncm_json_t *j, const char *path); + +#ifdef __cplusplus +} +#endif +#endif /* NCM_JSON_H */ diff --git a/patch_v2/ncm_app/core/ncm_login.c b/patch_v2/ncm_app/core/ncm_login.c new file mode 100644 index 0000000..26ccda0 --- /dev/null +++ b/patch_v2/ncm_app/core/ncm_login.c @@ -0,0 +1,197 @@ +/* ncm_login.c — 扫码登录实现 */ +#include "ncm_login.h" +#include "ncm_common.h" +#include "ncm_http.h" +#include "ncm_json.h" +#include "ncm_req.h" + +#include +#include +#include + +#include "qrcodegen.h" + +#define QR_URL_FMT "https://music.163.com/login?codekey=%s" + +int ncm_login_qr_url(const char *unikey, char *url, size_t usz) { + if (!unikey || !url) return NCM_ERR_ARG; + int n = snprintf(url, usz, QR_URL_FMT, unikey); + return (n >= 0 && (size_t)n < usz) ? NCM_OK : NCM_ERR_FULL; +} + +int ncm_login_unikey(const char *device_id, char *unikey, size_t usz) { + char body[NCM_REQ_BODY_MAX], hdrs[NCM_REQ_HDRS_MAX], url[NCM_REQ_URL_MAX]; + int rc = ncm_req_build(device_id, NULL, "/api/login/qrcode/unikey", + "{\"type\":3}", NCM_CRYPT_EAPI, + body, sizeof body, hdrs, sizeof hdrs, url, sizeof url); + if (rc != NCM_OK) return rc; + ncm_http_req_t req; + memset(&req, 0, sizeof req); + req.url = url; + req.method = "POST"; + req.body = body; + req.body_len = strlen(body); + req.extra_hdrs = hdrs; + req.verify_ca = NCM_HTTP_VERIFY_DEFAULT; + req.timeout_ms = 15000; + + char respbuf[4096]; + ncm_http_resp_t resp; + rc = ncm_http_request(&req, respbuf, sizeof respbuf, &resp); + if (rc != NCM_OK) return rc; + + ncm_json_t j; + jsmntok_t toks[512]; + int parent[512]; + rc = ncm_json_parse(&j, resp.body, resp.body_len, toks, 512, parent); + if (rc < 0) return NCM_ERR_JSON; + + char u[64] = ""; + const char *v = ncm_json_path_str(&j, "unikey", u, sizeof u); + if (!v) v = ncm_json_path_str(&j, "data.unikey", u, sizeof u); + if (!v) v = ncm_json_path_str(&j, "data.uniKey", u, sizeof u); + if (!v) return NCM_ERR_NOTFOUND; + ncm_strlcpy(unikey, u, usz); + return NCM_OK; +} + +int ncm_login_qr_matrix(const char *url, unsigned char *mods, int max_size, int *out_size) { + if (!url || !mods || !out_size) return NCM_ERR_ARG; + uint8_t temp[qrcodegen_BUFFER_LEN_MAX], qr[qrcodegen_BUFFER_LEN_MAX]; + if (!qrcodegen_encodeText(url, temp, qr, qrcodegen_Ecc_MEDIUM, 1, 40, + qrcodegen_Mask_AUTO, true)) + return NCM_ERR_CRYPTO; + int size = qrcodegen_getSize(qr); + if (size > max_size) return NCM_ERR_FULL; + for (int y = 0; y < size; y++) + for (int x = 0; x < size; x++) + mods[y * size + x] = qrcodegen_getModule(qr, x, y) ? 1 : 0; + *out_size = size; + return NCM_OK; +} + +/* 合并 set-cookie 到会话:给 out 以 captured,若 captured 空则保留 cur_cookie 中已有的对 */ +static void merge_cookie(const char *cur, const char *captured, char *out, size_t out_sz) { + if (!captured || !*captured) { + ncm_strlcpy(out, cur ? cur : "", out_sz); + return; + } + ncm_strlcpy(out, captured, out_sz); +} + +int ncm_login_poll(const char *device_id, const char *unikey, const char *cur_cookie, + ncm_login_poll_t *r, char *out_cookie, size_t out_cookie_sz) { + if (!device_id || !unikey || !r) return NCM_ERR_ARG; + memset(r, 0, sizeof *r); + r->state = NCM_LOGIN_ERROR; + r->code = -1; + + char json[256]; + snprintf(json, sizeof json, "{\"key\":\"%s\",\"type\":3}", unikey); + + char body[NCM_REQ_BODY_MAX], hdrs[NCM_REQ_HDRS_MAX], url[NCM_REQ_URL_MAX]; + int rc = ncm_req_build(device_id, cur_cookie, "/api/login/qrcode/client/login", + json, NCM_CRYPT_EAPI, + body, sizeof body, hdrs, sizeof hdrs, url, sizeof url); + if (rc != NCM_OK) return rc; + + ncm_http_req_t req; + memset(&req, 0, sizeof req); + req.url = url; + req.method = "POST"; + req.body = body; + req.body_len = strlen(body); + req.extra_hdrs = hdrs; + req.verify_ca = NCM_HTTP_VERIFY_DEFAULT; + req.timeout_ms = 15000; + + char respbuf[4096]; + ncm_http_resp_t resp; + rc = ncm_http_request(&req, respbuf, sizeof respbuf, &resp); + if (rc != NCM_OK) return rc; + + /* 提取 set-cookie */ + char captured[1024] = ""; + ncm_http_parse_set_cookie(resp.headers, resp.headers_len, captured, sizeof captured); + if (captured[0]) r->cookie_was_set = 1; + if (out_cookie) merge_cookie(cur_cookie, captured, out_cookie, out_cookie_sz); + + ncm_json_t j; + jsmntok_t toks[512]; + int parent[512]; + rc = ncm_json_parse(&j, resp.body, resp.body_len, toks, 512, parent); + if (rc < 0) return NCM_ERR_JSON; + + long code = 0; + int crc = ncm_json_path_int(&j, "code", &code); + if (crc != NCM_OK) code = -1; + r->code = (int)code; + ncm_json_path_str(&j, "message", r->message, sizeof r->message); + + switch (r->code) { + case 800: r->state = NCM_LOGIN_EXPIRED; break; + case 801: r->state = NCM_LOGIN_PENDING; break; + case 802: r->state = NCM_LOGIN_SCANNED; break; + case 803: + case 200: r->state = NCM_LOGIN_OK; break; + default: r->state = NCM_LOGIN_ERROR; break; + } + return NCM_OK; +} + +int ncm_login_status_check(const char *device_id, const char *cookie, + char *uid, size_t usz, char *nickname, size_t nsz) { + char body[NCM_REQ_BODY_MAX], hdrs[NCM_REQ_HDRS_MAX], url[NCM_REQ_URL_MAX]; + int rc = ncm_req_build(device_id, cookie, "/api/w/nuser/account/get", "{}", NCM_CRYPT_WEAPI, + body, sizeof body, hdrs, sizeof hdrs, url, sizeof url); + if (rc != NCM_OK) return rc; + + ncm_http_req_t req; + memset(&req, 0, sizeof req); + req.url = url; + req.method = "POST"; + req.body = body; + req.body_len = strlen(body); + req.extra_hdrs = hdrs; + req.verify_ca = NCM_HTTP_VERIFY_DEFAULT; + req.timeout_ms = 15000; + + char respbuf[4096]; + ncm_http_resp_t resp; + rc = ncm_http_request(&req, respbuf, sizeof respbuf, &resp); + if (rc != NCM_OK) return rc; + + ncm_json_t j; + jsmntok_t toks[512]; + int parent[1024]; + rc = ncm_json_parse(&j, resp.body, resp.body_len, toks, 1024, parent); + if (rc < 0) return NCM_ERR_JSON; + + long code; + if (ncm_json_path_int(&j, "code", &code) != NCM_OK) return NCM_ERR_JSON; + if (code != 200) return NCM_ERR_AUTH; + /* 未登录(guest)时 code 可能仍为 200 但 profile 为 null —— 必须 profile 是对象才算已登录 */ + int ptok = ncm_json_path(&j, "profile"); + if (ptok < 0 || ncm_json_type(&j, ptok) != JSMN_OBJECT) return NCM_ERR_AUTH; + + if (uid) { + uid[0] = 0; + if (!ncm_json_path_str(&j, "account.id", uid, usz)) + ncm_json_path_str(&j, "profile.userId", uid, usz); + if (uid[0] == 0) + ncm_json_path_str(&j, "profile.uid", uid, usz); + } + if (nickname) + ncm_json_path_str(&j, "profile.nickname", nickname, nsz); + return NCM_OK; +} + +int ncm_login_save_cookie(const ncm_store_t *store, const char *cookie) { + return ncm_store_save_session(store, cookie); +} +int ncm_login_load_cookie(const ncm_store_t *store, char *cookie, size_t sz) { + return ncm_store_load_session(store, cookie, sz); +} +int ncm_login_clear_cookie(const ncm_store_t *store) { + return ncm_store_clear_session(store); +} diff --git a/patch_v2/ncm_app/core/ncm_login.h b/patch_v2/ncm_app/core/ncm_login.h new file mode 100644 index 0000000..5c64544 --- /dev/null +++ b/patch_v2/ncm_app/core/ncm_login.h @@ -0,0 +1,58 @@ +/* ncm_login.h — 扫码登录 + * + * 流程:unikey(eapi) → 本地构造二维码 → 轮询(801/802/803) → 捕获 set-cookie(MUSIC_U) + * → 加密落盘 → login_status(weapi) 校验。 + * 二维码位图用 qrcodegen 生成 1 bit/模块 矩阵,交给 UI 层渲染。 + */ +#ifndef NCM_LOGIN_H +#define NCM_LOGIN_H + +#include "ncm_store.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* 登录状态(映射服务端 code) */ +enum { + NCM_LOGIN_PENDING = 0, /* 801 等待扫码 */ + NCM_LOGIN_SCANNED = 1, /* 802 已扫码待确认 */ + NCM_LOGIN_OK = 2, /* 803/200 成功 */ + NCM_LOGIN_EXPIRED = 3, /* 800 过期 */ + NCM_LOGIN_ERROR = 4, /* 其它异常 */ +}; + +/* 二维码 URL(本地构造) */ +int ncm_login_qr_url(const char *unikey, char *url, size_t usz); + +/* 拿 unikey(请求 /eapi/login/qrcode/unikey) */ +int ncm_login_unikey(const char *device_id, char *unikey, size_t usz); + +/* 二维码位图矩阵:mods 为 size*size 字节(1=暗)。max_size 为 mods 容量对应边长。 */ +int ncm_login_qr_matrix(const char *url, unsigned char *mods, int max_size, int *out_size); + +typedef struct ncm_login_poll { + int state; /* NCM_LOGIN_* */ + int code; /* 服务端 code(800/801/802/803/200) */ + int cookie_was_set; /* 本次响应是否带 set-cookie */ + char message[64]; /* 服务端 message */ +} ncm_login_poll_t; + +/* 轮询扫码状态。cur_cookie 为当前会话 cookie(可为空);成功时捕获 set-cookie 合并写入 out_cookie。 */ +int ncm_login_poll(const char *device_id, const char *unikey, const char *cur_cookie, + ncm_login_poll_t *r, char *out_cookie, size_t out_cookie_sz); + +/* login_status(weapi):校验 cookie 是否仍有效。有效写 uid/nickname 并返回 NCM_OK;失效返回 NCM_ERR_AUTH。 */ +int ncm_login_status_check(const char *device_id, const char *cookie, + char *uid, size_t usz, char *nickname, size_t nsz); + +/* 会话 cookie 加密落盘/读回(机器绑定密钥,仅防裸读)。 */ +int ncm_login_save_cookie(const ncm_store_t *store, const char *cookie); +int ncm_login_load_cookie(const ncm_store_t *store, char *cookie, size_t sz); +int ncm_login_clear_cookie(const ncm_store_t *store); + +#ifdef __cplusplus +} +#endif +#endif /* NCM_LOGIN_H */ diff --git a/patch_v2/ncm_app/core/ncm_req.c b/patch_v2/ncm_app/core/ncm_req.c new file mode 100644 index 0000000..35efb70 --- /dev/null +++ b/patch_v2/ncm_app/core/ncm_req.c @@ -0,0 +1,298 @@ +/* ncm_req.c — 加密请求构建实现 */ +#include "ncm_req.h" +#include "ncm_common.h" +#include "ncm_crypto.h" + +#include +#include +#include +#include + +#define UA_EAPI "NeteaseMusic 9.0.90/5038 (iPhone; iOS 16.2; zh_CN)" +#define UA_WEAPI "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36 Edg/124.0.0.0" +#define API_DOMAIN "https://interface.music.163.com" +#define DOMAIN "https://music.163.com" + +#define OSVER "Microsoft-Windows-10-Professional-build-19045-64bit" +#define APPVER "3.1.17.204416" +#define CHANNEL "netease" + +/* ---------- cookie map ---------- */ +typedef struct { char name[48]; char val[192]; } ck_t; +typedef struct { ck_t p[48]; int n; } ckmap_t; + +static void ck_add_ev(ckmap_t *m, const char *name, const char *val) { + if (m->n >= (int)(sizeof m->p / sizeof m->p[0])) return; + ncm_strlcpy(m->p[m->n].name, name, sizeof m->p[m->n].name); + ncm_strlcpy(m->p[m->n].val, val ? val : "", sizeof m->p[m->n].val); + m->n++; +} +static int ck_find(const ckmap_t *m, const char *name) { + for (int i = 0; i < m->n; i++) if (ncm_streq(m->p[i].name, name)) return i; + return -1; +} +static void ck_set(ckmap_t *m, const char *name, const char *val) { + int i = ck_find(m, name); + if (i >= 0) ncm_strlcpy(m->p[i].val, val ? val : "", sizeof m->p[i].val); + else ck_add_ev(m, name, val); +} +static void ck_set_default(ckmap_t *m, const char *name, const char *val) { + if (ck_find(m, name) < 0) ck_add_ev(m, name, val); +} +static void ck_to_string(const ckmap_t *m, char *out, size_t out_sz) { + size_t o = 0; + for (int i = 0; i < m->n; i++) { + int sep = (o > 0) ? 2 : 0; /* "; " */ + if (o + sep + strlen(m->p[i].name) + 1 + strlen(m->p[i].val) + 1 > out_sz) break; + if (sep) { out[o++] = ';'; out[o++] = ' '; } + size_t nl = strlen(m->p[i].name); + memcpy(out + o, m->p[i].name, nl); o += nl; + out[o++] = '='; + size_t vl = strlen(m->p[i].val); + memcpy(out + o, m->p[i].val, vl); o += vl; + } + out[o] = 0; +} + +/* 解析 cookie 字符串(; 分隔) 进 map */ +static void ck_parse(ckmap_t *m, const char *cookie) { + if (!cookie) return; + const char *p = cookie; + while (*p) { + while (*p == ' ' || *p == ';') p++; + if (!*p) break; + const char *eq = strchr(p, '='); + const char *semi = strchr(p, ';'); + size_t name_len = eq ? (size_t)(eq - p) : (semi ? (size_t)(semi - p) : strlen(p)); + if (eq) { + size_t val_len = semi ? (size_t)(semi - eq - 1) : strlen(eq + 1); + char name[48], val[192]; + if (name_len >= sizeof name) name_len = sizeof name - 1; + memcpy(name, p, name_len); name[name_len] = 0; + if (val_len >= sizeof val) val_len = sizeof val - 1; + memcpy(val, eq + 1, val_len); val[val_len] = 0; + ck_set(m, name, val); + } + p = semi ? semi + 1 : p + strlen(p); + } +} + +int ncm_req_cookie_get(const char *cookie, const char *name, char *out, size_t out_sz) { + if (!cookie || !name || !out) return NCM_ERR_ARG; + ckmap_t m; memset(&m, 0, sizeof m); + ck_parse(&m, cookie); + int i = ck_find(&m, name); + if (i < 0) return NCM_ERR_NOTFOUND; + ncm_strlcpy(out, m.p[i].val, out_sz); + return NCM_OK; +} + +/* ---------- json 注入 ---------- */ +/* 把 json{...} 内部插入 ","(尾部)。extra 形如 "\"csrf_token\":\"x\""(无前导逗号) */ +static int json_inject(const char *json, const char *extra, char *out, size_t out_sz) { + size_t jl = strlen(json); + if (jl < 2 || json[0] != '{' || json[jl - 1] != '}') return -1; + const char *inner = json + 1; + size_t inner_len = jl - 2; + int first = 1; + /* 检查内部是否为空 */ + for (size_t i = 0; i < inner_len; i++) { + char c = inner[i]; + if (c != ' ' && c != '\t' && c != '\n' && c != '\r') { first = 0; break; } + } + const char *sep = first ? "" : ","; + int n = snprintf(out, out_sz, "{%s%s%s}", inner, sep, extra); + return (n >= 0 && (size_t)n < out_sz) ? 0 : -1; +} + +/* ---------- eapi header map ---------- */ +typedef struct hmap { + char key[24]; + char val[256]; +} hmap_t; +typedef struct { hmap_t e[16]; int n; } hmap_tab; + +static void hm_add(hmap_tab *h, const char *k, const char *v) { + if (h->n >= (int)(sizeof h->e / sizeof h->e[0])) return; + ncm_strlcpy(h->e[h->n].key, k, sizeof h->e[h->n].key); + ncm_strlcpy(h->e[h->n].val, v, sizeof h->e[h->n].val); + h->n++; +} +static void hm_to_json(const hmap_tab *h, char *out, size_t out_sz) { + size_t o = 0; + o += (size_t)snprintf(out + o, out_sz - o, "{"); + for (int i = 0; i < h->n; i++) { + int n = snprintf(out + o, out_sz - o, "%s\"%s\":\"%s\"", i ? "," : "", + h->e[i].key, h->e[i].val); + if (n < 0 || (size_t)n >= out_sz - o) break; + o += (size_t)n; + } + snprintf(out + o, out_sz - o, "}"); +} +static void hm_to_cookie(const hmap_tab *h, char *out, size_t out_sz) { + size_t o = 0; + for (int i = 0; i < h->n; i++) { + char ev[512], ec[512]; + if (ncm_url_encode(h->e[i].val, ev, sizeof ev) < 0 || + ncm_url_encode(h->e[i].key, ec, sizeof ec) < 0) break; + int n = snprintf(out + o, out_sz - o, "%s%s=%s", i ? "; " : "", ec, ev); + if (n < 0 || (size_t)n >= out_sz - o) break; + o += (size_t)n; + } + out[o < out_sz ? o : out_sz - 1] = 0; +} + +/* head 注入(eapi):把 __csrf/deviceId/os/... 等填到 header map 与 cookie。 + * 同时产出 json.header 片段。 */ +static void eapi_fill_header(const char *device_id, const char *csrf, + hmap_tab *h, char *buildver, size_t bvsz, + char *request_id, size_t ri_sz) { + (void)bvsz; + char ts[32], ms[48]; + snprintf(ts, sizeof ts, "%lld", (long long)time(NULL)); + snprintf(ms, sizeof ms, "%lld", (long long)(ncm_now_ms())); + memcpy(buildver, ts, 10); buildver[10] = 0; + snprintf(request_id, ri_sz, "%s_0000", ms); + + hm_add(h, "osver", OSVER); + hm_add(h, "deviceId", device_id); + hm_add(h, "os", "pc"); + hm_add(h, "appver", APPVER); + hm_add(h, "versioncode", "140"); + hm_add(h, "mobilename", ""); + hm_add(h, "buildver", buildver); + hm_add(h, "resolution", "1920x1080"); + hm_add(h, "__csrf", csrf ? csrf : ""); + hm_add(h, "channel", CHANNEL); + hm_add(h, "requestId", request_id); +} + +int ncm_req_build(const char *device_id, const char *cookie, const char *path, + const char *json, int kind, + char *body, size_t body_sz, + char *hdrs, size_t hdrs_sz, + char *url, size_t url_sz) { + if (!device_id || !path || !json || !body || !hdrs || !url) return NCM_ERR_ARG; + + if (kind == NCM_CRYPT_WEAPI) { + /* csrf_token */ + char csrf[128] = ""; + ncm_req_cookie_get(cookie, "__csrf", csrf, sizeof csrf); + char full[2048], extra[256]; + snprintf(extra, sizeof extra, "\"csrf_token\":\"%s\"", csrf); + if (json_inject(json, extra, full, sizeof full) != 0) return NCM_ERR_ARG; + + char params[1024], encsk[300]; + if (ncm_crypto_weapi(full, params, sizeof params, encsk, sizeof encsk) != 0) + return NCM_ERR_CRYPTO; + char p_enc[1024]; + if (ncm_url_encode(params, p_enc, sizeof p_enc) < 0) return NCM_ERR_FULL; + char referer[256]; + snprintf(referer, sizeof referer, "https://music.163.com"); + /* 会话 cookie + 默认伪装字段补齐 */ + ckmap_t m; memset(&m, 0, sizeof m); + ck_parse(&m, cookie); + ck_add_ev(&m, "__remember_me", "true"); + ck_add_ev(&m, "ntes_kaola_ad", "1"); + char nuid[96]; ncm_random_bytes((unsigned char *)nuid, 16); + /* _ntes_nnid = nuid,ts ; _ntes_nuid = nuid */ + { + char nuid_hex[33]; ncm_hex_encode((const unsigned char *)nuid, 16, nuid_hex, 0); + char nnid[96]; + snprintf(nnid, sizeof nnid, "%s,%lld", nuid_hex, (long long)ncm_now_ms()); + ck_add_ev(&m, "_ntes_nnid", nnid); + ck_add_ev(&m, "_ntes_nuid", nuid_hex); + } + char wnmcid[40]; { + unsigned char r[16]; ncm_random_bytes(r, 16); + char h[33]; ncm_hex_encode(r, 16, h, 0); snprintf(wnmcid, sizeof wnmcid, "%s", h); + } + ck_set_default(&m, "WNMCID", wnmcid); + ck_set_default(&m, "WEVNSM", "1.0.0"); + ck_set_default(&m, "osver", OSVER); + ck_set_default(&m, "deviceId", device_id); + ck_set_default(&m, "os", "pc"); + ck_set_default(&m, "channel", CHANNEL); + ck_set_default(&m, "appver", APPVER); + if (!strstr(path, "login")) { + unsigned char r[4]; ncm_random_bytes(r, 4); + char h[9]; ncm_hex_encode(r, 4, h, 1); + ck_set_default(&m, "NMTID", h); + } + char cookie_full[2048]; + ck_to_string(&m, cookie_full, sizeof cookie_full); + + int n = snprintf(hdrs, hdrs_sz, + "User-Agent: %s\r\nContent-Type: application/x-www-form-urlencoded\r\n" + "Cookie: %s\r\nReferer: %s", UA_WEAPI, cookie_full, referer); + if (n < 0 || (size_t)n >= hdrs_sz) return NCM_ERR_FULL; + + /* body */ + n = snprintf(body, body_sz, "params=%s&encSecKey=%s", p_enc, encsk); + if (n < 0 || (size_t)n >= body_sz) return NCM_ERR_FULL; + + /* url */ + const char *suffix = path + 5; /* 去 "/api/" */ + n = snprintf(url, url_sz, "%s/weapi/%s", DOMAIN, suffix); + if (n < 0 || (size_t)n >= url_sz) return NCM_ERR_FULL; + return NCM_OK; + } + + if (kind == NCM_CRYPT_EAPI) { + char csrf[128] = ""; + ncm_req_cookie_get(cookie, "__csrf", csrf, sizeof csrf); + hmap_tab h; memset(&h, 0, sizeof h); + char buildver[16], rid[64]; + eapi_fill_header(device_id, csrf, &h, buildver, sizeof buildver, rid, sizeof rid); + char header_json[1024]; + hm_to_json(&h, header_json, sizeof header_json); + + /* 注入 header 与 e_r 到加密 JSON */ + char full2[3072]; + { + size_t jl = strlen(json); + if (jl >= 2 && json[0]=='{' && json[jl-1]=='}') { + int fn = snprintf(full2, sizeof full2, "{%s,\"header\":%s,\"e_r\":false}", + json + 1, header_json); + if (fn < 0 || (size_t)fn >= sizeof full2) return NCM_ERR_FULL; + } else { + return NCM_ERR_ARG; + } + } + + char params[2048]; + if (ncm_crypto_eapi(path, full2, params, sizeof params) != 0) return NCM_ERR_CRYPTO; + + char cookie_hdr[2048]; + hm_to_cookie(&h, cookie_hdr, sizeof cookie_hdr); + + int n = snprintf(hdrs, hdrs_sz, + "User-Agent: %s\r\nContent-Type: application/x-www-form-urlencoded\r\nCookie: %s", + UA_EAPI, cookie_hdr); + if (n < 0 || (size_t)n >= hdrs_sz) return NCM_ERR_FULL; + + /* 此处注意:我们已把 header 插入到加密 JSON 内,同时 Cookie 头也带同一组键值(对齐 request.rs) */ + n = snprintf(body, body_sz, "params=%s", params); + if (n < 0 || (size_t)n >= body_sz) return NCM_ERR_FULL; + + const char *suffix = path + 5; + n = snprintf(url, url_sz, "%s/eapi/%s", API_DOMAIN, suffix); + if (n < 0 || (size_t)n >= url_sz) return NCM_ERR_FULL; + return NCM_OK; + } + + if (kind == NCM_CRYPT_LINUX) { + char params[1024]; + if (ncm_crypto_linuxapi(json, params, sizeof params) != 0) return NCM_ERR_CRYPTO; + int n = snprintf(hdrs, hdrs_sz, + "User-Agent: %s\r\nContent-Type: application/x-www-form-urlencoded", UA_WEAPI); + if (n < 0 || (size_t)n >= hdrs_sz) return NCM_ERR_FULL; + n = snprintf(body, body_sz, "eparams=%s", params); + if (n < 0 || (size_t)n >= body_sz) return NCM_ERR_FULL; + n = snprintf(url, url_sz, "%s/api/linux/forward", API_DOMAIN); + if (n < 0 || (size_t)n >= url_sz) return NCM_ERR_FULL; + return NCM_OK; + } + + return NCM_ERR_ARG; +} diff --git a/patch_v2/ncm_app/core/ncm_req.h b/patch_v2/ncm_app/core/ncm_req.h new file mode 100644 index 0000000..b990784 --- /dev/null +++ b/patch_v2/ncm_app/core/ncm_req.h @@ -0,0 +1,50 @@ +/* ncm_req.h — 加密请求构建 + * + * 统一把「核心参数 JSON」+ deviceId/cookie 组装成一条可直接 POST 的请求: + * - eapi: 注入 header/e_r,MD5+AES-ECB 得 params;Cookie 头=urlencode(header map) + * - weapi: 注入 csrf_token,双层 AES-CBC+RSA raw 得 params/encSecKey;Referer+Chrome UA + * 头注入对齐 CNMPlayer request.rs(deviceId/UA 稳定是风控关键)。 + */ +#ifndef NCM_REQ_H +#define NCM_REQ_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* 加密类型 */ +enum { + NCM_CRYPT_EAPI = 0, + NCM_CRYPT_WEAPI = 1, + NCM_CRYPT_LINUX = 2, + NCM_CRYPT_API = 3 /* 明文 not supported here */ +}; + +#define NCM_REQ_URL_MAX 2048 +#define NCM_REQ_BODY_MAX 8192 +#define NCM_REQ_HDRS_MAX 4096 + +/* 构建一条 POST 请求。参数: + * device_id 52hex deviceId(已持久化) + * cookie 会话 cookie(可为空;weapi 会补齐默认伪装字段;eapi 只用其 __csrf) + * path API 路径(以 "/api/" 开头,如 /api/login/qrcode/unikey) + * json 核心参数 JSON(扁平对象,如 {"type":3}) + * kind NCM_CRYPT_* + * 输出:body(表单体)、hdrs(extra 头,仅 UA/Content-Type/Cookie/Referer),url(完整 URL) + * 返回 NCM_OK 或负错误码。 + */ +int ncm_req_build(const char *device_id, const char *cookie, const char *path, + const char *json, int kind, + char *body, size_t body_sz, + char *hdrs, size_t hdrs_sz, + char *url, size_t url_sz); + +/* 从 cookie 串取某个字段值(如 __csrf)。找到返回 0。*/ +int ncm_req_cookie_get(const char *cookie, const char *name, char *out, size_t out_sz); + +#ifdef __cplusplus +} +#endif +#endif /* NCM_REQ_H */ diff --git a/patch_v2/ncm_app/core/ncm_store.c b/patch_v2/ncm_app/core/ncm_store.c new file mode 100644 index 0000000..2dd9dc1 --- /dev/null +++ b/patch_v2/ncm_app/core/ncm_store.c @@ -0,0 +1,329 @@ +/* ncm_store.c — 持久化存储层实现 */ +#include "ncm_store.h" +#include "ncm_common.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "mbedtls/aes.h" + +#define SESSION_FILE "session.enc" +#define SESSION_MAGIC "NCM1" +#define SESSION_MAGIC_LEN 4 +#define SESSION_SALT "os.meow.ncm.session.v1" +#define DEVICE_FILE "deviceId" +#define MKEY_FILE ".mkey" + +/* 数据目录快照(ncm_store_init 设置)。用于无 MAC 时派生机器绑定密钥。单实例约定。 */ +static char g_store_dir[NCM_STORE_DIR_MAX] = ""; + +int ncm_store_mkdir_p(const char *path) { + if (!path || !*path) return -1; + char tmp[NCM_STORE_DIR_MAX]; + size_t len = strlen(path); + if (len >= sizeof tmp) return -1; + memcpy(tmp, path, len + 1); + if (tmp[len - 1] == '/') tmp[len - 1] = '\0'; + for (size_t i = 1; i <= strlen(tmp); i++) { + if (tmp[i] == '/' || tmp[i] == '\0') { + char ch = tmp[i]; + tmp[i] = '\0'; + if (tmp[0] && mkdir(tmp, 0755) != 0 && errno != EEXIST) return -1; + tmp[i] = ch; + } + } + return 0; +} + +int ncm_store_init(ncm_store_t *st, const char *dir) { + if (!st) return NCM_ERR_ARG; + memset(st, 0, sizeof *st); + const char *d = dir; + if (!d || !*d) { + d = getenv("MEOW_DATA_DIR"); + if (!d || !*d) { + snprintf(st->data_dir, sizeof st->data_dir, "/tmp/meowcs_%d", (int)getpid()); + d = st->data_dir; /* 回退后指向自身 */ + } + } + if (strlen(d) >= sizeof st->data_dir) return NCM_ERR_ARG; + ncm_strlcpy(st->data_dir, d, sizeof st->data_dir); + /* 去尾斜杠 */ + size_t n = strlen(st->data_dir); + while (n > 1 && st->data_dir[n - 1] == '/') st->data_dir[--n] = '\0'; + ncm_store_mkdir_p(st->data_dir); + ncm_strlcpy(g_store_dir, st->data_dir, sizeof g_store_dir); + return NCM_OK; +} + +const char *ncm_store_data_dir(const ncm_store_t *st) { + return st->data_dir; +} + +int ncm_store_get_device_id(ncm_store_t *st, char out[NCM_STORE_ID_MAX]) { + if (!st || !out) return NCM_ERR_ARG; + char path[NCM_STORE_DIR_MAX + 16]; + snprintf(path, sizeof path, "%s/%s", st->data_dir, DEVICE_FILE); + char buf[NCM_STORE_ID_MAX]; + int n = ncm_store_read_file(path, buf, sizeof buf); + if (n >= NCM_DEVICE_ID_LEN) { + /* 找到已持久化的 52hex(容错小写→大写) */ + char up[NCM_STORE_ID_MAX]; + for (int i = 0; i < NCM_DEVICE_ID_LEN; i++) up[i] = (char)toupper((unsigned char)buf[i]); + up[NCM_DEVICE_ID_LEN] = 0; + ncm_strlcpy(out, up, NCM_STORE_ID_MAX); + return NCM_OK; + } + /* 生成并持久化 */ + unsigned char r[26]; + ncm_random_bytes(r, sizeof r); + char id[NCM_STORE_ID_MAX]; + ncm_hex_encode(r, sizeof r, id, 1); + ncm_strlcpy(out, id, NCM_STORE_ID_MAX); + ncm_store_write_file(path, id, strlen(id)); + return NCM_OK; +} + +int ncm_store_set_device_id(ncm_store_t *st, const char id[NCM_STORE_ID_MAX]) { + if (!st || !id || strlen(id) != NCM_DEVICE_ID_LEN) return NCM_ERR_ARG; + char path[NCM_STORE_DIR_MAX + 16]; + snprintf(path, sizeof path, "%s/%s", st->data_dir, DEVICE_FILE); + return ncm_store_write_file(path, id, strlen(id)); +} + +/* 首要网卡 MAC 小写 "aa:bb:cc:dd:ee:ff";NCM_MAC 优先;失败返回非 0。 */ +static int read_mac(char out[32]) { + out[0] = 0; + const char *env = getenv("NCM_MAC"); + if (env && strlen(env) == 17) { + ncm_strlcpy(out, env, 18); + for (char *p = out; *p; p++) *p = (char)tolower((unsigned char)*p); + return 0; + } + DIR *d = opendir("/sys/class/net"); + if (!d) return -1; + int rc = -1; + struct dirent *e; + while ((e = readdir(d))) { + if (e->d_name[0] == '.') continue; + if (strcmp(e->d_name, "lo") == 0) continue; + char p[320], addr[64] = {0}; + snprintf(p, sizeof p, "/sys/class/net/%s/address", e->d_name); + FILE *f = fopen(p, "r"); + if (!f) continue; + if (fgets(addr, sizeof addr, f)) { + fclose(f); + size_t l = strlen(addr); + while (l && (addr[l-1]=='\n' || addr[l-1]=='\r')) addr[--l] = 0; + if (l == 17 && strcmp(addr, "00:00:00:00:00:00") != 0) { + for (char *q = addr; *q; q++) *q = (char)tolower((unsigned char)*q); + ncm_strlcpy(out, addr, 18); + rc = 0; + break; + } + } + } + closedir(d); + return rc; +} + +/* 读取或生成设备私有密钥(32字节):/.mkey。成功返回 0。 */ +static int get_or_create_mkey(unsigned char out[32]) { + char path[NCM_STORE_DIR_MAX + 16]; + snprintf(path, sizeof path, "%s/%s", g_store_dir, MKEY_FILE); + char raw[80]; + int n = ncm_store_read_file(path, raw, sizeof raw); + if (n >= 32) { + memcpy(out, raw, 32); + return 0; + } + ncm_random_bytes(out, 32); + return ncm_store_write_file(path, out, 32); +} + +int ncm_store_machine_key(const char *salt, unsigned char key[16]) { + char mac[32]; + unsigned char h[32]; + if (read_mac(mac) == 0) { + char buf[64]; + snprintf(buf, sizeof buf, "%s%s", mac, salt ? salt : ""); + if (ncm_sha256(buf, strlen(buf), h) != 0) return -1; + } else { + /* 无 MAC(如 qemu/无网卡环境):回退到设备私有 .mkey,绑定本机数据目录。 + * 仍是模糊防裸读,绝非真安全(注释见头文件)。 */ + unsigned char mkey[32]; + if (get_or_create_mkey(mkey) != 0) return -1; + char mkey_hex[65]; + ncm_hex_encode(mkey, 32, mkey_hex, 0); + char buf[96]; + snprintf(buf, sizeof buf, "%s%s", mkey_hex, salt ? salt : ""); + if (ncm_sha256(buf, strlen(buf), h) != 0) return -1; + } + memcpy(key, h, 16); + return 0; +} + +static int pkcs7_pad_len(size_t n) { + return (int)(16 - (n % 16)); /* 1..16 */ +} + +int ncm_store_cookie_encrypt(const char *plain, + unsigned char *out, size_t *out_len, size_t cap) { + if (!plain || !out || !out_len) return NCM_ERR_ARG; + unsigned char key[16]; + if (ncm_store_machine_key(SESSION_SALT, key) != 0) return NCM_ERR_CRYPTO; + + size_t n = strlen(plain); + int pad = pkcs7_pad_len(n); + size_t total = n + (size_t)pad; + if (cap < SESSION_MAGIC_LEN + 16 + total) return NCM_ERR_FULL; + + unsigned char iv[16], iv_file[16]; + ncm_random_bytes(iv, sizeof iv); + memcpy(iv_file, iv, 16); /* crypt_cbc 会就地改写 iv,必须先存原始值 */ + + unsigned char *ct = (unsigned char *)malloc(total); + if (!ct) return NCM_ERR_OOM; + + /* AES-CBC 加密 */ + mbedtls_aes_context aes; + mbedtls_aes_init(&aes); + mbedtls_aes_setkey_enc(&aes, key, 128); + unsigned char *in = (unsigned char *)malloc(total); + if (!in) { free(ct); return NCM_ERR_OOM; } + memcpy(in, plain, n); + for (int i = 0; i < pad; i++) in[n + i] = (unsigned char)pad; + mbedtls_aes_crypt_cbc(&aes, MBEDTLS_AES_ENCRYPT, total, iv, in, ct); + mbedtls_aes_free(&aes); + free(in); + + memcpy(out, SESSION_MAGIC, SESSION_MAGIC_LEN); + memcpy(out + SESSION_MAGIC_LEN, iv_file, 16); + memcpy(out + SESSION_MAGIC_LEN + 16, ct, total); + *out_len = SESSION_MAGIC_LEN + 16 + total; + free(ct); + return NCM_OK; +} + +int ncm_store_cookie_decrypt(const unsigned char *in, size_t in_len, + char *out, size_t out_sz) { + if (!in || !out || !out_sz) return NCM_ERR_ARG; + if (in_len < SESSION_MAGIC_LEN + 16 || memcmp(in, SESSION_MAGIC, SESSION_MAGIC_LEN) != 0) + return NCM_ERR_CRYPTO; + unsigned char key[16]; + if (ncm_store_machine_key(SESSION_SALT, key) != 0) return NCM_ERR_CRYPTO; + const unsigned char *iv = in + SESSION_MAGIC_LEN; + size_t clen = in_len - SESSION_MAGIC_LEN - 16; + if (clen == 0 || clen % 16) return NCM_ERR_CRYPTO; + + unsigned char *pt = (unsigned char *)malloc(clen); + if (!pt) return NCM_ERR_OOM; + mbedtls_aes_context aes; + mbedtls_aes_init(&aes); + mbedtls_aes_setkey_dec(&aes, key, 128); + unsigned char iv2[16]; + memcpy(iv2, iv, 16); + mbedtls_aes_crypt_cbc(&aes, MBEDTLS_AES_DECRYPT, clen, iv2, in + SESSION_MAGIC_LEN + 16, pt); + mbedtls_aes_free(&aes); + + /* 去 PKCS7 */ + unsigned char pad = pt[clen - 1]; + if (pad < 1 || pad > 16 || (size_t)pad > clen) { free(pt); return NCM_ERR_CRYPTO; } + for (size_t i = 0; i < pad; i++) + if (pt[clen - 1 - i] != pad) { free(pt); return NCM_ERR_CRYPTO; } + size_t plen = clen - pad; + if (plen >= out_sz) { free(pt); return NCM_ERR_FULL; } + memcpy(out, pt, plen); + out[plen] = 0; + free(pt); + return NCM_OK; +} + +int ncm_store_save_session(const ncm_store_t *st, const char *cookie) { + if (!st || !cookie) return NCM_ERR_ARG; + unsigned char enc[8192]; + size_t elen = 0; + int rc = ncm_store_cookie_encrypt(cookie, enc, &elen, sizeof enc); + if (rc != NCM_OK) return rc; + char path[NCM_STORE_DIR_MAX + 16]; + snprintf(path, sizeof path, "%s/%s", st->data_dir, SESSION_FILE); + return ncm_store_write_file(path, enc, elen); +} + +int ncm_store_load_session(const ncm_store_t *st, char *cookie, size_t sz) { + if (!st || !cookie) return NCM_ERR_ARG; + char path[NCM_STORE_DIR_MAX + 16]; + snprintf(path, sizeof path, "%s/%s", st->data_dir, SESSION_FILE); + char raw[8192]; + int n = ncm_store_read_file(path, raw, sizeof raw); + if (n <= 0) return NCM_ERR_NOENT; + return ncm_store_cookie_decrypt((const unsigned char *)raw, (size_t)n, cookie, sz); +} + +int ncm_store_clear_session(const ncm_store_t *st) { + if (!st) return NCM_ERR_ARG; + char path[NCM_STORE_DIR_MAX + 16]; + snprintf(path, sizeof path, "%s/%s", st->data_dir, SESSION_FILE); + unlink(path); + return NCM_OK; +} + +int ncm_store_write_file(const char *path, const void *data, size_t len) { + if (!path || !data) return NCM_ERR_ARG; + char tmp[NCM_STORE_DIR_MAX + 32]; + snprintf(tmp, sizeof tmp, "%s.tmp", path); + int fd = open(tmp, O_WRONLY | O_CREAT | O_TRUNC, 0600); + if (fd < 0) return NCM_ERR_IO; + size_t off = 0; + while (off < len) { + ssize_t w = write(fd, (const char *)data + off, len - off); + if (w <= 0) { close(fd); unlink(tmp); return NCM_ERR_IO; } + off += (size_t)w; + } + if (fsync(fd) != 0) { close(fd); unlink(tmp); return NCM_ERR_IO; } + close(fd); + if (rename(tmp, path) != 0) { unlink(tmp); return NCM_ERR_IO; } + return NCM_OK; +} + +int ncm_store_read_file(const char *path, char *buf, size_t sz) { + if (!path || !buf || sz == 0) return NCM_ERR_ARG; + int fd = open(path, O_RDONLY); + if (fd < 0) return NCM_ERR_NOENT; + ssize_t n = read(fd, buf, sz - 1); + close(fd); + if (n < 0) return NCM_ERR_IO; + buf[n] = 0; + return (int)n; +} + +int ncm_store_read_cfg_int(const char *dir, const char *key, int def) { + if (!dir || !key) return def; + /* key 清洗(对齐 SDK:允许 [A-Za-z0-9._-],其余换 '_') */ + char k[128], out[32]; + size_t len = 0; + for (const unsigned char *p = (const unsigned char *)key; *p && len < sizeof k - 1; p++) { + unsigned char c = *p; + if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || + (c >= '0' && c <= '9') || c == '.' || c == '_' || c == '-') + k[len++] = (char)c; + else + k[len++] = '_'; + } + if (len == 0) return def; + k[len] = 0; + char path[NCM_STORE_DIR_MAX + 160]; + snprintf(path, sizeof path, "%s/%s.cfg", dir, k); + int n = ncm_store_read_file(path, out, sizeof out); + if (n <= 0) return def; + long v; + if (ncm_parse_int(out, &v) != 0) return def; + return (int)v; +} diff --git a/patch_v2/ncm_app/core/ncm_store.h b/patch_v2/ncm_app/core/ncm_store.h new file mode 100644 index 0000000..b99de93 --- /dev/null +++ b/patch_v2/ncm_app/core/ncm_store.h @@ -0,0 +1,62 @@ +/* ncm_store.h — 持久化存储层 + * + * 职责(纯 C,不依赖 UI/SDK): + * - 应用数据目录推断(env MEOW_DATA_DIR 优先,否则 /tmp 回退) + * - deviceId(52hex) 首生成 + 持久化(风控要求稳定) + * - 机器绑定密钥派生:sha256(MAC + 盐) → AES-128-CBC key(防裸读,非真安全) + * - 登录 cookie 加密落盘/读回(AES-128-CBC + 随机 IV + 魔数头) + * - 原子写文件、读取、配置键读取(/.cfg,对齐 SDK meow_config) + */ +#ifndef NCM_STORE_H +#define NCM_STORE_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define NCM_STORE_DIR_MAX 512 +#define NCM_STORE_ID_MAX 65 /* 52 hex + NUL */ + +typedef struct ncm_store { + char data_dir[NCM_STORE_DIR_MAX]; /* 无尾斜杠 */ +} ncm_store_t; + +/* 初始化数据目录。dir 为 NULL 时用 env MEOW_DATA_DIR(无则 /tmp/meowcs_)。 + * 返回 0=成功。 */ +int ncm_store_init(ncm_store_t *st, const char *dir); +const char *ncm_store_data_dir(const ncm_store_t *st); + +/* deviceId:读持久化;缺失则生成 26 随机字节 → 52hex 大写并落盘。 */ +int ncm_store_get_device_id(ncm_store_t *st, char out[NCM_STORE_ID_MAX]); +int ncm_store_set_device_id(ncm_store_t *st, const char id[NCM_STORE_ID_MAX]); + +/* 机器绑定密钥:sha256(mac + salt) 取前 16 字节作为 AES-128 key。 + * mac 取首选网卡 MAC 小写;NCM_MAC 环境变量可覆盖(测试用)。失败返回非 0。 */ +int ncm_store_machine_key(const char *salt, unsigned char key[16]); + +/* cookie 加解密(AES-128-CBC,PKCS7)。注意:这是防裸读模糊,非真安全。 */ +int ncm_store_cookie_encrypt(const char *plain, + unsigned char *out, size_t *out_len, size_t cap); +int ncm_store_cookie_decrypt(const unsigned char *in, size_t in_len, + char *out, size_t out_sz); + +/* session 加密落盘/读回:/session.enc */ +int ncm_store_save_session(const ncm_store_t *st, const char *cookie); +int ncm_store_load_session(const ncm_store_t *st, char *cookie, size_t sz); +int ncm_store_clear_session(const ncm_store_t *st); + +/* 通用原子写 / 读 / 建目录 */ +int ncm_store_write_file(const char *path, const void *data, size_t len); +int ncm_store_read_file(const char *path, char *buf, size_t sz); +int ncm_store_mkdir_p(const char *path); + +/* 读配置整型键:/.cfg(与 SDK meow_config_int 同约定)。未设/非法返回 def。 */ +int ncm_store_read_cfg_int(const char *dir, const char *key, int def); + +#ifdef __cplusplus +} +#endif +#endif /* NCM_STORE_H */ diff --git a/patch_v2/ncm_app/test/test_ncm_core.c b/patch_v2/ncm_app/test/test_ncm_core.c new file mode 100644 index 0000000..b7c46a3 --- /dev/null +++ b/patch_v2/ncm_app/test/test_ncm_core.c @@ -0,0 +1,242 @@ +/* test_ncm_core.c — 网易云核心库宿主实测 + * + * 覆盖:加密(eapi 往返/weapi 形状/linuxapi)、AES/hex/base64、 + * 缓存 LRU、设备键/cookie 加解密、二维码矩阵、以及 + * 网络接口(unikey 实拿 / 轮询 801 / 无凭据错误处理)。 + * 网络不可用时网络项按 SKIP 处理,不判失败;内部逻辑错才 FAIL。 + * 用法:test_ncm_core [data_dir](缺省 /tmp/ncm_test) + */ +#include +#include +#include + +#include "ncm.h" +#include "mbedtls/aes.h" + +static int g_fail = 0; +#define CHECK(cond, fmt, ...) do { \ + if (cond) printf(" PASS " fmt "\n", ##__VA_ARGS__); \ + else { printf(" FAIL " fmt "\n", ##__VA_ARGS__); g_fail = 1; } \ +} while (0) + +#define CHECKRC(expr, fmt, ...) do { \ + int _r = (expr); \ + if (_r == NCM_OK) printf(" PASS " fmt "\n", ##__VA_ARGS__); \ + else { printf(" FAIL " fmt " (rc=%d)\n", ##__VA_ARGS__, _r); g_fail = 1; } \ +} while (0) + +/* ---------- 辅助: AES-128-ECB 解密回明文(验证 eapi 往返) ---------- */ +static int aes_ecb_decrypt_hex(const char *hex_upper, const unsigned char *key, char *out, size_t out_sz) { + int nbytes = strlen(hex_upper) / 2; + unsigned char *ct = malloc((size_t)nbytes); + unsigned char *pt = malloc((size_t)nbytes); + unsigned char *kv = malloc(16); + if (!ct || !pt || !kv) return -1; + kv[0]=0; + memcpy(kv, key, 16); + for (int i = 0; i < nbytes; i++) { + int hi, lo; + char a = hex_upper[i*2], b = hex_upper[i*2+1]; + hi = (a <= '9') ? a-'0' : (a <= 'F' ? a-'A'+10 : a-'a'+10); + lo = (b <= '9') ? b-'0' : (b <= 'F' ? b-'A'+10 : b-'a'+10); + ct[i] = (unsigned char)((hi<<4)|lo); + } + mbedtls_aes_context aes; mbedtls_aes_init(&aes); + mbedtls_aes_setkey_dec(&aes, kv, 128); + for (int off = 0; off < nbytes; off += 16) + mbedtls_aes_crypt_ecb(&aes, MBEDTLS_AES_DECRYPT, ct+off, pt+off); + mbedtls_aes_free(&aes); + /* 去 PKCS7 */ + int pad = pt[nbytes-1]; + if (pad < 1 || pad > 16 || pad > nbytes) { free(ct);free(pt);free(kv); return -1; } + int plen = nbytes - pad; + if ((size_t)plen >= out_sz) { free(ct);free(pt);free(kv); return -1; } + memcpy(out, pt, (size_t)plen); out[plen] = 0; + free(ct); free(pt); free(kv); + return plen; +} + +static void test_crypto(void) { + printf("== crypto ==\n"); + /* eapi 往返 */ + char params[2048]; + CHECKRC(ncm_crypto_eapi("/api/login/qrcode/unikey", "{\"type\":3}", params, sizeof params), + "eapi params produced"); + char plain[2048]; + int pl = aes_ecb_decrypt_hex(params, (const unsigned char *)NCM_EAPI_KEY, plain, sizeof plain); + CHECK(pl > 0, "eapi params decrypts (%d bytes)", pl); + if (pl > 0) { + CHECK(strstr(plain, "/api/login/qrcode/unikey") != NULL, "eapi url present in plain"); + CHECK(strstr(plain, "{\"type\":3}") != NULL, "eapi json present in plain"); + } + /* weapi 形状 */ + char p2[1024], es[300]; + CHECKRC(ncm_crypto_weapi("{\"id\":123}", p2, sizeof p2, es, sizeof es), "weapi produced"); + CHECK(strlen(es) == 256, "weapi encSecKey is 256 hex (got %zu)", strlen(es)); + CHECK(p2[0] != 0, "weapi params non-empty"); + /* linuxapi */ + char lp[2048]; + CHECKRC(ncm_crypto_linuxapi("{\"a\":1}", lp, sizeof lp), "linuxapi produced"); +} + +static void test_store_cookie(void) { + printf("== store/device/cookie ==\n"); + ncm_store_t st; + ncm_store_init(&st, NULL); /* env MEOW_DATA_DIR 或 /tmp */ + char id1[NCM_STORE_ID_MAX], id2[NCM_STORE_ID_MAX]; + ncm_store_get_device_id(&st, id1); + ncm_store_get_device_id(&st, id2); + CHECK(strcmp(id1, id2) == 0, "deviceId stable across calls"); + CHECK(strlen(id1) == 52, "deviceId length 52 (got %zu)", strlen(id1)); + unsigned char kb[8192]; + size_t klen; + const char *cs = "MUSIC_U=abcdef123456; __csrf=xyz; os=pc"; + CHECKRC(ncm_store_cookie_encrypt(cs, kb, &klen, sizeof kb), "cookie encrypt"); + char cs2[4096]; + CHECKRC(ncm_store_cookie_decrypt(kb, klen, cs2, sizeof cs2), "cookie decrypt"); + CHECK(strcmp(cs, cs2) == 0, "cookie roundtrip matches"); + /* 机器密钥可派生且 16 字节 */ + unsigned char key[16]; + CHECK(ncm_store_machine_key("t", key) == 0, "machine key derivable"); +} + +static void test_cache(void) { + printf("== cache ==\n"); + ncm_cache_t c; + char dir[] = "/tmp/ncm_cache_test"; + ncm_cache_init(&c, dir); + /* 清空目录 */ + { + char cmd[128]; + snprintf(cmd, sizeof cmd, "rm -rf %s; mkdir -p %s", dir, dir); + if (system(cmd) != 0) { /* best-effort */ } + } + /* miss */ + char path[NCM_CACHE_DIR_MAX + 32]; + int mrc = ncm_cache_lookup(&c, "1", "mp3", path, sizeof path); + CHECK(mrc == NCM_ERR_NOENT, "lookup miss returns NOENT (rc=%d)", mrc); + /* write + commit */ + ncm_cache_writer_t *w; + CHECKRC(ncm_cache_open(&c, "100", "mp3", &w), "cache open"); + CHECKRC(ncm_cache_write(w, (const unsigned char *)"AUDIODATA", 9), "cache write"); + CHECKRC(ncm_cache_commit(w), "cache commit"); + CHECKRC(ncm_cache_lookup(&c, "100", "mp3", path, sizeof path), "lookup hit"); + CHECK(strstr(path, "song_100.mp3") != NULL, "hit path name"); + CHECK(ncm_cache_total_bytes(&c) >= 9, "total_bytes >= 9"); + /* abort leaves nothing */ + ncm_cache_writer_t *w2; + ncm_cache_open(&c, "101", "mp3", &w2); + ncm_cache_write(w2, (const unsigned char *)"x", 1); + ncm_cache_abort(w2); + int arc = ncm_cache_lookup(&c, "101", "mp3", path, sizeof path); + CHECK(arc == NCM_ERR_NOENT, "aborted not cached (rc=%d)", arc); + /* 强制小上限测 LRU 淘汰:设 limit_bytes 极小,写入第二首歌触发淘汰 */ + c.limit_bytes = 5; /* 仅 5 字节,任何条目超限 */ + ncm_cache_writer_t *w3; + ncm_cache_open(&c, "102", "mp3", &w3); + ncm_cache_write(w3, (const unsigned char *)"abcdefgh", 8); + ncm_cache_commit(w3); + ncm_cache_evict(&c); + CHECK(ncm_cache_total_bytes(&c) <= 5, "evict kept total <= limit (%llu bytes)", + (unsigned long long)ncm_cache_total_bytes(&c)); + /* 恢复默认上限 */ + ncm_cache_set_limit_gb(&c, 10); + CHECK(ncm_cache_limit_gb(&c) == 10, "limit_gb reset to 10"); +} + +static void test_qr(void) { + printf("== qrcodegen ==\n"); + unsigned char mods[177 * 177]; + int size = 0; + CHECKRC(ncm_login_qr_matrix("https://music.163.com/login?codekey=test-uuid-1234", mods, 177, &size), + "qr matrix"); + CHECK(size >= 21 && size <= 177, "qr size sane (got %d)", size); + int dark = 0; + for (int i = 0; i < size*size; i++) if (mods[i]) dark++; + CHECK(dark > 0, "qr has dark modules (%d)", dark); +} + +static void test_crypto_vectors(void) { + /* 交叉:固定密文来源已在 rsa_raw_test 验证;这里仅核对 eapi 对已知 JSON 的确定性。 */ + printf("== known eapi (deterministic) ==\n"); + char a[2048], b[2048]; + ncm_crypto_eapi("/api/x", "{\"k\":1}", a, sizeof a); + ncm_crypto_eapi("/api/x", "{\"k\":1}", b, sizeof b); + CHECK(strcmp(a, b) == 0, "eapi deterministic for same input"); +} + +static void test_network(void) { + printf("== network (live) ==\n"); + int net_ok = 0; + char device_id[NCM_STORE_ID_MAX]; + ncm_store_t st; ncm_store_init(&st, NULL); + ncm_store_get_device_id(&st, device_id); + + /* unikey 实拿 */ + char unikey[64] = ""; + int rc = ncm_login_unikey(device_id, unikey, sizeof unikey); + if (rc == NCM_OK && unikey[0]) { + net_ok = 1; + printf(" PASS unikey = %s\n", unikey); + char qurl[256]; + ncm_login_qr_url(unikey, qurl, sizeof qurl); + CHECK(strstr(qurl, "codekey=") != NULL, "qr url built : %s", qurl); + /* 轮询(未扫码,期望 801 等待扫码,或无效 key 800 过期) */ + char cookiebuf[1024]; + ncm_login_poll_t pr; + rc = ncm_login_poll(device_id, unikey, NULL, &pr, cookiebuf, sizeof cookiebuf); + if (rc == NCM_OK) { + printf(" PASS poll code=%d state=%d msg=%s\n", pr.code, pr.state, pr.message); + if (pr.state == NCM_LOGIN_PENDING) + printf(" PASS state=等待扫码(801)\n"); + else + printf(" NOTE state=%d (code=%d), 非 801(可能已过期/已扫码)\n", pr.state, pr.code); + } else { + printf(" SKIP poll rc=%d (网络/被拒)\n", rc); + } + } else { + printf(" SKIP unikey rc=%d (网络不可达?) %s\n", rc, rc != NCM_OK ? "网络/证书" : ""); + } + + /* 无凭据/无效凭据的错误处理:不应崩溃,且应给出可判定的失败 */ + printf("-- no-credential error handling --\n"); + /* 伪造 MUSIC_U → guest → profile null → NCM_ERR_AUTH */ + int r2 = ncm_login_status_check(device_id, "MUSIC_U=deadbeef0000", NULL, 0, NULL, 0); + printf(" NOTE login_status(bogus cookie) rc=%d\n", r2); + CHECK(r2 != NCM_OK, "login_status(bogus) not OK (rc=%d)", r2); + + /* 无 cookie 也应优雅返回(可能 200 公开数据,或错误码)——只验证不崩溃且计数合法 */ + ncm_playlist_t pls[8]; int pn = 0; + int r3 = ncm_api_user_playlist(device_id, "", "0", 30, 0, pls, 8, &pn); + printf(" NOTE user_playlist(uid=0, no cookie) rc=%d count=%d%s\n", + r3, pn, pn > 0 ? " (公开数据)" : ""); + CHECK(r3 == NCM_OK || r3 < 0, "user_playlist no-cred graceful (rc=%d)", r3); + CHECK(pn >= 0, "user_playlist count sane (%d)", pn); + + /* 无效 id → url 为 null,应无人可播 */ + ncm_play_url_t pu; + int r4 = ncm_api_song_url(device_id, "", "0", NCM_LEVEL_HIGHER, &pu); + printf(" NOTE song_url(id=0) rc=%d url='%s'\n", r4, pu.url); + CHECK(r4 != NCM_OK || !pu.url[0], "song_url(bogus id) no url (rc=%d)", r4); + + if (!net_ok) printf(" SKIP network live checks (host unreachable or TLS CA missing)\n"); +} + +int main(int argc, char **argv) { + const char *data_dir = (argc > 1) ? argv[1] : "/tmp/ncm_test"; + printf("ncm_core self-test, data_dir=%s\n", data_dir); + ncm_ctx_t ctx; + ncm_ctx_init(&ctx, data_dir); + printf("deviceId=%s\n", ctx.device_id); + printf("cache_dir=%s limit_gb=%d\n", ctx.cache.dir, ctx.cache.limit_gb); + + test_crypto(); + test_crypto_vectors(); + test_store_cookie(); + test_cache(); + test_qr(); + test_network(); + + printf("\n%s\n", g_fail ? "== RESULT: FAIL ==" : "== RESULT: PASS =="); + return g_fail ? 1 : 0; +} diff --git a/patch_v2/ncm_app/test/test_ncm_core_host b/patch_v2/ncm_app/test/test_ncm_core_host new file mode 100755 index 0000000000000000000000000000000000000000..ec123ba3ed95a167dd20464e316c9d6475c126eb GIT binary patch literal 553848 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 z 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