commit 13025d676de08597f7f31523bdb274d0b556dbfc
parent 2e6b4f98c82d0cd1c1bf77a5eeb2d8d68b406528
Author: parazyd <parazyd@dyne.org>
Date: Sun, 10 Jul 2016 00:13:14 +0200
net-p2p/ctorrent: Add 3.3.2-r3 with libressl support.
Diffstat:
5 files changed, 453 insertions(+), 0 deletions(-)
diff --git a/net-p2p/ctorrent/Manifest b/net-p2p/ctorrent/Manifest
@@ -0,0 +1 @@
+DIST ctorrent-dnh3.3.2.tar.gz 219053 SHA256 c87366c91475931f75b924119580abd06a7b3cb3f00fef47346552cab1e24863 SHA512 e59b2b899b8603e42a5754d5ce65f661b135b8e107140e0472af379b2b06ee2985239ed0ebf19dcaef788e617b99eac35ad32ad2d10352e2fcf5a6dc084d27dd WHIRLPOOL e89518e8fccd27e91027b954e0a25367536ebab1d91a959d51229a6779cdd0649154536df61316b88c4d9f236af90e0638d81df5c56d8230a4081a35604dc910
diff --git a/net-p2p/ctorrent/ctorrent-3.3.2-r3.ebuild b/net-p2p/ctorrent/ctorrent-3.3.2-r3.ebuild
@@ -0,0 +1,33 @@
+# Copyright 1999-2015 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Id$
+
+EAPI="5"
+
+inherit eutils
+
+MY_P="${PN}-dnh${PV}"
+
+DESCRIPTION="Enhanced CTorrent is a BitTorrent console client written in C and C++"
+HOMEPAGE="http://www.rahul.net/dholmes/ctorrent/"
+SRC_URI="mirror://sourceforge/dtorrent/${MY_P}.tar.gz"
+
+LICENSE="GPL-2"
+SLOT="0"
+KEYWORDS="~amd64 ~arm ~ppc ~s390 ~sh ~sparc ~x86 ~x86-fbsd"
+IUSE="libressl"
+
+S=${WORKDIR}/${MY_P}
+
+DEPEND="
+ !libressl? ( dev-libs/openssl:= )
+ libressl? ( dev-libs/libressl:= )
+"
+
+RDEPEND="${DEPEND}"
+
+src_prepare() {
+ epatch "${FILESDIR}"/${PN}-CVE-2009-1759.patch
+ epatch "${FILESDIR}"/${P}-negative-ints.patch
+ epatch "${FILESDIR}"/${P}-empty-path-components.patch
+}
diff --git a/net-p2p/ctorrent/files/ctorrent-3.3.2-empty-path-components.patch b/net-p2p/ctorrent/files/ctorrent-3.3.2-empty-path-components.patch
@@ -0,0 +1,38 @@
+rTorrent sometimes creates invalid torrents which has empty path components.
+the bitorrent spec allows for "" strings, but they make no sense in paths.
+so instead of always adding a / in between, skip them. ugh.
+
+for example:
+dict {
+ 'info' => dict {
+ 'name' => str = "some dir" (len = 8)
+ 'files' => list [
+ dict {
+ 'length' => int = 12345567
+ 'path' => list [
+ str = "" (len = 0)
+ str = "foo.bin" (len = 7)
+ ]
+ }
+ ...
+ ]
+ ...
+ }
+ ...
+}
+
+ctorrent will then try to fetch the file "/some dir/foo.bin" instead of
+"some dir/foo.bin" (relative to $PWD).
+
+--- a/bencode.cpp
++++ b/bencode.cpp
+@@ -258,7 +258,8 @@
+ n -= r;
+ if( 'e' == *pb ) break;
+ if( pathname >= endmax ) return 0;
+- *pathname++ = PATH_SP;
++ if (q)
++ *pathname++ = PATH_SP;
+ }
+ *pathname = '\0';
+ return (pb - b + 1);
diff --git a/net-p2p/ctorrent/files/ctorrent-3.3.2-negative-ints.patch b/net-p2p/ctorrent/files/ctorrent-3.3.2-negative-ints.patch
@@ -0,0 +1,17 @@
+allow negative integers ... should fix random "error, initial meta info failed"
+
+https://sourceforge.net/tracker/?func=detail&aid=3159066&group_id=202532&atid=981959
+
+--- ctorrent-dnh3.3.2/bencode.cpp
++++ ctorrent-dnh3.3.2/bencode.cpp
+@@ -44,6 +44,10 @@
+ p++; len--;
+ }
+
++ if( *p == '-'){
++ p++; len--;
++ }
++
+ for(psave = p; len && isdigit(*p); p++,len--) ;
+
+ if(!len || MAX_INT_SIZ < (p - psave) || *p != endchar) return 0;
diff --git a/net-p2p/ctorrent/files/ctorrent-CVE-2009-1759.patch b/net-p2p/ctorrent/files/ctorrent-CVE-2009-1759.patch
@@ -0,0 +1,364 @@
+Patch for CVE-2009-1759.
+Source: Upstream SVN, rev 302 from the drorrent-3 branch.
+
+Index: bencode.h
+===================================================================
+--- bencode.h (revision 300)
++++ bencode.h (revision 302)
+@@ -25,7 +25,7 @@
+ size_t decode_list(const char *b,size_t len,const char *keylist);
+ size_t decode_rev(const char *b,size_t len,const char *keylist);
+ size_t decode_query(const char *b,size_t len,const char *keylist,const char **ps,size_t *pi,int64_t *pl,int method);
+-size_t decode_list2path(const char *b, size_t n, char *pathname);
++size_t decode_list2path(const char *b, size_t n, char *pathname, size_t maxlen);
+ size_t bencode_buf(const char *str,size_t len,FILE *fp);
+ size_t bencode_str(const char *str, FILE *fp);
+ size_t bencode_int(const uint64_t integer, FILE *fp);
+Index: bencode.cpp
+===================================================================
+--- bencode.cpp (revision 300)
++++ bencode.cpp (revision 302)
+@@ -233,22 +233,28 @@
+ return bencode_end_dict_list(fp);
+ }
+
+-size_t decode_list2path(const char *b, size_t n, char *pathname)
++size_t decode_list2path(const char *b, size_t n, char *pathname, size_t maxlen)
+ {
+ const char *pb = b;
+ const char *s = (char *) 0;
++ const char *endmax = pathname + maxlen - 1;
+ size_t r,q;
+
+ if( 'l' != *pb ) return 0;
+ pb++;
+ n--;
+ if( !n ) return 0;
+- for(; n;){
++ while( n && pathname < endmax ){
+ if(!(r = buf_str(pb, n, &s, &q)) ) return 0;
++ if( q >= maxlen ) return 0;
+ memcpy(pathname, s, q);
+ pathname += q;
+- pb += r; n -= r;
+- if( 'e' != *pb ){*pathname = PATH_SP, pathname++;} else break;
++ maxlen -= q;
++ pb += r;
++ n -= r;
++ if( 'e' == *pb ) break;
++ if( pathname >= endmax ) return 0;
++ *pathname++ = PATH_SP;
+ }
+ *pathname = '\0';
+ return (pb - b + 1);
+Index: btfiles.cpp
+===================================================================
+--- btfiles.cpp (revision 300)
++++ btfiles.cpp (revision 302)
+@@ -449,7 +449,8 @@
+ return 0;
+ }
+
+-int btFiles::BuildFromMI(const char *metabuf, const size_t metabuf_len, const char *saveas)
++int btFiles::BuildFromMI(const char *metabuf, const size_t metabuf_len,
++ const char *saveas, unsigned char exam_only)
+ {
+ char path[MAXPATHLEN];
+ const char *s, *p;
+@@ -458,11 +459,19 @@
+ int f_warned = 0;
+
+ if( !decode_query(metabuf, metabuf_len, "info|name", &s, &q, (int64_t*)0,
+- QUERY_STR) || MAXPATHLEN <= q )
++ QUERY_STR) || MAXPATHLEN <= q ){
++ errno = EINVAL;
+ return -1;
++ }
+
+ memcpy(path, s, q);
+ path[q] = '\0';
++ if( !exam_only &&
++ (PATH_SP == path[0] || '/' == path[0] || 0==strncmp("..", path, 2)) ){
++ CONSOLE.Warning(1, "error, unsafe path \"%s\" in torrent data", path);
++ errno = EINVAL;
++ return -1;
++ }
+
+ r = decode_query(metabuf, metabuf_len, "info|files", (const char**)0, &q,
+ (int64_t*)0, QUERY_POS);
+@@ -471,21 +480,31 @@
+ BTFILE *pbf_last = (BTFILE*) 0;
+ BTFILE *pbf = (BTFILE*) 0;
+ size_t dl;
++ unsigned long nfiles = 0;
++
+ if( decode_query(metabuf,metabuf_len,"info|length",
+- (const char**) 0,(size_t*) 0,(int64_t*) 0,QUERY_LONG) )
++ (const char**) 0,(size_t*) 0,(int64_t*) 0,QUERY_LONG) ){
++ errno = EINVAL;
+ return -1;
++ }
+
+ if( saveas ){
+ m_directory = new char[strlen(saveas) + 1];
+ #ifndef WINDOWS
+- if(!m_directory) return -1;
++ if( !m_directory ){
++ errno = ENOMEM;
++ return -1;
++ }
+ #endif
+ strcpy(m_directory,saveas);
+ }else{
+ int f_conv;
+ char *tmpfn = new char[strlen(path)*2+5];
+ #ifndef WINDOWS
+- if( !tmpfn ) return -1;
++ if( !tmpfn ){
++ errno = ENOMEM;
++ return -1;
++ }
+ #endif
+ if( f_conv = ConvertFilename(tmpfn, path, strlen(path)*2+5) ){
+ if( arg_flg_convert_filenames ){
+@@ -493,6 +512,7 @@
+ #ifndef WINDOWS
+ if( !m_directory ){
+ delete []tmpfn;
++ errno = ENOMEM;
+ return -1;
+ }
+ #endif
+@@ -507,7 +527,10 @@
+ if( !f_conv || !arg_flg_convert_filenames ){
+ m_directory = new char[strlen(path) + 1];
+ #ifndef WINDOWS
+- if( !m_directory ) return -1;
++ if( !m_directory ){
++ errno = ENOMEM;
++ return -1;
++ }
+ #endif
+ strcpy(m_directory,path);
+ }
+@@ -517,24 +540,50 @@
+ p = metabuf + r + 1;
+ q--;
+ for(; q && 'e' != *p; p += dl, q -= dl){
+- if(!(dl = decode_dict(p, q, (const char*) 0)) ) return -1;
+- if( !decode_query(p, dl, "length", (const char**) 0,
+- (size_t*) 0,&t,QUERY_LONG) ) return -1;
++ if( !(dl = decode_dict(p, q, (const char*) 0)) ||
++ !decode_query(p, dl, "length", (const char**) 0, (size_t*) 0, &t,
++ QUERY_LONG) ){
++ errno = EINVAL;
++ return -1;
++ }
+ pbf = _new_bfnode();
+ #ifndef WINDOWS
+- if( !pbf ) return -1;
++ if( !pbf ){
++ errno = ENOMEM;
++ return -1;
++ }
+ #endif
++ nfiles++;
+ pbf->bf_length = t;
+ m_total_files_length += t;
+ r = decode_query(p, dl, "path", (const char **)0, &n, (int64_t*)0,
+ QUERY_POS);
+- if( !r ) return -1;
+- if(!decode_list2path(p + r, n, path)) return -1;
++ if( !r || !decode_list2path(p + r, n, path, sizeof(path)) ){
++ CONSOLE.Warning(1,
++ "error, invalid path in torrent data for file %lu at offset %llu",
++ nfiles, m_total_files_length - t);
++ delete pbf;
++ errno = EINVAL;
++ return -1;
++ }
++ if( !exam_only &&
++ (PATH_SP == path[0] || '/' == path[0] || 0==strncmp("..", path, 2)) ){
++ CONSOLE.Warning(1,
++ "error, unsafe path \"%s\" in torrent data for file %lu",
++ path, nfiles);
++ delete pbf;
++ errno = EINVAL;
++ return -1;
++ }
+
++
+ int f_conv;
+ char *tmpfn = new char[strlen(path)*2+5];
+ #ifndef WINDOWS
+- if( !tmpfn ) return -1;
++ if( !tmpfn ){
++ errno = ENOMEM;
++ return -1;
++ }
+ #endif
+ if( f_conv = ConvertFilename(tmpfn, path, strlen(path)*2+5) ){
+ if( arg_flg_convert_filenames ){
+@@ -542,6 +591,7 @@
+ #ifndef WINDOWS
+ if( !pbf->bf_filename ){
+ delete []tmpfn;
++ errno = ENOMEM;
+ return -1;
+ }
+ #endif
+@@ -556,7 +606,10 @@
+ if( !f_conv || !arg_flg_convert_filenames ){
+ pbf->bf_filename = new char[strlen(path) + 1];
+ #ifndef WINDOWS
+- if( !pbf->bf_filename ) return -1;
++ if( !pbf->bf_filename ){
++ errno = ENOMEM;
++ return -1;
++ }
+ #endif
+ strcpy(pbf->bf_filename, path);
+ }
+@@ -564,30 +617,42 @@
+ pbf_last = pbf;
+ }
+ }else{
+- if( !decode_query(metabuf,metabuf_len,"info|length",
+- (const char**) 0,(size_t*) 0,&t,QUERY_LONG) )
++ if( !decode_query(metabuf,metabuf_len, "info|length",
++ (const char**)0, (size_t*) 0, &t, QUERY_LONG) ){
++ errno = EINVAL;
+ return -1;
++ }
+ m_btfhead = _new_bfnode();
+ #ifndef WINDOWS
+- if( !m_btfhead) return -1;
++ if( !m_btfhead ){
++ errno = ENOMEM;
++ return -1;
++ }
+ #endif
+ m_btfhead->bf_length = m_total_files_length = t;
+ if( saveas ){
+ m_btfhead->bf_filename = new char[strlen(saveas) + 1];
+ #ifndef WINDOWS
+- if(!m_btfhead->bf_filename ) return -1;
++ if( !m_btfhead->bf_filename ){
++ errno = ENOMEM;
++ return -1;
++ }
+ #endif
+ strcpy(m_btfhead->bf_filename, saveas);
+ }else if( arg_flg_convert_filenames ){
+ char *tmpfn = new char[strlen(path)*2+5];
+ #ifndef WINDOWS
+- if( !tmpfn ) return -1;
++ if( !tmpfn ){
++ errno = ENOMEM;
++ return -1;
++ }
+ #endif
+ ConvertFilename(tmpfn, path, strlen(path)*2+5);
+ m_btfhead->bf_filename = new char[strlen(tmpfn) + 1];
+ #ifndef WINDOWS
+ if( !m_btfhead->bf_filename ){
+ delete []tmpfn;
++ errno = ENOMEM;
+ return -1;
+ }
+ #endif
+@@ -596,7 +661,10 @@
+ }else{
+ m_btfhead->bf_filename = new char[strlen(path) + 1];
+ #ifndef WINDOWS
+- if(!m_btfhead->bf_filename ) return -1;
++ if( !m_btfhead->bf_filename ){
++ errno = ENOMEM;
++ return -1;
++ }
+ #endif
+ strcpy(m_btfhead->bf_filename, path);
+ }
+@@ -694,6 +762,32 @@
+ size_t btFiles::FillMetaInfo(FILE* fp)
+ {
+ BTFILE *p;
++ const char *refname, *s;
++ char path[MAXPATHLEN];
++
++ refname = m_directory ? m_directory : m_btfhead->bf_filename;
++ while( (s = strchr(refname, PATH_SP)) && *(s + 1) ){
++ refname = s + 1;
++ }
++ if( m_directory && '.' == *refname ){
++ char dir[MAXPATHLEN];
++ if( getcwd(dir, sizeof(dir)) && 0==chdir(m_directory) ){
++ if( getcwd(path, sizeof(path)) ){
++ refname = path;
++ while( (s = strchr(refname, PATH_SP)) && *(s + 1) ){
++ refname = s + 1;
++ }
++ }
++ chdir(dir);
++ }
++ }
++ if( '/' == *refname || '\0' == *refname || '.' == *refname ){
++ CONSOLE.Warning(1, "error, inappropriate file or directory name \"%s\"",
++ m_directory ? m_directory : m_btfhead->bf_filename);
++ errno = EINVAL;
++ return 0;
++ }
++
+ if( m_directory ){
+ // multi files
+ if( bencode_str("files", fp) != 1 ) return 0;
+@@ -715,16 +809,15 @@
+ if(bencode_end_dict_list(fp) != 1 ) return 0;
+
+ if(bencode_str("name", fp) != 1) return 0;
+- return bencode_str(m_directory, fp);
+-
++ return bencode_str(refname, fp);
+ }else{
+ if( bencode_str("length", fp) != 1 ) return 0;
+ if( bencode_int(m_btfhead->bf_length, fp) != 1) return 0;
+
+ if( bencode_str("name", fp) != 1 ) return 0;
+- return bencode_str(m_btfhead->bf_filename, fp);
++ return bencode_str(refname, fp);
+ }
+- return 1;
++ return 0;
+ }
+
+
+Index: btcontent.cpp
+===================================================================
+--- btcontent.cpp (revision 300)
++++ btcontent.cpp (revision 302)
+@@ -357,7 +357,11 @@
+
+ cfg_req_queue_length = (m_piece_length / cfg_req_slice_size) * 2 - 1;
+
+- if( m_btfiles.BuildFromMI(b, flen, saveas) < 0 ) ERR_RETURN();
++ if( m_btfiles.BuildFromMI(b, flen, saveas, arg_flg_exam_only) < 0 ){
++ if( EINVAL == errno )
++ CONSOLE.Warning(1, "Torrent metainfo file data is invalid or unusable.");
++ ERR_RETURN();
++ }
+
+ delete []b;
+ b = (char *)0;
+Index: btfiles.h
+===================================================================
+--- btfiles.h (revision 300)
++++ btfiles.h (revision 302)
+@@ -61,7 +61,7 @@
+
+ int BuildFromFS(const char *pathname);
+ int BuildFromMI(const char *metabuf, const size_t metabuf_len,
+- const char *saveas);
++ const char *saveas, unsigned char exam_only);
+
+ char *GetDataName() const;
+ uint64_t GetTotalLength() const { return m_total_files_length; }