diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index e4c3d42..530da91 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -4,6 +4,7 @@ "name": "MinGW64", "includePath": [ "${workspaceFolder}/include", + "${workspaceFolder}/qrcodegen", "${workspaceFolder}", "C:\\MinGW64\\include", "C:\\MinGW64\\x86_64-w64-mingw32\\include" diff --git a/CMakeLists.txt b/CMakeLists.txt index 922cffb..10d9649 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,12 +1,39 @@ cmake_minimum_required(VERSION 3.15) set(CMAKE_BUILD_TYPE Release) +option(USE_SYSTEM_CURL "use system installed libcurl" ON) find_package(mbedtls REQUIRED) -find_package(CURL REQUIRED) + +if (USE_SYSTEM_CURL) + find_package(CURL REQUIRED) +else () + include(FetchContent) + FetchContent_Declare(curl + URL https://curl.se/download/curl-8.16.0.tar.xz + DOWNLOAD_EXTRACT_TIMESTAMP TRUE + ) + set(ZLIB_USE_STATIC_LIBS ON) + set(CURL_USE_MBEDTLS ON) + set(HTTP_ONLY ON) + set(BUILD_CURL_EXE OFF) + set(BUILD_TESTING OFF) + set(BUILD_EXAMPLES OFF) + set(BUILD_LIBCURL_DOCS OFF) + set(BUILD_MISC_DOCS OFF) + set(ENABLE_CURL_MANUAL OFF) + set(USE_NGHTTP2 OFF) + set(USE_LIBIDN2 OFF) + set(CURL_BROTLI OFF) + set(CURL_ZSTD OFF) + set(CURL_USE_LIBSSH2 OFF) + set(CURL_USE_LIBPSL OFF) + set(CURL_DISABLE_PROGRESS_METER ON) + FetchContent_MakeAvailable(curl) +endif () project(clist) -file(GLOB_RECURSE MAIN_SRC "${CMAKE_SOURCE_DIR}/src/*.cpp") +file(GLOB_RECURSE MAIN_SRC "${CMAKE_SOURCE_DIR}/src/*.cpp" "qrcodegen/qrcodegen.c") add_executable(${PROJECT_NAME} ${MAIN_SRC}) target_include_directories(${PROJECT_NAME} PRIVATE include qrcodegen) -target_link_libraries(${PROJECT_NAME} PRIVATE mbedtls CURL::libcurl) \ No newline at end of file +target_link_libraries(${PROJECT_NAME} PRIVATE fmt mbedcrypto CURL::libcurl bcrypt) \ No newline at end of file diff --git a/include/drive.h b/include/drive.h index 56874ad..6624609 100644 --- a/include/drive.h +++ b/include/drive.h @@ -4,6 +4,8 @@ #include #include +namespace drive { + enum drive_type { dt_alipan, dt_filebrowser, @@ -35,3 +37,5 @@ drive::ref new_drive(drive_type type); std::string hex_encode(const unsigned char* data, size_t len); std::string device_name(); + +} \ No newline at end of file diff --git a/src/drive/alipan.cpp b/src/drive/alipan.cpp index d7ba257..98ebc30 100644 --- a/src/drive/alipan.cpp +++ b/src/drive/alipan.cpp @@ -10,6 +10,8 @@ #include #include +namespace drive { + using json = nlohmann::json; namespace fs = std::filesystem; @@ -116,7 +118,7 @@ bool alipan::qrLogin(fnQrcode printQr) { this->refresh_token = login.at("refreshToken"); // 计算设备ID unsigned char digest[32]; - mbedtls_sha256_ret((uint8_t*)this->user_id.c_str(), this->user_id.size(), digest, 0); + mbedtls_sha256((uint8_t*)this->user_id.c_str(), this->user_id.size(), digest, 0); this->device_id = hex_encode(digest, sizeof(digest)); fmt::print("login user_id({}) drive_id({})\n", this->user_id, this->drive_id); @@ -307,18 +309,19 @@ bool alipan::createSession() { size_t pub_len = 0; std::vector pub(MBEDTLS_ECP_MAX_BYTES, 0); mbedtls_ecp_point_write_binary( - &ctx_sign.grp, &ctx_sign.Q, MBEDTLS_ECP_PF_UNCOMPRESSED, &pub_len, pub.data(), pub.size()); + &ctx_sign.private_grp, &ctx_sign.private_Q, MBEDTLS_ECP_PF_UNCOMPRESSED, &pub_len, pub.data(), pub.size()); pub_key = hex_encode(pub.data(), pub_len); // sign message unsigned char msg_hash[32]; - mbedtls_sha256_ret((uint8_t*)msg.c_str(), msg.size(), msg_hash, 0); + mbedtls_sha256((uint8_t*)msg.c_str(), msg.size(), msg_hash, 0); mbedtls_mpi r, s; std::vector sigdata(MBEDTLS_ECDSA_MAX_LEN, 0); mbedtls_mpi_init(&r); mbedtls_mpi_init(&s); - mbedtls_ecdsa_sign(&ctx_sign.grp, &r, &s, &ctx_sign.d, msg_hash, sizeof(msg_hash), mbd_rand, nullptr); + mbedtls_ecdsa_sign( + &ctx_sign.private_grp, &r, &s, &ctx_sign.private_d, msg_hash, sizeof(msg_hash), mbd_rand, nullptr); size_t plen = mbedtls_mpi_size(&r); mbedtls_mpi_write_binary(&r, sigdata.data(), plen); @@ -343,4 +346,6 @@ bool alipan::createSession() { {"device_id", this->device_id}, }); return j.at("success").get(); -} \ No newline at end of file +} + +} // namespace drive \ No newline at end of file diff --git a/src/drive/alipan.h b/src/drive/alipan.h index f3282f5..7788a63 100644 --- a/src/drive/alipan.h +++ b/src/drive/alipan.h @@ -4,6 +4,8 @@ #include "http.h" #include "drive.h" +namespace drive { + class alipan : public drive { public: bool qrLogin(fnQrcode printQr) override; @@ -28,4 +30,6 @@ private: std::string drive_id; std::string user_id; -}; \ No newline at end of file +}; + +} \ No newline at end of file diff --git a/src/drive/drive.cpp b/src/drive/drive.cpp index b6cf6b3..c1b31d2 100644 --- a/src/drive/drive.cpp +++ b/src/drive/drive.cpp @@ -1,5 +1,7 @@ #include "alipan.h" +namespace drive { + static std::map m; drive::ref new_drive(drive_type type) { @@ -15,4 +17,6 @@ drive::ref new_drive(drive_type type) { m.insert(std::make_pair(type, it->second)); } return it->second; +} + } \ No newline at end of file diff --git a/src/drive/misc.cpp b/src/drive/misc.cpp index 4f47bf8..7d5521e 100644 --- a/src/drive/misc.cpp +++ b/src/drive/misc.cpp @@ -15,7 +15,7 @@ #include #endif -std::string hex_encode(const unsigned char* data, size_t len) { +std::string drive::hex_encode(const unsigned char* data, size_t len) { std::stringstream ss; for (size_t i = 0; i < len; i++) ss << std::hex << std::setw(2) << std::setfill('0') << (int)data[i]; return ss.str(); @@ -36,7 +36,7 @@ std::string ansi_to_utf8(const char* locale, std::string const& str_gbk) { return cutf8.to_bytes(std::wstring(buff.data(), to_next)); } -std::string device_name() { +std::string drive::device_name() { #ifdef __SWITCH__ SetSysDeviceNickName nick; if (R_SUCCEEDED(setsysGetDeviceNickname(&nick))) { diff --git a/src/main.cpp b/src/main.cpp index 7a6bf49..bee2cb5 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,6 +1,6 @@ #include "http.h" #include "drive.h" -#include +#include #include void printQr(const std::string& text) { @@ -23,7 +23,7 @@ void printQr(const std::string& text) { int main(int argc, char* argv[]) { curl_global_init(CURL_GLOBAL_ALL); - drive::ref c = new_drive(dt_alipan); + auto c = drive::new_drive(drive::dt_alipan); if (!c->qrLogin(printQr)) return 1; uint32_t choice = 0;