public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
From: "Mike Gilbert" <floppym@gentoo.org>
To: gentoo-commits@lists.gentoo.org
Subject: [gentoo-commits] repo/gentoo:master commit in: net-p2p/transmission/, net-p2p/transmission/files/
Date: Sat, 13 Jan 2018 22:00:27 +0000 (UTC)	[thread overview]
Message-ID: <1515880820.1c26accdac5c7872b9215fc3a99adcc57a71eebf.floppym@gentoo> (raw)

commit:     1c26accdac5c7872b9215fc3a99adcc57a71eebf
Author:     Mike Gilbert <floppym <AT> gentoo <DOT> org>
AuthorDate: Sat Jan 13 21:54:39 2018 +0000
Commit:     Mike Gilbert <floppym <AT> gentoo <DOT> org>
CommitDate: Sat Jan 13 22:00:20 2018 +0000
URL:        https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=1c26accd

net-p2p/transmission: backport rpc host check

Bug: https://bugs.gentoo.org/644406
Package-Manager: Portage-2.3.19_p11, Repoman-2.3.6_p45

 .../files/transmission-2.92-pr468.patch            | 302 +++++++++++++++++++++
 net-p2p/transmission/transmission-2.92-r3.ebuild   | 165 +++++++++++
 2 files changed, 467 insertions(+)

