diff options
Diffstat (limited to 'devel/viewvc-devel')
-rw-r--r-- | devel/viewvc-devel/Makefile | 1 | ||||
-rw-r--r-- | devel/viewvc-devel/files/patch-bin_standalone.py | 74 | ||||
-rw-r--r-- | devel/viewvc-devel/files/patch-lib_viewvc.py | 39 | ||||
-rw-r--r-- | devel/viewvc-devel/pkg-plist | 58 |
4 files changed, 143 insertions, 29 deletions
diff --git a/devel/viewvc-devel/Makefile b/devel/viewvc-devel/Makefile index 658733568732..96e7f66c20a4 100644 --- a/devel/viewvc-devel/Makefile +++ b/devel/viewvc-devel/Makefile @@ -1,5 +1,6 @@ PORTNAME= viewvc DISTVERSION= 1.3.0-20250316 +PORTREVISION= 1 CATEGORIES= devel python PKGNAMEPREFIX= ${PYTHON_PKGNAMEPREFIX} PKGNAMESUFFIX= -devel diff --git a/devel/viewvc-devel/files/patch-bin_standalone.py b/devel/viewvc-devel/files/patch-bin_standalone.py new file mode 100644 index 000000000000..4397053b7391 --- /dev/null +++ b/devel/viewvc-devel/files/patch-bin_standalone.py @@ -0,0 +1,74 @@ +--- bin/standalone.py.orig 2025-07-22 12:12:06 UTC ++++ bin/standalone.py +@@ -191,18 +191,17 @@ class ViewVCHTTPRequestHandler(_http_server.BaseHTTPRe + </html>""" + ) + +- def is_viewvc(self): ++ def is_viewvc(self, path): + """Check whether self.path is, or is a child of, the ScriptAlias""" ++ if not path.startswith("/"): ++ return False + if not options.script_alias: +- return 1 +- if self.path == "/" + options.script_alias: +- return 1 +- alias_len = len(options.script_alias) +- if self.path[: (alias_len + 2)] == "/" + options.script_alias + "/": +- return 1 +- if self.path[: (alias_len + 2)] == "/" + options.script_alias + "?": +- return 1 +- return 0 ++ return True ++ if path == "/" + options.script_alias: ++ return True ++ if path.startswith("/" + options.script_alias + "/"): ++ return True ++ return False + + def validate_password(self, htpasswd_file, username, password): + """Compare USERNAME and PASSWORD against HTPASSWD_FILE.""" +@@ -219,8 +218,18 @@ class ViewVCHTTPRequestHandler(_http_server.BaseHTTPRe + # NOTE: Much of this is adapter from Python's standard library + # module CGIHTTPServer. + ++ i = self.path.rfind("?") ++ if i >= 0: ++ path = _unquote(self.path[:i], "utf-8", "surrogateescape") ++ query = self.path[(i + 1) :] ++ else: ++ path = _unquote(self.path) ++ query = "" ++ # normalize path ++ path = os.path.normpath(path) + ("/" if path[-1] == "/" else "") ++ + # Is this request even aimed at ViewVC? If not, complain. +- if not self.is_viewvc(): ++ if not self.is_viewvc(path): + raise NotViewVCLocationException() + + # If htpasswd authentication is enabled, try to authenticate the user. +@@ -245,12 +254,7 @@ class ViewVCHTTPRequestHandler(_http_server.BaseHTTPRe + + scriptname = options.script_alias and "/" + options.script_alias or "" + +- rest = self.path[len(scriptname) :] +- i = rest.rfind("?") +- if i >= 0: +- rest, query = rest[:i], rest[(i + 1) :] +- else: +- query = "" ++ rest = path[len(scriptname) :] + + # Since we're going to modify the env in the parent, provide empty + # values to override previously set values +@@ -274,8 +278,7 @@ class ViewVCHTTPRequestHandler(_http_server.BaseHTTPRe + env["SERVER_PROTOCOL"] = self.protocol_version + env["SERVER_PORT"] = str(self.server.server_port) + env["REQUEST_METHOD"] = self.command +- uqrest = _unquote(rest, "utf-8", "surrogateescape") +- env["PATH_INFO"] = uqrest ++ env["PATH_INFO"] = rest + env["SCRIPT_NAME"] = scriptname + if query: + env["QUERY_STRING"] = query diff --git a/devel/viewvc-devel/files/patch-lib_viewvc.py b/devel/viewvc-devel/files/patch-lib_viewvc.py new file mode 100644 index 000000000000..739d60e1a50a --- /dev/null +++ b/devel/viewvc-devel/files/patch-lib_viewvc.py @@ -0,0 +1,39 @@ +--- lib/viewvc.py.orig 2025-07-22 12:12:06 UTC ++++ lib/viewvc.py +@@ -193,6 +193,10 @@ class Request: + # TODO: we might want to redirect to the cleaned up URL + path_parts = _path_parts(path_info) + ++ # Protect against directory traversal attacks. ++ if ".." in path_parts: ++ raise ViewVCException("An illegal path was provided.", "400 Bad Request") ++ + if path_parts: + # handle docroot magic path prefixes + if path_parts[0] == docroot_magic_path: +@@ -3401,10 +3405,8 @@ def view_doc(request): + # Stat the file to get content length and last-modified date. + try: + info = os.stat(filename) +- except OSError as v: +- raise ViewVCException( +- 'Static file "%s" not available (%s)' % (document, str(v)), "404 Not Found" +- ) ++ except OSError: ++ raise ViewVCException('Static file "%s" not available' % (document), "404 Not Found") + content_length = str(info[stat.ST_SIZE]) + last_modified = info[stat.ST_MTIME] + +@@ -3414,10 +3416,8 @@ def view_doc(request): + + try: + fp = open(filename, "rb") +- except IOError as v: +- raise ViewVCException( +- 'Static file "%s" not available (%s)' % (document, str(v)), "404 Not Found" +- ) ++ except IOError: ++ raise ViewVCException('Static file "%s" not available' % (document), "404 Not Found") + + if document[-3:] == "png": + mime_type = "image/png" diff --git a/devel/viewvc-devel/pkg-plist b/devel/viewvc-devel/pkg-plist index a5b30420e2f9..e7ec935b8792 100644 --- a/devel/viewvc-devel/pkg-plist +++ b/devel/viewvc-devel/pkg-plist @@ -10,17 +10,17 @@ viewvc/bin/standalone.py viewvc/bin/wsgi/viewvc.fcgi viewvc/bin/wsgi/viewvc.wsgi @sample viewvc/cvsgraph.conf.sample -viewvc/lib/__pycache__/accept%%PYTHON_EXT_SUFFIX%%.pyc -viewvc/lib/__pycache__/blame%%PYTHON_EXT_SUFFIX%%.pyc -viewvc/lib/__pycache__/common%%PYTHON_EXT_SUFFIX%%.pyc -viewvc/lib/__pycache__/config%%PYTHON_EXT_SUFFIX%%.pyc -viewvc/lib/__pycache__/cvsdb%%PYTHON_EXT_SUFFIX%%.pyc -viewvc/lib/__pycache__/dbi%%PYTHON_EXT_SUFFIX%%.pyc -viewvc/lib/__pycache__/ezt%%PYTHON_EXT_SUFFIX%%.pyc -viewvc/lib/__pycache__/idiff%%PYTHON_EXT_SUFFIX%%.pyc -viewvc/lib/__pycache__/popen%%PYTHON_EXT_SUFFIX%%.pyc -viewvc/lib/__pycache__/sapi%%PYTHON_EXT_SUFFIX%%.pyc -viewvc/lib/__pycache__/viewvc%%PYTHON_EXT_SUFFIX%%.pyc +viewvc/lib/__pycache__/accept%%PYTHON_TAG%%.pyc +viewvc/lib/__pycache__/blame%%PYTHON_TAG%%.pyc +viewvc/lib/__pycache__/common%%PYTHON_TAG%%.pyc +viewvc/lib/__pycache__/config%%PYTHON_TAG%%.pyc +viewvc/lib/__pycache__/cvsdb%%PYTHON_TAG%%.pyc +viewvc/lib/__pycache__/dbi%%PYTHON_TAG%%.pyc +viewvc/lib/__pycache__/ezt%%PYTHON_TAG%%.pyc +viewvc/lib/__pycache__/idiff%%PYTHON_TAG%%.pyc +viewvc/lib/__pycache__/popen%%PYTHON_TAG%%.pyc +viewvc/lib/__pycache__/sapi%%PYTHON_TAG%%.pyc +viewvc/lib/__pycache__/viewvc%%PYTHON_TAG%%.pyc viewvc/lib/accept.py viewvc/lib/blame.py viewvc/lib/common.py @@ -32,30 +32,30 @@ viewvc/lib/idiff.py viewvc/lib/popen.py viewvc/lib/sapi.py viewvc/lib/vcauth/__init__.py -viewvc/lib/vcauth/__pycache__/__init__%%PYTHON_EXT_SUFFIX%%.pyc +viewvc/lib/vcauth/__pycache__/__init__%%PYTHON_TAG%%.pyc viewvc/lib/vcauth/forbidden/__init__.py -viewvc/lib/vcauth/forbidden/__pycache__/__init__%%PYTHON_EXT_SUFFIX%%.pyc +viewvc/lib/vcauth/forbidden/__pycache__/__init__%%PYTHON_TAG%%.pyc viewvc/lib/vcauth/forbiddenre/__init__.py -viewvc/lib/vcauth/forbiddenre/__pycache__/__init__%%PYTHON_EXT_SUFFIX%%.pyc +viewvc/lib/vcauth/forbiddenre/__pycache__/__init__%%PYTHON_TAG%%.pyc viewvc/lib/vcauth/svnauthz/__init__.py -viewvc/lib/vcauth/svnauthz/__pycache__/__init__%%PYTHON_EXT_SUFFIX%%.pyc +viewvc/lib/vcauth/svnauthz/__pycache__/__init__%%PYTHON_TAG%%.pyc viewvc/lib/vclib/__init__.py -viewvc/lib/vclib/__pycache__/__init__%%PYTHON_EXT_SUFFIX%%.pyc +viewvc/lib/vclib/__pycache__/__init__%%PYTHON_TAG%%.pyc viewvc/lib/vclib/ccvs/__init__.py -viewvc/lib/vclib/ccvs/__pycache__/__init__%%PYTHON_EXT_SUFFIX%%.pyc -viewvc/lib/vclib/ccvs/__pycache__/bincvs%%PYTHON_EXT_SUFFIX%%.pyc -viewvc/lib/vclib/ccvs/__pycache__/blame%%PYTHON_EXT_SUFFIX%%.pyc -viewvc/lib/vclib/ccvs/__pycache__/ccvs%%PYTHON_EXT_SUFFIX%%.pyc +viewvc/lib/vclib/ccvs/__pycache__/__init__%%PYTHON_TAG%%.pyc +viewvc/lib/vclib/ccvs/__pycache__/bincvs%%PYTHON_TAG%%.pyc +viewvc/lib/vclib/ccvs/__pycache__/blame%%PYTHON_TAG%%.pyc +viewvc/lib/vclib/ccvs/__pycache__/ccvs%%PYTHON_TAG%%.pyc viewvc/lib/vclib/ccvs/bincvs.py viewvc/lib/vclib/ccvs/blame.py viewvc/lib/vclib/ccvs/ccvs.py viewvc/lib/vclib/ccvs/rcsparse/__init__.py -viewvc/lib/vclib/ccvs/rcsparse/__pycache__/__init__%%PYTHON_EXT_SUFFIX%%.pyc -viewvc/lib/vclib/ccvs/rcsparse/__pycache__/common%%PYTHON_EXT_SUFFIX%%.pyc -viewvc/lib/vclib/ccvs/rcsparse/__pycache__/debug%%PYTHON_EXT_SUFFIX%%.pyc -viewvc/lib/vclib/ccvs/rcsparse/__pycache__/default%%PYTHON_EXT_SUFFIX%%.pyc -viewvc/lib/vclib/ccvs/rcsparse/__pycache__/parse_rcs_file%%PYTHON_EXT_SUFFIX%%.pyc -viewvc/lib/vclib/ccvs/rcsparse/__pycache__/run-tests%%PYTHON_EXT_SUFFIX%%.pyc +viewvc/lib/vclib/ccvs/rcsparse/__pycache__/__init__%%PYTHON_TAG%%.pyc +viewvc/lib/vclib/ccvs/rcsparse/__pycache__/common%%PYTHON_TAG%%.pyc +viewvc/lib/vclib/ccvs/rcsparse/__pycache__/debug%%PYTHON_TAG%%.pyc +viewvc/lib/vclib/ccvs/rcsparse/__pycache__/default%%PYTHON_TAG%%.pyc +viewvc/lib/vclib/ccvs/rcsparse/__pycache__/parse_rcs_file%%PYTHON_TAG%%.pyc +viewvc/lib/vclib/ccvs/rcsparse/__pycache__/run-tests%%PYTHON_TAG%%.pyc viewvc/lib/vclib/ccvs/rcsparse/common.py viewvc/lib/vclib/ccvs/rcsparse/debug.py viewvc/lib/vclib/ccvs/rcsparse/default.py @@ -66,9 +66,9 @@ viewvc/lib/vclib/ccvs/rcsparse/test-data/default.out viewvc/lib/vclib/ccvs/rcsparse/test-data/empty-file,v viewvc/lib/vclib/ccvs/rcsparse/test-data/empty-file.out viewvc/lib/vclib/svn/__init__.py -viewvc/lib/vclib/svn/__pycache__/__init__%%PYTHON_EXT_SUFFIX%%.pyc -viewvc/lib/vclib/svn/__pycache__/svn_ra%%PYTHON_EXT_SUFFIX%%.pyc -viewvc/lib/vclib/svn/__pycache__/svn_repos%%PYTHON_EXT_SUFFIX%%.pyc +viewvc/lib/vclib/svn/__pycache__/__init__%%PYTHON_TAG%%.pyc +viewvc/lib/vclib/svn/__pycache__/svn_ra%%PYTHON_TAG%%.pyc +viewvc/lib/vclib/svn/__pycache__/svn_repos%%PYTHON_TAG%%.pyc viewvc/lib/vclib/svn/svn_ra.py viewvc/lib/vclib/svn/svn_repos.py viewvc/lib/viewvc.py |