diff --git a/trunk/PKGBUILD b/trunk/PKGBUILD index e188853..24f08d7 100644 --- a/trunk/PKGBUILD +++ b/trunk/PKGBUILD @@ -11,17 +11,23 @@ license=(MIT) makedepends=(gtk3 intltool curl qt5-base libevent systemd qt5-tools libappindicator-gtk3 libnatpmp miniupnpc cmake) source=(https://github.com/transmission/transmission-releases/raw/master/transmission-${pkgver}.tar.xz transmission-3.00-tarball-missing-files.patch # https://github.com/transmission/transmission/issues/1248 + transmission-3.00-arc4.patch # based on https://github.com/transmission/transmission/commit/a459e5e11b2d2524b649f7487368de30c8d2af21 + arc4-1.0.0.tar.gz::https://github.com/transmission/arc4/archive/refs/tags/v1.0.0.tar.gz transmission-cli.sysusers transmission-cli.tmpfiles) sha256sums=('9144652fe742f7f7dd6657716e378da60b751aaeda8bef8344b3eefc4db255f2' '25717d638b84f368ae3e8ba17f26a17eb1f5767c1218946c7c03ee9fbaaf9b5d' + '8f07c225959fe11ea473cc6012eba5dad603b70b2c1a9ac5617499424af1655c' + 'dd098dd34be65c81e8dd1e984e031b66346350909132b3b5af80e76d60aa55f1' '641310fb0590d40e00bea1b5b9c843953ab78edf019109f276be9c6a7bdaf5b2' '1266032bb07e47d6bcdc7dabd74df2557cc466c33bf983a5881316a4cc098451') prepare() { cd $pkgbase-$pkgver + mv ../arc4-1.0.0 third-party/arc4 patch -p1 -i ../transmission-3.00-tarball-missing-files.patch + patch -p1 -i ../transmission-3.00-arc4.patch sed -i '/^Icon=/ s/$/-qt/' qt/transmission-qt.desktop } @@ -30,10 +36,16 @@ build() { cmake -B build -S $pkgbase-$pkgver \ -D CMAKE_INSTALL_PREFIX='/usr' \ -D ENABLE_CLI=TRUE \ + -D ENABLE_TESTS=TRUE \ -Wno-dev cmake --build build } +check() { + cd build + ctest --output-on-failure +} + package_transmission-cli() { pkgdesc='Fast, easy, and free BitTorrent client (CLI tools, daemon)' depends=(curl libevent libnatpmp miniupnpc systemd) diff --git a/trunk/transmission-3.00-arc4.patch b/trunk/transmission-3.00-arc4.patch new file mode 100644 index 0000000..712db9f --- /dev/null +++ b/trunk/transmission-3.00-arc4.patch @@ -0,0 +1,445 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 62bf87be7..0607620d8 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -334,6 +334,8 @@ endif() + + tr_add_external_auto_library(B64 libb64 b64) + ++add_subdirectory(third-party/arc4) ++ + if(WITH_INOTIFY) + tr_get_required_flag(WITH_INOTIFY INOTIFY_IS_REQUIRED) + +diff --git a/libtransmission/CMakeLists.txt b/libtransmission/CMakeLists.txt +index 672cd0e0b..62b68b948 100644 +--- a/libtransmission/CMakeLists.txt ++++ b/libtransmission/CMakeLists.txt +@@ -274,6 +274,7 @@ target_link_libraries(${TR_NAME} + ${LIBINTL_LIBRARY} + ${LIBM_LIBRARY} + ${TR_NETWORK_LIBRARIES} ++ arc4::arc4 + ) + + if(ICONV_FOUND) +diff --git a/libtransmission/crypto-test-ref.h b/libtransmission/crypto-test-ref.h +index d809ebb0b..6ab8b11ed 100644 +--- a/libtransmission/crypto-test-ref.h ++++ b/libtransmission/crypto-test-ref.h +@@ -16,7 +16,6 @@ + #define KEY_LEN KEY_LEN_ + + #define tr_sha1_ctx_t tr_sha1_ctx_t_ +-#define tr_rc4_ctx_t tr_rc4_ctx_t_ + #define tr_dh_ctx_t tr_dh_ctx_t_ + #define tr_dh_secret_t tr_dh_secret_t_ + #define tr_ssl_ctx_t tr_ssl_ctx_t_ +@@ -39,10 +38,6 @@ + #define tr_sha1_init tr_sha1_init_ + #define tr_sha1_update tr_sha1_update_ + #define tr_sha1_final tr_sha1_final_ +-#define tr_rc4_new tr_rc4_new_ +-#define tr_rc4_free tr_rc4_free_ +-#define tr_rc4_set_key tr_rc4_set_key_ +-#define tr_rc4_process tr_rc4_process_ + #define tr_dh_new tr_dh_new_ + #define tr_dh_free tr_dh_free_ + #define tr_dh_make_key tr_dh_make_key_ +@@ -80,7 +75,6 @@ + #undef KEY_LEN_ + + #undef tr_sha1_ctx_t +-#undef tr_rc4_ctx_t + #undef tr_dh_ctx_t + #undef tr_dh_secret_t + #undef tr_ssl_ctx_t +@@ -103,10 +97,6 @@ + #undef tr_sha1_init + #undef tr_sha1_update + #undef tr_sha1_final +-#undef tr_rc4_new +-#undef tr_rc4_free +-#undef tr_rc4_set_key +-#undef tr_rc4_process + #undef tr_dh_new + #undef tr_dh_free + #undef tr_dh_make_key +@@ -137,7 +127,6 @@ + #define KEY_LEN_ KEY_LEN + + #define tr_sha1_ctx_t_ tr_sha1_ctx_t +-#define tr_rc4_ctx_t_ tr_rc4_ctx_t + #define tr_dh_ctx_t_ tr_dh_ctx_t + #define tr_dh_secret_t_ tr_dh_secret_t + #define tr_ssl_ctx_t_ tr_ssl_ctx_t +@@ -160,10 +149,6 @@ + #define tr_sha1_init_ tr_sha1_init + #define tr_sha1_update_ tr_sha1_update + #define tr_sha1_final_ tr_sha1_final +-#define tr_rc4_new_ tr_rc4_new +-#define tr_rc4_free_ tr_rc4_free +-#define tr_rc4_set_key_ tr_rc4_set_key +-#define tr_rc4_process_ tr_rc4_process + #define tr_dh_new_ tr_dh_new + #define tr_dh_free_ tr_dh_free + #define tr_dh_make_key_ tr_dh_make_key +diff --git a/libtransmission/crypto-utils-cyassl.c b/libtransmission/crypto-utils-cyassl.c +index 60659ff85..a95bfb53d 100644 +--- a/libtransmission/crypto-utils-cyassl.c ++++ b/libtransmission/crypto-utils-cyassl.c +@@ -19,7 +19,6 @@ + #define API_VERSION_HEX LIBCYASSL_VERSION_HEX + #endif + +-#include API_HEADER_CRYPT(arc4.h) + #include API_HEADER_CRYPT(dh.h) + #include API_HEADER_CRYPT(error-crypt.h) + #include API_HEADER_CRYPT(random.h) +@@ -166,44 +165,6 @@ bool tr_sha1_final(tr_sha1_ctx_t handle, uint8_t* hash) + /*** + **** + ***/ +- +-tr_rc4_ctx_t tr_rc4_new(void) +-{ +- return tr_new0(Arc4, 1); +-} +- +-void tr_rc4_free(tr_rc4_ctx_t handle) +-{ +- tr_free(handle); +-} +- +-void tr_rc4_set_key(tr_rc4_ctx_t handle, uint8_t const* key, size_t key_length) +-{ +- TR_ASSERT(handle != NULL); +- TR_ASSERT(key != NULL); +- +- API(Arc4SetKey)(handle, key, key_length); +-} +- +-void tr_rc4_process(tr_rc4_ctx_t handle, void const* input, void* output, size_t length) +-{ +- TR_ASSERT(handle != NULL); +- +- if (length == 0) +- { +- return; +- } +- +- TR_ASSERT(input != NULL); +- TR_ASSERT(output != NULL); +- +- API(Arc4Process)(handle, output, input, length); +-} +- +-/*** +-**** +-***/ +- + tr_dh_ctx_t tr_dh_new(uint8_t const* prime_num, size_t prime_num_length, uint8_t const* generator_num, + size_t generator_num_length) + { +diff --git a/libtransmission/crypto-utils-openssl.c b/libtransmission/crypto-utils-openssl.c +index 45fd71913..ca6909e48 100644 +--- a/libtransmission/crypto-utils-openssl.c ++++ b/libtransmission/crypto-utils-openssl.c +@@ -182,59 +182,6 @@ static void openssl_evp_cipher_context_free(EVP_CIPHER_CTX* handle) + + #endif + +-tr_rc4_ctx_t tr_rc4_new(void) +-{ +- EVP_CIPHER_CTX* handle = EVP_CIPHER_CTX_new(); +- +- if (check_result(EVP_CipherInit_ex(handle, EVP_rc4(), NULL, NULL, NULL, -1))) +- { +- return handle; +- } +- +- EVP_CIPHER_CTX_free(handle); +- return NULL; +-} +- +-void tr_rc4_free(tr_rc4_ctx_t handle) +-{ +- if (handle == NULL) +- { +- return; +- } +- +- EVP_CIPHER_CTX_free(handle); +-} +- +-void tr_rc4_set_key(tr_rc4_ctx_t handle, uint8_t const* key, size_t key_length) +-{ +- TR_ASSERT(handle != NULL); +- TR_ASSERT(key != NULL); +- +- if (!check_result(EVP_CIPHER_CTX_set_key_length(handle, key_length))) +- { +- return; +- } +- +- check_result(EVP_CipherInit_ex(handle, NULL, NULL, key, NULL, -1)); +-} +- +-void tr_rc4_process(tr_rc4_ctx_t handle, void const* input, void* output, size_t length) +-{ +- TR_ASSERT(handle != NULL); +- +- if (length == 0) +- { +- return; +- } +- +- TR_ASSERT(input != NULL); +- TR_ASSERT(output != NULL); +- +- int output_length; +- +- check_result(EVP_CipherUpdate(handle, output, &output_length, input, length)); +-} +- + /*** + **** + ***/ +diff --git a/libtransmission/crypto-utils-polarssl.c b/libtransmission/crypto-utils-polarssl.c +index 889332a3a..8f9afeea3 100644 +--- a/libtransmission/crypto-utils-polarssl.c ++++ b/libtransmission/crypto-utils-polarssl.c +@@ -186,53 +186,6 @@ bool tr_sha1_final(tr_sha1_ctx_t handle, uint8_t* hash) + **** + ***/ + +-tr_rc4_ctx_t tr_rc4_new(void) +-{ +- api_arc4_context* handle = tr_new0(api_arc4_context, 1); +- +-#if API_VERSION_NUMBER >= 0x01030800 +- API(arc4_init)(handle); +-#endif +- +- return handle; +-} +- +-void tr_rc4_free(tr_rc4_ctx_t handle) +-{ +-#if API_VERSION_NUMBER >= 0x01030800 +- API(arc4_free)(handle); +-#endif +- +- tr_free(handle); +-} +- +-void tr_rc4_set_key(tr_rc4_ctx_t handle, uint8_t const* key, size_t key_length) +-{ +- TR_ASSERT(handle != NULL); +- TR_ASSERT(key != NULL); +- +- API(arc4_setup)(handle, key, key_length); +-} +- +-void tr_rc4_process(tr_rc4_ctx_t handle, void const* input, void* output, size_t length) +-{ +- TR_ASSERT(handle != NULL); +- +- if (length == 0) +- { +- return; +- } +- +- TR_ASSERT(input != NULL); +- TR_ASSERT(output != NULL); +- +- API(arc4_crypt)(handle, length, input, output); +-} +- +-/*** +-**** +-***/ +- + tr_dh_ctx_t tr_dh_new(uint8_t const* prime_num, size_t prime_num_length, uint8_t const* generator_num, + size_t generator_num_length) + { +diff --git a/libtransmission/crypto-utils.c b/libtransmission/crypto-utils.c +index 329adc009..bc6ae0e72 100644 +--- a/libtransmission/crypto-utils.c ++++ b/libtransmission/crypto-utils.c +@@ -10,6 +10,7 @@ + #include /* abs(), srand(), rand() */ + #include /* memcpy(), memmove(), memset(), strcmp(), strlen() */ + ++#include + #include + #include + +diff --git a/libtransmission/crypto-utils.h b/libtransmission/crypto-utils.h +index 7ae3cee86..9c223d00e 100644 +--- a/libtransmission/crypto-utils.h ++++ b/libtransmission/crypto-utils.h +@@ -27,8 +27,6 @@ extern "C" + + /** @brief Opaque SHA1 context type. */ + typedef void* tr_sha1_ctx_t; +-/** @brief Opaque RC4 context type. */ +-typedef void* tr_rc4_ctx_t; + /** @brief Opaque DH context type. */ + typedef void* tr_dh_ctx_t; + /** @brief Opaque DH secret key type. */ +@@ -60,26 +58,6 @@ bool tr_sha1_update(tr_sha1_ctx_t handle, void const* data, size_t data_length); + */ + bool tr_sha1_final(tr_sha1_ctx_t handle, uint8_t* hash); + +-/** +- * @brief Allocate and initialize new RC4 cipher context. +- */ +-tr_rc4_ctx_t tr_rc4_new(void); +- +-/** +- * @brief Free RC4 cipher context. +- */ +-void tr_rc4_free(tr_rc4_ctx_t handle); +- +-/** +- * @brief Set RC4 cipher key. +- */ +-void tr_rc4_set_key(tr_rc4_ctx_t handle, uint8_t const* key, size_t key_length); +- +-/** +- * @brief Process memory block with RC4 cipher. +- */ +-void tr_rc4_process(tr_rc4_ctx_t handle, void const* input, void* output, size_t length); +- + /** + * @brief Allocate and initialize new Diffie-Hellman (DH) key exchange context. + */ +diff --git a/libtransmission/crypto.c b/libtransmission/crypto.c +index e64b998df..289f6dbb9 100644 +--- a/libtransmission/crypto.c ++++ b/libtransmission/crypto.c +@@ -8,6 +8,8 @@ + + #include /* memcpy(), memmove(), memset() */ + ++#include ++ + #include "transmission.h" + #include "crypto.h" + #include "crypto-utils.h" +@@ -64,8 +66,8 @@ void tr_cryptoDestruct(tr_crypto* crypto) + { + tr_dh_secret_free(crypto->mySecret); + tr_dh_free(crypto->dh); +- tr_rc4_free(crypto->enc_key); +- tr_rc4_free(crypto->dec_key); ++ tr_free(crypto->enc_key); ++ tr_free(crypto->dec_key); + } + + /** +@@ -90,36 +92,27 @@ uint8_t const* tr_cryptoGetMyPublicKey(tr_crypto const* crypto, int* setme_len) + *** + **/ + +-static void initRC4(tr_crypto* crypto, tr_rc4_ctx_t* setme, char const* key) ++static void init_rc4(tr_crypto const* crypto, struct arc4_context** setme, char const* key) + { + TR_ASSERT(crypto->torrentHashIsSet); + + if (*setme == NULL) + { +- *setme = tr_rc4_new(); ++ *setme = tr_new0(struct arc4_context, 1); + } + + uint8_t buf[SHA_DIGEST_LENGTH]; + + if (tr_cryptoSecretKeySha1(crypto, key, 4, crypto->torrentHash, SHA_DIGEST_LENGTH, buf)) + { +- tr_rc4_set_key(*setme, buf, SHA_DIGEST_LENGTH); ++ arc4_init(*setme, buf, SHA_DIGEST_LENGTH); ++ arc4_discard(*setme, 1024); + } + } + +-void tr_cryptoDecryptInit(tr_crypto* crypto) +-{ +- uint8_t discard[1024]; +- char const* txt = crypto->isIncoming ? "keyA" : "keyB"; +- +- initRC4(crypto, &crypto->dec_key, txt); +- tr_rc4_process(crypto->dec_key, discard, discard, sizeof(discard)); +-} +- +-void tr_cryptoDecrypt(tr_crypto* crypto, size_t buf_len, void const* buf_in, void* buf_out) ++static void crypt_rc4(struct arc4_context* key, size_t buf_len, void const* buf_in, void* buf_out) + { +- /* FIXME: someone calls this function with uninitialized key */ +- if (crypto->dec_key == NULL) ++ if (key == NULL) + { + if (buf_in != buf_out) + { +@@ -129,32 +122,27 @@ void tr_cryptoDecrypt(tr_crypto* crypto, size_t buf_len, void const* buf_in, voi + return; + } + +- tr_rc4_process(crypto->dec_key, buf_in, buf_out, buf_len); ++ arc4_process(key, buf_in, buf_out, buf_len); + } + +-void tr_cryptoEncryptInit(tr_crypto* crypto) ++void tr_cryptoDecryptInit(tr_crypto* crypto) + { +- uint8_t discard[1024]; +- char const* txt = crypto->isIncoming ? "keyB" : "keyA"; +- +- initRC4(crypto, &crypto->enc_key, txt); +- tr_rc4_process(crypto->enc_key, discard, discard, sizeof(discard)); ++ init_rc4(crypto, &crypto->dec_key, crypto->isIncoming ? "keyA" : "keyB"); // lgtm[cpp/weak-cryptographic-algorithm] + } + +-void tr_cryptoEncrypt(tr_crypto* crypto, size_t buf_len, void const* buf_in, void* buf_out) ++void tr_cryptoDecrypt(tr_crypto* crypto, size_t buf_len, void const* buf_in, void* buf_out) + { +- /* FIXME: someone calls this function with uninitialized key */ +- if (crypto->enc_key == NULL) +- { +- if (buf_in != buf_out) +- { +- memmove(buf_out, buf_in, buf_len); +- } ++ crypt_rc4(crypto->dec_key, buf_len, buf_in, buf_out); // lgtm[cpp/weak-cryptographic-algorithm] ++} + +- return; +- } ++void tr_cryptoEncryptInit(tr_crypto* crypto) ++{ ++ init_rc4(crypto, &crypto->enc_key, crypto->isIncoming ? "keyB" : "keyA"); // lgtm[cpp/weak-cryptographic-algorithm] ++} + +- tr_rc4_process(crypto->enc_key, buf_in, buf_out, buf_len); ++void tr_cryptoEncrypt(tr_crypto* crypto, size_t buf_len, void const* buf_in, void* buf_out) ++{ ++ crypt_rc4(crypto->enc_key, buf_len, buf_in, buf_out); // lgtm[cpp/weak-cryptographic-algorithm] + } + + bool tr_cryptoSecretKeySha1(tr_crypto const* crypto, void const* prepend_data, size_t prepend_data_size, +diff --git a/libtransmission/crypto.h b/libtransmission/crypto.h +index 7e6c85d42..7fe14f768 100644 +--- a/libtransmission/crypto.h ++++ b/libtransmission/crypto.h +@@ -31,8 +31,8 @@ enum + /** @brief Holds state information for encrypted peer communications */ + typedef struct + { +- tr_rc4_ctx_t dec_key; +- tr_rc4_ctx_t enc_key; ++ struct arc4_context* dec_key; ++ struct arc4_context* enc_key; + tr_dh_ctx_t dh; + uint8_t myPublicKey[KEY_LEN]; + tr_dh_secret_t mySecret;