diff --git a/net-p2p/transmission/files/transmission-2.92-pr468.patch b/net-p2p/transmission/files/transmission-2.92-pr468.patch
new file mode 100644
index 00000000000..a3a0cf16082
--- /dev/null
+++ b/net-p2p/transmission/files/transmission-2.92-pr468.patch
@@ -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
+<leo@famulari.name>:
+
+https://github.com/transmission/transmission/pull/468/commits
+
+From fe2d3c6e75088f3d9b6040ce06da3d530358bc2f Mon Sep 17 00:00:00 2001
+From: Tavis Ormandy <taviso@google.com>
+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
+--- a/libtransmission/quark.c
++++ b/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
+--- a/libtransmission/quark.h
++++ b/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
+--- a/libtransmission/rpc-server.c
++++ b/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(
++                "<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 +736,7 @@ handle_request (struct evhttp_request * req, void * arg)
+             "<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 +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
+--- a/libtransmission/rpc-server.h
++++ b/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
+--- a/libtransmission/session.c
++++ b/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
+--- a/libtransmission/transmission.h
++++ b/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
+--- a/libtransmission/web.c
++++ b/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";

diff --git a/net-p2p/transmission/transmission-2.92-r3.ebuild b/net-p2p/transmission/transmission-2.92-r3.ebuild
new file mode 100644
index 00000000000..839052138da
--- /dev/null
+++ b/net-p2p/transmission/transmission-2.92-r3.ebuild
@@ -0,0 +1,165 @@
+# Copyright 1999-2018 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=6
+inherit autotools fdo-mime flag-o-matic gnome2-utils qmake-utils systemd user
+
+DESCRIPTION="A Fast, Easy and Free BitTorrent client"
+HOMEPAGE="http://www.transmissionbt.com/"
+SRC_URI="http://download.transmissionbt.com/${PN}/files/${P}.tar.xz"
+
+# web/LICENSE is always GPL-2 whereas COPYING allows either GPL-2 or GPL-3 for the rest
+# transmission in licenses/ is for mentioning OpenSSL linking exception
+# MIT is in several libtransmission/ headers
+LICENSE="|| ( GPL-2 GPL-3 Transmission-OpenSSL-exception ) GPL-2 MIT"
+SLOT=0
+IUSE="ayatana gtk libressl lightweight systemd qt5 xfs"
+KEYWORDS="~amd64 ~arm ~mips ~ppc ~ppc64 ~x86 ~x86-fbsd ~amd64-linux"
+
+RDEPEND=">=dev-libs/libevent-2.0.10:=
+	!libressl? ( dev-libs/openssl:0= )
+	libressl? ( dev-libs/libressl:0= )
+	net-libs/libnatpmp
+	>=net-libs/miniupnpc-1.7:=
+	>=net-misc/curl-7.16.3[ssl]
+	sys-libs/zlib:=
+	gtk? (
+		>=dev-libs/dbus-glib-0.100
+		>=dev-libs/glib-2.32:2
+		>=x11-libs/gtk+-3.4:3
+		ayatana? ( >=dev-libs/libappindicator-0.4.90:3 )
+		)
+	qt5? (
+		dev-qt/qtcore:5
+		dev-qt/qtdbus:5
+		dev-qt/qtgui:5
+		dev-qt/qtnetwork:5
+		dev-qt/qtwidgets:5
+		)
+	systemd? ( >=sys-apps/systemd-209:= )"
+DEPEND="${RDEPEND}
+	>=dev-libs/glib-2.32
+	dev-util/intltool
+	sys-devel/gettext
+	virtual/os-headers
+	virtual/pkgconfig
+	qt5? ( dev-qt/linguist-tools:5 )
+	xfs? ( sys-fs/xfsprogs )"
+
+REQUIRED_USE="ayatana? ( gtk )"
+
+DOCS=( AUTHORS NEWS qt/README.txt )
+
+PATCHES=(
+	"${FILESDIR}"/libsystemd.patch
+	"${FILESDIR}"/transmission-2.92-handshake.patch
+	"${FILESDIR}"/transmission-2.92-pr468.patch
+)
+
+src_prepare() {
+	sed -i -e '/CFLAGS/s:-ggdb3::' configure.ac || die
+
+	# Trick to avoid automagic dependency
+	if ! use ayatana ; then
+		sed -i -e '/^LIBAPPINDICATOR_MINIMUM/s:=.*:=9999:' configure.ac || die
+	fi
+
+	# http://trac.transmissionbt.com/ticket/4324
+	sed -i -e 's|noinst\(_PROGRAMS = $(TESTS)\)|check\1|' libtransmission/Makefile.am || die
+
+	# Prevent m4_copy error when running aclocal
+	# m4_copy: won't overwrite defined macro: glib_DEFUN
+	rm m4/glib-gettext.m4 || die
+
+	default
+	eautoreconf
+}
+
+src_configure() {
+	export ac_cv_header_xfs_xfs_h=$(usex xfs)
+
+	# https://bugs.gentoo.org/577528
+	append-lfs-flags
+
+	econf \
+		--enable-external-natpmp \
+		$(use_enable lightweight) \
+		$(use_with systemd systemd-daemon) \
+		$(use_with gtk)
+
+	if use qt5; then
+		pushd qt >/dev/null || die
+		eqmake5 qtr.pro
+		popd >/dev/null || die
+	fi
+}
+
+src_compile() {
+	emake
+
+	if use qt5; then
+		emake -C qt
+		$(qt5_get_bindir)/lrelease qt/translations/*.ts || die
+	fi
+}
+
+src_install() {
+	default
+
+	rm "${ED%/}"/usr/share/transmission/web/LICENSE || die
+
+	newinitd "${FILESDIR}"/transmission-daemon.initd.10 transmission-daemon
+	newconfd "${FILESDIR}"/transmission-daemon.confd.4 transmission-daemon
+	systemd_dounit daemon/transmission-daemon.service
+	systemd_install_serviced "${FILESDIR}"/transmission-daemon.service.conf
+
+	if use qt5; then
+		pushd qt >/dev/null || die
+		emake INSTALL_ROOT="${ED%/}"/usr install
+
+		domenu transmission-qt.desktop
+
+		local res
+		for res in 16 22 24 32 48 64 72 96 128 192 256; do
+			doicon -s ${res} icons/hicolor/${res}x${res}/transmission-qt.png
+		done
+		doicon -s scalable icons/hicolor/scalable/transmission-qt.svg
+
+		insinto /usr/share/qt5/translations
+		doins translations/*.qm
+		popd >/dev/null || die
+	fi
+}
+
+pkg_preinst() {
+	gnome2_icon_savelist
+}
+
+pkg_postinst() {
+	fdo-mime_desktop_database_update
+	gnome2_icon_cache_update
+
+	enewgroup transmission
+	enewuser transmission -1 -1 /var/lib/transmission transmission
+
+	if [[ ! -e "${EROOT%/}"/var/lib/transmission ]]; then
+		mkdir -p "${EROOT%/}"/var/lib/transmission || die
+		chown transmission:transmission "${EROOT%/}"/var/lib/transmission || die
+	fi
+
+	elog "If you use transmission-daemon, please, set 'rpc-username' and"
+	elog "'rpc-password' (in plain text, transmission-daemon will hash it on"
+	elog "start) in settings.json file located at /var/lib/transmission/config or"
+	elog "any other appropriate config directory."
+	elog
+	elog "Since µTP is enabled by default, transmission needs large kernel buffers for"
+	elog "the UDP socket. You can append following lines into /etc/sysctl.conf:"
+	elog " net.core.rmem_max = 4194304"
+	elog " net.core.wmem_max = 1048576"
+	elog "and run sysctl -p"
+}
+
+pkg_postrm() {
+	fdo-mime_desktop_database_update
+	gnome2_icon_cache_update
+}


             reply	other threads:[~2018-01-13 22:00 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-01-13 22:00 Mike Gilbert [this message]
  -- strict thread matches above, loose matches on Subject: below --
2024-06-11  1:05 [gentoo-commits] repo/gentoo:master commit in: net-p2p/transmission/, net-p2p/transmission/files/ Mike Gilbert
2023-02-23 19:52 Craig Andrews
2023-02-10 23:11 Mike Gilbert
2023-02-09  1:06 Mike Gilbert
2022-05-15 23:52 Mike Gilbert
2022-05-15 15:11 Mike Gilbert
2020-05-24  2:33 Mike Gilbert
2019-09-02 18:45 Mike Gilbert
2017-01-10 15:31 Sergey Popov
2016-03-06 22:14 Mike Gilbert
2015-10-03 19:09 Mike Gilbert
2015-10-03 18:26 Mike Gilbert

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1515880820.1c26accdac5c7872b9215fc3a99adcc57a71eebf.floppym@gentoo \
    --to=floppym@gentoo.org \
    --cc=gentoo-commits@lists.gentoo.org \
    --cc=gentoo-dev@lists.gentoo.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox