Compare commits
33 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cb5965263c | ||
|
|
a96fdb7828 | ||
|
|
e2cc44637e | ||
|
|
c41bfb7f57 | ||
|
|
91e84d7225 | ||
|
|
ac00c1c43e | ||
|
|
f66dd5959a | ||
|
|
11b4bc888d | ||
|
|
d0da9ba348 | ||
|
|
c0325ba991 | ||
|
|
5614e7fd15 | ||
|
|
a24ade1723 | ||
|
|
51195094a8 | ||
|
|
6196b1a0ed | ||
|
|
4c3d6134a6 | ||
|
|
4ec0479c68 | ||
|
|
a9d75e6644 | ||
|
|
e84794303a | ||
|
|
8ae612179c | ||
|
|
6606afa0cd | ||
|
|
e96af0a3c9 | ||
|
|
6a6a98e3c3 | ||
|
|
de07a8cc67 | ||
|
|
766eae26ed | ||
|
|
23a0e06149 | ||
|
|
6859d7092c | ||
|
|
1d4a4aa823 | ||
|
|
e62eb5289d | ||
|
|
2cc9f0adbf | ||
|
|
c9d3920f74 | ||
|
|
bfa7928076 | ||
|
|
038d15cdf3 | ||
|
|
651e6647bb |
9 changed files with 199 additions and 52 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -4,3 +4,6 @@
|
|||
/*.src.rpm
|
||||
/.build-*
|
||||
/acme-tiny-4.1.0.tar.gz
|
||||
/results_acme-tiny
|
||||
/acme-tiny-4.1.1.tar.gz
|
||||
/acme-tiny-5.0.1.tar.gz
|
||||
|
|
|
|||
|
|
@ -1,3 +1,8 @@
|
|||
# acme-tiny-core Fedora package
|
||||
|
||||
This package contains only the upstream python script - for those
|
||||
who prefer their own framework for cert maintenance.
|
||||
|
||||
# acme-tiny Fedora package
|
||||
|
||||
The Fedora package for acme-tiny adds a tiny framework to make issuing
|
||||
|
|
@ -100,28 +105,32 @@ Sendmail is a special problem - it insists that any certificates it loads be
|
|||
only writable by root. This is at odds with the privilege separation of the
|
||||
acme user. (Obviously, the private key must be accessible only by root.) You
|
||||
can, of course, copy the crt file to `/etc/pki/tls/certs` as root and change
|
||||
the mode. But this has to be done every time the cert is renewed. You can
|
||||
install `incron` to do this. After installing, create `/etc/incron.d/acme`
|
||||
with the line
|
||||
```
|
||||
/var/lib/acme/certs/mail.crt IN_MOVED_TO /etc/acme-tiny/notify.sh $@
|
||||
```
|
||||
where `mail.crt` is the certificate sendmail will use. The notify.sh script
|
||||
the mode. But this has to be done every time the cert is renewed.
|
||||
The systemd `acme-tiny.service` runs `acme-tiny-notify.service`
|
||||
afterward which executes as root. It calls
|
||||
`/usr/libexec/acme-tiny/notify` for each nenewed cert. (This used
|
||||
to be `/etc/acme-tiny/notify.sh` - which is now a symlink.)
|
||||
|
||||
Suppose `/var/lib/acme/certs/mail.crt` is renewed, where `mail.crt` is the
|
||||
certificate sendmail will use. The notify script
|
||||
sees the reference to `/etc/pki/tls/certs/mail.crt` in `/etc/mail/*.cf`, and
|
||||
copies it to `/etc/pki/tls/certs`. Sendmail can then load it from there and be
|
||||
happy. This also solves the file context problem if you add lines for other
|
||||
certificates. You might wonder why we don't simply supply an acme incrontab as
|
||||
part of the package with a wildcard, for example:
|
||||
```
|
||||
/var/lib/acme/certs/*.crt IN_MOVED_TO /etc/acme-tiny/notify.sh $@
|
||||
```
|
||||
The answer is that incron is insecure, and very nasty things can be
|
||||
done by putting shell meta characters (including semicolon and quote!) in
|
||||
filenames that then become part of a command run as root. The first example
|
||||
above uses a fixed filename, so that is safe. Complain to incron
|
||||
upstream - they need an option to use a simple execvpe instead of
|
||||
using the shell. Then it would at least be possible to carefully
|
||||
handle [malicious names](https://www.xkcd.com/327/).
|
||||
copies the renewed cert to `/etc/pki/tls/certs`. Sendmail can then load it
|
||||
from there and be happy. This also solves the file context problem.
|
||||
|
||||
The notify script has built in support for the httpd, sendmail, and dovecot
|
||||
packages for Fedora. To avoid restarting services multiple times,
|
||||
the notify script records in `/var/lib/acme/.notify`
|
||||
when it last restarted each service.
|
||||
|
||||
By dropping scripts with names ending in `.sh` in `/etc/acme-tiny/notify.d`,
|
||||
additional packages (e.g. nginx) can be supported.
|
||||
|
||||
This new system should be compatible with older incrond configs,
|
||||
but the additional `/etc/acme-tiny/notify.sh` calls from incrond are redundant.
|
||||
Making them redundant, incidentally fixes
|
||||
[BZ#1839904](https://bugzilla.redhat.com/show_bug.cgi?id=1839904). There
|
||||
could still be a race condition missed in testing, so I would disable your old
|
||||
acme incrontab.
|
||||
|
||||
## Logging and Error Reporting
|
||||
|
||||
|
|
@ -140,3 +149,4 @@ so notify.sh simply does `apachectl graceful`.
|
|||
Put all the CSRs in `/var/lib/acme/csr` and the acme-tiny service will keep
|
||||
them all renewed. This also works for certificates used by other SSL
|
||||
applications, such as dovecot, sendmail, jabberd, or znc.
|
||||
|
||||
|
|
|
|||
8
acme-tiny-notify.service
Normal file
8
acme-tiny-notify.service
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
[Unit]
|
||||
Description=Notify services of updates to acme certs
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
Nice=19
|
||||
SyslogIdentifier=acme-tiny
|
||||
ExecStart=/usr/libexec/acme-tiny/notify --scan
|
||||
14
acme-tiny-sign.sh
Normal file → Executable file
14
acme-tiny-sign.sh
Normal file → Executable file
|
|
@ -1,11 +1,20 @@
|
|||
#!/bin/sh
|
||||
#!/bin/bash
|
||||
|
||||
if test "$(id -u)" -eq 0; then
|
||||
echo "Do not run as root!"
|
||||
exit 2
|
||||
fi
|
||||
|
||||
DAYS="${1:-7}"
|
||||
. /etc/sysconfig/acme-tiny
|
||||
DAYS="${1:-$DAYS}"
|
||||
test -n "$DAYS" || DAYS="7"
|
||||
if [[ "$DAYS" =~ ^[0-9]+$ ]]; then
|
||||
echo "Days before expiration: $DAYS"
|
||||
secs=$(( $DAYS * 24 * 60 * 60 ))
|
||||
else
|
||||
echo "Invalid number of days: $DAYS"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd /var/lib/acme
|
||||
|
||||
|
|
@ -22,7 +31,6 @@ for csr in csr/*.csr; do
|
|||
crt="${csr%%.csr}"
|
||||
tmp="certs/${crt##csr/}.tmp"
|
||||
crt="certs/${crt##csr/}.crt"
|
||||
secs=$(( "$DAYS" * 24 * 60 * 60 ))
|
||||
if test -s "$crt" && openssl x509 -in "$crt" -noout -checkend "$secs"; then
|
||||
continue
|
||||
fi
|
||||
|
|
|
|||
4
acme-tiny.conf
Normal file
4
acme-tiny.conf
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
# Default settings for acme-tiny wrapper script
|
||||
|
||||
# Number of days before expiration to renew a certificate
|
||||
DAYS=7
|
||||
|
|
@ -1,5 +1,7 @@
|
|||
[Unit]
|
||||
Description=Check for acme certs about to expire
|
||||
Wants=acme-tiny-notify.service
|
||||
Before=acme-tiny-notify.service
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
|
|
@ -9,7 +11,7 @@ ProtectSystem=true
|
|||
User=acme
|
||||
Group=acme
|
||||
SyslogIdentifier=acme-tiny
|
||||
ExecStart=/usr/libexec/acme-tiny/sign 7
|
||||
ExecStart=/usr/libexec/acme-tiny/sign
|
||||
|
||||
[Install]
|
||||
Also=acme-tiny.timer
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@
|
|||
%endif
|
||||
|
||||
Name: acme-tiny
|
||||
Version: 4.1.0
|
||||
Release: 3%{?dist}
|
||||
Version: 5.0.1
|
||||
Release: 13%{?dist}
|
||||
Summary: Tiny auditable script to issue, renew Let's Encrypt certificates
|
||||
|
||||
License: MIT
|
||||
|
|
@ -23,10 +23,11 @@ Source7: acme-tiny.service
|
|||
Source8: README-fedora.md
|
||||
# simple script hook to kick services when cert is updated
|
||||
Source9: notify.sh
|
||||
Source10: acme-tiny-notify.service
|
||||
Source11: acme-tiny.conf
|
||||
|
||||
Requires(pre): shadow-utils
|
||||
# systemd macros are not defined unless systemd is present
|
||||
BuildRequires: systemd
|
||||
BuildRequires: systemd-rpm-macros
|
||||
%{?systemd_requires}
|
||||
Requires: %{name}-core = %{version}-%{release}
|
||||
BuildArch: noarch
|
||||
|
|
@ -47,7 +48,7 @@ This package adds a simple directory layout and timer service that runs
|
|||
acme_tiny on installed CSRs as the acme user for privilege separation.
|
||||
|
||||
%package core
|
||||
Summary: core python module of acme-tiny
|
||||
Summary: Core python module of acme-tiny
|
||||
Requires: openssl
|
||||
%if 0%{?rhel} >= 5 && 0%{?rhel} < 7
|
||||
# EL6 uses python2.6, which does not include argparse
|
||||
|
|
@ -68,6 +69,8 @@ sed -i.orig -e '1,1 s,^.*python$,#!/usr/bin/python,' acme_tiny.py
|
|||
sed -i.old -e '1,1 s/python$/python3/' *.py
|
||||
%endif
|
||||
|
||||
echo 'u acme - "Tiny Auditable ACME Client" %{_sharedstatedir}/acme' >acme.sysusers.conf
|
||||
|
||||
%build
|
||||
|
||||
%install
|
||||
|
|
@ -75,20 +78,25 @@ mkdir -p %{buildroot}/var/www/challenges
|
|||
mkdir -p %{buildroot}%{_sysconfdir}/httpd/conf.d
|
||||
mkdir -p %{buildroot}%{_sbindir}
|
||||
mkdir -p %{buildroot}%{_libexecdir}/%{name}
|
||||
mkdir -p %{buildroot}%{_sharedstatedir}/acme/{private,csr,certs}
|
||||
mkdir -p %{buildroot}%{_sharedstatedir}/acme/{private,csr,certs,.notify}
|
||||
mkdir -p %{buildroot}%{_sysconfdir}/%{name}/notify.d
|
||||
mkdir -p %{buildroot}%{_sysconfdir}/sysconfig
|
||||
chmod 0700 %{buildroot}%{_sharedstatedir}/acme/private
|
||||
|
||||
install -m 0755 acme-tiny-sign.sh %{buildroot}%{_libexecdir}/%{name}/sign
|
||||
install -m 0755 %{SOURCE9} %{buildroot}%{_libexecdir}/%{name}/notify
|
||||
install -m 0755 acme_tiny.py %{buildroot}%{_sbindir}/acme_tiny
|
||||
ln -sf acme_tiny %{buildroot}%{_sbindir}/%{name}
|
||||
ln -sf %{_libexecdir}/%{name}/sign %{buildroot}%{_sbindir}/acme-tiny-sign
|
||||
ln -sf %{_libexecdir}/%{name}/notify %{buildroot}%{_sysconfdir}/%{name}/notify.sh
|
||||
install -m 0755 cert-check.py %{buildroot}%{_sbindir}/cert-check
|
||||
install -m 0644 %{SOURCE3} %{buildroot}%{_sysconfdir}/httpd/conf.d
|
||||
install -m 0755 %{SOURCE9} %{buildroot}%{_sysconfdir}/%{name}
|
||||
mkdir -p %{buildroot}%{_unitdir}
|
||||
install -pm 644 %{SOURCE6} %{buildroot}%{_unitdir}
|
||||
install -pm 644 %{SOURCE7} %{buildroot}%{_unitdir}
|
||||
install -pm 644 %{SOURCE10} %{buildroot}%{_unitdir}
|
||||
install -m 0644 %{SOURCE11} %{buildroot}%{_sysconfdir}/sysconfig/%{name}
|
||||
install -m 0644 -D acme.sysusers.conf %{buildroot}%{_sysusersdir}/acme.conf
|
||||
|
||||
%pre
|
||||
getent group acme > /dev/null || groupadd -r acme
|
||||
|
|
@ -98,13 +106,13 @@ getent passwd acme > /dev/null || /usr/sbin/useradd -g acme \
|
|||
exit 0
|
||||
|
||||
%post
|
||||
%systemd_post acme-tiny.service acme-tiny.timer
|
||||
%systemd_post acme-tiny.service acme-tiny-notice.service acme-tiny.timer
|
||||
|
||||
%postun
|
||||
%systemd_postun_with_restart acme-tiny.service acme-tiny.timer
|
||||
%systemd_postun_with_restart acme-tiny.service acme-tiny-notice.service acme-tiny.timer
|
||||
|
||||
%preun
|
||||
%systemd_preun acme-tiny.service acme-tiny.timer
|
||||
%systemd_preun acme-tiny.service acme-tiny-notice.service acme-tiny.timer
|
||||
|
||||
%files
|
||||
%{!?_licensedir:%global license %%doc}
|
||||
|
|
@ -114,11 +122,13 @@ exit 0
|
|||
%attr(-,acme,acme) %{_sharedstatedir}/acme
|
||||
%{_libexecdir}/%{name}
|
||||
%config(noreplace) %{_sysconfdir}/httpd/conf.d/acme.conf
|
||||
%config(noreplace) %{_sysconfdir}/sysconfig/%{name}
|
||||
%{_unitdir}/*
|
||||
%{_sbindir}/acme-tiny-sign
|
||||
%{_sbindir}/cert-check
|
||||
%{_sbindir}/%{name}
|
||||
%{_sysconfdir}/%{name}
|
||||
%{_sysusersdir}/acme.conf
|
||||
|
||||
%files core
|
||||
%license LICENSE
|
||||
|
|
@ -126,6 +136,69 @@ exit 0
|
|||
%{_sbindir}/acme_tiny
|
||||
|
||||
%changelog
|
||||
* Fri Jan 16 2026 Fedora Release Engineering <releng@fedoraproject.org> - 5.0.1-13
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_44_Mass_Rebuild
|
||||
|
||||
* Wed Jul 23 2025 Fedora Release Engineering <releng@fedoraproject.org> - 5.0.1-12
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild
|
||||
|
||||
* Thu Jan 16 2025 Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> - 5.0.1-11
|
||||
- Add sysusers.d config file
|
||||
|
||||
* Thu Jan 16 2025 Fedora Release Engineering <releng@fedoraproject.org> - 5.0.1-10
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild
|
||||
|
||||
* Wed Jul 17 2024 Fedora Release Engineering <releng@fedoraproject.org> - 5.0.1-9
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild
|
||||
|
||||
* Mon Jan 22 2024 Fedora Release Engineering <releng@fedoraproject.org> - 5.0.1-8
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
|
||||
|
||||
* Fri Jan 19 2024 Fedora Release Engineering <releng@fedoraproject.org> - 5.0.1-7
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
|
||||
|
||||
* Wed Jul 19 2023 Fedora Release Engineering <releng@fedoraproject.org> - 5.0.1-6
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild
|
||||
|
||||
* Tue Mar 28 2023 Stuart D. Gathman <stuart@gathman.org> - 5.0.1-5
|
||||
- Verified SPDX license
|
||||
|
||||
* Wed Jan 18 2023 Fedora Release Engineering <releng@fedoraproject.org> - 5.0.1-4
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild
|
||||
|
||||
* Wed Jul 20 2022 Fedora Release Engineering <releng@fedoraproject.org> - 5.0.1-3
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild
|
||||
|
||||
* Wed Jan 19 2022 Fedora Release Engineering <releng@fedoraproject.org> - 5.0.1-2
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild
|
||||
|
||||
* Thu Oct 28 2021 Stuart D. Gathman <stuart@gathman.org> 5.0.1-1
|
||||
- New upstream release
|
||||
|
||||
* Wed Sep 8 2021 Stuart D. Gathman <stuart@gathman.org> 4.1.1-2
|
||||
- Remove CLI override in acme-tiny.service (uses /etc/sysconfig/acme-tiny now)
|
||||
|
||||
* Tue Sep 7 2021 Stuart D. Gathman <stuart@gathman.org> 4.1.1-1
|
||||
- New upstream release
|
||||
- Set days before expiration in /etc/sysconfig
|
||||
|
||||
* Wed Jul 21 2021 Fedora Release Engineering <releng@fedoraproject.org> - 4.1.0-8
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild
|
||||
|
||||
* Thu May 27 2021 Stuart D. Gathman <stuart@gathman.org> 4.1.0-7
|
||||
- Fix BZ#1839904
|
||||
- enhance notify after cert update, incrond no longer needed
|
||||
|
||||
* Tue Mar 02 2021 Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> - 4.1.0-6
|
||||
- Rebuilt for updated systemd-rpm-macros
|
||||
See https://pagure.io/fesco/issue/2583.
|
||||
|
||||
* Mon Jan 25 2021 Fedora Release Engineering <releng@fedoraproject.org> - 4.1.0-5
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild
|
||||
|
||||
* Mon Jul 27 2020 Fedora Release Engineering <releng@fedoraproject.org> - 4.1.0-4
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild
|
||||
|
||||
* Thu Apr 9 2020 Stuart D. Gathman <stuart@gathman.org> 4.1.0-3
|
||||
- Update README-fedora.md to describe notify.sh
|
||||
- Apply selected changes from Marcel Metz <mmetz@adrian-broher.net>:
|
||||
|
|
|
|||
70
notify.sh
70
notify.sh
|
|
@ -1,20 +1,58 @@
|
|||
#!/bin/sh
|
||||
#!/usr/bin/sh
|
||||
|
||||
cert="$1"
|
||||
name="${cert##*/}"
|
||||
script="/etc/acme-tiny/notify.d/${name%.crt}.sh"
|
||||
acmedir="/var/lib/acme"
|
||||
#acmedir="test"
|
||||
notify="${acmedir}/.notify"
|
||||
verbose="n"
|
||||
mkdir -p "$notify"
|
||||
|
||||
# kick apache if cert is mentioned
|
||||
if grep "$cert" /etc/httpd/conf.d/*.conf >/dev/null 2>&1; then
|
||||
apachectl graceful
|
||||
fi
|
||||
scancerts() {
|
||||
if test -e "${notify}/notify"; then
|
||||
find "${acmedir}/certs" -name '*.crt' -newer "${notify}/notify" -print0
|
||||
else
|
||||
find "${acmedir}/certs" -name '*.crt' -print0
|
||||
fi | xargs -0 /usr/libexec/acme-tiny/notify -v
|
||||
touch "${notify}/notify"
|
||||
}
|
||||
|
||||
# kick sendmail if cert is mentioned
|
||||
if grep "/etc/pki/tls/certs/$name" /etc/mail/*.cf >/dev/null 2>&1; then
|
||||
cp "$cert" /etc/pki/tls/certs && systemctl restart sendmail
|
||||
fi
|
||||
for cert in "$@"; do
|
||||
case "$cert" in
|
||||
-v|--verbose) verbose="y"; continue;;
|
||||
-s|--scan) scancerts; continue;;
|
||||
-*) echo "Invalid option $cert"; exit 2;;
|
||||
esac
|
||||
name="${cert##*/}"
|
||||
script="/etc/acme-tiny/notify.d/${name%.crt}.sh"
|
||||
|
||||
# run any dropin extension
|
||||
if test -x "$script"; then
|
||||
"$script" "$cert"
|
||||
fi
|
||||
# kick apache if cert is mentioned
|
||||
if test "$cert" -nt "${notify}/httpd"; then
|
||||
if grep "$cert" /etc/httpd/conf.d/*.conf >/dev/null 2>&1; then
|
||||
apachectl graceful && touch "${notify}/httpd" && \
|
||||
[ "$verbose" = "y" ] && echo "Httpd reloaded"
|
||||
fi
|
||||
fi
|
||||
|
||||
# kick sendmail if cert is mentioned
|
||||
if test "$cert" -nt "${notify}/sendmail"; then
|
||||
if grep "/etc/pki/tls/certs/$name" /etc/mail/*.cf >/dev/null 2>&1; then
|
||||
cp "$cert" /etc/pki/tls/certs && systemctl restart sendmail \
|
||||
&& touch "${notify}/sendmail" && \
|
||||
[ "$verbose" = "y" ] && echo "Sendmail reloaded"
|
||||
fi
|
||||
fi
|
||||
|
||||
# kick dovecot if cert is mentioned
|
||||
if test "$cert" -nt "${notify}/dovecot"; then
|
||||
if grep "/etc/pki/dovecot/certs/$name" /etc/dovecot/conf.d/10-ssl.conf >/dev/null 2>&1; then
|
||||
cp "$cert" /etc/pki/dovecot/certs && systemctl restart dovecot \
|
||||
&& touch "${notify}/dovecot" && \
|
||||
[ "$verbose" = "y" ] && echo "Dovecot reloaded"
|
||||
fi
|
||||
fi
|
||||
|
||||
# run any dropin extension
|
||||
if test -x "$script"; then
|
||||
[ "$verbose" = "y" ] && echo "Running $script $cert"
|
||||
ACMEDIR="$acmedir" NOTIFY="$notify" VERBOSE="$verbose" "$script" "$cert"
|
||||
fi
|
||||
done
|
||||
|
|
|
|||
3
sources
3
sources
|
|
@ -1 +1,2 @@
|
|||
SHA512 (acme-tiny-4.1.0.tar.gz) = 31d69a5031c019acbc23b3f06041eae8e261766396d4a7420fd70a71cfa16de953bea4c0c2ad0c6a6e793ed61ab5331f40145352ffce69f4f062f35dd0db7519
|
||||
SHA512 (acme-tiny-4.1.1.tar.gz) = 9e1aac03f3aa744061b8b03bb7bb6ede52ccf1a72d729775f106eb0fef786ee495dedd4f44c672e4ee2a8fc385477366bf164ab5e78d85e0a031558cde68f4b1
|
||||
SHA512 (acme-tiny-5.0.1.tar.gz) = 6e0619917b31a5795c2c7d8aa811b46231b81fc6b57227f611f7f4b9f73eb3de669676482563c33d935a4a0812498677bcbe974663a561af61abb441a880947e
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue