def _really_install_bucket(self, current_bucket): """Really install current bucket and bind signals""" bucket = current_bucket["bucket"] logger.debug("Starting {} installation".format(bucket)) # exchange file output for apt and dpkg after the fork() call (open it empty) self.apt_fd = tempfile.NamedTemporaryFile(delete=False) self.apt_fd.close() if self.is_bucket_uptodate(bucket): return True need_cache_reload = False for pkg_name in bucket: if ":" in pkg_name: arch = pkg_name.split(":", -1)[-1] need_cache_reload = need_cache_reload or add_foreign_arch(arch) if need_cache_reload: with as_root(): self._force_reload_apt_cache() self.cache.update() self._force_reload_apt_cache() # mark for install and so on for pkg_name in bucket: # /!\ danger: if current arch == ':appended_arch', on a non multiarch system, dpkg doesn't understand that # strip :arch then if ":" in pkg_name: (pkg_without_arch_name, arch) = pkg_name.split(":", -1) if arch == get_current_arch(): pkg_name = pkg_without_arch_name try: pkg = self.cache[pkg_name] if pkg.is_installed and pkg.is_upgradable: logger.debug("Marking {} for upgrade".format(pkg_name)) pkg.mark_upgrade() else: logger.debug("Marking {} for install".format(pkg_name)) pkg.mark_install(auto_fix=False) except Exception as msg: message = "Can't mark for install {}: {}".format(pkg_name, msg) raise BaseException(message) # this can raise on installedArchives() exception if the commit() fails with as_root(): self.cache.commit(fetch_progress=self._FetchProgress( current_bucket, self.STATUS_DOWNLOADING, current_bucket["progress_callback"]), install_progress=self._InstallProgress( current_bucket, self.STATUS_INSTALLING, current_bucket["progress_callback"], self._force_reload_apt_cache, self.apt_fd.name)) return True
def _really_install_bucket(self, current_bucket): """Really install current bucket and bind signals""" bucket = current_bucket["bucket"] logger.debug("Starting {} installation".format(bucket)) # exchange file output for apt and dpkg after the fork() call (open it empty) self.apt_fd = tempfile.NamedTemporaryFile(delete=False) self.apt_fd.close() if self.is_bucket_uptodate(bucket): return True need_cache_reload = False for pkg_name in bucket: if ":" in pkg_name: arch = pkg_name.split(":", -1)[-1] need_cache_reload = need_cache_reload or add_foreign_arch(arch) if need_cache_reload: with as_root(): self._force_reload_apt_cache() self.cache.update() self._force_reload_apt_cache() # mark for install and so on for pkg_name in bucket: # /!\ danger: if current arch == ':appended_arch', on a non multiarch system, dpkg doesn't understand that # strip :arch then if ":" in pkg_name: (pkg_without_arch_name, arch) = pkg_name.split(":", -1) if arch == get_current_arch(): pkg_name = pkg_without_arch_name try: pkg = self.cache[pkg_name] if pkg.is_installed and pkg.is_upgradable: logger.debug("Marking {} for upgrade".format(pkg_name)) pkg.mark_upgrade() else: logger.debug("Marking {} for install".format(pkg_name)) pkg.mark_install(auto_fix=False) except Exception as msg: message = "Can't mark for install {}: {}".format(pkg_name, msg) raise BaseException(message) # this can raise on installedArchives() exception if the commit() fails with as_root(): self.cache.commit(fetch_progress=self._FetchProgress(current_bucket, self.STATUS_DOWNLOADING, current_bucket["progress_callback"]), install_progress=self._InstallProgress(current_bucket, self.STATUS_INSTALLING, current_bucket["progress_callback"], self._force_reload_apt_cache, self.apt_fd.name)) return True
def check_gpg_and_start_download(self, download_result): asc_content = download_result.pop( self.asc_url).buffer.getvalue().decode('utf-8') sig_url = list(download_result.keys())[0] res = download_result[sig_url] sig = res.buffer.getvalue().decode('utf-8').split()[0] # When we install new packages, we are executing as root and then dropping # as the user for extracting and such. However, for signature verification, # we use gpg. This one doesn't like privilege drop (if uid = 0 and # euid = 1000) and asserts if uid != euid. # Importing the key as root as well creates new gnupg files owned as root if # new keys weren't imported first. # Consequently, run gpg as root if we needed root access or as the user # otherwise. We store the gpg public key in a temporary gnupg directory that # will be removed under the same user rights (this directory needs to be owned # by the same user id to not be rejected by gpg).Z if self.need_root_access: with as_root(): with tempfile.TemporaryDirectory() as tmpdirname: self._check_gpg_signature(tmpdirname, asc_content, sig) else: with tempfile.TemporaryDirectory() as tmpdirname: self._check_gpg_signature(tmpdirname, asc_content, sig) # you get and store self.download_url url = re.sub('.sig', '', sig_url) if url is None: logger.error( "Download page changed its syntax or is not parsable (missing url)" ) UI.return_main_screen(status_code=1) logger.debug("Found download link for {}".format(url)) self.download_requests.append(DownloadItem(url, None)) self.start_download_and_install()
def check_gpg_and_start_download(self, download_result): asc_content = download_result.pop(self.asc_url).buffer.getvalue().decode('utf-8') sig_url = list(download_result.keys())[0] res = download_result[sig_url] sig = res.buffer.getvalue().decode('utf-8').split()[0] # When we install new packages, we are executing as root and then dropping # as the user for extracting and such. However, for signature verification, # we use gpg. This one doesn't like priviledge drop (if uid = 0 and # euid = 1000) and asserts if uid != euid. # Importing the key as root as well creates new gnupg files owned as root if # new keys weren't imported first. # Consequently, run gpg as root if we needed root access or as the user # otherwise. We store the gpg public key in a temporary gnupg directory that # will be removed under the same user rights (this directory needs to be owned # by the same user id to not be rejected by gpg).Z if self.need_root_access: with as_root(): with tempfile.TemporaryDirectory() as tmpdirname: self._check_gpg_signature(tmpdirname, asc_content, sig) else: with tempfile.TemporaryDirectory() as tmpdirname: self._check_gpg_signature(tmpdirname, asc_content, sig) # you get and store self.download_url url = re.sub('.sig', '', sig_url) if url is None: logger.error("Download page changed its syntax or is not parsable (missing url)") UI.return_main_screen(status_code=1) logger.debug("Found download link for {}".format(url)) self.download_requests.append(DownloadItem(url, None)) self.start_download_and_install()
def _add_to_group(user, group): """Add user to group""" # switch to root with as_root(): try: output = subprocess.check_output(["adduser", user, group]) logger.debug("Added {} to {}: {}".format(user, group, output)) return True except subprocess.CalledProcessError as e: logger.error("Couldn't add {} to {}".format(user, group)) return False
def _chrome_sandbox_setuid(path): """Chown and setUID to chrome sandbox""" # switch to root with as_root(): try: os.chown(path, 0, -1) os.chmod(path, stat.S_ISUID | stat.S_IRWXU | stat.S_IRGRP | stat.S_IXGRP | stat.S_IROTH | stat.S_IXOTH) logger.debug("Changed setUID mode {}".format(path)) return True except Exception as e: logger.error("Couldn't change owner and file perm to {}: {}".format(path, e)) return False