parent
b770fba9eb
commit
30990d7727
@ -0,0 +1,229 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: "Miss Islington (bot)"
|
||||||
|
<31488909+miss-islington@users.noreply.github.com>
|
||||||
|
Date: Wed, 17 May 2023 14:41:25 -0700
|
||||||
|
Subject: [PATCH] 00399: CVE-2023-24329
|
||||||
|
|
||||||
|
* gh-102153: Start stripping C0 control and space chars in `urlsplit` (GH-102508)
|
||||||
|
|
||||||
|
`urllib.parse.urlsplit` has already been respecting the WHATWG spec a bit GH-25595.
|
||||||
|
|
||||||
|
This adds more sanitizing to respect the "Remove any leading C0 control or space from input" [rule](https://url.spec.whatwg.org/GH-url-parsing:~:text=Remove%20any%20leading%20and%20trailing%20C0%20control%20or%20space%20from%20input.) in response to [CVE-2023-24329](https://nvd.nist.gov/vuln/detail/CVE-2023-24329).
|
||||||
|
|
||||||
|
---------
|
||||||
|
|
||||||
|
(cherry picked from commit 2f630e1ce18ad2e07428296532a68b11dc66ad10)
|
||||||
|
|
||||||
|
Co-authored-by: Illia Volochii <illia.volochii@gmail.com>
|
||||||
|
Co-authored-by: Gregory P. Smith [Google] <greg@krypto.org>
|
||||||
|
---
|
||||||
|
Doc/library/urllib.parse.rst | 46 +++++++++++++-
|
||||||
|
Lib/test/test_urlparse.py | 61 ++++++++++++++++++-
|
||||||
|
Lib/urllib/parse.py | 12 ++++
|
||||||
|
...-03-07-20-59-17.gh-issue-102153.14CLSZ.rst | 3 +
|
||||||
|
4 files changed, 119 insertions(+), 3 deletions(-)
|
||||||
|
create mode 100644 Misc/NEWS.d/next/Security/2023-03-07-20-59-17.gh-issue-102153.14CLSZ.rst
|
||||||
|
|
||||||
|
diff --git a/Doc/library/urllib.parse.rst b/Doc/library/urllib.parse.rst
|
||||||
|
index 96b3965107..a326e82e30 100644
|
||||||
|
--- a/Doc/library/urllib.parse.rst
|
||||||
|
+++ b/Doc/library/urllib.parse.rst
|
||||||
|
@@ -159,6 +159,10 @@ or on combining URL components into a URL string.
|
||||||
|
ParseResult(scheme='http', netloc='www.cwi.nl:80', path='/%7Eguido/Python.html',
|
||||||
|
params='', query='', fragment='')
|
||||||
|
|
||||||
|
+ .. warning::
|
||||||
|
+
|
||||||
|
+ :func:`urlparse` does not perform validation. See :ref:`URL parsing
|
||||||
|
+ security <url-parsing-security>` for details.
|
||||||
|
|
||||||
|
.. versionchanged:: 3.2
|
||||||
|
Added IPv6 URL parsing capabilities.
|
||||||
|
@@ -324,8 +328,14 @@ or on combining URL components into a URL string.
|
||||||
|
``#``, ``@``, or ``:`` will raise a :exc:`ValueError`. If the URL is
|
||||||
|
decomposed before parsing, no error will be raised.
|
||||||
|
|
||||||
|
- Following the `WHATWG spec`_ that updates RFC 3986, ASCII newline
|
||||||
|
- ``\n``, ``\r`` and tab ``\t`` characters are stripped from the URL.
|
||||||
|
+ Following some of the `WHATWG spec`_ that updates RFC 3986, leading C0
|
||||||
|
+ control and space characters are stripped from the URL. ``\n``,
|
||||||
|
+ ``\r`` and tab ``\t`` characters are removed from the URL at any position.
|
||||||
|
+
|
||||||
|
+ .. warning::
|
||||||
|
+
|
||||||
|
+ :func:`urlsplit` does not perform validation. See :ref:`URL parsing
|
||||||
|
+ security <url-parsing-security>` for details.
|
||||||
|
|
||||||
|
.. versionchanged:: 3.6
|
||||||
|
Out-of-range port numbers now raise :exc:`ValueError`, instead of
|
||||||
|
@@ -338,6 +348,9 @@ or on combining URL components into a URL string.
|
||||||
|
.. versionchanged:: 3.10
|
||||||
|
ASCII newline and tab characters are stripped from the URL.
|
||||||
|
|
||||||
|
+ .. versionchanged:: 3.11.4
|
||||||
|
+ Leading WHATWG C0 control and space characters are stripped from the URL.
|
||||||
|
+
|
||||||
|
.. _WHATWG spec: https://url.spec.whatwg.org/#concept-basic-url-parser
|
||||||
|
|
||||||
|
.. function:: urlunsplit(parts)
|
||||||
|
@@ -414,6 +427,35 @@ or on combining URL components into a URL string.
|
||||||
|
or ``scheme://host/path``). If *url* is not a wrapped URL, it is returned
|
||||||
|
without changes.
|
||||||
|
|
||||||
|
+.. _url-parsing-security:
|
||||||
|
+
|
||||||
|
+URL parsing security
|
||||||
|
+--------------------
|
||||||
|
+
|
||||||
|
+The :func:`urlsplit` and :func:`urlparse` APIs do not perform **validation** of
|
||||||
|
+inputs. They may not raise errors on inputs that other applications consider
|
||||||
|
+invalid. They may also succeed on some inputs that might not be considered
|
||||||
|
+URLs elsewhere. Their purpose is for practical functionality rather than
|
||||||
|
+purity.
|
||||||
|
+
|
||||||
|
+Instead of raising an exception on unusual input, they may instead return some
|
||||||
|
+component parts as empty strings. Or components may contain more than perhaps
|
||||||
|
+they should.
|
||||||
|
+
|
||||||
|
+We recommend that users of these APIs where the values may be used anywhere
|
||||||
|
+with security implications code defensively. Do some verification within your
|
||||||
|
+code before trusting a returned component part. Does that ``scheme`` make
|
||||||
|
+sense? Is that a sensible ``path``? Is there anything strange about that
|
||||||
|
+``hostname``? etc.
|
||||||
|
+
|
||||||
|
+What constitutes a URL is not universally well defined. Different applications
|
||||||
|
+have different needs and desired constraints. For instance the living `WHATWG
|
||||||
|
+spec`_ describes what user facing web clients such as a web browser require.
|
||||||
|
+While :rfc:`3986` is more general. These functions incorporate some aspects of
|
||||||
|
+both, but cannot be claimed compliant with either. The APIs and existing user
|
||||||
|
+code with expectations on specific behaviors predate both standards leading us
|
||||||
|
+to be very cautious about making API behavior changes.
|
||||||
|
+
|
||||||
|
.. _parsing-ascii-encoded-bytes:
|
||||||
|
|
||||||
|
Parsing ASCII Encoded Bytes
|
||||||
|
diff --git a/Lib/test/test_urlparse.py b/Lib/test/test_urlparse.py
|
||||||
|
index b426110723..40f13d631c 100644
|
||||||
|
--- a/Lib/test/test_urlparse.py
|
||||||
|
+++ b/Lib/test/test_urlparse.py
|
||||||
|
@@ -649,6 +649,65 @@ def test_urlsplit_remove_unsafe_bytes(self):
|
||||||
|
self.assertEqual(p.scheme, "http")
|
||||||
|
self.assertEqual(p.geturl(), "http://www.python.org/javascript:alert('msg')/?query=something#fragment")
|
||||||
|
|
||||||
|
+ def test_urlsplit_strip_url(self):
|
||||||
|
+ noise = bytes(range(0, 0x20 + 1))
|
||||||
|
+ base_url = "http://User:Pass@www.python.org:080/doc/?query=yes#frag"
|
||||||
|
+
|
||||||
|
+ url = noise.decode("utf-8") + base_url
|
||||||
|
+ p = urllib.parse.urlsplit(url)
|
||||||
|
+ self.assertEqual(p.scheme, "http")
|
||||||
|
+ self.assertEqual(p.netloc, "User:Pass@www.python.org:080")
|
||||||
|
+ self.assertEqual(p.path, "/doc/")
|
||||||
|
+ self.assertEqual(p.query, "query=yes")
|
||||||
|
+ self.assertEqual(p.fragment, "frag")
|
||||||
|
+ self.assertEqual(p.username, "User")
|
||||||
|
+ self.assertEqual(p.password, "Pass")
|
||||||
|
+ self.assertEqual(p.hostname, "www.python.org")
|
||||||
|
+ self.assertEqual(p.port, 80)
|
||||||
|
+ self.assertEqual(p.geturl(), base_url)
|
||||||
|
+
|
||||||
|
+ url = noise + base_url.encode("utf-8")
|
||||||
|
+ p = urllib.parse.urlsplit(url)
|
||||||
|
+ self.assertEqual(p.scheme, b"http")
|
||||||
|
+ self.assertEqual(p.netloc, b"User:Pass@www.python.org:080")
|
||||||
|
+ self.assertEqual(p.path, b"/doc/")
|
||||||
|
+ self.assertEqual(p.query, b"query=yes")
|
||||||
|
+ self.assertEqual(p.fragment, b"frag")
|
||||||
|
+ self.assertEqual(p.username, b"User")
|
||||||
|
+ self.assertEqual(p.password, b"Pass")
|
||||||
|
+ self.assertEqual(p.hostname, b"www.python.org")
|
||||||
|
+ self.assertEqual(p.port, 80)
|
||||||
|
+ self.assertEqual(p.geturl(), base_url.encode("utf-8"))
|
||||||
|
+
|
||||||
|
+ # Test that trailing space is preserved as some applications rely on
|
||||||
|
+ # this within query strings.
|
||||||
|
+ query_spaces_url = "https://www.python.org:88/doc/?query= "
|
||||||
|
+ p = urllib.parse.urlsplit(noise.decode("utf-8") + query_spaces_url)
|
||||||
|
+ self.assertEqual(p.scheme, "https")
|
||||||
|
+ self.assertEqual(p.netloc, "www.python.org:88")
|
||||||
|
+ self.assertEqual(p.path, "/doc/")
|
||||||
|
+ self.assertEqual(p.query, "query= ")
|
||||||
|
+ self.assertEqual(p.port, 88)
|
||||||
|
+ self.assertEqual(p.geturl(), query_spaces_url)
|
||||||
|
+
|
||||||
|
+ p = urllib.parse.urlsplit("www.pypi.org ")
|
||||||
|
+ # That "hostname" gets considered a "path" due to the
|
||||||
|
+ # trailing space and our existing logic... YUCK...
|
||||||
|
+ # and re-assembles via geturl aka unurlsplit into the original.
|
||||||
|
+ # django.core.validators.URLValidator (at least through v3.2) relies on
|
||||||
|
+ # this, for better or worse, to catch it in a ValidationError via its
|
||||||
|
+ # regular expressions.
|
||||||
|
+ # Here we test the basic round trip concept of such a trailing space.
|
||||||
|
+ self.assertEqual(urllib.parse.urlunsplit(p), "www.pypi.org ")
|
||||||
|
+
|
||||||
|
+ # with scheme as cache-key
|
||||||
|
+ url = "//www.python.org/"
|
||||||
|
+ scheme = noise.decode("utf-8") + "https" + noise.decode("utf-8")
|
||||||
|
+ for _ in range(2):
|
||||||
|
+ p = urllib.parse.urlsplit(url, scheme=scheme)
|
||||||
|
+ self.assertEqual(p.scheme, "https")
|
||||||
|
+ self.assertEqual(p.geturl(), "https://www.python.org/")
|
||||||
|
+
|
||||||
|
def test_attributes_bad_port(self):
|
||||||
|
"""Check handling of invalid ports."""
|
||||||
|
for bytes in (False, True):
|
||||||
|
@@ -656,7 +715,7 @@ def test_attributes_bad_port(self):
|
||||||
|
for port in ("foo", "1.5", "-1", "0x10", "-0", "1_1", " 1", "1 ", "६"):
|
||||||
|
with self.subTest(bytes=bytes, parse=parse, port=port):
|
||||||
|
netloc = "www.example.net:" + port
|
||||||
|
- url = "http://" + netloc
|
||||||
|
+ url = "http://" + netloc + "/"
|
||||||
|
if bytes:
|
||||||
|
if netloc.isascii() and port.isascii():
|
||||||
|
netloc = netloc.encode("ascii")
|
||||||
|
diff --git a/Lib/urllib/parse.py b/Lib/urllib/parse.py
|
||||||
|
index 69631cbb81..4f06fd509e 100644
|
||||||
|
--- a/Lib/urllib/parse.py
|
||||||
|
+++ b/Lib/urllib/parse.py
|
||||||
|
@@ -25,6 +25,10 @@
|
||||||
|
scenarios for parsing, and for backward compatibility purposes, some
|
||||||
|
parsing quirks from older RFCs are retained. The testcases in
|
||||||
|
test_urlparse.py provides a good indicator of parsing behavior.
|
||||||
|
+
|
||||||
|
+The WHATWG URL Parser spec should also be considered. We are not compliant with
|
||||||
|
+it either due to existing user code API behavior expectations (Hyrum's Law).
|
||||||
|
+It serves as a useful guide when making changes.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from collections import namedtuple
|
||||||
|
@@ -79,6 +83,10 @@
|
||||||
|
'0123456789'
|
||||||
|
'+-.')
|
||||||
|
|
||||||
|
+# Leading and trailing C0 control and space to be stripped per WHATWG spec.
|
||||||
|
+# == "".join([chr(i) for i in range(0, 0x20 + 1)])
|
||||||
|
+_WHATWG_C0_CONTROL_OR_SPACE = '\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f '
|
||||||
|
+
|
||||||
|
# Unsafe bytes to be removed per WHATWG spec
|
||||||
|
_UNSAFE_URL_BYTES_TO_REMOVE = ['\t', '\r', '\n']
|
||||||
|
|
||||||
|
@@ -452,6 +460,10 @@ def urlsplit(url, scheme='', allow_fragments=True):
|
||||||
|
"""
|
||||||
|
|
||||||
|
url, scheme, _coerce_result = _coerce_args(url, scheme)
|
||||||
|
+ # Only lstrip url as some applications rely on preserving trailing space.
|
||||||
|
+ # (https://url.spec.whatwg.org/#concept-basic-url-parser would strip both)
|
||||||
|
+ url = url.lstrip(_WHATWG_C0_CONTROL_OR_SPACE)
|
||||||
|
+ scheme = scheme.strip(_WHATWG_C0_CONTROL_OR_SPACE)
|
||||||
|
|
||||||
|
for b in _UNSAFE_URL_BYTES_TO_REMOVE:
|
||||||
|
url = url.replace(b, "")
|
||||||
|
diff --git a/Misc/NEWS.d/next/Security/2023-03-07-20-59-17.gh-issue-102153.14CLSZ.rst b/Misc/NEWS.d/next/Security/2023-03-07-20-59-17.gh-issue-102153.14CLSZ.rst
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000..e57ac4ed3a
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/Misc/NEWS.d/next/Security/2023-03-07-20-59-17.gh-issue-102153.14CLSZ.rst
|
||||||
|
@@ -0,0 +1,3 @@
|
||||||
|
+:func:`urllib.parse.urlsplit` now strips leading C0 control and space
|
||||||
|
+characters following the specification for URLs defined by WHATWG in
|
||||||
|
+response to CVE-2023-24329. Patch by Illia Volochii.
|
@ -0,0 +1,109 @@
|
|||||||
|
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||||
|
|
||||||
|
mQINBFq+ToQBEADRYvIVtbK6owynD3j3nxwpW2KEk/p+aDvtXmc2SR2dBcZ8sFW2
|
||||||
|
R5vEsG8d3/D3wgv5pcL3KfNNXQYUnXVbobrFUUWQYc79qIsE3MgiPf5NVOtwKPUR
|
||||||
|
i5g9YJgKvpBxkQfqp3LYGm9ZBtwo3DVLA3yn7KsazCmAgTNFJYw7ku1XxgmIzY6K
|
||||||
|
5J30DfbJiqDqj4f9GslCCCCH3qiPnuLG/HUyVLHMpbWlaiy9NI0GcaLxjJewHj9w
|
||||||
|
W2D2lydkxe5JGo7egUkV3ILcuLVSVKA35SKY27dYqfuyqp9tAzaRbjDYjsYdHA6G
|
||||||
|
BqrNrKBn/GwlFDPrVdcvN3ZSY2wMLTxWE3Axc/FweuHxFnou/80FwX7F3JD+oEQ6
|
||||||
|
rofmcxOBCC7J98I7HZAhP9jBn88XIS2hztbLq8d6rZJZRtcz0k61VR0ddO+TrFmf
|
||||||
|
9rMYCPgCckRtVxeFIVIabrN1IzKynLFeo040h8hSGswd6YKDOVwjJY6Oa6EmVefZ
|
||||||
|
a8QSt4+M65RSzH6SEPY008F3nJUAK6MEkzTak+tFltZNrVWu8p2xd1j9nmxAwEhZ
|
||||||
|
/lgbxLqzYgaUWmfyHeZ8yVA0MhHzdiAL8nVUEdG3KecIq0RWCJLGLWWIjd6KAJl1
|
||||||
|
yAmhRYKK/sjPDsL3elHsFACfZbyx3o5GGQNlas1FYoPLWbaNGaJtgFTF2QARAQAB
|
||||||
|
tCtQYWJsbyBHYWxpbmRvIFNhbGdhZG8gPHBhYmxvZ3NhbEBnbWFpbC5jb20+iQJO
|
||||||
|
BBMBCgA4FiEEoDXIwZIZuoIezqhrZOYo+NaEaW0FAlq+ToQCGwMFCwkIBwMFFQoJ
|
||||||
|
CAsFFgIDAQACHgECF4AACgkQZOYo+NaEaW2bmA/+PXIap2udLoUVOHxnsIBdqYwp
|
||||||
|
sv1Aj5lfIJmNhmxPbHShwp1Jg+w4urxe+2Dj5ofKVlIo1i83bQkvnKJMDXDVuc/K
|
||||||
|
P6zqhBJ3rT4Q3qx2mzX8bIfQoJ2JHuH4lkP+I7doDcHHRyeNASyk72VdQmU4twNw
|
||||||
|
Ibn8nSNV6ThKHdoPYzVnO2rZUFcGIqH5HNsvR+B7cc1MBCHsgURYwSVhSePIFGlZ
|
||||||
|
iasdBD6QQkDSe4QWi7AcJFWFElw4kbOKJWxAWsrEk+tMXJVGRjnmL289EmPCx/vx
|
||||||
|
BqKy7Mse0yWCSRR3vB+O6TB1S5SgEyEgqlYsfGNv1qf/rfRD4KkyCbNU3LhY1Aim
|
||||||
|
vJP4pDW+KFxTk2Ks8vrx8gOSd2aFqPeO/pFDrpsF7PD62XwsfoXu4xc5V0Giw7r1
|
||||||
|
Nai0nax7kOrldNF8TbbtRjW0jmoC7wLIDujAkwDIOroZ0CXA3N4HVHdSbrHm/urX
|
||||||
|
nyxJXupXAQNwGx64JCBcbF2fp3Kvu1VAXBEFnd01KaopthHcbG5pA50Kl2Vhe+98
|
||||||
|
OdezUX42fHkQpQkB7HgtXfm6W1bw6YRBamrNvs1OoHBYmUjlECpe566IIu25Hc8s
|
||||||
|
x3qA+6eca7iqizyLG+WyMT8ZIYTWGAS59jxwR4esqGczbbZPSAPHFwLbGv7Wr0Rd
|
||||||
|
TPu5B0FcKpDkTd4IxQW5Ag0EWr5O2gEQAMjLe4CtbSfofmJrz5wfNkMVsZ81Gbqe
|
||||||
|
MoYd3dtkJnQYERUj8flzBj3ucaxGJ+Cuf7ybh3naPopKvEI1q0vkcgCDqrEgXK//
|
||||||
|
jKJbP28uPSMGhOG28q4PbamG55gy5FtM3ezzAxPWWKe9qBpV65GMmFy7eBQx2iJs
|
||||||
|
yiDIOOQQ4kraS+cTqNFimEXAGLCOQRNLcwIZzwAAHoW7HEpNUfVwaBD9kMlbo1ND
|
||||||
|
I60IKcNrNcmcmRxhJqfxjj8YBMwcKHO6GBE3AVpaE/+UO9zyr4TH+0YuQUgxKlPW
|
||||||
|
Dkg5XlkDo0S1GyLY5e9ckIDIlkTdDa2pOkoE2yB5MQCEga3YiHrKUVTTWaxn9XVJ
|
||||||
|
6x5ZjUF6bgSWGkrG5dUqSYoO1iDMuNVjtiujNyf/rvfj5cNxS7/lgxchhQKZHZXL
|
||||||
|
WVqxlneeVJ6s0P4+ROVG9ga2Sve7aUJ6wXIewZwulBcV2sE/W/DgxHgLBi53CUQt
|
||||||
|
vEzFzKvo48GnDqL5VYjA7l0HMYHd4GksCLi8E8U6Cgj+imXiM8voL7pHRZfs8mY8
|
||||||
|
udR+UT4e1Scl2MYP2qBJ9/17B/X52B3s1EZdqI/r+hfOyqrhPs+dbAN0mtMPn68+
|
||||||
|
nrvY1+nscvrSYEP6ZBlc9Hp2mgJdb6IcTvINXBEeLRjgc3pjViva443pkiFp9Axm
|
||||||
|
ecOckMKP3uSlABEBAAGJBGwEGAEKACAWIQSgNcjBkhm6gh7OqGtk5ij41oRpbQUC
|
||||||
|
Wr5O2gIbAgJACRBk5ij41oRpbcF0IAQZAQoAHRYhBM/cokWxBDzypfl4Zf/odAQW
|
||||||
|
i9hHBQJavk7aAAoJEP/odAQWi9hHr7YP/RCLre1CmOoWYpAtoa1yVCeYMDV6eQgL
|
||||||
|
B488/BEZHQE1zbrYy16XkhORob3JF/kUMjmJW7XaFF8FrWvRcdj/xaUGbOOEulKg
|
||||||
|
v+8zWfswYQRiZ4/JlwER4vRLi6fTE89MVER6Fkj2ASD4D2cifY+EztD4flV3sq3s
|
||||||
|
vIogGFaN9IvdrdeptOVGXs1RmAyoTsiS2mKQ6xsGh8B9ZAm55W8fBOGiSzLX21Xk
|
||||||
|
Ofdw53BrFQxn3cu/JgIKpdeZxgukcvEAI62B6X+YL6Na4j0eqEGLzsNtU1+xeJlo
|
||||||
|
WtVvmRwnRHGSxF6fzIZ3mk/p/aFiXAEq/xITCTY6tDv7x7pFE/RpdlJZyNJ+R5Y4
|
||||||
|
SQiuDsylxNCa/4G5EB6q+7iVYtbEQ9MnZg2phowEE42tlj0rz8/rvDK3LH3xibot
|
||||||
|
KHIodCWKlWByxH99u2PuHUQ0c1oCVBUE1KkruMpvI236DpU/dvdq4JLSg/fWrys/
|
||||||
|
VIjqLZgsIE5g/KO9XqngWHkLcBLh4CNAmHJ8Iia+s+/rfgsejQWB5uJb6eYg2JjB
|
||||||
|
4WP1EI0rULM6fdrCNB+MJ36wE2Lnb4bfT0phOMgjjH5/Ki7ZCbkxkOsBs4SRjiS+
|
||||||
|
weCsmpAtMqodWY/Cnw9pWSA/qLSRD5/mKeb9SO6OZ/OPfAatwnGHsvZ2sAueC6rR
|
||||||
|
04W5BfXZWrnJUXQP/id/EKE1Ksp5fKoxSCbkKTCig+Sf5Afwe36yFN+niZBqzn5b
|
||||||
|
BgL/HIKaZM97oDHersPPANeEgS+JVlBf95iKIYnQbZP43FLVbvOuaINhBIVtFO54
|
||||||
|
2Y7EYwl41kP7ILDElVy36KAmdQyBAfrjnZiRA70xShOxApLug1L0lxhR3YfmLwNi
|
||||||
|
RJ0V6KnYDKf0pfdhO9VFyFFWUojX1usn2SmSsXNizsNtvRqHXzPnX0rbJzZ9+N4O
|
||||||
|
9k1nxygYFG/2R/jGonVmTjRzcAHrAkNJETMWXMA7/8wRMDwluz8j+cCldey9x8Vk
|
||||||
|
JwgLGnZSbQtVpcFAnm5r/36Gt+9wc1VWMyrUrVr6Z679aqAbG7PMaeR5h5ygMj1k
|
||||||
|
VqRTYAUPSk1f8bZKRssQkQwEbp9dVIjm9SsR8VT7/tB+UuB85dABxgHfv3psJRT+
|
||||||
|
tL8g9V7kSZqQfcLNGmvEVvr2Zl9NtxwXtsFM2OBprxCenwb+e9Ppm1LjfJG/NE72
|
||||||
|
mAnOERfDaiLt4bqNo36Ei5sGCJ4Fx61phzNBXzkdRNM47i8J5UZRKFkE91c99BVM
|
||||||
|
HKUaY61NRK24fR0zP98ftDU82YFw0VRFJpTeBrO5ivN1MlQxUPzUWxKxMxO+20wa
|
||||||
|
UOXroEw11Tb4SRLGOla1pCl6lCUPJRy9IzadPDgTr/OTMkob/snt/XLdnV5/uQIN
|
||||||
|
BFq+TvoBEAC8Oy1g6pPWBbrCMhIq7VWY2fjylJ1fwg5BPXkOKVK1dsGYO4QD7oW9
|
||||||
|
L0aSqcFSNFGF9Cl0Ri4TFXZC3hnG4HeSXUWApuKdBLn21H3jba36Ay1oGcGfdm0v
|
||||||
|
Zght4c6BlMVBpGCw2wIkJbUNEy6InMM+O8CCbbaH3iJkJ4141P7pODHignx5AmZI
|
||||||
|
conMui4YOhC+IXQXynVEv1Juk7erB1Nh1RcRvsA4lb44HWx49lIwe85ejOmoZ0O3
|
||||||
|
6f9NJRer6bV0+rHWmg4IV5Q9h/Gn4IhEDZxA0DZl1RQI7dMgaMbIFbXGq7Kgzstz
|
||||||
|
EUnOoy29hXodxVmwIsMrAiQUYtwJ9hW+ESsw47+W2iPHVgviGWl7r/SgcgMYmf6m
|
||||||
|
5kiTBtwU7BQPS9G3zwwP2Rm3AA/6g39Q+tQKjOwi1I8+GZsY2On44Zly7BreBNg5
|
||||||
|
4gJgdAGcMOYU9etr050clH3UpTYcAEtX++ahtOKhJgLIPNcIAQNlnifqvU0VYpgw
|
||||||
|
R4YpZ7hgg+AVDzC73PIM0lFI0XiDuqChbxE+K1jmLXWe5iJF0dzgVTwP+PmsifNZ
|
||||||
|
Wg3+YxSsS+hDMPQ2xPiQN49gT4JJDHcDuyhHyCGYgyMiVJCsku9KrkubbfVRivyN
|
||||||
|
ZF2Zfo3f+nbrRxsftz0yjAq8byCvb0V0XOpt4pJ/ddlug9ytRxALNwARAQABiQI2
|
||||||
|
BBgBCgAgFiEEoDXIwZIZuoIezqhrZOYo+NaEaW0FAlq+TvoCGwwACgkQZOYo+NaE
|
||||||
|
aW3urA//UQ/cKQ7HvWjcLphzQOZc+6m5YL0wxvZkSjemU7mqjZdpacteIvRAoers
|
||||||
|
EqXHc208liIBtNfRzoreXdcXNzie65xXkrRnWoHVH/fTWy4lOnHr2CMXLeHjUgg/
|
||||||
|
M6PYi8+sARm05YFB8nsYhlhx3IdLhcfeVVbJedQKO0yL3CK1okT30DUVq5Lq6X/K
|
||||||
|
DC6AxuJR3D6UMSoT0WLaoX8qbhAp88qLynInfBVL18d97h916WPLTPeP0eHwhwND
|
||||||
|
bYtKDCMDuKQ9XX5+QsNH0RmbxlX274LHrUMMvkLKxcfCBvP+iuqrBeIuoeVzXYJZ
|
||||||
|
j7ZJtEH79bW44eecl/CY/STFYgSQ2XGTp2BI2q60wAmtKlNhwxY5ena0FgyFl6Tm
|
||||||
|
5OBHW/Pwo+ndQJGfbrCyWkTgRay9c8er3gl3GQYIBH6X0kCiG7h/Epj0b5CHOPU5
|
||||||
|
hCw0kEB8MB4poTIjeiY+Q01472/lQ68CL3DX158hR5d3XaPSIxAN+qFsfB1o316p
|
||||||
|
yjxhfK1MD/IfrOgjlggPPnc/KmLkCzpgdwKcZwLCdZq9hYBvF1Zs34HbaVMYbWTK
|
||||||
|
uxLowtXGU43vatCXXqmPOvl4/g4tZD6rysJDgOrHQnEHzT+Napn07s0BRC0IbbNn
|
||||||
|
FynUrkr5KMSuRz7Hg7xMApENOrb0nqdHSUJ914ZpuMIS6RhJgGu5Ag0EWr5PIAEQ
|
||||||
|
ALfh9vPD2B+miHDTMADI8aRZ7g9tnzynZYkk3+2sCiiusetsQQ+HIPJ/ASEJB7On
|
||||||
|
ane9dyT/LTRhrK9qaxgVMimk2COXB/xyh7Mnw7nJgFU0aRSbtX0vbvQz2suSzrQ6
|
||||||
|
9mPKzan28JGoClqB0bw1vwf3VjjxHV2dgD57CmqFPv7kAC/2a56dE+etzXattZAL
|
||||||
|
+2JWTpmfQ0ePRRadtBm0VahQhnU8x0+jvAVrEawqpVW83ozYFyW/0WInM2J7jHgQ
|
||||||
|
16OosY4lj5L/DxpVxaArhRFoRfWPXfC37iE8Mou/I95isvPQIhp1wTo4jG0KM02B
|
||||||
|
oIVbp/QRNBQ6WtpOzvJs1gqQiJJTfqbKJXQ3NDEY9crpVS83HJ+Zv99PNsyNkFjG
|
||||||
|
QpU84U3ZhsI4ygjdY45mpZueqI1RVcRQdu8Hgvoo/78Q/Sir6gMGop3mVdVo2guI
|
||||||
|
kFcJrXh0Xk3ech4aVqrmKx/mPXGwOAQU0DAul4RW3fKg1QxQE7Tlw3+95Ee/+q5j
|
||||||
|
HARL0uDbCJpRO8Sl8NDEuL32n/2Ot6kQeCSHrU7KJRYAkTxkKvr8zNow7hFhHFPE
|
||||||
|
SnHvTnskI6noh0VY6NwMhmLvhm0wKkRxZPzUNc3sgLvbK1NymIZ9aKCZamzhZrmG
|
||||||
|
vnblEz/OSLwGUua465H3hM1vvBQiartj7+6ZqWIkSmBPABEBAAGJAjYEGAEKACAW
|
||||||
|
IQSgNcjBkhm6gh7OqGtk5ij41oRpbQUCWr5PIAIbIAAKCRBk5ij41oRpbWmeEACG
|
||||||
|
+axtDC8UoNp9ORiYwEWLzZWDuugE+ah7DYYGD4Vs633FXVZW3SgM/bFtJ/0Lg8CF
|
||||||
|
74jI4LMHyIjDzEjcoItwnhBLix+kUoJTvrY58GPydwekLuw1p4KXLqtRs4fsZbNQ
|
||||||
|
YTknl4jYtRWoxO98x7tun7Gq2gqmJkIB2uj630fKz5cBk6p6oDFKjzyrHe+V7BiK
|
||||||
|
3okQPaD4x7hq8OnTy7lOy92ZZAqztS4tNEb4DkYW1MpuwsJ7hbBZitc1siI+FVVb
|
||||||
|
GjVVGZz6ssXoW67Tz8+VxdWJxNLXlv27eMcj4sme5S0th/YYNA5fRRv6zuzqZAru
|
||||||
|
YNGLpYYU7JLvZJ+3lCwa5j5ycOGBF0GvsGs6gj6h+CHkjR/BgzAgWC+GgUgslt6q
|
||||||
|
aH04rWtV6rVz+Y91LcrX5P6OM4anmXD3Gp3kl35AypXb4KyASF19+11RUziD4Z7q
|
||||||
|
wQEWfbwOltNyZv2lD8s2jPr7P02axWRQUbZAEhxRmvOQev/FZPyCF6gqUo/HxRbQ
|
||||||
|
y3bzmnipyHSv1DlXNfCFCHvN8kGyZnRWARqIKRg+j9ediJgOUqlLhg6KmrTVxd5v
|
||||||
|
3Dfv52PW2UODDTM20s3cQGuX/UswzMRwPI/+P44iCMwEKdm7duM/5oisZT9Vhy7g
|
||||||
|
P15MreFZLcZvUVgjqgy0u57cstyGK1Bo9e2sFcK2fA==
|
||||||
|
=6Zb4
|
||||||
|
-----END PGP PUBLIC KEY BLOCK-----
|
Loading…
Reference in new issue