From 5da742394e61813ac64a6875843d40033b8d92a9 Mon Sep 17 00:00:00 2001 From: grossmj Date: Sat, 5 Aug 2023 22:21:08 +1000 Subject: [PATCH] Use bundled cacert file on Windows and macOS --- gns3server/controller/appliance_manager.py | 12 ++++++-- gns3server/crash_report.py | 12 ++------ gns3server/utils/cacert.py | 34 ++++++++++++++++++++++ 3 files changed, 45 insertions(+), 13 deletions(-) create mode 100644 gns3server/utils/cacert.py diff --git a/gns3server/controller/appliance_manager.py b/gns3server/controller/appliance_manager.py index 679926f1..e8c6c2cf 100644 --- a/gns3server/controller/appliance_manager.py +++ b/gns3server/controller/appliance_manager.py @@ -15,13 +15,13 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import sys import os import json import uuid import asyncio import aiohttp import shutil +import ssl try: import importlib_resources @@ -32,6 +32,7 @@ except ImportError: from .appliance import Appliance from ..config import Config from ..utils.asyncio import locking +from ..utils.cacert import get_cacert import logging log = logging.getLogger(__name__) @@ -46,6 +47,7 @@ class ApplianceManager: self._appliances = {} self._appliances_etag = None + self._sslcontext = ssl.create_default_context(cafile=get_cacert()) @property def appliances_etag(self): @@ -174,7 +176,7 @@ class ApplianceManager: symbol_url = "https://raw.githubusercontent.com/GNS3/gns3-registry/master/symbols/{}".format(symbol) async with aiohttp.ClientSession() as session: - async with session.get(symbol_url) as response: + async with session.get(symbol_url, ssl=self._sslcontext) as response: if response.status != 200: log.warning("Could not retrieve appliance symbol {} from GitHub due to HTTP error code {}".format(symbol, response.status)) else: @@ -200,7 +202,11 @@ class ApplianceManager: log.info("Checking if appliances are up-to-date (ETag {})".format(self._appliances_etag)) headers["If-None-Match"] = self._appliances_etag async with aiohttp.ClientSession() as session: - async with session.get('https://api.github.com/repos/GNS3/gns3-registry/contents/appliances', headers=headers) as response: + async with session.get( + 'https://api.github.com/repos/GNS3/gns3-registry/contents/appliances', + ssl=self._sslcontext, + headers=headers + ) as response: if response.status == 304: log.info("Appliances are already up-to-date (ETag {})".format(self._appliances_etag)) return diff --git a/gns3server/crash_report.py b/gns3server/crash_report.py index ce97b167..530b598b 100644 --- a/gns3server/crash_report.py +++ b/gns3server/crash_report.py @@ -32,7 +32,7 @@ import distro from .version import __version__, __version_info__ from .config import Config -from .utils.get_resource import get_resource +from .utils.cacert import get_cacert import logging log = logging.getLogger(__name__) @@ -71,21 +71,13 @@ class CrashReport: sentry_uncaught.disabled = True if SENTRY_SDK_AVAILABLE: - cacert = None - if hasattr(sys, "frozen"): - cacert_resource = get_resource("cacert.pem") - if cacert_resource is not None and os.path.isfile(cacert_resource): - cacert = cacert_resource - else: - log.error("The SSL certificate bundle file '{}' could not be found".format(cacert_resource)) - # Don't send log records as events. sentry_logging = LoggingIntegration(level=logging.INFO, event_level=None) try: sentry_sdk.init(dsn=CrashReport.DSN, release=__version__, - ca_certs=cacert, + ca_certs=get_cacert(), default_integrations=False, integrations=[sentry_logging]) except Exception as e: diff --git a/gns3server/utils/cacert.py b/gns3server/utils/cacert.py new file mode 100644 index 00000000..3ec3672d --- /dev/null +++ b/gns3server/utils/cacert.py @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2023 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 os +import sys + +from .get_resource import get_resource + +import logging +log = logging.getLogger(__name__) + + +def get_cacert(): + if hasattr(sys, "frozen"): + cacert_resource = get_resource("cacert.pem") + if cacert_resource is not None and os.path.isfile(cacert_resource): + return cacert_resource + else: + log.error("The SSL certificate bundle file '{}' could not be found".format(cacert_resource)) + return None # this means we use the system's CA bundle