From 4232ea8a00c3506a6bcec68224f8a328e123409b Mon Sep 17 00:00:00 2001 From: Julien Duponchelle Date: Wed, 7 Oct 2015 10:25:34 +0200 Subject: [PATCH] Protect dynamips against bad glob Fix #332 --- gns3server/modules/dynamips/__init__.py | 13 +++---- gns3server/utils/glob.py | 45 +++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 6 deletions(-) create mode 100644 gns3server/utils/glob.py diff --git a/gns3server/modules/dynamips/__init__.py b/gns3server/modules/dynamips/__init__.py index d2cc958e..2b00849b 100644 --- a/gns3server/modules/dynamips/__init__.py +++ b/gns3server/modules/dynamips/__init__.py @@ -27,13 +27,14 @@ import socket import time import asyncio import tempfile -import glob import logging +import glob log = logging.getLogger(__name__) from gns3server.utils.interfaces import get_windows_interfaces from gns3server.utils.asyncio import wait_run_in_executor +from gns3server.utils.glob import glob_escape from pkg_resources import parse_version from uuid import UUID, uuid4 from ..base_manager import BaseManager @@ -168,11 +169,11 @@ class Dynamips(BaseManager): yield from super().project_closed(project) # delete useless Dynamips files project_dir = project.module_working_path(self.module_name.lower()) - files = glob.glob(os.path.join(project_dir, "*.ghost")) - files += glob.glob(os.path.join(project_dir, "*_lock")) - files += glob.glob(os.path.join(project_dir, "ilt_*")) - files += glob.glob(os.path.join(project_dir, "c[0-9][0-9][0-9][0-9]_i[0-9]*_rommon_vars")) - files += glob.glob(os.path.join(project_dir, "c[0-9][0-9][0-9][0-9]_i[0-9]*_log.txt")) + files = glob.glob(glob_escape(os.path.join(project_dir, "*.ghost"))) + files += glob.glob(glob_escape(os.path.join(project_dir, "*_lock"))) + files += glob.glob(glob_escape(os.path.join(project_dir, "ilt_*"))) + files += glob.glob(glob_escape(os.path.join(project_dir, "c[0-9][0-9][0-9][0-9]_i[0-9]*_rommon_vars"))) + files += glob.glob(glob_escape(os.path.join(project_dir, "c[0-9][0-9][0-9][0-9]_i[0-9]*_log.txt"))) for file in files: try: log.debug("Deleting file {}".format(file)) diff --git a/gns3server/utils/glob.py b/gns3server/utils/glob.py new file mode 100644 index 00000000..6198ced9 --- /dev/null +++ b/gns3server/utils/glob.py @@ -0,0 +1,45 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2013 GNS3 Technologies Inc. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +import sys +import re +import os +import glob + + +def glob_escape(pathname): + """ + Escape all special chars for glob. + For Python after 3.4 we use the glob.escape method. + + :returns: Escaped path + """ + + if sys.version_info < (3, 4): + # Extracted from Python 3.4 source code + # Escaping is done by wrapping any of "*?[" between square brackets. + # Metacharacters do not work in the drive part and shouldn't be escaped. + magic_check = re.compile('([*?[])') + magic_check_bytes = re.compile(b'([*?[])') + drive, pathname = os.path.splitdrive(pathname) + if isinstance(pathname, bytes): + pathname = magic_check_bytes.sub(br'[\1]', pathname) + else: + pathname = magic_check.sub(r'[\1]', pathname) + return drive + pathname + else: + return glob.escape(pathname)