Commit b387a8ea authored by tous's avatar tous Committed by quaristice
Browse files

Merge remote-tracking branch 'upstream/stable' into HEAD

parents a12c577e 253af106
......@@ -61,7 +61,6 @@ git_only_doc_changes_since() {
'*' \
':!/wiki' \
':!/ikiwiki.setup' \
':!/ikiwiki-cgi.setup' \
':!*.po' \
)"
......
......@@ -8,7 +8,7 @@ rm -f config/gitlab-triage/policies/stalled.yml
./config/gitlab-triage/bin/generate-stalled-policy \
> config/gitlab-triage/policies/stalled.yml
sudo "$(dirname "$0")"/../config/gitlab-triage/bin/gitlab-triage \
"$(dirname "$0")"/../config/gitlab-triage/bin/gitlab-triage \
--source-id tails --source groups \
--policies-file /etc/gitlab-triage-policies/stalled.yml \
"${@}"
......@@ -4,7 +4,7 @@ set -e
set -u
set -x
export DOCKER_ARGS="--env VERSION --env NEXT_PLANNED_VERSION"
export PODMAN_ARGS="--env VERSION --env NEXT_PLANNED_VERSION"
"$(dirname "$0")"/../config/gitlab-triage/bin/gitlab-triage \
--source-id tails --source groups \
......
#! /usr/bin/python3
# Documentation: https://tails.boum.org/contribute/working_together/GitLab/#api
import datetime
import logging
import os
from pathlib import Path
import sys
import dateutil.parser
import gitlab # type: ignore
import django.utils.dateparse # type: ignore
PYTHON_GITLAB_CONFIG_FILE = os.getenv(
"PYTHON_GITLAB_CONFIG_FILE", default=Path.home() / ".python-gitlab.cfg"
)
PYTHON_GITLAB_NAME = os.getenv("GITLAB_NAME", default="Tails")
LOG_FORMAT = "%(asctime)-15s %(levelname)s %(message)s"
log = logging.getLogger()
if __name__ == "__main__":
import argparse
parser = argparse.ArgumentParser()
# Filters
parser.add_argument(
"--blocked", action="store_true", help="Only consider blocked users"
)
parser.add_argument(
"--active", action="store_true", help="Only consider active users"
)
parser.add_argument(
"--deactivated",
action="store_true",
help="Only consider deactivated users",
)
parser.add_argument(
"--min-creation-age",
type=django.utils.dateparse.parse_duration,
required=True,
help="Only consider users created at least this duration ago",
)
parser.add_argument(
"--min-inactivity",
type=django.utils.dateparse.parse_duration,
required=True,
help="Only consider users inactive since this duration",
)
parser.add_argument(
"--max-post-sign-up-activity",
type=django.utils.dateparse.parse_duration,
required=True,
help="Don't consider users who have been active for at least this duration after signing-up",
)
parser.add_argument(
"--max-sign-in-count",
type=int,
default=7,
help="Only consider users who have not signed-in more often than this",
)
parser.add_argument(
"--max-issues-events",
type=int,
default=0,
help="Only consider users who have not acted on issues more often than this",
)
parser.add_argument(
"--not-in-group",
type=str,
default="contributors-team",
help="Only consider users who are not members of this group",
)
parser.add_argument(
"--search",
type=str,
help="Only consider users who satisfy this search criterion",
)
parser.add_argument(
"--email-ends-with",
type=str,
help="Only consider users whose email address ends with this string",
)
# Actions
parser.add_argument(
"--action",
type=str,
help="Action to take on selected users, among: deactivate, block, deactivate-or-block, delete",
)
# General behavior control
parser.add_argument("--debug", action="store_true", help="debug output")
parser.add_argument(
"--dry-run",
action="store_true",
help="Don't actually update anything, just print",
)
args = parser.parse_args()
if args.deactivated and args.active:
sys.exit("Cannot use --deactivated and --active at the same time")
if args.debug:
logging.basicConfig(level=logging.DEBUG, format=LOG_FORMAT)
else:
logging.basicConfig(level=logging.INFO, format=LOG_FORMAT)
gl = gitlab.Gitlab.from_config(
PYTHON_GITLAB_NAME, config_files=[PYTHON_GITLAB_CONFIG_FILE]
)
gl.auth()
now = datetime.datetime.now(tz=datetime.timezone.utc)
max_creation_date = now - args.min_creation_age
log.debug("Max creation date: %s", max_creation_date)
max_activity_date = now - args.min_inactivity
log.debug("Max activity date: %s", max_activity_date)
log.debug("Max post-sign-up activity: %s", args.max_post_sign_up_activity)
if args.not_in_group is not None:
group = [
g
for g in gl.groups.list(all=True)
# Disambiguate between groups whose names share a common prefix
if g.full_path == args.not_in_group
][0]
group_members_ids = [m.id for m in group.members.all(all=True)]
else:
group_members_ids = []
log.debug("Group members: %s", group_members_ids)
user_filters = {
"exclude_internal": True,
"two_factor": "disabled",
}
if args.blocked:
user_filters["blocked"] = True
if args.active:
user_filters["active"] = True
if args.search is not None:
user_filters["search"] = args.search
users = gl.users.list(all=True, **user_filters)
log.debug("Users: %s", users)
for user in users:
user_desc = f"{user.username} (id={user.id})"
# Filter out users we don't want to act upon
if args.deactivated and user.state != "deactivated":
log.debug(
"User %s is not deactivated (state: %s) ⇒ skipping",
user_desc,
user.state,
)
continue
if dateutil.parser.isoparse(user.created_at) < max_creation_date:
log.info(
"User %s was created more than %s ago",
user_desc,
args.min_creation_age,
)
else:
log.debug(
"User %s was created less than %s ago ⇒ skipping",
user_desc,
args.min_creation_age,
)
continue
if user.last_activity_on is None:
log.info("User %s was never active", user_desc)
elif (
dateutil.parser.isoparse(user.last_activity_on + "T00Z")
< max_activity_date
):
log.info(
"User %s is inactive since at least %s",
user_desc,
args.min_inactivity,
)
else:
log.debug(
"User %s was active in the last %s ⇒ skipping",
user_desc,
args.min_inactivity,
)
continue
if (
user.last_activity_on is not None
and args.max_post_sign_up_activity is not None
):
created_at = dateutil.parser.isoparse(user.created_at)
last_activity_on = dateutil.parser.isoparse(
user.last_activity_on + "T00Z"
)
if last_activity_on < created_at + args.max_post_sign_up_activity:
log.info(
"User %s has not been active for more than %s after sign-up",
user_desc,
args.max_post_sign_up_activity,
)
else:
log.debug(
"User %s has been active for more than %s after sign-up ⇒ skipping",
user_desc,
args.max_post_sign_up_activity,
)
continue
if user.id in group_members_ids:
log.info(
"User %s is in group %s ⇒ skipping",
user_desc,
args.not_in_group,
)
continue
if args.email_ends_with is not None:
if user.email.endswith(args.email_ends_with):
log.info("User %s has an email address that ends with %s", user_desc, args.email_ends_with)
else:
log.debug("User %s has no email address that ends with %s", user_desc, args.email_ends_with)
continue
user_obj = gl.users.get(user.id)
if user_obj.sign_in_count <= args.max_sign_in_count:
log.info(
"User %s has signed-in %i <= %i times",
user_desc,
user_obj.sign_in_count,
args.max_sign_in_count,
)
else:
log.debug(
"User %s has signed-in %i > %i times ⇒ skipping",
user_desc,
user_obj.sign_in_count,
args.max_sign_in_count,
)
continue
events = user_obj.events.list()
issues_events = [
e for e in events if e.target_type in ["Note", "DiscussionNote", "Issue"]
]
if len(issues_events) <= args.max_issues_events:
log.info(
"User %s has done less than %i operations on issues",
user_desc,
args.max_issues_events,
)
else:
log.debug(
"User %s has done at least %i operations on issues ⇒ skipping",
user_desc,
len(issues_events),
)
continue
# If we reached this point, perform args.action
if args.action == "deactivate":
if user.state == "blocked":
log.debug(
"User %s is already blocked, cannot deactivate", user_desc
)
elif user.state == "deactivated":
log.debug("User %s is already deactivated", user_desc)
else:
log.info(
"Deactivating user %s (previous state: %s)",
user_desc,
user.state,
)
if not args.dry_run:
user.deactivate()
elif args.action == "block":
if user.state == "blocked":
log.debug("User %s is already blocked", user_desc)
else:
log.info(
"Blocking user %s (previous state: %s)",
user_desc,
user.state,
)
if not args.dry_run:
user.block()
elif args.action == "deactivate-or-block":
if user.state in ["blocked", "deactivated"]:
log.debug("User %s is already %s", user_desc, user.state)
else:
log.info(
"Deactivating user %s (previous state: %s)",
user_desc,
user.state,
)
if not args.dry_run:
try:
user.deactivate()
# The GitLab API forbids deactivating a user who
# has been active in the past 90 days, so block them.
except gitlab.exceptions.GitlabDeactivateError:
log.info(
"Deactivating user %s (previous state: %s) failed, so blocking them",
user_desc,
user.state,
)
user.block()
elif args.action == "delete":
raise NotImplementedError("User deletion is not implemented yet.")
else:
sys.exit("Unsupported action: %s" % args.action)
......@@ -3,7 +3,7 @@
set -e
set -u
IGNORED_TAGS="4.2.1"
IGNORED_TAGS="4.2.1 4.19-beta1"
major_version () {
local version="$1"
......
......@@ -23,6 +23,7 @@ echo "${TRACE_TIME:?}" > "${MASTER_CHECKOUT:?}/wiki/src/inc/trace"
(
set -eux
cd "${MASTER_CHECKOUT:?}"
git pull
git commit wiki/src/inc/trace -m "$MESSAGE"
git push origin master
)
......@@ -20,7 +20,7 @@ except ImportError:
try:
from cachecontrol import CacheControlAdapter # type: ignore
from cachecontrol.heuristics import OneDayCache
from cachecontrol.heuristics import OneDayCache # type: ignore
except ImportError:
sys.exit("You need to install python3-cachecontrol to use this program.")
......
#!/bin/sh
set -e
echo "Creating CA bundle for authenticating https://tails.boum.org/"
BUNDLE=/usr/local/etc/ssl/certs/tails.boum.org-CA.pem
mkdir -p $(dirname "${BUNDLE}")
### Last updated: 2021-01-19
# - R3: RSA 2048, active
# - R4: RSA 2048, backup
# - E1: ECDSA P-384, upcoming
# - E2: ECDSA P-384, upcoming backup
# References:
# - https://letsencrypt.org/certificates/
# - https://letsencrypt.org/2020/09/17/new-root-and-intermediates.html
cat \
/usr/share/tails/certs/lets-encrypt-r3.pem \
/usr/share/tails/certs/lets-encrypt-r4.pem \
/usr/share/tails/certs/lets-encrypt-e1.pem \
/usr/share/tails/certs/lets-encrypt-e2.pem \
> "$BUNDLE"
chmod a+r "$BUNDLE"
rm \
/usr/share/tails/certs/lets-encrypt-*.pem
-----BEGIN CERTIFICATE-----
MIIEkjCCA3qgAwIBAgIQCgFBQgAAAVOFc2oLheynCDANBgkqhkiG9w0BAQsFADA/
MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
DkRTVCBSb290IENBIFgzMB4XDTE2MDMxNzE2NDA0NloXDTIxMDMxNzE2NDA0Nlow
SjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUxldCdzIEVuY3J5cHQxIzAhBgNVBAMT
GkxldCdzIEVuY3J5cHQgQXV0aG9yaXR5IFgzMIIBIjANBgkqhkiG9w0BAQEFAAOC
AQ8AMIIBCgKCAQEAnNMM8FrlLke3cl03g7NoYzDq1zUmGSXhvb418XCSL7e4S0EF
q6meNQhY7LEqxGiHC6PjdeTm86dicbp5gWAf15Gan/PQeGdxyGkOlZHP/uaZ6WA8
SMx+yk13EiSdRxta67nsHjcAHJyse6cF6s5K671B5TaYucv9bTyWaN8jKkKQDIZ0
Z8h/pZq4UmEUEz9l6YKHy9v6Dlb2honzhT+Xhq+w3Brvaw2VFn3EK6BlspkENnWA
a6xK8xuQSXgvopZPKiAlKQTGdMDQMc2PMTiVFrqoM7hD8bEfwzB/onkxEz0tNvjj
/PIzark5McWvxI0NHWQWM6r6hCm21AvA2H3DkwIDAQABo4IBfTCCAXkwEgYDVR0T
AQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYwfwYIKwYBBQUHAQEEczBxMDIG
CCsGAQUFBzABhiZodHRwOi8vaXNyZy50cnVzdGlkLm9jc3AuaWRlbnRydXN0LmNv
bTA7BggrBgEFBQcwAoYvaHR0cDovL2FwcHMuaWRlbnRydXN0LmNvbS9yb290cy9k
c3Ryb290Y2F4My5wN2MwHwYDVR0jBBgwFoAUxKexpHsscfrb4UuQdf/EFWCFiRAw
VAYDVR0gBE0wSzAIBgZngQwBAgEwPwYLKwYBBAGC3xMBAQEwMDAuBggrBgEFBQcC
ARYiaHR0cDovL2Nwcy5yb290LXgxLmxldHNlbmNyeXB0Lm9yZzA8BgNVHR8ENTAz
MDGgL6AthitodHRwOi8vY3JsLmlkZW50cnVzdC5jb20vRFNUUk9PVENBWDNDUkwu
Y3JsMB0GA1UdDgQWBBSoSmpjBH3duubRObemRWXv86jsoTANBgkqhkiG9w0BAQsF
AAOCAQEA3TPXEfNjWDjdGBX7CVW+dla5cEilaUcne8IkCJLxWh9KEik3JHRRHGJo
uM2VcGfl96S8TihRzZvoroed6ti6WqEBmtzw3Wodatg+VyOeph4EYpr/1wXKtx8/
wApIvJSwtmVi4MFU5aMqrSDE6ea73Mj2tcMyo5jMd6jmeWUHK8so/joWUoHOUgwu
X4Po1QYz+3dszkDqMp4fklxBwXRsW10KXzPMTZ+sOPAveyxindmjkW8lGy+QsRlG
PfZ+G6Z6h7mjem0Y+iWlkYcV4PIWL1iwBi8saCbGS5jN2p8M+X+Q7UNKEkROb3N6
KOqkqm57TH2H3eDJAkSnh6/DNFu0Qg==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIICxjCCAk2gAwIBAgIRALO93/inhFu86QOgQTWzSkUwCgYIKoZIzj0EAwMwTzEL
MAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2VhcmNo
IEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDIwHhcNMjAwOTA0MDAwMDAwWhcN
MjUwOTE1MTYwMDAwWjAyMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNTGV0J3MgRW5j
cnlwdDELMAkGA1UEAxMCRTEwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQkXC2iKv0c
S6Zdl3MnMayyoGli72XoprDwrEuf/xwLcA/TmC9N/A8AmzfwdAVXMpcuBe8qQyWj
+240JxP2T35p0wKZXuskR5LBJJvmsSGPwSSB/GjMH2m6WPUZIvd0xhajggEIMIIB
BDAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMB
MBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFFrz7Sv8NsI3eblSMOpUb89V
yy6sMB8GA1UdIwQYMBaAFHxClq7eS0g7+pL4nozPbYupcjeVMDIGCCsGAQUFBwEB
BCYwJDAiBggrBgEFBQcwAoYWaHR0cDovL3gyLmkubGVuY3Iub3JnLzAnBgNVHR8E
IDAeMBygGqAYhhZodHRwOi8veDIuYy5sZW5jci5vcmcvMCIGA1UdIAQbMBkwCAYG
Z4EMAQIBMA0GCysGAQQBgt8TAQEBMAoGCCqGSM49BAMDA2cAMGQCMHt01VITjWH+
Dbo/AwCd89eYhNlXLr3pD5xcSAQh8suzYHKOl9YST8pE9kLJ03uGqQIwWrGxtO3q
YJkgsTgDyj2gJrjubi1K9sZmHzOa25JK1fUpE8ZwYii6I4zPPS/Lgul/
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIICxjCCAkygAwIBAgIQTtI99q9+x/mwxHJv+VEqdzAKBggqhkjOPQQDAzBPMQsw
CQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJuZXQgU2VjdXJpdHkgUmVzZWFyY2gg
R3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBYMjAeFw0yMDA5MDQwMDAwMDBaFw0y
NTA5MTUxNjAwMDBaMDIxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNy
eXB0MQswCQYDVQQDEwJFMjB2MBAGByqGSM49AgEGBSuBBAAiA2IABCOaLO3lixmN
YVWex+ZVYOiTLgi0SgNWtU4hufk50VU4Zp/LbBVDxCsnsI7vuf4xp4Cu+ETNggGE
yBqJ3j8iUwe5Yt/qfSrRf1/D5R58duaJ+IvLRXeASRqEL+VkDXrW3qOCAQgwggEE
MA4GA1UdDwEB/wQEAwIBhjAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEw
EgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUbZkq9U0C6+MRwWC6km+NPS7x
6kQwHwYDVR0jBBgwFoAUfEKWrt5LSDv6kviejM9ti6lyN5UwMgYIKwYBBQUHAQEE
JjAkMCIGCCsGAQUFBzAChhZodHRwOi8veDIuaS5sZW5jci5vcmcvMCcGA1UdHwQg
MB4wHKAaoBiGFmh0dHA6Ly94Mi5jLmxlbmNyLm9yZy8wIgYDVR0gBBswGTAIBgZn
gQwBAgEwDQYLKwYBBAGC3xMBAQEwCgYIKoZIzj0EAwMDaAAwZQIxAPJCN9qpyDmZ
tX8K3m8UYQvK51BrXclM6WfrdeZlUBKyhTXUmFAtJw4X6A0x9mQFPAIwJa/No+KQ
UAM1u34E36neL/Zba7ombkIOchSgx1iVxzqtFWGddgoG+tppRPWhuhhn
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIFFjCCAv6gAwIBAgIRAJErCErPDBinU/bWLiWnX1owDQYJKoZIhvcNAQELBQAw
TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMjAwOTA0MDAwMDAw
WhcNMjUwOTE1MTYwMDAwWjAyMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNTGV0J3Mg
RW5jcnlwdDELMAkGA1UEAxMCUjMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
AoIBAQC7AhUozPaglNMPEuyNVZLD+ILxmaZ6QoinXSaqtSu5xUyxr45r+XXIo9cP
R5QUVTVXjJ6oojkZ9YI8QqlObvU7wy7bjcCwXPNZOOftz2nwWgsbvsCUJCWH+jdx
sxPnHKzhm+/b5DtFUkWWqcFTzjTIUu61ru2P3mBw4qVUq7ZtDpelQDRrK9O8Zutm
NHz6a4uPVymZ+DAXXbpyb/uBxa3Shlg9F8fnCbvxK/eG3MHacV3URuPMrSXBiLxg
Z3Vms/EY96Jc5lP/Ooi2R6X/ExjqmAl3P51T+c8B5fWmcBcUr2Ok/5mzk53cU6cG
/kiFHaFpriV1uxPMUgP17VGhi9sVAgMBAAGjggEIMIIBBDAOBgNVHQ8BAf8EBAMC
AYYwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMBMBIGA1UdEwEB/wQIMAYB
Af8CAQAwHQYDVR0OBBYEFBQusxe3WFbLrlAJQOYfr52LFMLGMB8GA1UdIwQYMBaA
FHm0WeZ7tuXkAXOACIjIGlj26ZtuMDIGCCsGAQUFBwEBBCYwJDAiBggrBgEFBQcw
AoYWaHR0cDovL3gxLmkubGVuY3Iub3JnLzAnBgNVHR8EIDAeMBygGqAYhhZodHRw
Oi8veDEuYy5sZW5jci5vcmcvMCIGA1UdIAQbMBkwCAYGZ4EMAQIBMA0GCysGAQQB
gt8TAQEBMA0GCSqGSIb3DQEBCwUAA4ICAQCFyk5HPqP3hUSFvNVneLKYY611TR6W
PTNlclQtgaDqw+34IL9fzLdwALduO/ZelN7kIJ+m74uyA+eitRY8kc607TkC53wl
ikfmZW4/RvTZ8M6UK+5UzhK8jCdLuMGYL6KvzXGRSgi3yLgjewQtCPkIVz6D2QQz
CkcheAmCJ8MqyJu5zlzyZMjAvnnAT45tRAxekrsu94sQ4egdRCnbWSDtY7kh+BIm
lJNXoB1lBMEKIq4QDUOXoRgffuDghje1WrG9ML+Hbisq/yFOGwXD9RiX8F6sw6W4
avAuvDszue5L3sz85K+EC4Y/wFVDNvZo4TYXao6Z0f+lQKc0t8DQYzk1OXVu8rp2
yJMC6alLbBfODALZvYH7n7do1AZls4I9d1P4jnkDrQoxB3UqQ9hVl3LEKQ73xF1O
yK5GhDDX8oVfGKF5u+decIsH4YaTw7mP3GFxJSqv3+0lUFJoi5Lc5da149p90Ids
hCExroL1+7mryIkXPeFM5TgO9r0rvZaBFOvV2z0gp35Z0+L4WPlbuEjN/lxPFin+
HlUjr8gRsI3qfJOQFy/9rKIJR0Y/8Omwt/8oTWgy1mdeHmmjk7j1nYsvC9JSQ6Zv
MldlTTKB3zhThV1+XWYp6rjd5JW1zbVWEkLNxE7GJThEUG3szgBVGP7pSWTUTsqX
nLRbwHOoq7hHwg==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIFFjCCAv6gAwIBAgIRAIp5IlCr5SxSbO7Pf8lC3WIwDQYJKoZIhvcNAQELBQAw
TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMjAwOTA0MDAwMDAw
WhcNMjUwOTE1MTYwMDAwWjAyMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNTGV0J3Mg
RW5jcnlwdDELMAkGA1UEAxMCUjQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
AoIBAQCzKNx3KdPnkb7ztwoAx/vyVQslImNTNq/pCCDfDa8oPs3Gq1e2naQlGaXS
Mm1Jpgi5xy+hm5PFIEBrhDEgoo4wYCVg79kaiT8faXGy2uo/c0HEkG9m/X2eWNh3
z81ZdUTJoQp7nz8bDjpmb7Z1z4vLr53AcMX/0oIKr13N4uichZSk5gA16H5OOYHH
IYlgd+odlvKLg3tHxG0ywFJ+Ix5FtXHuo+8XwgOpk4nd9Z/buvHa4H6Xh3GBHhqC
VuQ+fBiiCOUWX6j6qOBIUU0YFKAMo+W2yrO1VRJrcsdafzuM+efZ0Y4STTMzAyrx
E+FCPMIuWWAubeAHRzNl39Jnyk2FAgMBAAGjggEIMIIBBDAOBgNVHQ8BAf8EBAMC
AYYwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMBMBIGA1UdEwEB/wQIMAYB
Af8CAQAwHQYDVR0OBBYEFDadPuCxQPYnLHy/jZ0xivZUpkYmMB8GA1UdIwQYMBaA
FHm0WeZ7tuXkAXOACIjIGlj26ZtuMDIGCCsGAQUFBwEBBCYwJDAiBggrBgEFBQcw
AoYWaHR0cDovL3gxLmkubGVuY3Iub3JnLzAnBgNVHR8EIDAeMBygGqAYhhZodHRw
Oi8veDEuYy5sZW5jci5vcmcvMCIGA1UdIAQbMBkwCAYGZ4EMAQIBMA0GCysGAQQB
gt8TAQEBMA0GCSqGSIb3DQEBCwUAA4ICAQCJbu5CalWO+H+Az0lmIG14DXmlYHQE
k26umjuCyioWs2icOlZznPTcZvbfq02YPHGTCu3ctggVDULJ+fwOxKekzIqeyLNk
p8dyFwSAr23DYBIVeXDpxHhShvv0MLJzqqDFBTHYe1X5X2Y7oogy+UDJxV2N24/g
Z8lxG4Vr2/VEfUOrw4Tosl5Z+1uzOdvTyBcxD/E5rGgTLczmulctHy3IMTmdTFr0
FnU0/HMQoquWQuODhFqzMqNcsdbjANUBwOEQrKI8Sy6+b84kHP7PtO+S4Ik8R2k7
ZeMlE1JmxBi/PZU860YlwT8/qOYToCHVyDjhv8qutbf2QnUl3SV86th2I1QQE14s
0y7CdAHcHkw3sAEeYGkwCA74MO+VFtnYbf9B2JBOhyyWb5087rGzitu5MTAW41X9
DwTeXEg+a24tAeht+Y1MionHUwa4j7FB/trN3Fnb/r90+4P66ZETVIEcjseUSMHO
w6yqv10/H/dw/8r2EDUincBBX3o9DL3SadqragkKy96HtMiLcqMMGAPm0gti1b6f
bnvOdr0mrIVIKX5nzOeGZORaYLoSD4C8qvFT7U+Um6DMo36cVDNsPmkF575/s3C2
CxGiCPQqVxPgfNSh+2CPd2Xv04lNeuw6gG89DlOhHuoFKRlmPnom+gwqhz3ZXMfz
TfmvjrBokzCICA==
-----END CERTIFICATE-----
http://torbrowser-archive.tails.boum.org/10.0.16-build1/
http://torbrowser-archive.tails.boum.org/10.0.17-build1/
fc0acea2d62767a67038296e0cc041dea2bc7b80ca5dc9333d0173ce4c7b021e tor-browser-linux64-10.0.16_en-US.tar.xz
f6580761e819581a8f2b8bd9dc470078bceefe58ef5d42413517e8f41022061e langpacks-tor-browser-linux64-10.0.16.tar.xz
55d404c251b6e0f111d8fb9d57ffd7454cd12952cd0927c197bde2cd8245a38f tor-browser-linux64-10.0.17_en-US.tar.xz
518173be5b0e008a847defb3a1ac50ad0f32b9eb1f2f94e305892da419f045b0 langpacks-tor-browser-linux64-10.0.17.tar.xz
......@@ -56,12 +56,12 @@ method _build_curl_opts () {
push @opts, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5_HOSTNAME;
push @opts, CURLOPT_PROXY, '127.0.0.1:9062';
}
my $cafile = $ENV{HTTPS_CA_FILE};
$cafile //= '/usr/local/etc/ssl/certs/tails.boum.org-CA.pem';
if ($ENV{HARNESS_ACTIVE}) {
# Trust the additional Certificate Authority requested by the test suite
push @opts, CURLOPT_CAINFO, $ENV{HTTPS_CA_FILE};
}
push @opts, CURLOPT_SSL_VERIFYHOST, 2;
push @opts, CURLOPT_SSL_VERIFYPEER, 1;
push @opts, CURLOPT_CAINFO, $cafile;
push @opts, CURLOPT_CAPATH, '';
push @opts, CURLOPT_PROTOCOLS, CURLPROTO_HTTPS;
push @opts, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTPS;
my %opts = @opts;
......
......@@ -222,7 +222,7 @@ method _build__presets () {
id => 'Dotfiles',
name => __(q{Dotfiles}),
description => __(
q{Symlink into $HOME every file or directory found in the `dotfiles' directory}
q{Symlink every file in the Dotfiles folder into the Home folder}
),
icon_name => 'preferences-desktop',
enabled => 0,
......
Section: python
Priority: optional
Homepage: https://tails.boum.org/
Standards-Version: 3.9.6
Package: libpython-stdlib
Version: 2.7.17-2.0tails1
Maintainer: Tails developers <tails@boum.org>
Architecture: amd64
Multi-Arch: allowed
Depends: libpython2-stdlib
Description: (Fake) libpython-stdlib
Dummy package that meet the dependencies of the obsolete bits of Tails'
build & test system (#15349, #17031).