From owner-svn-ports-all@freebsd.org Sat Jan 20 01:28:58 2018 Return-Path: Delivered-To: svn-ports-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 05A82ED4993; Sat, 20 Jan 2018 01:28:58 +0000 (UTC) (envelope-from woodsb02@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id D30EF80D0B; Sat, 20 Jan 2018 01:28:57 +0000 (UTC) (envelope-from woodsb02@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 1F2631562D; Sat, 20 Jan 2018 01:28:57 +0000 (UTC) (envelope-from woodsb02@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id w0K1SvuU022517; Sat, 20 Jan 2018 01:28:57 GMT (envelope-from woodsb02@FreeBSD.org) Received: (from woodsb02@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id w0K1SuA1022513; Sat, 20 Jan 2018 01:28:56 GMT (envelope-from woodsb02@FreeBSD.org) Message-Id: <201801200128.w0K1SuA1022513@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: woodsb02 set sender to woodsb02@FreeBSD.org using -f From: Ben Woods Date: Sat, 20 Jan 2018 01:28:56 +0000 (UTC) To: ports-committers@freebsd.org, svn-ports-all@freebsd.org, svn-ports-branches@freebsd.org Subject: svn commit: r459493 - in branches/2018Q1: . net-p2p/transmission-cli/files net-p2p/transmission-daemon X-SVN-Group: ports-branches X-SVN-Commit-Author: woodsb02 X-SVN-Commit-Paths: in branches/2018Q1: . net-p2p/transmission-cli/files net-p2p/transmission-daemon X-SVN-Commit-Revision: 459493 X-SVN-Commit-Repository: ports MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-ports-all@freebsd.org X-Mailman-Version: 2.1.25 Precedence: list List-Id: SVN commit messages for the ports tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 20 Jan 2018 01:28:58 -0000 Author: woodsb02 Date: Sat Jan 20 01:28:56 2018 New Revision: 459493 URL: https://svnweb.freebsd.org/changeset/ports/459493 Log: MFH: r459011 r459013 r459492 net-p2p/transmission-daemon: Mitigate DNS rebinding attack Incorporate upstream pull request 468, proposed by Tavis Ormandy from Google Project Zero, which mitigates this attack by requiring a host whitelist for requests that cannot be proven to be secure, but it can be disabled if a user does not want security. PR: 225150 Submitted by: Tavis Ormandy Approved by: crees (maintainer) Obtained from: https://github.com/transmission/transmission/pull/468#issuecomment-357098126 Security: https://www.vuxml.org/freebsd/3e5b8bd3-0c32-452f-a60e-beab7b762351.html Add note to UPDATING for net-p2p/transmission-daemon explaining how to allow client access with the new DNS rebinding mitigations. PR: 225150 Security: https://www.vuxml.org/freebsd/3e5b8bd3-0c32-452f-a60e-beab7b762351.html net-p2p/transmission-daemon: Improve UPDATING entry and add pkg-message This will ensure users who do not read UPDATING are still presented with the message about how to allow clients to connect to the daemon using DNS when they upgrade the package. PR: 225150 Reported by: swills Security: https://www.vuxml.org/freebsd/3e5b8bd3-0c32-452f-a60e-beab7b762351.html Approved by: ports-secteam (swills) Added: branches/2018Q1/net-p2p/transmission-cli/files/patch-fix_dns_rebinding_vuln - copied unchanged from r459011, head/net-p2p/transmission-cli/files/patch-fix_dns_rebinding_vuln branches/2018Q1/net-p2p/transmission-daemon/pkg-message - copied unchanged from r459492, head/net-p2p/transmission-daemon/pkg-message Modified: branches/2018Q1/UPDATING branches/2018Q1/net-p2p/transmission-daemon/Makefile Directory Properties: branches/2018Q1/ (props changed) Modified: branches/2018Q1/UPDATING ============================================================================== --- branches/2018Q1/UPDATING Sat Jan 20 01:20:19 2018 (r459492) +++ branches/2018Q1/UPDATING Sat Jan 20 01:28:56 2018 (r459493) @@ -5,6 +5,30 @@ they are unavoidable. You should get into the habit of checking this file for changes each time you update your ports collection, before attempting any port upgrades. +20180115 + AFFECTS: users of net-p2p/transmission-daemon + AUTHOR: woodsb02@FreeBSD.org + + The transmission-daemon port has been updated to 2.92_4 to incorporate + a patch which mitigates DNS rebinding attacks. This will prevent + clients from being able to connect to the transmission daemon using + DNS with any hostname other than localhost, unless one of the + following is done: + - Enable password authentication, then any hostname is allowed. + This can be achieved by either: + - setting rpc-authentication-required to true, and adding + credentials to the rpc-username and rpc-password fields in + settings.json (must be done whilst the transmission service is + stopped); or + - running transmission-daemon with the following arguments + (these can be set with transmission_flags in /etc/rc.conf): + -t -u USERNAME -v PASSWORD + OR + - Add the allowed server hostnames to the rpc-host-whitelist setting + in settings.json (must be done whilst the transmission service is + stopped). Note that this value is NOT a list of allowed CLIENTS, + but instead a list of allowed SERVER hostnames. + 20171230: AFFECTS: users of net-im/ejabberd AUTHOR: ashish@FreeBSD.org Copied: branches/2018Q1/net-p2p/transmission-cli/files/patch-fix_dns_rebinding_vuln (from r459011, head/net-p2p/transmission-cli/files/patch-fix_dns_rebinding_vuln) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ branches/2018Q1/net-p2p/transmission-cli/files/patch-fix_dns_rebinding_vuln Sat Jan 20 01:28:56 2018 (r459493, copy of r459011, head/net-p2p/transmission-cli/files/patch-fix_dns_rebinding_vuln) @@ -0,0 +1,302 @@ +Fix a weakness that allows remote code execution via the Transmission +RPC server using DNS rebinding: + +https://bugs.chromium.org/p/project-zero/issues/detail?id=1447 + +Patch adapted from Tavis Ormandy's patch on the Transmission master +branch to the Transmission 2.92 release by Leo Famulari +: + +https://github.com/transmission/transmission/pull/468/commits + +From fe2d3c6e75088f3d9b6040ce06da3d530358bc2f Mon Sep 17 00:00:00 2001 +From: Tavis Ormandy +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 | 116 +++++++++++++++++++++++++++++++++++++---- + libtransmission/rpc-server.h | 4 ++ + libtransmission/session.c | 2 + + libtransmission/transmission.h | 1 + + libtransmission/web.c | 3 ++ + 7 files changed, 121 insertions(+), 9 deletions(-) + +diff --git a/libtransmission/quark.c b/libtransmission/quark.c +index 30cc2bca4..b4fd7aabd 100644 +--- libtransmission/quark.c.orig ++++ libtransmission/quark.c +@@ -289,6 +289,8 @@ static const struct tr_key_struct my_static[] = + { "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 }, +diff --git a/libtransmission/quark.h b/libtransmission/quark.h +index 7f5212733..17464be8f 100644 +--- libtransmission/quark.h.orig ++++ 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, +diff --git a/libtransmission/rpc-server.c b/libtransmission/rpc-server.c +index a3485f3fa..292cd5fce 100644 +--- libtransmission/rpc-server.c.orig ++++ 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,49 @@ isAddressAllowed (const tr_rpc_server * server, const char * address) + 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; ++ } ++ ++ char const* const host = evhttp_find_header(req->input_headers, "Host"); ++ ++ // If whitelist is disabled, no restrictions. ++ if (!server->isHostWhitelistEnabled) ++ return true; ++ ++ /* 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 +708,23 @@ handle_request (struct evhttp_request * req, void * arg) + handle_upload (req, server); + } + #ifdef REQUIRE_SESSION_ID ++ else if (!isHostnameAllowed(server, req)) ++ { ++ char* tmp = tr_strdup_printf( ++ "

Transmission received your request, but the hostname was unrecognized.

" ++ "

To fix this, choose one of the following options:" ++ "

    " ++ "
  • Enable password authentication, then any hostname is allowed.
  • " ++ "
  • Add the hostname you want to use to the whitelist in settings.
  • " ++ "

" ++ "

If you're editing settings.json, see the 'rpc-host-whitelist' and 'rpc-host-whitelist-enabled' entries.

" ++ "

This requirement has been added to help prevent " ++ "DNS Rebinding " ++ "attacks.

"); ++ 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 +736,7 @@ handle_request (struct evhttp_request * req, void * arg) + "
  • When you get this 409 error message, resend your request with the updated header" + "

    " + "

    This requirement has been added to help prevent " +- "CSRF " ++ "CSRF " + "attacks.

    " + "

    %s: %s

    ", + TR_RPC_SESSION_ID_HEADER, sessionId); +@@ -875,19 +937,14 @@ tr_rpcGetUrl (const tr_rpc_server * server) + return server->url ? server->url : ""; + } + +-void +-tr_rpcSetWhitelist (tr_rpc_server * server, const char * whitelistStr) ++static 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 +953,7 @@ tr_rpcSetWhitelist (tr_rpc_server * server, const char * whitelistStr) + 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 +966,21 @@ tr_rpcSetWhitelist (tr_rpc_server * server, const char * whitelistStr) + } + } + ++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 +1002,11 @@ tr_rpcGetWhitelistEnabled (const tr_rpc_server * server) + return server->isWhitelistEnabled; + } + ++void tr_rpcSetHostWhitelistEnabled(tr_rpc_server* server, bool isEnabled) ++{ ++ server->isHostWhitelistEnabled = isEnabled; ++} ++ + /**** + ***** PASSWORD + ****/ +@@ -1063,6 +1140,28 @@ tr_rpcInit (tr_session * session, tr_variant * settings) + 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); +diff --git a/libtransmission/rpc-server.h b/libtransmission/rpc-server.h +index e0302c5ea..8c9e6b24e 100644 +--- libtransmission/rpc-server.h.orig ++++ libtransmission/rpc-server.h +@@ -49,6 +49,10 @@ void tr_rpcSetWhitelist (tr_rpc_server * server, + + 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); + +diff --git a/libtransmission/session.c b/libtransmission/session.c +index 844cadba8..58b717913 100644 +--- libtransmission/session.c.orig ++++ libtransmission/session.c +@@ -359,6 +359,8 @@ tr_sessionGetDefaultSettings (tr_variant * d) + 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); +diff --git a/libtransmission/transmission.h b/libtransmission/transmission.h +index 4f76adfd6..e213a8f4e 100644 +--- libtransmission/transmission.h.orig ++++ libtransmission/transmission.h +@@ -123,6 +123,7 @@ const char* tr_getDefaultDownloadDir (void); + #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" +diff --git a/libtransmission/web.c b/libtransmission/web.c +index ee495e9fc..c7f062730 100644 +--- libtransmission/web.c.orig ++++ 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"; Modified: branches/2018Q1/net-p2p/transmission-daemon/Makefile ============================================================================== --- branches/2018Q1/net-p2p/transmission-daemon/Makefile Sat Jan 20 01:20:19 2018 (r459492) +++ branches/2018Q1/net-p2p/transmission-daemon/Makefile Sat Jan 20 01:28:56 2018 (r459493) @@ -1,6 +1,6 @@ # $FreeBSD$ -PORTREVISION= 3 +PORTREVISION= 4 PKGNAMESUFFIX= -daemon MAINTAINER= crees@FreeBSD.org @@ -12,6 +12,7 @@ DESCR= ${.CURDIR}/pkg-descr MASTERDIR= ${.CURDIR}/../transmission-cli PLIST= ${.CURDIR}/pkg-plist SLAVEPORT= daemon +PKGMESSAGE= ${.CURDIR}/pkg-message USE_RC_SUBR= transmission USERS= transmission Copied: branches/2018Q1/net-p2p/transmission-daemon/pkg-message (from r459492, head/net-p2p/transmission-daemon/pkg-message) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ branches/2018Q1/net-p2p/transmission-daemon/pkg-message Sat Jan 20 01:28:56 2018 (r459493, copy of r459492, head/net-p2p/transmission-daemon/pkg-message) @@ -0,0 +1,18 @@ +------------------------------------------------------------------------ +To allow clients to connect to the transmission daemon using DNS with +any hostname other than localhost, do one of the following: + - Enable password authentication, then any hostname is allowed. + This can be achieved by either: + - setting rpc-authentication-required to true, and adding + credentials to the rpc-username and rpc-password fields in + settings.json (must be done whilst the transmission service is + stopped); or + - running transmission-daemon with the following arguments + (these can be set with transmission_flags in /etc/rc.conf): + -t -u USERNAME -v PASSWORD + OR + - Add the allowed server hostnames to the rpc-host-whitelist setting + in settings.json (must be done whilst the transmission service is + stopped). Note that this value is NOT a list of allowed CLIENTS, + but instead a list of allowed SERVER hostnames. +------------------------------------------------------------------------