From f7329a61e9c484b69087b428c6a6373b71ebaa71 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Sat, 6 Jul 2019 18:37:01 +0200 Subject: [PATCH 01/13] Use the new acme-v02 API, fixes the newAccount keyError issue in acme_tiny --- src/yunohost/certificate.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/yunohost/certificate.py b/src/yunohost/certificate.py index a4a31055d..d141ac8e5 100644 --- a/src/yunohost/certificate.py +++ b/src/yunohost/certificate.py @@ -65,7 +65,7 @@ VALIDITY_LIMIT = 15 # days # For tests STAGING_CERTIFICATION_AUTHORITY = "https://acme-staging.api.letsencrypt.org" # For prod -PRODUCTION_CERTIFICATION_AUTHORITY = "https://acme-v01.api.letsencrypt.org" +PRODUCTION_CERTIFICATION_AUTHORITY = "https://acme-v02.api.letsencrypt.org" INTERMEDIATE_CERTIFICATE_URL = "https://letsencrypt.org/certs/lets-encrypt-x3-cross-signed.pem" From 9c221a30d4e219eea0197a67c54740cba801e280 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Sat, 6 Jul 2019 18:38:12 +0200 Subject: [PATCH 02/13] Update changelog for 3.6.4.2 --- debian/changelog | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/debian/changelog b/debian/changelog index 1d2481513..cfbcf5eb6 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +yunohost (3.6.4.2) stable; urgency=low + + - [hotfix] Use the acme-v02 API to fix the newAccount keyError in acme_tiny + + -- Alexandre Aubin Set, 06 Jul 2019 18:40:00 +0000 + yunohost (3.6.4.1) stable; urgency=low - [hotfix] Slapd not being able to start on ipv4-only instances From 4ef30b7f10c94d7046feaeb5835889795b93141e Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Sat, 6 Jul 2019 19:30:57 +0200 Subject: [PATCH 03/13] Also redact percent-escaped passwords which may appear in the metadata for webadmin installs --- src/yunohost/app.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/yunohost/app.py b/src/yunohost/app.py index b08f99e99..e1ceeeb5c 100644 --- a/src/yunohost/app.py +++ b/src/yunohost/app.py @@ -35,6 +35,7 @@ import subprocess import glob import pwd import grp +import urllib from collections import OrderedDict from datetime import datetime @@ -809,9 +810,14 @@ def app_install(operation_logger, app, label=None, args=None, no_remove_on_failu # Start register change on system operation_logger.extra.update({'env': env_dict}) + # Tell the operation_logger to redact all password-type args + # Also redact the % escaped version of the password that might appear in + # the 'args' section of metadata (relevant for password with non-alphanumeric char) data_to_redact = [ value[0] for value in args_odict.values() if value[1] == "password" ] + data_to_redact += [ urllib.quote(data) for data in data_to_redact if urllib.quote(data) != data ] operation_logger.data_to_redact.extend(data_to_redact) + operation_logger.related_to = [s for s in operation_logger.related_to if s[0] != "app"] operation_logger.related_to.append(("app", app_id)) operation_logger.start() From a9a9e5a44c1ee3ac572aa8b42dcbfe75ceee944e Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Sat, 6 Jul 2019 19:33:57 +0200 Subject: [PATCH 04/13] Also redact vars ending with 'secret' or 'key' --- src/yunohost/log.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/yunohost/log.py b/src/yunohost/log.py index 17a6ff87c..8f8c92010 100644 --- a/src/yunohost/log.py +++ b/src/yunohost/log.py @@ -310,7 +310,7 @@ class RedactingFormatter(Formatter): try: # This matches stuff like db_pwd=the_secret or admin_password=other_secret # (the secret part being at least 3 chars to avoid catching some lines like just "db_pwd=") - match = re.search(r'(pwd|pass|password)=(\S{3,})$', record.strip()) + match = re.search(r'(pwd|pass|password|secret|key)=(\S{3,})$', record.strip()) if match and match.group(2) not in self.data_to_redact: self.data_to_redact.append(match.group(2)) except Exception as e: From c83b5771acef6122778befb3bcdcb0da80949d4c Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Sat, 6 Jul 2019 19:35:18 +0200 Subject: [PATCH 05/13] Update changelog for 3.6.4.3 --- debian/changelog | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/debian/changelog b/debian/changelog index cfbcf5eb6..e0557021a 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +yunohost (3.6.4.3) stable; urgency=low + + - [hotfix] Fix some password-redacting cases that weren't caught up + + -- Alexandre Aubin Set, 06 Jul 2019 19:35:00 +0000 + yunohost (3.6.4.2) stable; urgency=low - [hotfix] Use the acme-v02 API to fix the newAccount keyError in acme_tiny From a7e49cd184e99c6c2396be057bc095ab51bca69e Mon Sep 17 00:00:00 2001 From: Laurent Peuch Date: Sun, 21 Jul 2019 17:16:32 +0200 Subject: [PATCH 06/13] [fix] retreive the actual value --- src/yunohost/app.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/yunohost/app.py b/src/yunohost/app.py index e1ceeeb5c..d9a349579 100644 --- a/src/yunohost/app.py +++ b/src/yunohost/app.py @@ -1647,7 +1647,7 @@ def app_config_show_panel(app): [{option["name"]: parsed_values[generated_name]}], [option] ) - option["default"] = args_dict[option["name"]] + option["default"] = args_dict[option["name"]][0] else: logger.debug("Variable '%s' is not declared by config script, using default", generated_name) # do nothing, we'll use the default if present From 705d50fa6e38e0eb03873e0b20fec5e2ac1367f5 Mon Sep 17 00:00:00 2001 From: "ljf (zamentur)" Date: Fri, 12 Jul 2019 14:17:35 +0200 Subject: [PATCH 07/13] [fix] Path not displayed in log_corrupted_md_file --- src/yunohost/log.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/yunohost/log.py b/src/yunohost/log.py index 8f8c92010..62775d619 100644 --- a/src/yunohost/log.py +++ b/src/yunohost/log.py @@ -106,7 +106,7 @@ def log_list(category=[], limit=None, with_details=False): try: metadata = yaml.safe_load(md_file) except yaml.YAMLError: - logger.warning(m18n.n('log_corrupted_md_file', file=md_path)) + logger.warning(m18n.n('log_corrupted_md_file', md_file=md_path)) entry["success"] = metadata.get("success", "?") if metadata else "?" @@ -192,7 +192,7 @@ def log_display(path, number=50, share=False): if 'log_path' in metadata: log_path = metadata['log_path'] except yaml.YAMLError: - error = m18n.n('log_corrupted_md_file', file=md_path) + error = m18n.n('log_corrupted_md_file', md_file=md_path) if os.path.exists(log_path): logger.warning(error) else: From 008c2886aa7b1aeba71918e13ef1089dd2d178c8 Mon Sep 17 00:00:00 2001 From: "ljf (zamentur)" Date: Mon, 15 Jul 2019 13:30:22 +0200 Subject: [PATCH 08/13] [fix] Use read_yaml instead of custom yaml load --- src/yunohost/log.py | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/yunohost/log.py b/src/yunohost/log.py index 62775d619..c9314eca8 100644 --- a/src/yunohost/log.py +++ b/src/yunohost/log.py @@ -35,7 +35,7 @@ from logging import FileHandler, getLogger, Formatter from moulinette import m18n, msettings from yunohost.utils.error import YunohostError from moulinette.utils.log import getActionLogger -from moulinette.utils.filesystem import read_file +from moulinette.utils.filesystem import read_file, read_yaml CATEGORIES_PATH = '/var/log/yunohost/categories/' OPERATIONS_PATH = '/var/log/yunohost/categories/operation/' @@ -102,13 +102,8 @@ def log_list(category=[], limit=None, with_details=False): entry["started_at"] = log_datetime if with_details: - with open(md_path, "r") as md_file: - try: - metadata = yaml.safe_load(md_file) - except yaml.YAMLError: - logger.warning(m18n.n('log_corrupted_md_file', md_file=md_path)) - - entry["success"] = metadata.get("success", "?") if metadata else "?" + metadata = read_yaml(md_path) + entry["success"] = metadata.get("success", "?") if metadata else "?" result[category].append(entry) From e1a1e0bb3505b544e0be6a40577ee6387adf724e Mon Sep 17 00:00:00 2001 From: Laurent Peuch Date: Sun, 4 Aug 2019 17:44:53 +0200 Subject: [PATCH 09/13] [mod] use read_yaml and only keep sensible code inside of exception --- locales/en.json | 2 +- src/yunohost/log.py | 17 ++++++++++------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/locales/en.json b/locales/en.json index 22247c97e..d1203c757 100644 --- a/locales/en.json +++ b/locales/en.json @@ -234,7 +234,7 @@ "invalid_url_format": "Invalid URL format", "ip6tables_unavailable": "You cannot play with ip6tables here. You are either in a container or your kernel does not support it", "iptables_unavailable": "You cannot play with iptables here. You are either in a container or your kernel does not support it", - "log_corrupted_md_file": "The yaml metadata file associated with logs is corrupted: '{md_file}'", + "log_corrupted_md_file": "The yaml metadata file associated with logs is corrupted: '{md_file}\nError: {error}'", "log_category_404": "The log category '{category}' does not exist", "log_link_to_log": "Full log of this operation: '{desc}'", "log_help_to_get_log": "To view the log of the operation '{desc}', use the command 'yunohost log display {name}'", diff --git a/src/yunohost/log.py b/src/yunohost/log.py index c9314eca8..aa41cd85f 100644 --- a/src/yunohost/log.py +++ b/src/yunohost/log.py @@ -33,6 +33,7 @@ from datetime import datetime from logging import FileHandler, getLogger, Formatter from moulinette import m18n, msettings +from moulinette.core import MoulinetteError from yunohost.utils.error import YunohostError from moulinette.utils.log import getActionLogger from moulinette.utils.filesystem import read_file, read_yaml @@ -181,17 +182,19 @@ def log_display(path, number=50, share=False): if os.path.exists(md_path): with open(md_path, "r") as md_file: try: - metadata = yaml.safe_load(md_file) - infos['metadata_path'] = md_path - infos['metadata'] = metadata - if 'log_path' in metadata: - log_path = metadata['log_path'] - except yaml.YAMLError: - error = m18n.n('log_corrupted_md_file', md_file=md_path) + metadata = read_yaml(md_file) + except MoulinetteError as e: + error = m18n.n('log_corrupted_md_file', md_file=md_path, error=e) if os.path.exists(log_path): logger.warning(error) else: raise YunohostError(error) + else: + infos['metadata_path'] = md_path + infos['metadata'] = metadata + + if 'log_path' in metadata: + log_path = metadata['log_path'] # Display logs if exist if os.path.exists(log_path): From 8212010979977bff60a21a48232bd0294bee67ee Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Thu, 18 Jul 2019 18:16:46 +0200 Subject: [PATCH 10/13] Fix legit variable getting caught as an info to be redacted by the core --- data/helpers.d/utils | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/data/helpers.d/utils b/data/helpers.d/utils index a93fbf227..c9034ebc6 100644 --- a/data/helpers.d/utils +++ b/data/helpers.d/utils @@ -378,16 +378,18 @@ ynh_secure_remove () { ynh_get_plain_key() { local prefix="#" local founded=0 - local key=$1 + # We call this key_ so that it's not caught as + # an info to be redacted by the core + local key_=$1 shift while read line; do if [[ "$founded" == "1" ]] ; then [[ "$line" =~ ^${prefix}[^#] ]] && return echo $line - elif [[ "$line" =~ ^${prefix}${key}$ ]]; then + elif [[ "$line" =~ ^${prefix}${key_}$ ]]; then if [[ -n "${1:-}" ]]; then prefix+="#" - key=$1 + key_=$1 shift else founded=1 From 1cb0a26b06a793f10a8bc036f55fc7d490519b6c Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Thu, 18 Jul 2019 18:31:25 +0200 Subject: [PATCH 11/13] We don't need this ugly trick anymore if we forgot the adminpw --- sbin/yunohost-reset-ldap-password | 68 +------------------------------ 1 file changed, 1 insertion(+), 67 deletions(-) diff --git a/sbin/yunohost-reset-ldap-password b/sbin/yunohost-reset-ldap-password index 916b70b18..95f84875f 100755 --- a/sbin/yunohost-reset-ldap-password +++ b/sbin/yunohost-reset-ldap-password @@ -1,69 +1,3 @@ #!/bin/bash - -################################ -# Set a temporary password # -################################ - -# Generate a random temporary password (won't be valid after this script ends !) -# and hash it -TMP_LDAPROOT_PASSWORD=`slappasswd -g` -TMP_LDAPROOT_PASSWORD_HASH=`slappasswd -h {SSHA} -s ${TMP_LDAPROOT_PASSWORD}` - -# Stop slapd service... -service slapd stop - -# Backup slapd.conf (to be restored at the end of script) -cp /etc/ldap/slapd.conf /root/slapd.conf.bkp - -# Append lines to slapd.conf to manually define root password hash -echo 'rootdn "cn=admin,dc=yunohost,dc=org"' >> /etc/ldap/slapd.conf -echo "rootpw $TMP_LDAPROOT_PASSWORD_HASH" >> /etc/ldap/slapd.conf - -# Test conf (might not be entirely necessary though :P) -slaptest -Q -u -f /etc/ldap/slapd.conf - -# Regenerate slapd.d directory -rm -Rf /etc/ldap/slapd.d -mkdir /etc/ldap/slapd.d -slaptest -f /etc/ldap/slapd.conf -F /etc/ldap/slapd.d/ 2>&1 - -# Set permissions to slapd.d -chown -R openldap:openldap /etc/ldap/slapd.d/ - -# Restore slapd.conf -mv /root/slapd.conf.bkp /etc/ldap/slapd.conf - -# Restart slapd service -service slapd start - -####################################### -# Properly set new admin password # -####################################### - -# Display tmp password to user -# NB : we do NOT pass it as a command line argument for "yunohost tools adminpw" -# as a malicious user could run a script in background waiting for this command -# to pop in ps -ef and automatically do nasty stuff in the ldap database -# meanwhile. -echo "Use this temporary password when asked for the administration password : $TMP_LDAPROOT_PASSWORD" - -# Call yunohost tools adminpw for user to set new password +echo "Warning: this script is now deprecated. You can simply type 'yunohost tools adminpw' to change the root/admin password." yunohost tools adminpw - -########################### -# Forget tmp password # -########################### - -# Stop slapd service -service slapd stop - -# Regenerate slapd.d directory -rm -Rf /etc/ldap/slapd.d -mkdir /etc/ldap/slapd.d -slaptest -f /etc/ldap/slapd.conf -F /etc/ldap/slapd.d/ 2>&1 - -# Set permissions to slapd.d -chown -R openldap:openldap /etc/ldap/slapd.d/ - -# Restart slapd service -service slapd start From 1224380265fe2009465b89d45f1e7b0737921978 Mon Sep 17 00:00:00 2001 From: Laurent Peuch Date: Sun, 21 Jul 2019 17:16:32 +0200 Subject: [PATCH 12/13] [fix] retreive the actual value --- src/yunohost/app.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/yunohost/app.py b/src/yunohost/app.py index e1ceeeb5c..d9a349579 100644 --- a/src/yunohost/app.py +++ b/src/yunohost/app.py @@ -1647,7 +1647,7 @@ def app_config_show_panel(app): [{option["name"]: parsed_values[generated_name]}], [option] ) - option["default"] = args_dict[option["name"]] + option["default"] = args_dict[option["name"]][0] else: logger.debug("Variable '%s' is not declared by config script, using default", generated_name) # do nothing, we'll use the default if present From cd912db8b20a73c8d4aefa1f507f340f1e6c5122 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Sun, 4 Aug 2019 18:23:21 +0200 Subject: [PATCH 13/13] Update changelog for 3.6.4.4 --- debian/changelog | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/debian/changelog b/debian/changelog index e0557021a..bf38802ab 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,14 +1,25 @@ +yunohost (3.6.4.4) stable; urgency=low + + - [fix] Small typo breaking experimental config panel for apps (1224380) + - [mod] Remove the old ugly trick to change the admin password, not needed anymore (1cb0a26) + - [fix] Legit variable getting caught as an info to be redacted by the core (8212010) + - [fix] Exception handling for corrupted metadata about operation logs (#754) + + Contributors: Aleks, Bram, ljf + + -- Alexandre Aubin Sun, 04 Aug 2019 18:20:00 +0000 + yunohost (3.6.4.3) stable; urgency=low - [hotfix] Fix some password-redacting cases that weren't caught up - -- Alexandre Aubin Set, 06 Jul 2019 19:35:00 +0000 + -- Alexandre Aubin Sat, 06 Jul 2019 19:35:00 +0000 yunohost (3.6.4.2) stable; urgency=low - [hotfix] Use the acme-v02 API to fix the newAccount keyError in acme_tiny - -- Alexandre Aubin Set, 06 Jul 2019 18:40:00 +0000 + -- Alexandre Aubin Sat, 06 Jul 2019 18:40:00 +0000 yunohost (3.6.4.1) stable; urgency=low