From d64e57ba693f381219a97d902b9003a1e22a7319 Mon Sep 17 00:00:00 2001 From: Disassembler Date: Mon, 25 Feb 2019 22:20:41 +0100 Subject: [PATCH] Fixes to pre-abuild way of package handling --- usr/bin/vmmgr | 3 +-- usr/lib/python3.6/vmmgr/crypto.py | 3 ++- usr/lib/python3.6/vmmgr/pkgmgr.py | 16 +++++++++------- usr/lib/python3.6/vmmgr/validator.py | 2 +- usr/lib/python3.6/vmmgr/wsgiapp.py | 21 ++++++++++++++------- usr/lib/python3.6/vmmgr/wsgilang.py | 2 ++ 6 files changed, 29 insertions(+), 18 deletions(-) diff --git a/usr/bin/vmmgr b/usr/bin/vmmgr index 8076257..a8dc8b0 100755 --- a/usr/bin/vmmgr +++ b/usr/bin/vmmgr @@ -38,7 +38,6 @@ parser_unregister_container.set_defaults(action='unregister-container') parser_register_proxy = subparsers.add_parser('register-proxy') parser_register_proxy.set_defaults(action='register-proxy') parser_register_proxy.add_argument('app', help='Application name') -parser_register_proxy.add_argument('host', help='Application subdomain') parser_unregister_proxy = subparsers.add_parser('unregister-proxy') parser_unregister_proxy.set_defaults(action='unregister-proxy') @@ -66,7 +65,7 @@ elif args.action == 'unregister-container': lxcmgr.unregister_container() elif args.action == 'register-proxy': # Used in init scripts on application startup - vmmgr.register_proxy(args.app, args.host) + vmmgr.register_proxy(args.app) elif args.action == 'unregister-proxy': # Used in init scripts on application stop vmmgr.unregister_proxy(args.app) diff --git a/usr/lib/python3.6/vmmgr/crypto.py b/usr/lib/python3.6/vmmgr/crypto.py index 6c8c42f..5236d74 100644 --- a/usr/lib/python3.6/vmmgr/crypto.py +++ b/usr/lib/python3.6/vmmgr/crypto.py @@ -2,6 +2,7 @@ import bcrypt import datetime +import hashlib import os from cryptography import x509 @@ -19,7 +20,7 @@ def verify_signature(file, signature): pub_key = serialization.load_pem_public_key(f.read(), default_backend()) pub_key.verify(signature, file, ec.ECDSA(hashes.SHA512())) -def verify_hash(file, hash): +def verify_hash(file, expected_hash): # Verifies SHA512 hash of a file against expected hash sha512 = hashlib.sha512() with open(file, 'rb') as f: diff --git a/usr/lib/python3.6/vmmgr/pkgmgr.py b/usr/lib/python3.6/vmmgr/pkgmgr.py index 9fbb63f..b637fd0 100644 --- a/usr/lib/python3.6/vmmgr/pkgmgr.py +++ b/usr/lib/python3.6/vmmgr/pkgmgr.py @@ -6,7 +6,7 @@ import requests import shutil import subprocess -from werkzeug.exceptions import BadRequest, Unauthorized +from werkzeug.exceptions import BadRequest, NotFound, Unauthorized from . import crypto from .paths import LXC_ROOT @@ -28,14 +28,16 @@ class Pkg: class PkgMgr: def __init__(self, conf): - self.repo_url = repo_url self.conf = conf self.online_packages = {} def get_repo_resource(self, resource_url, stream=False): - r = requests.get('{}/{}'.format(self.repo_url, resource_url), auth=self.repo_auth, timeout=5, stream=stream) + # Download requested repository resource + r = requests.get('{}/{}'.format(self.conf['repo']['url'], resource_url), auth=(self.conf['repo']['user'], self.conf['repo']['pwd']), timeout=5, stream=stream) if r.status_code == 401: raise Unauthorized(r.url) + elif r.status_code == 404: + raise NotFound(r.url) elif r.status_code != 200: raise BadRequest(r.url) return r @@ -45,11 +47,11 @@ class PkgMgr: packages = self.get_repo_resource('packages').content packages_sig = self.get_repo_resource('packages.sig').content crypto.verify_signature(packages, packages_sig) - return json.loads(packages) + self.online_packages = json.loads(packages) def install_app(self, app, item): # Main installation function. Wrapper for download, registration and install script - self.online_packages = self.fetch_online_packages() + self.fetch_online_packages() # Get all packages on which the app depends and which have not been installed yet deps = [d for d in self.get_install_deps(app) if d not in self.conf['packages']] item.bytes_total = sum(self.online_packages[d]['size'] for d in deps) @@ -135,7 +137,7 @@ class PkgMgr: def get_install_deps(self, name, online=True): # Flatten dependency tree for a package while preserving the dependency order packages = self.online_packages if online else self.conf['packages'] - deps = packages[name]['deps'].copy() + deps = packages[name]['depends'].copy() for dep in deps[::-1]: deps[:0] = [d for d in self.get_install_deps(dep, online)] deps = list(dict.fromkeys(deps + [name])) @@ -145,6 +147,6 @@ class PkgMgr: # Create reverse dependency tree for all installed packages deps = {} for name in self.conf['packages'].copy(): - for d in self.conf['packages'][name]['deps']: + for d in self.conf['packages'][name]['depends']: deps.setdefault(d, []).append(name) return deps diff --git a/usr/lib/python3.6/vmmgr/validator.py b/usr/lib/python3.6/vmmgr/validator.py index cb90d11..7d199f7 100644 --- a/usr/lib/python3.6/vmmgr/validator.py +++ b/usr/lib/python3.6/vmmgr/validator.py @@ -25,7 +25,7 @@ def is_valid_repo_url(url): # Check if URL is valid http(s) and doesn't contain extra parts try: parsed = urlparse(url) - return parsed.scheme in ('http', 'https') and not parsed.parameters and not parsed.query and not parsed.fragment + return parsed.scheme in ('http', 'https') and not parsed.params and not parsed.query and not parsed.fragment except: pass return False diff --git a/usr/lib/python3.6/vmmgr/wsgiapp.py b/usr/lib/python3.6/vmmgr/wsgiapp.py index 00d32b2..8c3d9d2 100644 --- a/usr/lib/python3.6/vmmgr/wsgiapp.py +++ b/usr/lib/python3.6/vmmgr/wsgiapp.py @@ -124,7 +124,7 @@ class WSGIApp: message = request.session['msg'] del request.session['msg'] # Message is in format location:type:text - return message.split(':', 3) + return message.split(':', 2) def login_view(self, request): redir = request.args.get('redir', '') @@ -164,21 +164,22 @@ class WSGIApp: # Application manager view. repo_error = None try: - online_packages = self.appmgr.pkgmgr.fetch_online_packages() + self.appmgr.pkgmgr.fetch_online_packages() except InvalidSignature: repo_error = request.session.lang.invalid_packages_signature() except Unauthorized: repo_error = request.session.lang.repo_invalid_credentials() except: repo_error = request.session.lang.repo_unavailable() - table = self.render_setup_apps_table(request, online_packages) + table = self.render_setup_apps_table(request) message = self.get_session_message(request) return self.render_html('setup-apps.html', request, repo_error=repo_error, table=table, message=message) - def render_setup_apps_table(self, request, online_packages): + def render_setup_apps_table(self, request): lang = request.session.lang + online_packages = self.appmgr.pkgmgr.online_packages pending_actions = self.queue.get_actions() - actionable_apps = sorted(set([k for k, v in online_packages.items() if 'host' in v] + list(self.conf['apps'].keys()))) + actionable_apps = sorted(set([k for k, v in online_packages.items() if 'title' in v] + list(self.conf['apps'].keys()))) app_data = {} for app in actionable_apps: installed = app in self.conf['apps'] @@ -207,12 +208,18 @@ class WSGIApp: elif item.action == self.appmgr.install_app: if not item.started: status = '{} ({})'.format(lang.status_downloading(), lang.status_queued()) + elif isinstance(item.data, InvalidSignature): + status = '{} OK'.format(lang.repo_package_invalid_signature()) + actions = None + elif isinstance(item.data, NotFound): + status = '{} OK'.format(lang.repo_package_missing()) + actions = None elif isinstance(item.data, BaseException): status = '{} OK'.format(lang.package_manager_error()) actions = None else: if item.data.stage == 0: - status = '{} ({} %)'.format(lang.status_downloading(), item.data) + status = '{} ({} %)'.format(lang.status_downloading(), item.data.percent_downloaded) elif item.data.stage == 1: status = lang.status_installing_deps() else: @@ -320,7 +327,7 @@ class WSGIApp: # Update repository URL and credentials url = request.form['repourl'] if not validator.is_valid_repo_url(url): - request.session['msg'] = 'repo:error:{}'.format(request.session.lang.invalid_url(request.form['repourl'])) + request.session['msg'] = 'repo:error:{}'.format(request.session.lang.invalid_url(url)) else: self.appmgr.update_repo_settings(url, request.form['repousername'], request.form['repopassword']) request.session['msg'] = 'repo:info:{}'.format(request.session.lang.repo_updated()) diff --git a/usr/lib/python3.6/vmmgr/wsgilang.py b/usr/lib/python3.6/vmmgr/wsgilang.py index b6f967f..16310a3 100644 --- a/usr/lib/python3.6/vmmgr/wsgilang.py +++ b/usr/lib/python3.6/vmmgr/wsgilang.py @@ -26,6 +26,8 @@ class WSGILang: 'invalid_packages_signature': 'Digitální podpis seznamu balíků není platný. Kontaktujte správce distribučního serveru.', 'repo_invalid_credentials': 'Přístupové údaje k distribučnímu serveru nejsou správné.', 'repo_unavailable': 'Distribuční server není dostupný. Zkontroluje připojení k síti', + 'repo_package_missing': 'Požadovaný balík nebyl na distribučním serveru nalezen. Kontaktujte správce distribučního serveru.', + 'repo_package_invalid_hash': 'Požadovaný balík nemá spráný kontrolní součet. Zkuste akci opakovat nebo kKontaktujte správce distribučního serveru.', 'bad_password': 'Nesprávné heslo', 'password_mismatch': 'Zadaná hesla se neshodují', 'password_empty': 'Nové heslo nesmí být prázdné',