Hello community, here is the log from the commit of package transmission for openSUSE:Factory checked in at 2018-01-20 11:20:28 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/transmission (Old) and /work/SRC/openSUSE:Factory/.transmission.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "transmission" Sat Jan 20 11:20:28 2018 rev:82 rq:567445 version:2.92 Changes: -------- --- /work/SRC/openSUSE:Factory/transmission/transmission.changes 2017-08-29 11:39:51.224070723 +0200 +++ /work/SRC/openSUSE:Factory/.transmission.new/transmission.changes 2018-01-20 11:20:30.265787365 +0100 @@ -1,0 +2,10 @@ +Wed Jan 17 20:32:42 UTC 2018 - [email protected] + +- Add CVE-2018-5072.patch (backported from + gh#transmission/transmission#468): Mitigate dns rebind attacks + against daemon (boo#1075921, CVE-2018-5072). +- Conditionalize usage of desktop_database_post/postun macros to + suse_version < 1500: recent versions use file triggers. +- Add %check session: run make check. + +------------------------------------------------------------------- New: ---- CVE-2018-5072.patch ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ transmission.spec ++++++ --- /var/tmp/diff_new_pack.hcX4I8/_old 2018-01-20 11:20:32.193697233 +0100 +++ /var/tmp/diff_new_pack.hcX4I8/_new 2018-01-20 11:20:32.193697233 +0100 @@ -1,7 +1,7 @@ # # spec file for package transmission # -# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -37,6 +37,8 @@ Patch2: 0001-transmission-build-against-openssl-1.1.0.patch # PATCH-FIX-UPSTREAM support for OpenSSL 1.1 Patch3: 0002-Fix-coding-style-and-building-with-TR_LIGHTWEIGHT.patch +# PATCH-FIX-UPSTREAM CVE-2018-5072.patch boo#1075921 CVE-2018-5072 [email protected] -- Mitigate dns rebind attacks against daemon +Patch4: CVE-2018-5072.patch BuildRequires: fdupes BuildRequires: gcc-c++ BuildRequires: intltool @@ -145,6 +147,7 @@ %patch1 -p1 %patch2 -p1 %patch3 -p1 +%patch4 -p1 cp %{S:3} . %build @@ -197,6 +200,9 @@ %clean rm -rf %{buildroot} +%check +make check + %pre daemon getent group transmission >/dev/null || groupadd -r transmission getent passwd transmission >/dev/null || \ @@ -225,10 +231,12 @@ %post qt update-alternatives --install %{_bindir}/transmission transmission %{_bindir}/transmission-qt 10 \ --slave %{_mandir}/man1/transmission.1.gz transmission.1.gz %{_mandir}/man1/transmission-qt.1.gz +%if 0%{?suse_version} < 1500 %desktop_database_post %post common %icon_theme_cache_post +%endif %postun # Note: we don't use "$1 -eq 0", to avoid issues if the package gets renamed @@ -241,17 +249,21 @@ if [ ! -f %{_bindir}/transmission-gtk ]; then update-alternatives --remove transmission %{_bindir}/transmission-gtk fi +%if 0%{?suse_version} < 1500 %desktop_database_postun +%endif %postun qt # Note: we don't use "$1 -eq 0", to avoid issues if the package gets renamed if [ ! -f %{_bindir}/transmission-qt ]; then update-alternatives --remove transmission %{_bindir}/transmission-qt fi +%if 0%{?suse_version} < 1500 %desktop_database_postun %postun common %icon_theme_cache_postun +%endif %files %defattr(-,root,root) ++++++ CVE-2018-5072.patch ++++++ >From cf7173df930cfa7ac1b1b0e9027c1deffd0b3c84 Mon Sep 17 00:00:00 2001 From: Tavis Ormandy <[email protected]> Date: Thu, 11 Jan 2018 10:00:41 -0800 Subject: [PATCH] mitigate dns rebinding attacks against daemon --- libtransmission/quark.c | 2 + libtransmission/quark.h | 2 + libtransmission/rpc-server.c | 119 +++++++++++++++++++++++++++++++++++++---- libtransmission/rpc-server.h | 4 ++ libtransmission/session.c | 2 + libtransmission/transmission.h | 1 + libtransmission/web.c | 3 ++ 7 files changed, 124 insertions(+), 9 deletions(-) Index: transmission-2.92/libtransmission/quark.c =================================================================== --- transmission-2.92.orig/libtransmission/quark.c +++ transmission-2.92/libtransmission/quark.c @@ -289,6 +289,8 @@ static const struct tr_key_struct my_sta { "rpc-authentication-required", 27 }, { "rpc-bind-address", 16 }, { "rpc-enabled", 11 }, + { "rpc-host-whitelist", 18 }, + { "rpc-host-whitelist-enabled", 26 }, { "rpc-password", 12 }, { "rpc-port", 8 }, { "rpc-url", 7 }, Index: transmission-2.92/libtransmission/quark.h =================================================================== --- transmission-2.92.orig/libtransmission/quark.h +++ transmission-2.92/libtransmission/quark.h @@ -291,6 +291,8 @@ enum TR_KEY_rpc_authentication_required, TR_KEY_rpc_bind_address, TR_KEY_rpc_enabled, + TR_KEY_rpc_host_whitelist, + TR_KEY_rpc_host_whitelist_enabled, TR_KEY_rpc_password, TR_KEY_rpc_port, TR_KEY_rpc_url, Index: transmission-2.92/libtransmission/rpc-server.c =================================================================== --- transmission-2.92.orig/libtransmission/rpc-server.c +++ transmission-2.92/libtransmission/rpc-server.c @@ -52,6 +52,7 @@ struct tr_rpc_server bool isEnabled; bool isPasswordEnabled; bool isWhitelistEnabled; + bool isHostWhitelistEnabled; tr_port port; char * url; struct in_addr bindAddress; @@ -63,6 +64,7 @@ struct tr_rpc_server char * password; char * whitelistStr; tr_list * whitelist; + tr_list* hostWhitelist; char * sessionId; time_t sessionIdExpiresAt; @@ -588,6 +590,52 @@ isAddressAllowed (const tr_rpc_server * return false; } +static bool isHostnameAllowed(tr_rpc_server const* server, struct evhttp_request* req) +{ + /* If password auth is enabled, any hostname is permitted. */ + if (server->isPasswordEnabled) + { + return true; + } + + /* If whitelist is disabled, no restrictions. */ + if (!server->isHostWhitelistEnabled) + { + return true; + } + + char const* const host = evhttp_find_header(req->input_headers, "Host"); + + /* No host header, invalid request. */ + if (host == NULL) + { + return false; + } + + /* Host header might include the port. */ + char* const hostname = tr_strndup(host, strcspn(host, ":")); + + /* localhost or ipaddress is always acceptable. */ + if (strcmp(hostname, "localhost") == 0 || strcmp(hostname, "localhost.") == 0 || tr_addressIsIP(hostname)) + { + tr_free(hostname); + return true; + } + + /* Otherwise, hostname must be whitelisted. */ + for (tr_list* l = server->hostWhitelist; l != NULL; l = l->next) + { + if (tr_wildmat(hostname, l->data)) + { + tr_free(hostname); + return true; + } + } + + tr_free(hostname); + return false; +} + static bool test_session_id (struct tr_rpc_server * server, struct evhttp_request * req) { @@ -663,6 +711,22 @@ handle_request (struct evhttp_request * handle_upload (req, server); } #ifdef REQUIRE_SESSION_ID + else if (!isHostnameAllowed(server, req)) + { + char* const tmp = tr_strdup_printf( + "<p>Transmission received your request, but the hostname was unrecognized.</p>" + "<p>To fix this, choose one of the following options:" + "<ul>" + "<li>Enable password authentication, then any hostname is allowed.</li>" + "<li>Add the hostname you want to use to the whitelist in settings.</li>" + "</ul></p>" + "<p>If you're editing settings.json, see the 'rpc-host-whitelist' and 'rpc-host-whitelist-enabled' entries.</p>" + "<p>This requirement has been added to help prevent " + "<a href=\"https://en.wikipedia.org/wiki/DNS_rebinding\">DNS Rebinding</a> " + "attacks.</p>"); + send_simple_response(req, 421, tmp); + tr_free(tmp); + } else if (!test_session_id (server, req)) { const char * sessionId = get_current_session_id (server); @@ -674,7 +738,7 @@ handle_request (struct evhttp_request * "<li> When you get this 409 error message, resend your request with the updated header" "</ol></p>" "<p>This requirement has been added to help prevent " - "<a href=\"http://en.wikipedia.org/wiki/Cross-site_request_forgery\">CSRF</a> " + "<a href=\"https://en.wikipedia.org/wiki/Cross-site_request_forgery\">CSRF</a> " "attacks.</p>" "<p><code>%s: %s</code></p>", TR_RPC_SESSION_ID_HEADER, sessionId); @@ -875,19 +939,13 @@ tr_rpcGetUrl (const tr_rpc_server * serv return server->url ? server->url : ""; } -void -tr_rpcSetWhitelist (tr_rpc_server * server, const char * whitelistStr) +void tr_rpcSetList(char const* whitelistStr, tr_list** list) { void * tmp; const char * walk; - /* keep the string */ - tmp = server->whitelistStr; - server->whitelistStr = tr_strdup (whitelistStr); - tr_free (tmp); - /* clear out the old whitelist entries */ - while ((tmp = tr_list_pop_front (&server->whitelist))) + while ((tmp = tr_list_pop_front (list)) != NULL) tr_free (tmp); /* build the new whitelist entries */ @@ -896,7 +954,7 @@ tr_rpcSetWhitelist (tr_rpc_server * serv const char * delimiters = " ,;"; const size_t len = strcspn (walk, delimiters); char * token = tr_strndup (walk, len); - tr_list_append (&server->whitelist, token); + tr_list_append (list, token); if (strcspn (token, "+-") < len) tr_logAddNamedInfo (MY_NAME, "Adding address to whitelist: %s (And it has a '+' or '-'! Are you using an old ACL by mistake?)", token); else @@ -909,6 +967,22 @@ tr_rpcSetWhitelist (tr_rpc_server * serv } } +void tr_rpcSetHostWhitelist(tr_rpc_server* server, char const* whitelistStr) +{ + tr_rpcSetList(whitelistStr, &server->hostWhitelist); +} + +void tr_rpcSetWhitelist(tr_rpc_server* server, char const* whitelistStr) +{ + /* keep the string */ + char* const tmp = server->whitelistStr; + server->whitelistStr = tr_strdup(whitelistStr); + tr_free(tmp); + + tr_rpcSetList(whitelistStr, &server->whitelist); +} + + const char* tr_rpcGetWhitelist (const tr_rpc_server * server) { @@ -930,6 +1004,11 @@ tr_rpcGetWhitelistEnabled (const tr_rpc_ return server->isWhitelistEnabled; } +void tr_rpcSetHostWhitelistEnabled(tr_rpc_server* server, bool isEnabled) +{ + server->isHostWhitelistEnabled = isEnabled; +} + /**** ***** PASSWORD ****/ @@ -1063,6 +1142,28 @@ tr_rpcInit (tr_session * session, tr_va else tr_rpcSetWhitelistEnabled (s, boolVal); + key = TR_KEY_rpc_host_whitelist_enabled; + + if (!tr_variantDictFindBool(settings, key, &boolVal)) + { + missing_settings_key(key); + } + else + { + tr_rpcSetHostWhitelistEnabled(s, boolVal); + } + + key = TR_KEY_rpc_host_whitelist; + + if (!tr_variantDictFindStr(settings, key, &str, NULL) && str != NULL) + { + missing_settings_key(key); + } + else + { + tr_rpcSetHostWhitelist(s, str); + } + key = TR_KEY_rpc_authentication_required; if (!tr_variantDictFindBool (settings, key, &boolVal)) missing_settings_key (key); Index: transmission-2.92/libtransmission/rpc-server.h =================================================================== --- transmission-2.92.orig/libtransmission/rpc-server.h +++ transmission-2.92/libtransmission/rpc-server.h @@ -49,6 +49,10 @@ void tr_rpcSetWhitelist (tr_r const char* tr_rpcGetWhitelist (const tr_rpc_server * server); +void tr_rpcSetHostWhitelistEnabled(tr_rpc_server* server, bool isEnabled); + +void tr_rpcSetHostWhitelist(tr_rpc_server* server, char const* whitelist); + void tr_rpcSetPassword (tr_rpc_server * server, const char * password); Index: transmission-2.92/libtransmission/session.c =================================================================== --- transmission-2.92.orig/libtransmission/session.c +++ transmission-2.92/libtransmission/session.c @@ -359,6 +359,8 @@ tr_sessionGetDefaultSettings (tr_variant tr_variantDictAddStr (d, TR_KEY_rpc_username, ""); tr_variantDictAddStr (d, TR_KEY_rpc_whitelist, TR_DEFAULT_RPC_WHITELIST); tr_variantDictAddBool (d, TR_KEY_rpc_whitelist_enabled, true); + tr_variantDictAddStr(d, TR_KEY_rpc_host_whitelist, TR_DEFAULT_RPC_HOST_WHITELIST); + tr_variantDictAddBool(d, TR_KEY_rpc_host_whitelist_enabled, true); tr_variantDictAddInt (d, TR_KEY_rpc_port, atoi (TR_DEFAULT_RPC_PORT_STR)); tr_variantDictAddStr (d, TR_KEY_rpc_url, TR_DEFAULT_RPC_URL_STR); tr_variantDictAddBool (d, TR_KEY_scrape_paused_torrents_enabled, true); Index: transmission-2.92/libtransmission/transmission.h =================================================================== --- transmission-2.92.orig/libtransmission/transmission.h +++ transmission-2.92/libtransmission/transmission.h @@ -123,6 +123,7 @@ const char* tr_getDefaultDownloadDir (vo #define TR_DEFAULT_BIND_ADDRESS_IPV4 "0.0.0.0" #define TR_DEFAULT_BIND_ADDRESS_IPV6 "::" #define TR_DEFAULT_RPC_WHITELIST "127.0.0.1" +#define TR_DEFAULT_RPC_HOST_WHITELIST "" #define TR_DEFAULT_RPC_PORT_STR "9091" #define TR_DEFAULT_RPC_URL_STR "/transmission/" #define TR_DEFAULT_PEER_PORT_STR "51413" Index: transmission-2.92/libtransmission/web.c =================================================================== --- transmission-2.92.orig/libtransmission/web.c +++ transmission-2.92/libtransmission/web.c @@ -594,6 +594,7 @@ tr_webGetResponseStr (long code) case 415: return "Unsupported Media Type"; case 416: return "Requested Range Not Satisfiable"; case 417: return "Expectation Failed"; + case 421: return "Misdirected Request"; case 500: return "Internal Server Error"; case 501: return "Not Implemented"; case 502: return "Bad Gateway";
