Sync from SUSE:SLFO:Main python-Twisted revision 802ba959007571a4690a0d8363c46412
This commit is contained in:
parent
7350ac4448
commit
85bf7cb3e7
@ -10,11 +10,11 @@ Subject: [PATCH 1/2] delegate to stdlib parse qs
|
||||
3 files changed, 4 insertions(+), 28 deletions(-)
|
||||
create mode 100644 src/twisted/web/newsfragments/10096.bugfix
|
||||
|
||||
Index: Twisted-22.1.0/src/twisted/web/http.py
|
||||
Index: twisted-24.3.0/src/twisted/web/http.py
|
||||
===================================================================
|
||||
--- Twisted-22.1.0.orig/src/twisted/web/http.py
|
||||
+++ Twisted-22.1.0/src/twisted/web/http.py
|
||||
@@ -113,6 +113,7 @@ from urllib.parse import (
|
||||
--- twisted-24.3.0.orig/src/twisted/web/http.py
|
||||
+++ twisted-24.3.0/src/twisted/web/http.py
|
||||
@@ -115,6 +115,7 @@ from urllib.parse import (
|
||||
ParseResultBytes,
|
||||
unquote_to_bytes as unquote,
|
||||
urlparse as _urlparse,
|
||||
@ -22,7 +22,7 @@ Index: Twisted-22.1.0/src/twisted/web/http.py
|
||||
)
|
||||
|
||||
from zope.interface import Attribute, Interface, implementer, provider
|
||||
@@ -263,31 +264,6 @@ def urlparse(url):
|
||||
@@ -288,34 +289,6 @@ def urlparse(url):
|
||||
return ParseResultBytes(scheme, netloc, path, params, query, fragment)
|
||||
|
||||
|
||||
@ -30,6 +30,9 @@ Index: Twisted-22.1.0/src/twisted/web/http.py
|
||||
- """
|
||||
- Like C{cgi.parse_qs}, but with support for parsing byte strings on Python 3.
|
||||
-
|
||||
- This was created to help with Python 2 to Python 3 migration.
|
||||
- Consider using L{urllib.parse.parse_qs}.
|
||||
-
|
||||
- @type qs: C{bytes}
|
||||
- """
|
||||
- d = {}
|
||||
@ -54,16 +57,16 @@ Index: Twisted-22.1.0/src/twisted/web/http.py
|
||||
def datetimeToString(msSinceEpoch=None):
|
||||
"""
|
||||
Convert seconds since epoch to HTTP datetime string.
|
||||
Index: Twisted-22.1.0/src/twisted/web/newsfragments/10096.bugfix
|
||||
Index: twisted-24.3.0/src/twisted/web/newsfragments/10096.bugfix
|
||||
===================================================================
|
||||
--- /dev/null
|
||||
+++ Twisted-22.1.0/src/twisted/web/newsfragments/10096.bugfix
|
||||
+++ twisted-24.3.0/src/twisted/web/newsfragments/10096.bugfix
|
||||
@@ -0,0 +1 @@
|
||||
+delegate to urllib.parse:parse_qs in twisted.web.http:parse_qs to avoid CVE-2021-23336 and the associated CI failures
|
||||
Index: Twisted-22.1.0/src/twisted/web/server.py
|
||||
Index: twisted-24.3.0/src/twisted/web/server.py
|
||||
===================================================================
|
||||
--- Twisted-22.1.0.orig/src/twisted/web/server.py
|
||||
+++ Twisted-22.1.0/src/twisted/web/server.py
|
||||
--- twisted-24.3.0.orig/src/twisted/web/server.py
|
||||
+++ twisted-24.3.0/src/twisted/web/server.py
|
||||
@@ -21,7 +21,7 @@ import zlib
|
||||
from binascii import hexlify
|
||||
from html import escape
|
||||
@ -81,7 +84,7 @@ Index: Twisted-22.1.0/src/twisted/web/server.py
|
||||
|
||||
NOT_DONE_YET = 1
|
||||
|
||||
@@ -211,7 +210,7 @@ class Request(Copyable, http.Request, co
|
||||
@@ -210,7 +209,7 @@ class Request(Copyable, http.Request, co
|
||||
|
||||
# Resource Identification
|
||||
self.prepath = []
|
||||
|
@ -1,174 +0,0 @@
|
||||
---
|
||||
src/twisted/web/http.py | 32 +++++++++--
|
||||
src/twisted/web/newsfragments/11976.bugfix | 7 ++
|
||||
src/twisted/web/test/test_web.py | 81 ++++++++++++++++++++++++++++-
|
||||
3 files changed, 114 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/src/twisted/web/http.py
|
||||
+++ b/src/twisted/web/http.py
|
||||
@@ -2419,14 +2419,38 @@ class HTTPChannel(basic.LineReceiver, po
|
||||
|
||||
self._handlingRequest = True
|
||||
|
||||
+ # We go into raw mode here even though we will be receiving lines next
|
||||
+ # in the protocol; however, this data will be buffered and then passed
|
||||
+ # back to line mode in the setLineMode call in requestDone.
|
||||
+ self.setRawMode()
|
||||
+
|
||||
req = self.requests[-1]
|
||||
req.requestReceived(command, path, version)
|
||||
|
||||
- def dataReceived(self, data):
|
||||
+ def rawDataReceived(self, data: bytes) -> None:
|
||||
"""
|
||||
- Data was received from the network. Process it.
|
||||
+ This is called when this HTTP/1.1 parser is in raw mode rather than
|
||||
+ line mode.
|
||||
+
|
||||
+ It may be in raw mode for one of two reasons:
|
||||
+
|
||||
+ 1. All the headers of a request have been received and this
|
||||
+ L{HTTPChannel} is currently receiving its body.
|
||||
+
|
||||
+ 2. The full content of a request has been received and is currently
|
||||
+ being processed asynchronously, and this L{HTTPChannel} is
|
||||
+ buffering the data of all subsequent requests to be parsed
|
||||
+ later.
|
||||
+
|
||||
+ In the second state, the data will be played back later.
|
||||
+
|
||||
+ @note: This isn't really a public API, and should be invoked only by
|
||||
+ L{LineReceiver}'s line parsing logic. If you wish to drive an
|
||||
+ L{HTTPChannel} from a custom data source, call C{dataReceived} on
|
||||
+ it directly.
|
||||
+
|
||||
+ @see: L{LineReceive.rawDataReceived}
|
||||
"""
|
||||
- # If we're currently handling a request, buffer this data.
|
||||
if self._handlingRequest:
|
||||
self._dataBuffer.append(data)
|
||||
if (
|
||||
@@ -2438,9 +2462,7 @@ class HTTPChannel(basic.LineReceiver, po
|
||||
# ready. See docstring for _optimisticEagerReadSize above.
|
||||
self._networkProducer.pauseProducing()
|
||||
return
|
||||
- return basic.LineReceiver.dataReceived(self, data)
|
||||
|
||||
- def rawDataReceived(self, data):
|
||||
self.resetTimeout()
|
||||
|
||||
try:
|
||||
--- /dev/null
|
||||
+++ b/src/twisted/web/newsfragments/11976.bugfix
|
||||
@@ -0,0 +1,7 @@
|
||||
+In Twisted 16.3.0, we changed twisted.web to stop dispatching HTTP/1.1
|
||||
+pipelined requests to application code. There was a bug in this change which
|
||||
+still allowed clients which could send multiple full HTTP requests in a single
|
||||
+TCP segment to trigger asynchronous processing of later requests, which could
|
||||
+lead to out-of-order responses. This has now been corrected and twisted.web
|
||||
+should never process a pipelined request over HTTP/1.1 until the previous
|
||||
+request has fully completed.
|
||||
--- a/src/twisted/web/test/test_web.py
|
||||
+++ b/src/twisted/web/test/test_web.py
|
||||
@@ -8,6 +8,7 @@ Tests for various parts of L{twisted.web
|
||||
import os
|
||||
import zlib
|
||||
from io import BytesIO
|
||||
+from typing import List
|
||||
|
||||
from zope.interface import implementer
|
||||
from zope.interface.verify import verifyObject
|
||||
@@ -17,10 +18,13 @@ from twisted.internet.address import IPv
|
||||
from twisted.internet.task import Clock
|
||||
from twisted.logger import LogLevel, globalLogPublisher
|
||||
from twisted.python import failure, reflect
|
||||
+from twisted.python.compat import iterbytes
|
||||
from twisted.python.filepath import FilePath
|
||||
-from twisted.test.proto_helpers import EventLoggingObserver
|
||||
+from twisted.test.proto_helpers import EventLoggingObserver, StringTransport
|
||||
from twisted.trial import unittest
|
||||
from twisted.web import error, http, iweb, resource, server
|
||||
+from twisted.web.resource import Resource
|
||||
+from twisted.web.server import NOT_DONE_YET, Request, Site
|
||||
from twisted.web.static import Data
|
||||
from twisted.web.test.requesthelper import DummyChannel, DummyRequest
|
||||
from ._util import assertIsFilesystemTemporary
|
||||
@@ -1849,3 +1853,78 @@ class ExplicitHTTPFactoryReactor(unittes
|
||||
|
||||
factory = http.HTTPFactory()
|
||||
self.assertIs(factory.reactor, reactor)
|
||||
+
|
||||
+
|
||||
+class QueueResource(Resource):
|
||||
+ """
|
||||
+ Add all requests to an internal queue,
|
||||
+ without responding to the requests.
|
||||
+ You can access the requests from the queue and handle their response.
|
||||
+ """
|
||||
+
|
||||
+ isLeaf = True
|
||||
+
|
||||
+ def __init__(self) -> None:
|
||||
+ super().__init__()
|
||||
+ self.dispatchedRequests: List[Request] = []
|
||||
+
|
||||
+ def render_GET(self, request: Request) -> int:
|
||||
+ self.dispatchedRequests.append(request)
|
||||
+ return NOT_DONE_YET
|
||||
+
|
||||
+
|
||||
+class TestRFC9112Section932(unittest.TestCase):
|
||||
+ """
|
||||
+ Verify that HTTP/1.1 request ordering is preserved.
|
||||
+ """
|
||||
+
|
||||
+ def test_multipleRequestsInOneSegment(self) -> None:
|
||||
+ """
|
||||
+ Twisted MUST NOT respond to a second HTTP/1.1 request while the first
|
||||
+ is still pending.
|
||||
+ """
|
||||
+ qr = QueueResource()
|
||||
+ site = Site(qr)
|
||||
+ proto = site.buildProtocol(None)
|
||||
+ serverTransport = StringTransport()
|
||||
+ proto.makeConnection(serverTransport)
|
||||
+ proto.dataReceived(
|
||||
+ b"GET /first HTTP/1.1\r\nHost: a\r\n\r\n"
|
||||
+ b"GET /second HTTP/1.1\r\nHost: a\r\n\r\n"
|
||||
+ )
|
||||
+ # The TCP data contains 2 requests,
|
||||
+ # but only 1 request was dispatched,
|
||||
+ # as the first request was not yet finalized.
|
||||
+ self.assertEqual(len(qr.dispatchedRequests), 1)
|
||||
+ # The first request is finalized and the
|
||||
+ # second request is dispatched right away.
|
||||
+ qr.dispatchedRequests[0].finish()
|
||||
+ self.assertEqual(len(qr.dispatchedRequests), 2)
|
||||
+
|
||||
+ def test_multipleRequestsInDifferentSegments(self) -> None:
|
||||
+ """
|
||||
+ Twisted MUST NOT respond to a second HTTP/1.1 request while the first
|
||||
+ is still pending, even if the second request is received in a separate
|
||||
+ TCP package.
|
||||
+ """
|
||||
+ qr = QueueResource()
|
||||
+ site = Site(qr)
|
||||
+ proto = site.buildProtocol(None)
|
||||
+ serverTransport = StringTransport()
|
||||
+ proto.makeConnection(serverTransport)
|
||||
+ raw_data = (
|
||||
+ b"GET /first HTTP/1.1\r\nHost: a\r\n\r\n"
|
||||
+ b"GET /second HTTP/1.1\r\nHost: a\r\n\r\n"
|
||||
+ )
|
||||
+ # Just go byte by byte for the extreme case in which each byte is
|
||||
+ # received in a separate TCP package.
|
||||
+ for chunk in iterbytes(raw_data):
|
||||
+ proto.dataReceived(chunk)
|
||||
+ # The TCP data contains 2 requests,
|
||||
+ # but only 1 request was dispatched,
|
||||
+ # as the first request was not yet finalized.
|
||||
+ self.assertEqual(len(qr.dispatchedRequests), 1)
|
||||
+ # The first request is finalized and the
|
||||
+ # second request is dispatched right away.
|
||||
+ qr.dispatchedRequests[0].finish()
|
||||
+ self.assertEqual(len(qr.dispatchedRequests), 2)
|
242
CVE-2024-41671.patch
Normal file
242
CVE-2024-41671.patch
Normal file
@ -0,0 +1,242 @@
|
||||
Index: twisted-24.3.0/src/twisted/web/http.py
|
||||
===================================================================
|
||||
--- twisted-24.3.0.orig/src/twisted/web/http.py
|
||||
+++ twisted-24.3.0/src/twisted/web/http.py
|
||||
@@ -1973,16 +1973,21 @@ class _ChunkedTransferDecoder:
|
||||
@returns: C{False}, as there is either insufficient data to continue,
|
||||
or no data remains.
|
||||
"""
|
||||
- if (
|
||||
- self._receivedTrailerHeadersSize + len(self._buffer)
|
||||
- > self._maxTrailerHeadersSize
|
||||
- ):
|
||||
- raise _MalformedChunkedDataError("Trailer headers data is too long.")
|
||||
-
|
||||
eolIndex = self._buffer.find(b"\r\n", self._start)
|
||||
|
||||
if eolIndex == -1:
|
||||
# Still no end of network line marker found.
|
||||
+ #
|
||||
+ # Check if we've run up against the trailer size limit: if the next
|
||||
+ # read contains the terminating CRLF then we'll have this many bytes
|
||||
+ # of trailers (including the CRLFs).
|
||||
+ minTrailerSize = (
|
||||
+ self._receivedTrailerHeadersSize
|
||||
+ + len(self._buffer)
|
||||
+ + (1 if self._buffer.endswith(b"\r") else 2)
|
||||
+ )
|
||||
+ if minTrailerSize > self._maxTrailerHeadersSize:
|
||||
+ raise _MalformedChunkedDataError("Trailer headers data is too long.")
|
||||
# Continue processing more data.
|
||||
return False
|
||||
|
||||
@@ -1992,6 +1997,8 @@ class _ChunkedTransferDecoder:
|
||||
del self._buffer[0 : eolIndex + 2]
|
||||
self._start = 0
|
||||
self._receivedTrailerHeadersSize += eolIndex + 2
|
||||
+ if self._receivedTrailerHeadersSize > self._maxTrailerHeadersSize:
|
||||
+ raise _MalformedChunkedDataError("Trailer headers data is too long.")
|
||||
return True
|
||||
|
||||
# eolIndex in this part of code is equal to 0
|
||||
@@ -2315,8 +2322,8 @@ class HTTPChannel(basic.LineReceiver, po
|
||||
self.__header = line
|
||||
|
||||
def _finishRequestBody(self, data):
|
||||
- self.allContentReceived()
|
||||
self._dataBuffer.append(data)
|
||||
+ self.allContentReceived()
|
||||
|
||||
def _maybeChooseTransferDecoder(self, header, data):
|
||||
"""
|
||||
Index: twisted-24.3.0/src/twisted/web/newsfragments/12248.bugfix
|
||||
===================================================================
|
||||
--- /dev/null
|
||||
+++ twisted-24.3.0/src/twisted/web/newsfragments/12248.bugfix
|
||||
@@ -0,0 +1 @@
|
||||
+The HTTP 1.0 and 1.1 server provided by twisted.web could process pipelined HTTP requests out-of-order, possibly resulting in information disclosure (CVE-2024-41671/GHSA-c8m8-j448-xjx7)
|
||||
Index: twisted-24.3.0/src/twisted/web/test/test_http.py
|
||||
===================================================================
|
||||
--- twisted-24.3.0.orig/src/twisted/web/test/test_http.py
|
||||
+++ twisted-24.3.0/src/twisted/web/test/test_http.py
|
||||
@@ -135,7 +135,7 @@ class DummyHTTPHandler(http.Request):
|
||||
data = self.content.read()
|
||||
length = self.getHeader(b"content-length")
|
||||
if length is None:
|
||||
- length = networkString(str(length))
|
||||
+ length = str(length).encode()
|
||||
request = b"'''\n" + length + b"\n" + data + b"'''\n"
|
||||
self.setResponseCode(200)
|
||||
self.setHeader(b"Request", self.uri)
|
||||
@@ -563,17 +563,23 @@ class HTTP0_9Tests(HTTP1_0Tests):
|
||||
|
||||
class PipeliningBodyTests(unittest.TestCase, ResponseTestMixin):
|
||||
"""
|
||||
- Tests that multiple pipelined requests with bodies are correctly buffered.
|
||||
+ Pipelined requests get buffered and executed in the order received,
|
||||
+ not processed in parallel.
|
||||
"""
|
||||
|
||||
requests = (
|
||||
b"POST / HTTP/1.1\r\n"
|
||||
b"Content-Length: 10\r\n"
|
||||
b"\r\n"
|
||||
- b"0123456789POST / HTTP/1.1\r\n"
|
||||
- b"Content-Length: 10\r\n"
|
||||
- b"\r\n"
|
||||
b"0123456789"
|
||||
+ # Chunk encoded request.
|
||||
+ b"POST / HTTP/1.1\r\n"
|
||||
+ b"Transfer-Encoding: chunked\r\n"
|
||||
+ b"\r\n"
|
||||
+ b"a\r\n"
|
||||
+ b"0123456789\r\n"
|
||||
+ b"0\r\n"
|
||||
+ b"\r\n"
|
||||
)
|
||||
|
||||
expectedResponses = [
|
||||
@@ -590,14 +596,16 @@ class PipeliningBodyTests(unittest.TestC
|
||||
b"Request: /",
|
||||
b"Command: POST",
|
||||
b"Version: HTTP/1.1",
|
||||
- b"Content-Length: 21",
|
||||
- b"'''\n10\n0123456789'''\n",
|
||||
+ b"Content-Length: 23",
|
||||
+ b"'''\nNone\n0123456789'''\n",
|
||||
),
|
||||
]
|
||||
|
||||
- def test_noPipelining(self):
|
||||
+ def test_stepwiseTinyTube(self):
|
||||
"""
|
||||
- Test that pipelined requests get buffered, not processed in parallel.
|
||||
+ Imitate a slow connection that delivers one byte at a time.
|
||||
+ The request handler (L{DelayedHTTPHandler}) is puppeted to
|
||||
+ step through the handling of each request.
|
||||
"""
|
||||
b = StringTransport()
|
||||
a = http.HTTPChannel()
|
||||
@@ -606,10 +614,9 @@ class PipeliningBodyTests(unittest.TestC
|
||||
# one byte at a time, to stress it.
|
||||
for byte in iterbytes(self.requests):
|
||||
a.dataReceived(byte)
|
||||
- value = b.value()
|
||||
|
||||
# So far only one request should have been dispatched.
|
||||
- self.assertEqual(value, b"")
|
||||
+ self.assertEqual(b.value(), b"")
|
||||
self.assertEqual(1, len(a.requests))
|
||||
|
||||
# Now, process each request one at a time.
|
||||
@@ -618,8 +625,95 @@ class PipeliningBodyTests(unittest.TestC
|
||||
request = a.requests[0].original
|
||||
request.delayedProcess()
|
||||
|
||||
- value = b.value()
|
||||
- self.assertResponseEquals(value, self.expectedResponses)
|
||||
+ self.assertResponseEquals(b.value(), self.expectedResponses)
|
||||
+
|
||||
+ def test_stepwiseDumpTruck(self):
|
||||
+ """
|
||||
+ Imitate a fast connection where several pipelined
|
||||
+ requests arrive in a single read. The request handler
|
||||
+ (L{DelayedHTTPHandler}) is puppeted to step through the
|
||||
+ handling of each request.
|
||||
+ """
|
||||
+ b = StringTransport()
|
||||
+ a = http.HTTPChannel()
|
||||
+ a.requestFactory = DelayedHTTPHandlerProxy
|
||||
+ a.makeConnection(b)
|
||||
+
|
||||
+ a.dataReceived(self.requests)
|
||||
+
|
||||
+ # So far only one request should have been dispatched.
|
||||
+ self.assertEqual(b.value(), b"")
|
||||
+ self.assertEqual(1, len(a.requests))
|
||||
+
|
||||
+ # Now, process each request one at a time.
|
||||
+ while a.requests:
|
||||
+ self.assertEqual(1, len(a.requests))
|
||||
+ request = a.requests[0].original
|
||||
+ request.delayedProcess()
|
||||
+
|
||||
+ self.assertResponseEquals(b.value(), self.expectedResponses)
|
||||
+
|
||||
+ def test_immediateTinyTube(self):
|
||||
+ """
|
||||
+ Imitate a slow connection that delivers one byte at a time.
|
||||
+
|
||||
+ (L{DummyHTTPHandler}) immediately responds, but no more
|
||||
+ than one
|
||||
+ """
|
||||
+ b = StringTransport()
|
||||
+ a = http.HTTPChannel()
|
||||
+ a.requestFactory = DummyHTTPHandlerProxy # "sync"
|
||||
+ a.makeConnection(b)
|
||||
+
|
||||
+ # one byte at a time, to stress it.
|
||||
+ for byte in iterbytes(self.requests):
|
||||
+ a.dataReceived(byte)
|
||||
+ # There is never more than one request dispatched at a time:
|
||||
+ self.assertLessEqual(len(a.requests), 1)
|
||||
+
|
||||
+ self.assertResponseEquals(b.value(), self.expectedResponses)
|
||||
+
|
||||
+ def test_immediateDumpTruck(self):
|
||||
+ """
|
||||
+ Imitate a fast connection where several pipelined
|
||||
+ requests arrive in a single read. The request handler
|
||||
+ (L{DummyHTTPHandler}) immediately responds.
|
||||
+
|
||||
+ This doesn't check the at-most-one pending request
|
||||
+ invariant but exercises otherwise uncovered code paths.
|
||||
+ See GHSA-c8m8-j448-xjx7.
|
||||
+ """
|
||||
+ b = StringTransport()
|
||||
+ a = http.HTTPChannel()
|
||||
+ a.requestFactory = DummyHTTPHandlerProxy
|
||||
+ a.makeConnection(b)
|
||||
+
|
||||
+ # All bytes at once to ensure there's stuff to buffer.
|
||||
+ a.dataReceived(self.requests)
|
||||
+
|
||||
+ self.assertResponseEquals(b.value(), self.expectedResponses)
|
||||
+
|
||||
+ def test_immediateABiggerTruck(self):
|
||||
+ """
|
||||
+ Imitate a fast connection where a so many pipelined
|
||||
+ requests arrive in a single read that backpressure is indicated.
|
||||
+ The request handler (L{DummyHTTPHandler}) immediately responds.
|
||||
+
|
||||
+ This doesn't check the at-most-one pending request
|
||||
+ invariant but exercises otherwise uncovered code paths.
|
||||
+ See GHSA-c8m8-j448-xjx7.
|
||||
+
|
||||
+ @see: L{http.HTTPChannel._optimisticEagerReadSize}
|
||||
+ """
|
||||
+ b = StringTransport()
|
||||
+ a = http.HTTPChannel()
|
||||
+ a.requestFactory = DummyHTTPHandlerProxy
|
||||
+ a.makeConnection(b)
|
||||
+
|
||||
+ overLimitCount = a._optimisticEagerReadSize // len(self.requests) * 10
|
||||
+ a.dataReceived(self.requests * overLimitCount)
|
||||
+
|
||||
+ self.assertResponseEquals(b.value(), self.expectedResponses * overLimitCount)
|
||||
|
||||
def test_pipeliningReadLimit(self):
|
||||
"""
|
||||
@@ -1522,7 +1616,11 @@ class ChunkedTransferEncodingTests(unitt
|
||||
lambda b: None, # pragma: nocov
|
||||
)
|
||||
p._maxTrailerHeadersSize = 10
|
||||
- p.dataReceived(b"3\r\nabc\r\n0\r\n0123456789")
|
||||
+ # 9 bytes are received so far, in 2 packets.
|
||||
+ # For now, all is ok.
|
||||
+ p.dataReceived(b"3\r\nabc\r\n0\r\n01234567")
|
||||
+ p.dataReceived(b"\r")
|
||||
+ # Once the 10th byte is received, the processing fails.
|
||||
self.assertRaises(
|
||||
http._MalformedChunkedDataError,
|
||||
p.dataReceived,
|
83
CVE-2024-41810.patch
Normal file
83
CVE-2024-41810.patch
Normal file
@ -0,0 +1,83 @@
|
||||
Index: twisted-24.3.0/src/twisted/web/_template_util.py
|
||||
===================================================================
|
||||
--- twisted-24.3.0.orig/src/twisted/web/_template_util.py
|
||||
+++ twisted-24.3.0/src/twisted/web/_template_util.py
|
||||
@@ -92,7 +92,7 @@ def redirectTo(URL: bytes, request: IReq
|
||||
</body>
|
||||
</html>
|
||||
""" % {
|
||||
- b"url": URL
|
||||
+ b"url": escape(URL.decode("utf-8")).encode("utf-8")
|
||||
}
|
||||
return content
|
||||
|
||||
Index: twisted-24.3.0/src/twisted/web/newsfragments/12263.bugfix
|
||||
===================================================================
|
||||
--- /dev/null
|
||||
+++ twisted-24.3.0/src/twisted/web/newsfragments/12263.bugfix
|
||||
@@ -0,0 +1 @@
|
||||
+twisted.web.util.redirectTo now HTML-escapes the provided URL in the fallback response body it returns (GHSA-cf56-g6w6-pqq2). The issue is being tracked with CVE-2024-41810.
|
||||
\ No newline at end of file
|
||||
Index: twisted-24.3.0/src/twisted/web/newsfragments/9839.bugfix
|
||||
===================================================================
|
||||
--- /dev/null
|
||||
+++ twisted-24.3.0/src/twisted/web/newsfragments/9839.bugfix
|
||||
@@ -0,0 +1 @@
|
||||
+twisted.web.util.redirectTo now HTML-escapes the provided URL in the fallback response body it returns (GHSA-cf56-g6w6-pqq2, CVE-2024-41810).
|
||||
Index: twisted-24.3.0/src/twisted/web/test/test_util.py
|
||||
===================================================================
|
||||
--- twisted-24.3.0.orig/src/twisted/web/test/test_util.py
|
||||
+++ twisted-24.3.0/src/twisted/web/test/test_util.py
|
||||
@@ -5,7 +5,6 @@
|
||||
Tests for L{twisted.web.util}.
|
||||
"""
|
||||
|
||||
-
|
||||
import gc
|
||||
|
||||
from twisted.internet import defer
|
||||
@@ -64,6 +63,44 @@ class RedirectToTests(TestCase):
|
||||
targetURL = "http://target.example.com/4321"
|
||||
self.assertRaises(TypeError, redirectTo, targetURL, request)
|
||||
|
||||
+ def test_legitimateRedirect(self):
|
||||
+ """
|
||||
+ Legitimate URLs are fully interpolated in the `redirectTo` response body without transformation
|
||||
+ """
|
||||
+ request = DummyRequest([b""])
|
||||
+ html = redirectTo(b"https://twisted.org/", request)
|
||||
+ expected = b"""
|
||||
+<html>
|
||||
+ <head>
|
||||
+ <meta http-equiv=\"refresh\" content=\"0;URL=https://twisted.org/\">
|
||||
+ </head>
|
||||
+ <body bgcolor=\"#FFFFFF\" text=\"#000000\">
|
||||
+ <a href=\"https://twisted.org/\">click here</a>
|
||||
+ </body>
|
||||
+</html>
|
||||
+"""
|
||||
+ self.assertEqual(html, expected)
|
||||
+
|
||||
+ def test_maliciousRedirect(self):
|
||||
+ """
|
||||
+ Malicious URLs are HTML-escaped before interpolating them in the `redirectTo` response body
|
||||
+ """
|
||||
+ request = DummyRequest([b""])
|
||||
+ html = redirectTo(
|
||||
+ b'https://twisted.org/"><script>alert(document.location)</script>', request
|
||||
+ )
|
||||
+ expected = b"""
|
||||
+<html>
|
||||
+ <head>
|
||||
+ <meta http-equiv=\"refresh\" content=\"0;URL=https://twisted.org/"><script>alert(document.location)</script>\">
|
||||
+ </head>
|
||||
+ <body bgcolor=\"#FFFFFF\" text=\"#000000\">
|
||||
+ <a href=\"https://twisted.org/"><script>alert(document.location)</script>\">click here</a>
|
||||
+ </body>
|
||||
+</html>
|
||||
+"""
|
||||
+ self.assertEqual(html, expected)
|
||||
+
|
||||
|
||||
class ParentRedirectTests(SynchronousTestCase):
|
||||
"""
|
BIN
Twisted-22.10.0.tar.gz
(Stored with Git LFS)
BIN
Twisted-22.10.0.tar.gz
(Stored with Git LFS)
Binary file not shown.
@ -2,16 +2,16 @@
|
||||
src/twisted/test/test_failure.py | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
Index: Twisted-22.10.0/src/twisted/test/test_failure.py
|
||||
Index: twisted-24.3.0/src/twisted/test/test_failure.py
|
||||
===================================================================
|
||||
--- Twisted-22.10.0.orig/src/twisted/test/test_failure.py
|
||||
+++ Twisted-22.10.0/src/twisted/test/test_failure.py
|
||||
@@ -16,7 +16,8 @@ from io import StringIO
|
||||
from traceback import FrameSummary
|
||||
--- twisted-24.3.0.orig/src/twisted/test/test_failure.py
|
||||
+++ twisted-24.3.0/src/twisted/test/test_failure.py
|
||||
@@ -18,7 +18,8 @@ from types import TracebackType
|
||||
from typing import Any, Generator
|
||||
from unittest import skipIf
|
||||
|
||||
-from cython_test_exception_raiser import raiser # type: ignore[import]
|
||||
+# from cython_test_exception_raiser import raiser # type: ignore[import]
|
||||
-from cython_test_exception_raiser import raiser
|
||||
+# from cython_test_exception_raiser import raiser
|
||||
+raiser = None
|
||||
|
||||
from twisted.python import failure, reflect
|
||||
|
@ -1,36 +0,0 @@
|
||||
Index: Twisted-22.10.0/src/twisted/internet/gireactor.py
|
||||
===================================================================
|
||||
--- Twisted-22.10.0.orig/src/twisted/internet/gireactor.py
|
||||
+++ Twisted-22.10.0/src/twisted/internet/gireactor.py
|
||||
@@ -21,20 +21,24 @@ On Python 3, pygobject v3.4 or later is
|
||||
"""
|
||||
|
||||
|
||||
-import gi.pygtkcompat # type: ignore[import]
|
||||
from gi.repository import GLib # type: ignore[import]
|
||||
|
||||
from twisted.internet import _glibbase
|
||||
from twisted.internet.error import ReactorAlreadyRunning
|
||||
from twisted.python import runtime
|
||||
|
||||
-# We require a sufficiently new version of pygobject, so always exists:
|
||||
-_pygtkcompatPresent = True
|
||||
+try:
|
||||
+ import gi.pygtkcompat # type: ignore[import]
|
||||
+except ImportError:
|
||||
+ pass # This is probably Python 3, with pygtkcompat removed
|
||||
+else:
|
||||
+ # We require a sufficiently new version of pygobject, so always exists:
|
||||
+ _pygtkcompatPresent = True
|
||||
|
||||
-# Newer version of gi, so we can try to initialize compatibility layer; if
|
||||
-# real pygtk was already imported we'll get ImportError at this point
|
||||
-# rather than segfault, so unconditional import is fine.
|
||||
-gi.pygtkcompat.enable()
|
||||
+ # Newer version of gi, so we can try to initialize compatibility layer; if
|
||||
+ # real pygtk was already imported we'll get ImportError at this point
|
||||
+ # rather than segfault, so unconditional import is fine.
|
||||
+ gi.pygtkcompat.enable()
|
||||
# At this point importing gobject will get you gi version, and importing
|
||||
# e.g. gtk will either fail in non-segfaulty way or use gi version if user
|
||||
# does gi.pygtkcompat.enable_gtk(). So, no need to prevent imports of
|
@ -2,10 +2,10 @@
|
||||
src/twisted/conch/test/test_keys.py | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
Index: Twisted-22.10.0/src/twisted/conch/test/test_keys.py
|
||||
Index: twisted-24.3.0/src/twisted/conch/test/test_keys.py
|
||||
===================================================================
|
||||
--- Twisted-22.10.0.orig/src/twisted/conch/test/test_keys.py
|
||||
+++ Twisted-22.10.0/src/twisted/conch/test/test_keys.py
|
||||
--- twisted-24.3.0.orig/src/twisted/conch/test/test_keys.py
|
||||
+++ twisted-24.3.0/src/twisted/conch/test/test_keys.py
|
||||
@@ -15,6 +15,7 @@ from twisted.python import randbytes
|
||||
from twisted.python.filepath import FilePath
|
||||
from twisted.python.reflect import requireModule
|
||||
@ -14,7 +14,7 @@ Index: Twisted-22.10.0/src/twisted/conch/test/test_keys.py
|
||||
|
||||
cryptography = requireModule("cryptography")
|
||||
if cryptography is None:
|
||||
@@ -259,6 +260,8 @@ class KeyTests(unittest.TestCase):
|
||||
@@ -250,6 +251,8 @@ class KeyTests(unittest.TestCase):
|
||||
for k, v in data.items():
|
||||
self.assertEqual(privateKey.data()[k], v)
|
||||
|
||||
|
@ -1,117 +0,0 @@
|
||||
Index: Twisted-22.10.0/src/twisted/newsfragments/10343.feature
|
||||
===================================================================
|
||||
--- /dev/null
|
||||
+++ Twisted-22.10.0/src/twisted/newsfragments/10343.feature
|
||||
@@ -0,0 +1 @@
|
||||
+Twisted now officially supports Python 3.11.
|
||||
Index: Twisted-22.10.0/src/twisted/persisted/aot.py
|
||||
===================================================================
|
||||
--- Twisted-22.10.0.orig/src/twisted/persisted/aot.py
|
||||
+++ Twisted-22.10.0/src/twisted/persisted/aot.py
|
||||
@@ -399,8 +399,10 @@ class AOTUnjellier:
|
||||
inst = klass.__new__(klass)
|
||||
if hasattr(klass, "__setstate__"):
|
||||
self.callAfter(inst.__setstate__, state)
|
||||
- else:
|
||||
+ elif isinstance(state, dict):
|
||||
inst.__dict__ = state
|
||||
+ else:
|
||||
+ inst.__dict__ = state.__getstate__()
|
||||
return inst
|
||||
|
||||
elif c is Ref:
|
||||
Index: Twisted-22.10.0/src/twisted/spread/flavors.py
|
||||
===================================================================
|
||||
--- Twisted-22.10.0.orig/src/twisted/spread/flavors.py
|
||||
+++ Twisted-22.10.0/src/twisted/spread/flavors.py
|
||||
@@ -398,6 +398,8 @@ class RemoteCopy(Unjellyable):
|
||||
object's dictionary (or a filtered approximation of it depending
|
||||
on my peer's perspective).
|
||||
"""
|
||||
+ if not state:
|
||||
+ state = {}
|
||||
state = {
|
||||
x.decode("utf8") if isinstance(x, bytes) else x: y for x, y in state.items()
|
||||
}
|
||||
Index: Twisted-22.10.0/src/twisted/spread/jelly.py
|
||||
===================================================================
|
||||
--- Twisted-22.10.0.orig/src/twisted/spread/jelly.py
|
||||
+++ Twisted-22.10.0/src/twisted/spread/jelly.py
|
||||
@@ -154,7 +154,8 @@ def _newInstance(cls, state):
|
||||
instance = _createBlank(cls)
|
||||
|
||||
def defaultSetter(state):
|
||||
- instance.__dict__ = state
|
||||
+ if isinstance(state, dict):
|
||||
+ instance.__dict__ = state or {}
|
||||
|
||||
setter = getattr(instance, "__setstate__", defaultSetter)
|
||||
setter(state)
|
||||
Index: Twisted-22.10.0/src/twisted/test/test_persisted.py
|
||||
===================================================================
|
||||
--- Twisted-22.10.0.orig/src/twisted/test/test_persisted.py
|
||||
+++ Twisted-22.10.0/src/twisted/test/test_persisted.py
|
||||
@@ -378,6 +378,10 @@ class AOTTests(TestCase):
|
||||
def __dict__(self):
|
||||
raise AttributeError()
|
||||
|
||||
+ @property
|
||||
+ def __getstate__(self):
|
||||
+ raise AttributeError()
|
||||
+
|
||||
self.assertRaises(TypeError, aot.jellyToSource, UnknownType())
|
||||
|
||||
def test_basicIdentity(self):
|
||||
Index: Twisted-22.10.0/src/twisted/trial/test/test_pyunitcompat.py
|
||||
===================================================================
|
||||
--- Twisted-22.10.0.orig/src/twisted/trial/test/test_pyunitcompat.py
|
||||
+++ Twisted-22.10.0/src/twisted/trial/test/test_pyunitcompat.py
|
||||
@@ -218,8 +218,10 @@ class PyUnitResultTests(SynchronousTestC
|
||||
pyresult = pyunit.TestResult()
|
||||
result = PyUnitResultAdapter(pyresult)
|
||||
result.addError(self, f)
|
||||
+ tback = "".join(traceback.format_exception(*exc_info))
|
||||
self.assertEqual(
|
||||
- pyresult.errors[0][1], "".join(traceback.format_exception(*exc_info))
|
||||
+ pyresult.errors[0][1].endswith("ZeroDivisionError: division by zero\n"),
|
||||
+ tback.endswith("ZeroDivisionError: division by zero\n"),
|
||||
)
|
||||
|
||||
def test_trialSkip(self):
|
||||
Index: Twisted-22.10.0/src/twisted/web/test/test_flatten.py
|
||||
===================================================================
|
||||
--- Twisted-22.10.0.orig/src/twisted/web/test/test_flatten.py
|
||||
+++ Twisted-22.10.0/src/twisted/web/test/test_flatten.py
|
||||
@@ -706,15 +706,15 @@ class FlattenerErrorTests(SynchronousTes
|
||||
Exception while flattening:
|
||||
\\[<unrenderable>\\]
|
||||
<unrenderable>
|
||||
- .*
|
||||
+ <Deferred at .* current result: <twisted.python.failure.Failure builtins.RuntimeError: example>>
|
||||
File ".*", line \\d*, in _flattenTree
|
||||
- element = await element
|
||||
- RuntimeError: example
|
||||
+ element = await element.*
|
||||
"""
|
||||
),
|
||||
flags=re.MULTILINE,
|
||||
),
|
||||
)
|
||||
+ self.assertIn("RuntimeError: example", str(failure.value))
|
||||
# The original exception is unmodified and will be logged separately if
|
||||
# unhandled.
|
||||
self.failureResultOf(failing, RuntimeError)
|
||||
Index: Twisted-22.10.0/src/twisted/mail/test/test_smtp.py
|
||||
===================================================================
|
||||
--- Twisted-22.10.0.orig/src/twisted/mail/test/test_smtp.py
|
||||
+++ Twisted-22.10.0/src/twisted/mail/test/test_smtp.py
|
||||
@@ -1771,7 +1771,8 @@ class SendmailTests(TestCase):
|
||||
The default C{reactor} parameter of L{twisted.mail.smtp.sendmail} is
|
||||
L{twisted.internet.reactor}.
|
||||
"""
|
||||
- args, varArgs, keywords, defaults = inspect.getargspec(smtp.sendmail)
|
||||
+ fullSpec = inspect.getfullargspec(smtp.sendmail)
|
||||
+ defaults = fullSpec[3]
|
||||
self.assertEqual(reactor, defaults[2])
|
||||
|
||||
def _honorsESMTPArguments(self, username, password):
|
@ -1,3 +1,89 @@
|
||||
-------------------------------------------------------------------
|
||||
Wed Jul 31 06:07:19 UTC 2024 - Daniel Garcia <daniel.garcia@suse.com>
|
||||
|
||||
- Add a couple of upstream patches to fix http process information
|
||||
disclosure (CVE-2024-41671, bsc#1228549) and XSS via html injection
|
||||
(CVE-2024-41810, bsc#1228552):
|
||||
* CVE-2024-41671.patch gh#twisted/twisted@4a930de12fb6
|
||||
* CVE-2024-41810.patch gh#twisted/twisted@046a164f89a0
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Tue Jul 2 19:43:29 UTC 2024 - Dirk Müller <dmueller@suse.com>
|
||||
|
||||
- update to 24.3.0:
|
||||
* twisted.logger.formatEvent now honors dotted method names,
|
||||
not just flat function names, in format strings, as it has
|
||||
long been explicitly documented to do. So, you will now get
|
||||
the expected result from formatEvent("here's the result of
|
||||
calling a method at log-format time: {obj.method()}",
|
||||
obj=...)
|
||||
* twisted.web.http.HTTPChannel now ignores the trailer headers
|
||||
provided in the last chunk of a chunked encoded response,
|
||||
rather than raising an exception.
|
||||
* twisted.protocols.tls.BufferingTLSTransport, used by default
|
||||
by twisted.protocols.tls.TLSMemoryBIOFactory, was refactored
|
||||
for improved performance when doing a high number of small
|
||||
writes.
|
||||
* twisted.python.failure.Failure now throws exception for
|
||||
generators without triggering a deprecation warnings on
|
||||
Python 3.12.
|
||||
* twisted.internet.process.Process, used by
|
||||
reactor.spawnProcess, now copies the parent environment when
|
||||
the env=None argument is passed on Posix systems and
|
||||
os.posix_spawnp is used internally.
|
||||
* twisted.internet.defer.inlineCallbacks.returnValue's stack
|
||||
introspection was adjusted for the latest PyPy 7.3.14
|
||||
release, allowing legacy @inlineCallbacks to run on new PyPY
|
||||
versions.
|
||||
* twisted.trial.reporter.TestRun.startTest() is no longer
|
||||
called for tests with skip annotation or skip attribute for
|
||||
Python 3.12.1 or newer. This is the result of upstream Python
|
||||
gh-106584 change. The behavior is not change in 3.12.0 or
|
||||
older.
|
||||
- drop twisted-pr12054-testinvokationpy3.12.1.patch,
|
||||
stop-using-3-arg-throw.patch (upstream)
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Thu Feb 1 08:33:49 UTC 2024 - Steve Kowalik <steven.kowalik@suse.com>
|
||||
|
||||
- Add stop-using-3-arg-throw.patch:
|
||||
* Avoid 3-arg throw to fix a DeprecationWarning in Python 3.12.
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Thu Jan 18 21:33:05 UTC 2024 - Ben Greiner <code@bnavigator.de>
|
||||
|
||||
- Add twisted-pr12054-testinvokationpy3.12.1.patch
|
||||
* Pull request gh#twisted/twisted#12054 fixes failing tests on
|
||||
python312 gh#twisted/twisted#12052
|
||||
- Fix rpmlint errors
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Thu Nov 23 08:28:43 UTC 2023 - Markéta Machová <mmachova@suse.com>
|
||||
|
||||
- Update to 23.10.0
|
||||
* reactor.spawnProcess() now uses posix_spawnp when possible, making it much more efficient (#5710)
|
||||
* Twisted now officially supports Python 3.11. (#10343)
|
||||
* twisted.internet.defer.race has been added as a way to get the first available result from a list of Deferreds. (#11817)
|
||||
* The CI suite was updated to execute the tests using a Python 3.12 pre-release (#11857)
|
||||
* PyAsn1 has been removed as a conch dependency.
|
||||
* Due to changes in the way raw private key byte serialization are handled in Cryptography, and widespread support
|
||||
for Ed25519 in current versions of OpenSSL, we no longer support PyNaCl as a fallback for Ed25519 keys in Conch. (#11871)
|
||||
* In Twisted 16.3.0, we changed twisted.web to stop dispatching HTTP/1.1 pipelined requests to application code.
|
||||
There was a bug in this change which still allowed clients which could send multiple full HTTP requests in a single TCP segment
|
||||
to trigger asynchronous processing of later requests, which could lead to out-of-order responses. This has now been corrected
|
||||
and twisted.web should never process a pipelined request over HTTP/1.1 until the previous request has fully completed.
|
||||
(CVE-2023-46137, GHSA-cq7q-gv5w-rwx2) (#11976)
|
||||
* Drop support for Python 3.7. Remove twisted[contextvars] extra (contextvars are always available in Python 3.7+) (#11913)
|
||||
* When using CPython, functions wrapped by twisted.internet.defer.inlineCallbacks can have their arguments and return values
|
||||
freed immediately after completion (due to there no longer being circular references). (#11885)
|
||||
- Delete merged patches:
|
||||
* regenerate-cert-to-work-with-latest-service-identity.patch
|
||||
* no-pygtkcompat.patch
|
||||
* support-new-glibc.patch
|
||||
* CVE-2023-46137-HTTP-pipeline-response.patch
|
||||
* remove-pynacl-optional-dependency.patch
|
||||
* py311-tests-compat.patch
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Wed Nov 15 13:48:33 UTC 2023 - Matej Cepl <mcepl@cepl.eu>
|
||||
|
||||
@ -30,7 +116,7 @@ Thu Apr 13 22:45:37 UTC 2023 - Matej Cepl <mcepl@suse.com>
|
||||
Wed Feb 8 08:19:43 UTC 2023 - Steve Kowalik <steven.kowalik@suse.com>
|
||||
|
||||
- Add patch support-new-glibc.patch:
|
||||
* Support new glibc changes.
|
||||
* Support new glibc changes.
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Tue Jan 10 17:43:37 UTC 2023 - Daniel Garcia <daniel.garcia@suse.com>
|
||||
@ -74,7 +160,7 @@ Tue Nov 1 05:46:14 UTC 2022 - Steve Kowalik <steven.kowalik@suse.com>
|
||||
+ Implement twisted.python.failure._Code.co_positions for compatibility
|
||||
with Python 3.11.
|
||||
+ twisted.pair.tuntap._TUNSETIFF and ._TUNGETIFF values are now correct
|
||||
parisc, powerpc and sparc architectures.
|
||||
parisc, powerpc and sparc architectures.
|
||||
+ twisted.web.vhost.NameVirtualHost will no longerreturn a NoResource
|
||||
error. (bsc#1204781, CVE-2022-39348)
|
||||
+ drops CVE-2022-39348-do-not-echo-host-header.patch in older dists
|
||||
@ -140,7 +226,7 @@ Tue Jun 21 18:08:20 UTC 2022 - Ben Greiner <code@bnavigator.de>
|
||||
Wed May 4 06:39:10 UTC 2022 - Steve Kowalik <steven.kowalik@suse.com>
|
||||
|
||||
- Stop removing test directories, it also removes a public module.
|
||||
(bsc#1198852, bsc#1198854, bsc#1198855)
|
||||
(bsc#1198852, bsc#1198854, bsc#1198855)
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Thu Apr 7 02:31:24 UTC 2022 - Steve Kowalik <steven.kowalik@suse.com>
|
||||
@ -168,7 +254,7 @@ Thu Apr 7 02:31:24 UTC 2022 - Steve Kowalik <steven.kowalik@suse.com>
|
||||
Thu Mar 24 12:40:28 UTC 2022 - Matej Cepl <mcepl@suse.com>
|
||||
|
||||
- Add patch skip-namespacewithwhitespace.patch:
|
||||
* Skip a failing test with Expat 2.4.5.
|
||||
* Skip a failing test with Expat 2.4.5.
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Wed Feb 23 00:30:47 UTC 2022 - Steve Kowalik <steven.kowalik@suse.com>
|
||||
@ -258,7 +344,7 @@ Wed Feb 9 23:29:53 UTC 2022 - Marcus Rueckert <mrueckert@suse.de>
|
||||
Thu Jan 6 04:48:46 UTC 2022 - Steve Kowalik <steven.kowalik@suse.com>
|
||||
|
||||
- Add patch currentThread-deprecated.patch:
|
||||
* Do not call a deprecated method which causes reactor startup to abort.
|
||||
* Do not call a deprecated method which causes reactor startup to abort.
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Fri Dec 10 17:04:31 UTC 2021 - Ben Greiner <code@bnavigator.de>
|
||||
@ -309,7 +395,7 @@ Sat Jul 31 04:27:55 UTC 2021 - Matej Cepl <mcepl@suse.com>
|
||||
-------------------------------------------------------------------
|
||||
Mon May 17 10:15:13 UTC 2021 - Dirk Müller <dmueller@suse.com>
|
||||
|
||||
- add incremental-21.patch: support newer incremental versions
|
||||
- add incremental-21.patch: support newer incremental versions
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Wed Mar 10 06:11:42 UTC 2021 - Steve Kowalik <steven.kowalik@suse.com>
|
||||
@ -409,7 +495,7 @@ Thu Feb 11 15:49:07 UTC 2021 - Pedro Monreal <pmonreal@suse.com>
|
||||
-------------------------------------------------------------------
|
||||
Fri Dec 11 00:02:02 UTC 2020 - Benjamin Greiner <code@bnavigator.de>
|
||||
|
||||
- Add twisted-pr1369-remove-pyopenssl-npn.patch to support
|
||||
- Add twisted-pr1369-remove-pyopenssl-npn.patch to support
|
||||
pyOpenSSL 20
|
||||
- Add twisted-pr1487-increase-ffdh-keysize.patch to support
|
||||
crpytography 3.3
|
||||
@ -432,7 +518,7 @@ Thu May 28 12:43:51 UTC 2020 - Marketa Calabkova <mcalabkova@suse.com>
|
||||
- Update to 20.3.0
|
||||
* drop Python 2
|
||||
* twisted.news is deprecated.
|
||||
* twisted.conch.ssh now supports the curve25519-sha256 key exchange
|
||||
* twisted.conch.ssh now supports the curve25519-sha256 key exchange
|
||||
algorithm (requires OpenSSL >= 1.1.0).
|
||||
* many bugfixes and other miscelaneous fixes
|
||||
- Fixed update-alternatives mechanism
|
||||
|
@ -1 +1,2 @@
|
||||
addFilter("E: python-tests-in-package.*/usr/lib/.*/site-packages/twisted.*/test")
|
||||
# rpmlint is too stupid for the . in the name
|
||||
addFilter("python-.*-require .*zope.interface")
|
||||
|
@ -1,7 +1,7 @@
|
||||
#
|
||||
# spec file
|
||||
# spec file for package python-Twisted
|
||||
#
|
||||
# Copyright (c) 2023 SUSE LLC
|
||||
# Copyright (c) 2024 SUSE LLC
|
||||
#
|
||||
# All modifications and additions to the file contributed by third parties
|
||||
# remain the property of their copyright owners, unless otherwise agreed
|
||||
@ -25,15 +25,14 @@
|
||||
%define psuffix %{nil}
|
||||
%endif
|
||||
|
||||
%define skip_python2 1
|
||||
%{?sle15_python_module_pythons}
|
||||
Name: python-Twisted%{psuffix}
|
||||
Version: 22.10.0
|
||||
Version: 24.3.0
|
||||
Release: 0
|
||||
Summary: An asynchronous networking framework written in Python
|
||||
License: MIT
|
||||
URL: https://twistedmatrix.com/
|
||||
Source0: https://files.pythonhosted.org/packages/source/T/Twisted/Twisted-%{version}.tar.gz
|
||||
URL: https://twisted.org
|
||||
Source0: https://files.pythonhosted.org/packages/source/t/twisted/twisted-%{version}.tar.gz
|
||||
Source99: python-Twisted.rpmlintrc
|
||||
Patch0: skip_MultiCast.patch
|
||||
# PATCH-FIX-UPSTREAM no-test_successResultOfWithFailureHasTraceback.patch https://twistedmatrix.com/trac/ticket/9665 mcepl@suse.com
|
||||
@ -42,30 +41,25 @@ Patch2: no-test_successResultOfWithFailureHasTraceback.patch
|
||||
# PATCH-FIX-UPSTREAM 1521_delegate_parseqs_stdlib_bpo42967.patch https://twistedmatrix.com/trac/ticket/10096 mcepl@suse.com
|
||||
# overcome incompatibility with the solution for bpo#42967.
|
||||
Patch3: 1521_delegate_parseqs_stdlib_bpo42967.patch
|
||||
# We don't want to package yet another module, and it is easily skippable
|
||||
Patch4: no-cython_test_exception_raiser.patch
|
||||
# boo#1110669 Our variant of PyGObject has pygtkcompat stripped which Twisted does not handle
|
||||
Patch5: no-pygtkcompat.patch
|
||||
# PATCH-FIX-OPENSUSE We don't want to package yet another module, and it is easily skippable
|
||||
Patch5: no-cython_test_exception_raiser.patch
|
||||
# PATCH-FIX-OPENSUSE remove-dependency-version-upper-bounds.patch boo#1190036 -- run with h2 >= 4.0.0 and priority >= 2.0
|
||||
Patch6: remove-dependency-version-upper-bounds.patch
|
||||
# PATCH-FIX-UPSTREAM py311-tests-compat.patch gh#twisted/twisted#11734 gh#twisted/twisted#11733
|
||||
Patch7: py311-tests-compat.patch
|
||||
# PATCH-FIX-UPSTREAM gh#twisted/twisted#11787
|
||||
Patch8: support-new-glibc.patch
|
||||
# PATCH-FIX-UPSTREAM gh#twisted/twisted#11878
|
||||
Patch9: regenerate-cert-to-work-with-latest-service-identity.patch
|
||||
# PATCH-FIX-UPSTREAM gh#twisted/twisted#11873
|
||||
Patch10: remove-pynacl-optional-dependency.patch
|
||||
# PATCH-FIX-UPSTREAM CVE-2023-46137-HTTP-pipeline-response.patch bsc#1216588 mcepl@suse.com
|
||||
# disordered HTTP pipeline response in twisted.web
|
||||
Patch11: CVE-2023-46137-HTTP-pipeline-response.patch
|
||||
# PATCH-FIX-UPSTREAM CVE-2024-41671.patch gh#twisted/twisted@4a930de12fb6
|
||||
Patch7: CVE-2024-41671.patch
|
||||
# PATCH-FIX-UPSTREAM CVE-2024-41810.patch gh#twisted/twisted@046a164f89a0
|
||||
Patch8: CVE-2024-41810.patch
|
||||
BuildRequires: %{python_module hatch-fancy-pypi-readme}
|
||||
BuildRequires: %{python_module hatchling}
|
||||
BuildRequires: %{python_module incremental >= 21.3.0}
|
||||
BuildRequires: %{python_module pip}
|
||||
BuildRequires: %{python_module setuptools}
|
||||
BuildRequires: %{python_module wheel}
|
||||
BuildRequires: fdupes
|
||||
BuildRequires: git-core
|
||||
BuildRequires: python-rpm-macros
|
||||
Requires(post): update-alternatives
|
||||
Requires(postun):update-alternatives
|
||||
Requires(postun): update-alternatives
|
||||
# SECTION install requires
|
||||
Requires: python-Automat >= 0.8.0
|
||||
Requires: python-attrs >= 19.2.0
|
||||
@ -121,7 +115,6 @@ Requires: python-Twisted = %{version}
|
||||
Requires: python-appdirs >= 1.4.0
|
||||
Requires: python-bcrypt >= 3.0.0
|
||||
Requires: python-cryptography >= 2.6
|
||||
Requires: python-pyasn1
|
||||
|
||||
%description conch
|
||||
Twisted is an extensible framework for Python programming, with special focus
|
||||
@ -186,12 +179,14 @@ on event-based network programming and multiprotocol integration.
|
||||
This metapackage is for the optional dependency all_non_platform
|
||||
|
||||
%prep
|
||||
%autosetup -p1 -n Twisted-%{version}
|
||||
%autosetup -p1 -n twisted-%{version}
|
||||
sed -i '1{/env python/d}' src/twisted/mail/test/pop3testserver.py src/twisted/trial/test/scripttest.py
|
||||
find src/twisted -name .gitignore -delete
|
||||
find src/twisted -name '*.misc' -size 0 -delete
|
||||
|
||||
%if ! %{with test}
|
||||
%build
|
||||
%python_build
|
||||
%pyproject_wheel
|
||||
|
||||
# empty files
|
||||
rm docs/{fun/Twisted.Quotes,_static/.placeholder,_templates/.placeholder}
|
||||
@ -200,13 +195,18 @@ rm docs/{fun/Twisted.Quotes,_static/.placeholder,_templates/.placeholder}
|
||||
|
||||
%if ! %{with test}
|
||||
%install
|
||||
%python_install
|
||||
%pyproject_install
|
||||
find %{buildroot} -regex '.*\.[ch]' -exec rm {} ";" # Remove leftover C sources
|
||||
install -dm0755 %{buildroot}%{_mandir}/man1/
|
||||
install -m0644 docs/*/man/*.1 %{buildroot}%{_mandir}/man1/ # Install man pages
|
||||
find docs -type f -print0 | xargs -0 chmod a-x # Fix doc-file dependency by removing x flags
|
||||
#sed -i "s/\r//" docs/core/howto/listings/udp/{MulticastClient,MulticastServer}.py
|
||||
%python_expand %fdupes %{buildroot}%{$python_sitelib}
|
||||
%if 0%{?suse_version} > 1500
|
||||
mkdir -p %{buildroot}%{_docdir}/%{name}-doc
|
||||
cp -r docs/* %{buildroot}%{_docdir}/%{name}-doc
|
||||
%fdupes %{buildroot}%{_docdir}/%{name}-doc
|
||||
%endif
|
||||
|
||||
# Prepare for update-alternatives usage
|
||||
for p in twistd cftp ckeygen conch pyhtmlizer tkconch trial ; do
|
||||
@ -294,12 +294,14 @@ done
|
||||
%python_alternative %{_mandir}/man1/pyhtmlizer.1%{?ext_man}
|
||||
%python_alternative %{_mandir}/man1/trial.1%{?ext_man}
|
||||
%{python_sitelib}/twisted
|
||||
%{python_sitelib}/Twisted-%{version}*-info
|
||||
%{python_sitelib}/twisted-%{version}*-info
|
||||
|
||||
%if 0%{?suse_version} > 1500
|
||||
%files -n %{name}-doc
|
||||
%endif
|
||||
%doc %{_docdir}/%{name}-doc
|
||||
%else
|
||||
%doc docs/
|
||||
%endif
|
||||
|
||||
%endif
|
||||
|
||||
|
@ -1,413 +0,0 @@
|
||||
From 001fd99f209dce1ee853df87fc4e0627db3bc930 Mon Sep 17 00:00:00 2001
|
||||
From: Glyph <code@glyph.im>
|
||||
Date: Wed, 14 Jun 2023 13:41:33 -0700
|
||||
Subject: [PATCH 1/4] regenerate certificate to work with latest
|
||||
service_identity
|
||||
|
||||
also rewrite all the logic using cryptography rather than pyopenssl
|
||||
---
|
||||
src/twisted/newsfragments/11877.misc | 0
|
||||
src/twisted/test/cert.pem.no_trailing_newline | 40 ++--
|
||||
src/twisted/test/key.pem.no_trailing_newline | 55 +++---
|
||||
src/twisted/test/server.pem | 178 ++++++++++--------
|
||||
4 files changed, 150 insertions(+), 123 deletions(-)
|
||||
create mode 100644 src/twisted/newsfragments/11877.misc
|
||||
|
||||
diff --git a/src/twisted/newsfragments/11877.misc b/src/twisted/newsfragments/11877.misc
|
||||
new file mode 100644
|
||||
index 00000000000..e69de29bb2d
|
||||
diff --git a/src/twisted/test/cert.pem.no_trailing_newline b/src/twisted/test/cert.pem.no_trailing_newline
|
||||
index 59f1bae563e..11eb4db8119 100644
|
||||
--- a/src/twisted/test/cert.pem.no_trailing_newline
|
||||
+++ b/src/twisted/test/cert.pem.no_trailing_newline
|
||||
@@ -1,23 +1,25 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
-MIID6DCCAtACAwtEVjANBgkqhkiG9w0BAQsFADCBtzELMAkGA1UEBhMCVFIxDzAN
|
||||
-BgNVBAgMBsOHb3J1bTEUMBIGA1UEBwwLQmHFn21ha8OnxLExEjAQBgNVBAMMCWxv
|
||||
-Y2FsaG9zdDEcMBoGA1UECgwTVHdpc3RlZCBNYXRyaXggTGFiczEkMCIGA1UECwwb
|
||||
-QXV0b21hdGVkIFRlc3RpbmcgQXV0aG9yaXR5MSkwJwYJKoZIhvcNAQkBFhpzZWN1
|
||||
-cml0eUB0d2lzdGVkbWF0cml4LmNvbTAgFw0yMjA4MjMyMzUyNTJaGA8yMTIyMDcz
|
||||
-MDIzNTI1MlowgbcxCzAJBgNVBAYTAlRSMQ8wDQYDVQQIDAbDh29ydW0xFDASBgNV
|
||||
-BAcMC0JhxZ9tYWvDp8SxMRIwEAYDVQQDDAlsb2NhbGhvc3QxHDAaBgNVBAoME1R3
|
||||
+MIIEJDCCAwygAwIBAgIUKaSXgzt5gDMt9GbUzLz/A9HEyFEwDQYJKoZIhvcNAQEL
|
||||
+BQAwgb0xGDAWBgNVBAMMD0EgSG9zdCwgTG9jYWxseTELMAkGA1UEBhMCVFIxDzAN
|
||||
+BgNVBAgMBsOHb3J1bTEUMBIGA1UEBwwLQmHFn21ha8OnxLExHDAaBgNVBAoME1R3
|
||||
aXN0ZWQgTWF0cml4IExhYnMxJDAiBgNVBAsMG0F1dG9tYXRlZCBUZXN0aW5nIEF1
|
||||
dGhvcml0eTEpMCcGCSqGSIb3DQEJARYac2VjdXJpdHlAdHdpc3RlZG1hdHJpeC5j
|
||||
-b20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC9Gk1skmQfONi+GdM2
|
||||
-Rwb6a/2weSX7eM3MwT3vXYr+0dx9ScWERILTNkLGrvfslHKdUE7hBDKjtuj6KtAI
|
||||
-rVjeDDMD6Ue77EcbL3QEO1QZeBjJ3hQbaB447PhE1wwgEsWndPMcDDVm93sODELN
|
||||
-rzWMLhabgCJ5cJYo5RQs7IvVtE36KaoSgfC9rTP8Lva+MW5wNeHn2f0hDlUF8jLu
|
||||
-o1W+eDb9CHV7vwL19DZ3w74UkQ3RnfNDnZzVhsNI4YGaSBGtOHY3ioDspGQZqHHf
|
||||
-CSTjjMwq3ddEkPd7iNu4N5KUamnH69A0JfRODC8tXjFG9/WFROhYZkUQRhXkgRd3
|
||||
-9Yy9AgMBAAEwDQYJKoZIhvcNAQELBQADggEBABuOxiDnfrjQjbP4ZWrDj+doK8Zk
|
||||
-CUwtyM3gFVF1LBZxBCxVa6hzD2N7/1o0+KHjmiGks7SnXb6aG2nEqypciZ4xkPjt
|
||||
-wVIcTWCW8ddPrfMi4/esiQFlPck1p3QSfkPiAgHAjJiDDqDtqsMKr+5AkUaHlqjR
|
||||
-VV3YE27x/QyLZbV7igiTPdh1fTV7+Yl8VHpBdnMRUVTFoZaIiCe0efmqsvzBd73A
|
||||
-c75aKTwu6cPQ9dH/gIEOHCvrgweED7ZcabT7h/k7DXL2zhnJTPmQSJLWjfQebJOu
|
||||
-4l1p7tn35xbjqu906l4iII+YqWCAj/gNT2qdcIWQmxg/reg2tRbU7Nv3M0c=
|
||||
+b20wIBcNMjMwNjE0MTM0MDI4WhgPMjEyMzA1MjExMzQwMjhaMIG9MRgwFgYDVQQD
|
||||
+DA9BIEhvc3QsIExvY2FsbHkxCzAJBgNVBAYTAlRSMQ8wDQYDVQQIDAbDh29ydW0x
|
||||
+FDASBgNVBAcMC0JhxZ9tYWvDp8SxMRwwGgYDVQQKDBNUd2lzdGVkIE1hdHJpeCBM
|
||||
+YWJzMSQwIgYDVQQLDBtBdXRvbWF0ZWQgVGVzdGluZyBBdXRob3JpdHkxKTAnBgkq
|
||||
+hkiG9w0BCQEWGnNlY3VyaXR5QHR3aXN0ZWRtYXRyaXguY29tMIIBIjANBgkqhkiG
|
||||
+9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0rT5+hF+1BjE7qXms9PZWHskXZGXLPiYVmiY
|
||||
+jsVeJAOtHAYq8igzA49KgR1xR9M4jQ6U46nwPsnGCh4liyxdWkBLw9maxMoE+r6d
|
||||
+W1zZ8Tllunbdb/Da6L8P55SKb7QGet4CB1fZ2SqZD4GvTby6xpoR09AqrfjuEIYR
|
||||
+8V/y+8dG3mR5W0HqaJ58IWihAwIQSakuc8jTadJY55t7UW6Ebj2X2WTO6Zh7gJ1d
|
||||
+yHPMVkUHJF9Jsuj/4F4lx6hWGQzWO8Nf8Q7t364pagE3evUv/BECJLONNYLaFjLt
|
||||
+WnsCEJDV9owCjaxu785KuA7OM/f3h3xVIfTBTo2AlHiQnXdyrwIDAQABoxgwFjAU
|
||||
+BgNVHREEDTALgglsb2NhbGhvc3QwDQYJKoZIhvcNAQELBQADggEBAEHAErq/Fs8h
|
||||
+M+kwGCt5Ochqyu/IzPbwgQ27n5IJehl7kmpoXBxGa/u+ajoxrZaOheg8E2MYVwQi
|
||||
+FTKE9wJgaN3uGo4bzCbCYxDm7tflQORo6QOZlumfiQIzXON2RvgJpwFfkLNtq0t9
|
||||
+e453kJ7+e11Wah46bc3RAvBZpwswh6hDv2FvFUZ+IUcO0tU8O4kWrLIFPpJbcHQq
|
||||
+wezjky773X4CNEtoeuTb8/ws/eED/TGZ2AZO+BWT93OZJgwE2x3iUd3k8HbwxfoY
|
||||
+bZ+NHgtM7iKRcL59asB0OMi3Ays0+IOfZ1+3aB82zYlxFBoDyalR7NJjJGdTwNFt
|
||||
+3CPGCQ28cDk=
|
||||
-----END CERTIFICATE-----
|
||||
\ No newline at end of file
|
||||
diff --git a/src/twisted/test/key.pem.no_trailing_newline b/src/twisted/test/key.pem.no_trailing_newline
|
||||
index 63845f8249f..5d489fd73ac 100644
|
||||
--- a/src/twisted/test/key.pem.no_trailing_newline
|
||||
+++ b/src/twisted/test/key.pem.no_trailing_newline
|
||||
@@ -1,28 +1,27 @@
|
||||
------BEGIN PRIVATE KEY-----
|
||||
-MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC9Gk1skmQfONi+
|
||||
-GdM2Rwb6a/2weSX7eM3MwT3vXYr+0dx9ScWERILTNkLGrvfslHKdUE7hBDKjtuj6
|
||||
-KtAIrVjeDDMD6Ue77EcbL3QEO1QZeBjJ3hQbaB447PhE1wwgEsWndPMcDDVm93sO
|
||||
-DELNrzWMLhabgCJ5cJYo5RQs7IvVtE36KaoSgfC9rTP8Lva+MW5wNeHn2f0hDlUF
|
||||
-8jLuo1W+eDb9CHV7vwL19DZ3w74UkQ3RnfNDnZzVhsNI4YGaSBGtOHY3ioDspGQZ
|
||||
-qHHfCSTjjMwq3ddEkPd7iNu4N5KUamnH69A0JfRODC8tXjFG9/WFROhYZkUQRhXk
|
||||
-gRd39Yy9AgMBAAECggEAIvGt1f7VRpm8H6DpEVIdvX/gMNCqTqZ7rTcWaVmpWj5Q
|
||||
-lsxflfoNDNetjkZ95PdnmJ9i/BzI+MzPj48Cw1+5GMs7UCE3EshuOV1S/Ic0GsLB
|
||||
-HeiOYaQjVZSgqiPtBy5A3Rl05T1yTtUzpZxpadXTONS5c8HBXRyLewId8NFDY9ls
|
||||
-76PYRq4ui7QGOmXw7VAVzg/7RxcupuSkecE7472Ek1jtEdRdplBga/XE5/+FZhrr
|
||||
-NyAdVo/1VD8zpaenWiBgfqJTVc/VRBaE0kLa777E++ruqGGz/c5cQPOWzEp0vPbi
|
||||
-kXz16X2TQDeTe6QfBBYjzD2+LyJh2TXfRtEn56MtJwKBgQDaTzHFOoiPS0+JpOBH
|
||||
-yW2gIFigEH70Hi++m0okmewGLTGrjOsIVWx8u5QFMANEYXeXIT7sM1eyONYjtxNC
|
||||
-gpeLyyN9zTyLPWdx3CzNodY2Dg/irTZtPQp7/efAHcn7kW8V0OxCGTyXAzdhKXmN
|
||||
-thN9KMk6peQMU8L4FqypNznFrwKBgQDdwD0NBxqNk3/Q/qih2EJUOO7uuPAZnTJf
|
||||
-neRnY4Pc94ticdQbd03ZArP3ybl9wWy+Ri9D+I9P753Hyfb7BSKwwIyYRgxSjGU/
|
||||
-wqcmv0V/mSY7N4eCDaXqEjdovaZ76d3L60FPH5rJbn7yHZBYWaSqXgk0HDYUmQwg
|
||||
-huPLNu8bUwKBgQCH/rGohbAwY9/mhRlaXva1u7C59czAUlW3zZFAf8pyhpDcp2p6
|
||||
-xIxSn5+0I5bFcFpJgWJrTgihc5qioReUZTn20dMIOWQv8U6RtXELoHeLMPNgaDrx
|
||||
-jgcL+r32BhifaJfk5UNoYcRG5rAHDQk16Gj3nQLOUC1iKIPafHWO7GJG7QKBgQCj
|
||||
-yVfOhY6xP17K6S14zRjAyISCQorlAFyyjxai3rgIv7Zt8hFucAJJ5Vs0DAU7w2Ak
|
||||
-cgZ7N93ydtOdO6l24uYqky3FUwfK+PPX0lhPoDse8elxF6S5BIeliervLBUJtUUj
|
||||
-VxIX9QoI+do9zmRNPXkIdQhrOuMe96Qjaj5aXKrjDQKBgBS2LGghCFgqaxtHeIpl
|
||||
-RLOnpxLaiitGH412O6VKHkkXaNYEOlbtFVlPuE1zHeyIvLQb666lW/w0+HMmfMTU
|
||||
-SQI2gIndUb6pMzLjZUrCyYz618EoAmhx6+VnbRSY+iSEIdYqx6VBl0HY9RWJa18H
|
||||
-4LPzH6dfRnKf2jCer3DtWALD
|
||||
------END PRIVATE KEY-----
|
||||
\ No newline at end of file
|
||||
+-----BEGIN RSA PRIVATE KEY-----
|
||||
+MIIEogIBAAKCAQEA0rT5+hF+1BjE7qXms9PZWHskXZGXLPiYVmiYjsVeJAOtHAYq
|
||||
+8igzA49KgR1xR9M4jQ6U46nwPsnGCh4liyxdWkBLw9maxMoE+r6dW1zZ8Tllunbd
|
||||
+b/Da6L8P55SKb7QGet4CB1fZ2SqZD4GvTby6xpoR09AqrfjuEIYR8V/y+8dG3mR5
|
||||
+W0HqaJ58IWihAwIQSakuc8jTadJY55t7UW6Ebj2X2WTO6Zh7gJ1dyHPMVkUHJF9J
|
||||
+suj/4F4lx6hWGQzWO8Nf8Q7t364pagE3evUv/BECJLONNYLaFjLtWnsCEJDV9owC
|
||||
+jaxu785KuA7OM/f3h3xVIfTBTo2AlHiQnXdyrwIDAQABAoH/Ib7aSjKDHXTaFV58
|
||||
+lFBZftI6AMJQc+Ncgno99J+ndB0inFpghmfpw6gvRn5wphAt/mlXbx7IW0X1cali
|
||||
+WefBC7NAbx1qrBmusnnUuc0lGn0WzcY7sLHiXWQ8J9qiUUGDyCnGKWbofN9VpCYg
|
||||
+7VJMl4IVWNb9/t7fQcY3GXFEeQ4mzLo7p+gPxyeUcCLVrhVrHzw1HFTIlA51LjfI
|
||||
+xQM+QVeaEWQQ4UsDdPe5iGthDd7ze2F5ciDzMkShrf7URSudS+Us6vr6gDVpKAky
|
||||
+eCVyFPJXCfH4qJoa6mB6L6SFzMnN3OPp3RlYQWQ7sK/ELQfhPoyHyRvL1woUIO5C
|
||||
+tK0pAoGBAPS6ZSZ26M0guZ2K/2fKMiGq0jZQLcxP3N0jWm8R8ENOnuIjhCl5aKsB
|
||||
+DoV0BvPv1C2vWm+VgNArgTece9l8o5f8pcfjbT5r/k8zoqgcj9CmmDofBka4XxZb
|
||||
+wxsut+8rBSIoVKIre4Pyqfa9u1IrEnoOzMqvF16xUME2t2EaryUzAoGBANxpb4Jz
|
||||
+FjH7nfPc3iejd+cXovX6x2VTJzWaknA6hGsoc+UZ01KTaKyYpq+9q9VxXhWxYsh3
|
||||
+TL1JWuIBy6ao5tdt4nPBu07J7tfu5bfr3Imd8waNQxDEfKeFedskxORs+FIUzqBb
|
||||
+3nIkQH8sx0Syv620coIdtEn1raVXc9QfRgSVAoGAWNFhLoGPYgsTcnrk0N1QLmnZ
|
||||
+mv6kcHc3mEZhZtgi07qv7TCooYi/lPhwNbzzXQrYfbAbaU3gDy0K24z+YeNbWCjI
|
||||
+XfBLUJFPHZ2G1e5vv3EG5GkoFPiLAglRmQbumG2LkmcCuEyBqlSinLslRd/997Bx
|
||||
+YMoE+EfwH/9ktGhD0oMCgYEAxaSqAFDQ00ssjTM95k94Qjn4wBf7WwmgfDm6HHbs
|
||||
+rOZeXk61JzPVxgcwWSB8iG4bDtq8mMQZhRbVLxqrEiwcq4r2aBSNsI305Z5sUWtn
|
||||
+m+ONvA9J1yxKFzHiXjbvc2GfnoLX8gXPR4zoZOGzYg/jP5EyqSiXtUZfSodL7yeH
|
||||
+8q0CgYEA2OzA59AITJe8jhC5JsVbLs7Rj4kFTjD+iZ8P86FnWBf1iDeuywEZJqvG
|
||||
+n6SNK4KczDJ//DBV06w4L6iwe5iOCdf06+V7Hnkbvrjk0ONnXX7VXNgJ3/e7aJTx
|
||||
+gE42Ug0qu6lXtEfYqlhQoF2lAtnYq0fty/XWMVfpjVuh1lyd4C4=
|
||||
+-----END RSA PRIVATE KEY-----
|
||||
\ No newline at end of file
|
||||
diff --git a/src/twisted/test/server.pem b/src/twisted/test/server.pem
|
||||
index 0c633e6e9e3..6d2be8be95b 100644
|
||||
--- a/src/twisted/test/server.pem
|
||||
+++ b/src/twisted/test/server.pem
|
||||
@@ -1,97 +1,123 @@
|
||||
# coding: utf-8
|
||||
|
||||
-from inspect import getsource
|
||||
-from datetime import datetime
|
||||
|
||||
-from OpenSSL.crypto import FILETYPE_PEM, TYPE_RSA, X509, PKey, dump_privatekey, dump_certificate
|
||||
+from datetime import datetime, timedelta
|
||||
+from inspect import getsource
|
||||
|
||||
-key = PKey()
|
||||
-key.generate_key(TYPE_RSA, 2048)
|
||||
+from cryptography.hazmat.primitives.asymmetric.rsa import generate_private_key
|
||||
+from cryptography.hazmat.primitives.hashes import SHA256
|
||||
+from cryptography.hazmat.primitives.serialization import (
|
||||
+ Encoding,
|
||||
+ NoEncryption,
|
||||
+ PrivateFormat,
|
||||
+)
|
||||
+from cryptography.x509 import (
|
||||
+ CertificateBuilder,
|
||||
+ Name,
|
||||
+ NameAttribute,
|
||||
+ NameOID,
|
||||
+ SubjectAlternativeName,
|
||||
+ DNSName,
|
||||
+ random_serial_number,
|
||||
+)
|
||||
|
||||
-cert = X509()
|
||||
-issuer = cert.get_issuer()
|
||||
-subject = cert.get_subject()
|
||||
+pk = generate_private_key(key_size=2048, public_exponent=65537)
|
||||
|
||||
-for dn in [issuer, subject]:
|
||||
- dn.C = b"TR"
|
||||
- dn.ST = "Çorum".encode("utf-8")
|
||||
- dn.L = "Başmakçı".encode("utf-8")
|
||||
- dn.CN = b"localhost"
|
||||
- dn.O = b"Twisted Matrix Labs"
|
||||
- dn.OU = b"Automated Testing Authority"
|
||||
- dn.emailAddress = b"security@twistedmatrix.com"
|
||||
+me = Name(
|
||||
+ [
|
||||
+ NameAttribute(NameOID.COMMON_NAME, "A Host, Locally"),
|
||||
+ NameAttribute(NameOID.COUNTRY_NAME, "TR"),
|
||||
+ NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, "Çorum"),
|
||||
+ NameAttribute(NameOID.LOCALITY_NAME, "Başmakçı"),
|
||||
+ NameAttribute(NameOID.ORGANIZATION_NAME, "Twisted Matrix Labs"),
|
||||
+ NameAttribute(NameOID.ORGANIZATIONAL_UNIT_NAME, "Automated Testing Authority"),
|
||||
+ NameAttribute(NameOID.EMAIL_ADDRESS, "security@twistedmatrix.com"),
|
||||
+ ]
|
||||
+)
|
||||
|
||||
-cert.set_serial_number(datetime.now().toordinal())
|
||||
-cert.gmtime_adj_notBefore(0)
|
||||
-cert.gmtime_adj_notAfter(60 * 60 * 24 * 365 * 100)
|
||||
+certificate_bytes = (
|
||||
+ CertificateBuilder()
|
||||
+ .serial_number(random_serial_number())
|
||||
+ .not_valid_before(datetime.now())
|
||||
+ .not_valid_after(datetime.now() + timedelta(seconds=60 * 60 * 24 * 365 * 100))
|
||||
+ .subject_name(me)
|
||||
+ .add_extension(SubjectAlternativeName([DNSName("localhost")]), False)
|
||||
+ .issuer_name(me)
|
||||
+ .public_key(pk.public_key())
|
||||
+ .sign(pk, algorithm=SHA256())
|
||||
+).public_bytes(Encoding.PEM)
|
||||
|
||||
-cert.set_pubkey(key)
|
||||
-cert.sign(key, "sha256")
|
||||
+privkey_bytes = pk.private_bytes(
|
||||
+ Encoding.PEM, PrivateFormat.TraditionalOpenSSL, NoEncryption()
|
||||
+)
|
||||
|
||||
import __main__
|
||||
+
|
||||
source = getsource(__main__)
|
||||
source = source.split("\n" + "-" * 5)[0].rsplit("\n", 1)[0]
|
||||
with open("server.pem", "w") as fObj:
|
||||
fObj.write(source)
|
||||
fObj.write("\n")
|
||||
- fObj.write("'''\n")
|
||||
- fObj.write(dump_privatekey(FILETYPE_PEM, key).decode("ascii"))
|
||||
- fObj.write(dump_certificate(FILETYPE_PEM, cert).decode("ascii"))
|
||||
- fObj.write("'''\n")
|
||||
+ fObj.write('"""\n')
|
||||
+ fObj.write(privkey_bytes.decode("ascii"))
|
||||
+ fObj.write(certificate_bytes.decode("ascii"))
|
||||
+ fObj.write('"""\n')
|
||||
with open(b"key.pem.no_trailing_newline", "w") as fObj:
|
||||
- fObj.write(dump_privatekey(FILETYPE_PEM, key).decode("ascii").rstrip('\n'))
|
||||
+ fObj.write(privkey_bytes.decode("ascii").rstrip("\n"))
|
||||
with open(b"cert.pem.no_trailing_newline", "w") as fObj:
|
||||
- fObj.write(dump_certificate(FILETYPE_PEM, cert).decode("ascii").rstrip('\n'))
|
||||
-'''
|
||||
------BEGIN PRIVATE KEY-----
|
||||
-MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC9Gk1skmQfONi+
|
||||
-GdM2Rwb6a/2weSX7eM3MwT3vXYr+0dx9ScWERILTNkLGrvfslHKdUE7hBDKjtuj6
|
||||
-KtAIrVjeDDMD6Ue77EcbL3QEO1QZeBjJ3hQbaB447PhE1wwgEsWndPMcDDVm93sO
|
||||
-DELNrzWMLhabgCJ5cJYo5RQs7IvVtE36KaoSgfC9rTP8Lva+MW5wNeHn2f0hDlUF
|
||||
-8jLuo1W+eDb9CHV7vwL19DZ3w74UkQ3RnfNDnZzVhsNI4YGaSBGtOHY3ioDspGQZ
|
||||
-qHHfCSTjjMwq3ddEkPd7iNu4N5KUamnH69A0JfRODC8tXjFG9/WFROhYZkUQRhXk
|
||||
-gRd39Yy9AgMBAAECggEAIvGt1f7VRpm8H6DpEVIdvX/gMNCqTqZ7rTcWaVmpWj5Q
|
||||
-lsxflfoNDNetjkZ95PdnmJ9i/BzI+MzPj48Cw1+5GMs7UCE3EshuOV1S/Ic0GsLB
|
||||
-HeiOYaQjVZSgqiPtBy5A3Rl05T1yTtUzpZxpadXTONS5c8HBXRyLewId8NFDY9ls
|
||||
-76PYRq4ui7QGOmXw7VAVzg/7RxcupuSkecE7472Ek1jtEdRdplBga/XE5/+FZhrr
|
||||
-NyAdVo/1VD8zpaenWiBgfqJTVc/VRBaE0kLa777E++ruqGGz/c5cQPOWzEp0vPbi
|
||||
-kXz16X2TQDeTe6QfBBYjzD2+LyJh2TXfRtEn56MtJwKBgQDaTzHFOoiPS0+JpOBH
|
||||
-yW2gIFigEH70Hi++m0okmewGLTGrjOsIVWx8u5QFMANEYXeXIT7sM1eyONYjtxNC
|
||||
-gpeLyyN9zTyLPWdx3CzNodY2Dg/irTZtPQp7/efAHcn7kW8V0OxCGTyXAzdhKXmN
|
||||
-thN9KMk6peQMU8L4FqypNznFrwKBgQDdwD0NBxqNk3/Q/qih2EJUOO7uuPAZnTJf
|
||||
-neRnY4Pc94ticdQbd03ZArP3ybl9wWy+Ri9D+I9P753Hyfb7BSKwwIyYRgxSjGU/
|
||||
-wqcmv0V/mSY7N4eCDaXqEjdovaZ76d3L60FPH5rJbn7yHZBYWaSqXgk0HDYUmQwg
|
||||
-huPLNu8bUwKBgQCH/rGohbAwY9/mhRlaXva1u7C59czAUlW3zZFAf8pyhpDcp2p6
|
||||
-xIxSn5+0I5bFcFpJgWJrTgihc5qioReUZTn20dMIOWQv8U6RtXELoHeLMPNgaDrx
|
||||
-jgcL+r32BhifaJfk5UNoYcRG5rAHDQk16Gj3nQLOUC1iKIPafHWO7GJG7QKBgQCj
|
||||
-yVfOhY6xP17K6S14zRjAyISCQorlAFyyjxai3rgIv7Zt8hFucAJJ5Vs0DAU7w2Ak
|
||||
-cgZ7N93ydtOdO6l24uYqky3FUwfK+PPX0lhPoDse8elxF6S5BIeliervLBUJtUUj
|
||||
-VxIX9QoI+do9zmRNPXkIdQhrOuMe96Qjaj5aXKrjDQKBgBS2LGghCFgqaxtHeIpl
|
||||
-RLOnpxLaiitGH412O6VKHkkXaNYEOlbtFVlPuE1zHeyIvLQb666lW/w0+HMmfMTU
|
||||
-SQI2gIndUb6pMzLjZUrCyYz618EoAmhx6+VnbRSY+iSEIdYqx6VBl0HY9RWJa18H
|
||||
-4LPzH6dfRnKf2jCer3DtWALD
|
||||
------END PRIVATE KEY-----
|
||||
+ fObj.write(certificate_bytes.decode("ascii").rstrip("\n"))
|
||||
+
|
||||
+"""
|
||||
+-----BEGIN RSA PRIVATE KEY-----
|
||||
+MIIEogIBAAKCAQEA0rT5+hF+1BjE7qXms9PZWHskXZGXLPiYVmiYjsVeJAOtHAYq
|
||||
+8igzA49KgR1xR9M4jQ6U46nwPsnGCh4liyxdWkBLw9maxMoE+r6dW1zZ8Tllunbd
|
||||
+b/Da6L8P55SKb7QGet4CB1fZ2SqZD4GvTby6xpoR09AqrfjuEIYR8V/y+8dG3mR5
|
||||
+W0HqaJ58IWihAwIQSakuc8jTadJY55t7UW6Ebj2X2WTO6Zh7gJ1dyHPMVkUHJF9J
|
||||
+suj/4F4lx6hWGQzWO8Nf8Q7t364pagE3evUv/BECJLONNYLaFjLtWnsCEJDV9owC
|
||||
+jaxu785KuA7OM/f3h3xVIfTBTo2AlHiQnXdyrwIDAQABAoH/Ib7aSjKDHXTaFV58
|
||||
+lFBZftI6AMJQc+Ncgno99J+ndB0inFpghmfpw6gvRn5wphAt/mlXbx7IW0X1cali
|
||||
+WefBC7NAbx1qrBmusnnUuc0lGn0WzcY7sLHiXWQ8J9qiUUGDyCnGKWbofN9VpCYg
|
||||
+7VJMl4IVWNb9/t7fQcY3GXFEeQ4mzLo7p+gPxyeUcCLVrhVrHzw1HFTIlA51LjfI
|
||||
+xQM+QVeaEWQQ4UsDdPe5iGthDd7ze2F5ciDzMkShrf7URSudS+Us6vr6gDVpKAky
|
||||
+eCVyFPJXCfH4qJoa6mB6L6SFzMnN3OPp3RlYQWQ7sK/ELQfhPoyHyRvL1woUIO5C
|
||||
+tK0pAoGBAPS6ZSZ26M0guZ2K/2fKMiGq0jZQLcxP3N0jWm8R8ENOnuIjhCl5aKsB
|
||||
+DoV0BvPv1C2vWm+VgNArgTece9l8o5f8pcfjbT5r/k8zoqgcj9CmmDofBka4XxZb
|
||||
+wxsut+8rBSIoVKIre4Pyqfa9u1IrEnoOzMqvF16xUME2t2EaryUzAoGBANxpb4Jz
|
||||
+FjH7nfPc3iejd+cXovX6x2VTJzWaknA6hGsoc+UZ01KTaKyYpq+9q9VxXhWxYsh3
|
||||
+TL1JWuIBy6ao5tdt4nPBu07J7tfu5bfr3Imd8waNQxDEfKeFedskxORs+FIUzqBb
|
||||
+3nIkQH8sx0Syv620coIdtEn1raVXc9QfRgSVAoGAWNFhLoGPYgsTcnrk0N1QLmnZ
|
||||
+mv6kcHc3mEZhZtgi07qv7TCooYi/lPhwNbzzXQrYfbAbaU3gDy0K24z+YeNbWCjI
|
||||
+XfBLUJFPHZ2G1e5vv3EG5GkoFPiLAglRmQbumG2LkmcCuEyBqlSinLslRd/997Bx
|
||||
+YMoE+EfwH/9ktGhD0oMCgYEAxaSqAFDQ00ssjTM95k94Qjn4wBf7WwmgfDm6HHbs
|
||||
+rOZeXk61JzPVxgcwWSB8iG4bDtq8mMQZhRbVLxqrEiwcq4r2aBSNsI305Z5sUWtn
|
||||
+m+ONvA9J1yxKFzHiXjbvc2GfnoLX8gXPR4zoZOGzYg/jP5EyqSiXtUZfSodL7yeH
|
||||
+8q0CgYEA2OzA59AITJe8jhC5JsVbLs7Rj4kFTjD+iZ8P86FnWBf1iDeuywEZJqvG
|
||||
+n6SNK4KczDJ//DBV06w4L6iwe5iOCdf06+V7Hnkbvrjk0ONnXX7VXNgJ3/e7aJTx
|
||||
+gE42Ug0qu6lXtEfYqlhQoF2lAtnYq0fty/XWMVfpjVuh1lyd4C4=
|
||||
+-----END RSA PRIVATE KEY-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
-MIID6DCCAtACAwtEVjANBgkqhkiG9w0BAQsFADCBtzELMAkGA1UEBhMCVFIxDzAN
|
||||
-BgNVBAgMBsOHb3J1bTEUMBIGA1UEBwwLQmHFn21ha8OnxLExEjAQBgNVBAMMCWxv
|
||||
-Y2FsaG9zdDEcMBoGA1UECgwTVHdpc3RlZCBNYXRyaXggTGFiczEkMCIGA1UECwwb
|
||||
-QXV0b21hdGVkIFRlc3RpbmcgQXV0aG9yaXR5MSkwJwYJKoZIhvcNAQkBFhpzZWN1
|
||||
-cml0eUB0d2lzdGVkbWF0cml4LmNvbTAgFw0yMjA4MjMyMzUyNTJaGA8yMTIyMDcz
|
||||
-MDIzNTI1MlowgbcxCzAJBgNVBAYTAlRSMQ8wDQYDVQQIDAbDh29ydW0xFDASBgNV
|
||||
-BAcMC0JhxZ9tYWvDp8SxMRIwEAYDVQQDDAlsb2NhbGhvc3QxHDAaBgNVBAoME1R3
|
||||
+MIIEJDCCAwygAwIBAgIUKaSXgzt5gDMt9GbUzLz/A9HEyFEwDQYJKoZIhvcNAQEL
|
||||
+BQAwgb0xGDAWBgNVBAMMD0EgSG9zdCwgTG9jYWxseTELMAkGA1UEBhMCVFIxDzAN
|
||||
+BgNVBAgMBsOHb3J1bTEUMBIGA1UEBwwLQmHFn21ha8OnxLExHDAaBgNVBAoME1R3
|
||||
aXN0ZWQgTWF0cml4IExhYnMxJDAiBgNVBAsMG0F1dG9tYXRlZCBUZXN0aW5nIEF1
|
||||
dGhvcml0eTEpMCcGCSqGSIb3DQEJARYac2VjdXJpdHlAdHdpc3RlZG1hdHJpeC5j
|
||||
-b20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC9Gk1skmQfONi+GdM2
|
||||
-Rwb6a/2weSX7eM3MwT3vXYr+0dx9ScWERILTNkLGrvfslHKdUE7hBDKjtuj6KtAI
|
||||
-rVjeDDMD6Ue77EcbL3QEO1QZeBjJ3hQbaB447PhE1wwgEsWndPMcDDVm93sODELN
|
||||
-rzWMLhabgCJ5cJYo5RQs7IvVtE36KaoSgfC9rTP8Lva+MW5wNeHn2f0hDlUF8jLu
|
||||
-o1W+eDb9CHV7vwL19DZ3w74UkQ3RnfNDnZzVhsNI4YGaSBGtOHY3ioDspGQZqHHf
|
||||
-CSTjjMwq3ddEkPd7iNu4N5KUamnH69A0JfRODC8tXjFG9/WFROhYZkUQRhXkgRd3
|
||||
-9Yy9AgMBAAEwDQYJKoZIhvcNAQELBQADggEBABuOxiDnfrjQjbP4ZWrDj+doK8Zk
|
||||
-CUwtyM3gFVF1LBZxBCxVa6hzD2N7/1o0+KHjmiGks7SnXb6aG2nEqypciZ4xkPjt
|
||||
-wVIcTWCW8ddPrfMi4/esiQFlPck1p3QSfkPiAgHAjJiDDqDtqsMKr+5AkUaHlqjR
|
||||
-VV3YE27x/QyLZbV7igiTPdh1fTV7+Yl8VHpBdnMRUVTFoZaIiCe0efmqsvzBd73A
|
||||
-c75aKTwu6cPQ9dH/gIEOHCvrgweED7ZcabT7h/k7DXL2zhnJTPmQSJLWjfQebJOu
|
||||
-4l1p7tn35xbjqu906l4iII+YqWCAj/gNT2qdcIWQmxg/reg2tRbU7Nv3M0c=
|
||||
+b20wIBcNMjMwNjE0MTM0MDI4WhgPMjEyMzA1MjExMzQwMjhaMIG9MRgwFgYDVQQD
|
||||
+DA9BIEhvc3QsIExvY2FsbHkxCzAJBgNVBAYTAlRSMQ8wDQYDVQQIDAbDh29ydW0x
|
||||
+FDASBgNVBAcMC0JhxZ9tYWvDp8SxMRwwGgYDVQQKDBNUd2lzdGVkIE1hdHJpeCBM
|
||||
+YWJzMSQwIgYDVQQLDBtBdXRvbWF0ZWQgVGVzdGluZyBBdXRob3JpdHkxKTAnBgkq
|
||||
+hkiG9w0BCQEWGnNlY3VyaXR5QHR3aXN0ZWRtYXRyaXguY29tMIIBIjANBgkqhkiG
|
||||
+9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0rT5+hF+1BjE7qXms9PZWHskXZGXLPiYVmiY
|
||||
+jsVeJAOtHAYq8igzA49KgR1xR9M4jQ6U46nwPsnGCh4liyxdWkBLw9maxMoE+r6d
|
||||
+W1zZ8Tllunbdb/Da6L8P55SKb7QGet4CB1fZ2SqZD4GvTby6xpoR09AqrfjuEIYR
|
||||
+8V/y+8dG3mR5W0HqaJ58IWihAwIQSakuc8jTadJY55t7UW6Ebj2X2WTO6Zh7gJ1d
|
||||
+yHPMVkUHJF9Jsuj/4F4lx6hWGQzWO8Nf8Q7t364pagE3evUv/BECJLONNYLaFjLt
|
||||
+WnsCEJDV9owCjaxu785KuA7OM/f3h3xVIfTBTo2AlHiQnXdyrwIDAQABoxgwFjAU
|
||||
+BgNVHREEDTALgglsb2NhbGhvc3QwDQYJKoZIhvcNAQELBQADggEBAEHAErq/Fs8h
|
||||
+M+kwGCt5Ochqyu/IzPbwgQ27n5IJehl7kmpoXBxGa/u+ajoxrZaOheg8E2MYVwQi
|
||||
+FTKE9wJgaN3uGo4bzCbCYxDm7tflQORo6QOZlumfiQIzXON2RvgJpwFfkLNtq0t9
|
||||
+e453kJ7+e11Wah46bc3RAvBZpwswh6hDv2FvFUZ+IUcO0tU8O4kWrLIFPpJbcHQq
|
||||
+wezjky773X4CNEtoeuTb8/ws/eED/TGZ2AZO+BWT93OZJgwE2x3iUd3k8HbwxfoY
|
||||
+bZ+NHgtM7iKRcL59asB0OMi3Ays0+IOfZ1+3aB82zYlxFBoDyalR7NJjJGdTwNFt
|
||||
+3CPGCQ28cDk=
|
||||
-----END CERTIFICATE-----
|
||||
-'''
|
||||
+"""
|
||||
|
||||
From 1f0c2a3a774d89fb10782a8abf62e219d1f4818f Mon Sep 17 00:00:00 2001
|
||||
From: Glyph <code@glyph.im>
|
||||
Date: Wed, 14 Jun 2023 14:06:56 -0700
|
||||
Subject: [PATCH 2/4] todo server.pem should generate this too
|
||||
|
||||
---
|
||||
src/twisted/protocols/test/test_tls.py | 7 ++++---
|
||||
1 file changed, 4 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/src/twisted/protocols/test/test_tls.py b/src/twisted/protocols/test/test_tls.py
|
||||
index 5915d6bc5b2..37de80feb9f 100644
|
||||
--- a/src/twisted/protocols/test/test_tls.py
|
||||
+++ b/src/twisted/protocols/test/test_tls.py
|
||||
@@ -522,9 +522,10 @@ def cbHandshook(ignored):
|
||||
self.assertIsInstance(cert, crypto.X509)
|
||||
self.assertEqual(
|
||||
cert.digest("sha256"),
|
||||
- # openssl x509 -noout -sha256 -fingerprint -in server.pem
|
||||
- b"C4:F5:8E:9D:A0:AC:85:24:9B:2D:AA:2C:EC:87:DB:5F:33:22:94:"
|
||||
- b"01:94:DC:D3:42:4C:E4:B9:F5:0F:45:F2:24",
|
||||
+ # openssl x509 -noout -sha256 -fingerprint
|
||||
+ # -in src/twisted/test/server.pem
|
||||
+ b"D6:F2:2C:74:3B:E2:5E:F9:CA:DA:47:08:14:78:20:75:78:95:9E:52"
|
||||
+ b":BD:D2:7C:77:DD:D4:EE:DE:33:BF:34:40",
|
||||
)
|
||||
|
||||
handshakeDeferred.addCallback(cbHandshook)
|
||||
|
||||
From 137a3a6fa27374ecb879c67557197a3f0b37aab1 Mon Sep 17 00:00:00 2001
|
||||
From: Glyph <code@glyph.im>
|
||||
Date: Wed, 14 Jun 2023 14:08:13 -0700
|
||||
Subject: [PATCH 3/4] address review
|
||||
|
||||
---
|
||||
src/twisted/test/server.pem | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/twisted/test/server.pem b/src/twisted/test/server.pem
|
||||
index 6d2be8be95b..33fdbbd1cac 100644
|
||||
--- a/src/twisted/test/server.pem
|
||||
+++ b/src/twisted/test/server.pem
|
||||
@@ -41,7 +41,7 @@ certificate_bytes = (
|
||||
.not_valid_before(datetime.now())
|
||||
.not_valid_after(datetime.now() + timedelta(seconds=60 * 60 * 24 * 365 * 100))
|
||||
.subject_name(me)
|
||||
- .add_extension(SubjectAlternativeName([DNSName("localhost")]), False)
|
||||
+ .add_extension(SubjectAlternativeName([DNSName("localhost")]), critical=False)
|
||||
.issuer_name(me)
|
||||
.public_key(pk.public_key())
|
||||
.sign(pk, algorithm=SHA256())
|
||||
|
||||
From c8dce7b42b13466afd24ea5f9bbfc9a1c08c585f Mon Sep 17 00:00:00 2001
|
||||
From: Glyph <code@glyph.im>
|
||||
Date: Wed, 14 Jun 2023 14:17:12 -0700
|
||||
Subject: [PATCH 4/4] hooray, type stubs are updated too
|
||||
|
||||
---
|
||||
src/twisted/internet/_sslverify.py | 7 ++-----
|
||||
1 file changed, 2 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/src/twisted/internet/_sslverify.py b/src/twisted/internet/_sslverify.py
|
||||
index 6824482dc5b..d8f62e40954 100644
|
||||
--- a/src/twisted/internet/_sslverify.py
|
||||
+++ b/src/twisted/internet/_sslverify.py
|
||||
@@ -159,11 +159,8 @@ def _selectVerifyImplementation():
|
||||
)
|
||||
|
||||
try:
|
||||
- from service_identity import VerificationError # type: ignore[import]
|
||||
- from service_identity.pyopenssl import ( # type: ignore[import]
|
||||
- verify_hostname,
|
||||
- verify_ip_address,
|
||||
- )
|
||||
+ from service_identity import VerificationError
|
||||
+ from service_identity.pyopenssl import verify_hostname, verify_ip_address
|
||||
|
||||
return verify_hostname, verify_ip_address, VerificationError
|
||||
except ImportError as e:
|
@ -1,18 +1,15 @@
|
||||
Index: Twisted-22.10.0/setup.cfg
|
||||
Index: twisted-23.10.0/pyproject.toml
|
||||
===================================================================
|
||||
--- Twisted-22.10.0.orig/setup.cfg
|
||||
+++ Twisted-22.10.0/setup.cfg
|
||||
@@ -72,10 +72,10 @@ serial =
|
||||
pyserial >= 3.0
|
||||
pywin32 != 226; platform_system == "Windows"
|
||||
http2 =
|
||||
- h2 >= 3.0, < 5.0
|
||||
- priority >= 1.1.0, < 2.0
|
||||
+ h2 >= 3.0
|
||||
+ priority >= 1.1.0
|
||||
contextvars =
|
||||
- contextvars >= 2.4, < 3; python_version < "3.7"
|
||||
+ contextvars >= 2.4; python_version < "3.7"
|
||||
all_non_platform =
|
||||
%(test)s
|
||||
%(tls)s
|
||||
--- twisted-23.10.0.orig/pyproject.toml
|
||||
+++ twisted-23.10.0/pyproject.toml
|
||||
@@ -95,8 +95,8 @@ serial = [
|
||||
]
|
||||
|
||||
http2 = [
|
||||
- "h2 >= 3.0, < 5.0",
|
||||
- "priority >= 1.1.0, < 2.0",
|
||||
+ "h2 >= 3.0",
|
||||
+ "priority >= 1.1.0",
|
||||
]
|
||||
|
||||
all-non-platform = [
|
||||
|
@ -1,360 +0,0 @@
|
||||
From 1716d312600a9c49279e6c15da9ad8ca21431580 Mon Sep 17 00:00:00 2001
|
||||
From: Glyph <code@glyph.im>
|
||||
Date: Thu, 8 Jun 2023 18:13:11 -0700
|
||||
Subject: [PATCH 1/2] remove PyNaCl optional dependency
|
||||
|
||||
---
|
||||
docs/installation/howto/optional.rst | 3 -
|
||||
pyproject.toml | 6 -
|
||||
src/twisted/conch/newsfragments/11871.removal | 1 +
|
||||
src/twisted/conch/ssh/_keys_pynacl.py | 104 ------------
|
||||
src/twisted/conch/ssh/keys.py | 9 +-
|
||||
src/twisted/conch/test/test_keys.py | 157 +-----------------
|
||||
tox.ini | 4 +-
|
||||
7 files changed, 6 insertions(+), 278 deletions(-)
|
||||
create mode 100644 src/twisted/conch/newsfragments/11871.removal
|
||||
delete mode 100644 src/twisted/conch/ssh/_keys_pynacl.py
|
||||
|
||||
Index: Twisted-22.10.0/docs/installation/howto/optional.rst
|
||||
===================================================================
|
||||
--- Twisted-22.10.0.orig/docs/installation/howto/optional.rst
|
||||
+++ Twisted-22.10.0/docs/installation/howto/optional.rst
|
||||
@@ -67,7 +67,6 @@ The following optional dependencies are
|
||||
.. _service_identity: https://pypi.python.org/pypi/service_identity
|
||||
.. _pyasn1: https://pypi.python.org/pypi/pyasn1
|
||||
.. _cryptography: https://pypi.python.org/pypi/cryptography
|
||||
-.. _PyNaCl: https://pypi.python.org/pypi/PyNaCl
|
||||
.. _SOAPpy: https://pypi.python.org/pypi/SOAPpy
|
||||
.. _pyserial: https://pypi.python.org/pypi/pyserial
|
||||
.. _pyobjc: https://pypi.python.org/pypi/pyobjc
|
||||
Index: Twisted-22.10.0/src/twisted/conch/newsfragments/11871.removal
|
||||
===================================================================
|
||||
--- /dev/null
|
||||
+++ Twisted-22.10.0/src/twisted/conch/newsfragments/11871.removal
|
||||
@@ -0,0 +1 @@
|
||||
+Due to changes in the way raw private key byte serialization are handled in Cryptography, and widespread support for Ed25519 in current versions of OpenSSL, we no longer support PyNaCl as a fallback for Ed25519 keys in Conch.
|
||||
Index: Twisted-22.10.0/src/twisted/conch/ssh/_keys_pynacl.py
|
||||
===================================================================
|
||||
--- Twisted-22.10.0.orig/src/twisted/conch/ssh/_keys_pynacl.py
|
||||
+++ /dev/null
|
||||
@@ -1,104 +0,0 @@
|
||||
-# -*- test-case-name: twisted.conch.test.test_keys -*-
|
||||
-# Copyright (c) Twisted Matrix Laboratories.
|
||||
-# See LICENSE for details.
|
||||
-
|
||||
-"""
|
||||
-Optional PyNaCl fallback code for Ed25519 keys.
|
||||
-"""
|
||||
-
|
||||
-from cryptography.exceptions import InvalidSignature
|
||||
-from cryptography.hazmat.primitives import serialization
|
||||
-from cryptography.hazmat.primitives.asymmetric import ed25519
|
||||
-from nacl.exceptions import BadSignatureError
|
||||
-from nacl.signing import SigningKey, VerifyKey
|
||||
-
|
||||
-
|
||||
-class Ed25519PublicKey(ed25519.Ed25519PublicKey):
|
||||
- def __init__(self, data: bytes):
|
||||
- self._key = VerifyKey(data)
|
||||
-
|
||||
- def __bytes__(self) -> bytes:
|
||||
- return bytes(self._key)
|
||||
-
|
||||
- def __hash__(self) -> int:
|
||||
- return hash(bytes(self))
|
||||
-
|
||||
- def __eq__(self, other: object) -> bool:
|
||||
- if not isinstance(other, self.__class__):
|
||||
- return False
|
||||
- return self._key == other._key
|
||||
-
|
||||
- def __ne__(self, other: object) -> bool:
|
||||
- return not (self == other)
|
||||
-
|
||||
- @classmethod
|
||||
- def from_public_bytes(cls, data: bytes) -> ed25519.Ed25519PublicKey:
|
||||
- return cls(data)
|
||||
-
|
||||
- def public_bytes(
|
||||
- self,
|
||||
- encoding: serialization.Encoding,
|
||||
- format: serialization.PublicFormat,
|
||||
- ) -> bytes:
|
||||
- if (
|
||||
- encoding is not serialization.Encoding.Raw
|
||||
- or format is not serialization.PublicFormat.Raw
|
||||
- ):
|
||||
- raise ValueError("Both encoding and format must be Raw")
|
||||
- return bytes(self)
|
||||
-
|
||||
- def verify(self, signature: bytes, data: bytes) -> None:
|
||||
- try:
|
||||
- self._key.verify(data, signature)
|
||||
- except BadSignatureError as e:
|
||||
- raise InvalidSignature(str(e))
|
||||
-
|
||||
-
|
||||
-class Ed25519PrivateKey(ed25519.Ed25519PrivateKey):
|
||||
- def __init__(self, data: bytes):
|
||||
- self._key = SigningKey(data)
|
||||
-
|
||||
- def __bytes__(self) -> bytes:
|
||||
- return bytes(self._key)
|
||||
-
|
||||
- def __hash__(self) -> int:
|
||||
- return hash(bytes(self))
|
||||
-
|
||||
- def __eq__(self, other: object) -> bool:
|
||||
- if not isinstance(other, self.__class__):
|
||||
- return False
|
||||
- return self._key == other._key
|
||||
-
|
||||
- def __ne__(self, other: object) -> bool:
|
||||
- return not (self == other)
|
||||
-
|
||||
- @classmethod
|
||||
- def generate(cls) -> ed25519.Ed25519PrivateKey:
|
||||
- return cls(bytes(SigningKey.generate()))
|
||||
-
|
||||
- @classmethod
|
||||
- def from_private_bytes(cls, data: bytes) -> ed25519.Ed25519PrivateKey:
|
||||
- return cls(data)
|
||||
-
|
||||
- def public_key(self) -> ed25519.Ed25519PublicKey:
|
||||
- return Ed25519PublicKey(bytes(self._key.verify_key))
|
||||
-
|
||||
- def private_bytes(
|
||||
- self,
|
||||
- encoding: serialization.Encoding,
|
||||
- format: serialization.PrivateFormat,
|
||||
- encryption_algorithm: serialization.KeySerializationEncryption,
|
||||
- ) -> bytes:
|
||||
- if (
|
||||
- encoding is not serialization.Encoding.Raw
|
||||
- or format is not serialization.PrivateFormat.Raw
|
||||
- or not isinstance(encryption_algorithm, serialization.NoEncryption)
|
||||
- ):
|
||||
- raise ValueError(
|
||||
- "Encoding and format must be Raw and "
|
||||
- "encryption_algorithm must be NoEncryption"
|
||||
- )
|
||||
- return bytes(self)
|
||||
-
|
||||
- def sign(self, data: bytes) -> bytes:
|
||||
- return self._key.sign(data).signature
|
||||
Index: Twisted-22.10.0/src/twisted/conch/ssh/keys.py
|
||||
===================================================================
|
||||
--- Twisted-22.10.0.orig/src/twisted/conch/ssh/keys.py
|
||||
+++ Twisted-22.10.0/src/twisted/conch/ssh/keys.py
|
||||
@@ -14,7 +14,6 @@ import unicodedata
|
||||
import warnings
|
||||
from base64 import b64encode, decodebytes, encodebytes
|
||||
from hashlib import md5, sha256
|
||||
-from typing import Optional, Type
|
||||
|
||||
import bcrypt
|
||||
from cryptography import utils
|
||||
@@ -68,18 +67,8 @@ _secToNist = {
|
||||
}
|
||||
|
||||
|
||||
-Ed25519PublicKey: Optional[Type[ed25519.Ed25519PublicKey]]
|
||||
-Ed25519PrivateKey: Optional[Type[ed25519.Ed25519PrivateKey]]
|
||||
-
|
||||
-if default_backend().ed25519_supported():
|
||||
- Ed25519PublicKey = ed25519.Ed25519PublicKey
|
||||
- Ed25519PrivateKey = ed25519.Ed25519PrivateKey
|
||||
-else: # pragma: no cover
|
||||
- try:
|
||||
- from twisted.conch.ssh._keys_pynacl import Ed25519PrivateKey, Ed25519PublicKey
|
||||
- except ImportError:
|
||||
- Ed25519PublicKey = None
|
||||
- Ed25519PrivateKey = None
|
||||
+Ed25519PublicKey = ed25519.Ed25519PublicKey
|
||||
+Ed25519PrivateKey = ed25519.Ed25519PrivateKey
|
||||
|
||||
|
||||
class BadKeyError(Exception):
|
||||
Index: Twisted-22.10.0/src/twisted/conch/test/test_keys.py
|
||||
===================================================================
|
||||
--- Twisted-22.10.0.orig/src/twisted/conch/test/test_keys.py
|
||||
+++ Twisted-22.10.0/src/twisted/conch/test/test_keys.py
|
||||
@@ -22,20 +22,15 @@ if cryptography is None:
|
||||
skipCryptography = "Cannot run without cryptography."
|
||||
|
||||
pyasn1 = requireModule("pyasn1")
|
||||
-_keys_pynacl = requireModule("twisted.conch.ssh._keys_pynacl")
|
||||
-
|
||||
|
||||
if cryptography and pyasn1:
|
||||
- from cryptography.exceptions import InvalidSignature
|
||||
from cryptography.hazmat.backends import default_backend
|
||||
from cryptography.hazmat.primitives import hashes
|
||||
from cryptography.hazmat.primitives.asymmetric import padding
|
||||
|
||||
from twisted.conch.ssh import common, keys, sexpy
|
||||
|
||||
- ED25519_SUPPORTED = (
|
||||
- default_backend().ed25519_supported() or _keys_pynacl is not None
|
||||
- )
|
||||
+ ED25519_SUPPORTED = default_backend().ed25519_supported()
|
||||
else:
|
||||
ED25519_SUPPORTED = False
|
||||
|
||||
@@ -1676,156 +1671,6 @@ attr n:
|
||||
)
|
||||
|
||||
|
||||
-class PyNaClKeyTests(KeyTests):
|
||||
- """
|
||||
- Key tests, but forcing the use of C{PyNaCl}.
|
||||
- """
|
||||
-
|
||||
- if cryptography is None:
|
||||
- skip = skipCryptography
|
||||
- if _keys_pynacl is None:
|
||||
- skip = "Cannot run without PyNaCl"
|
||||
-
|
||||
- def setUp(self):
|
||||
- super().setUp()
|
||||
- self.patch(keys, "Ed25519PublicKey", _keys_pynacl.Ed25519PublicKey)
|
||||
- self.patch(keys, "Ed25519PrivateKey", _keys_pynacl.Ed25519PrivateKey)
|
||||
-
|
||||
- def test_naclPrivateBytes(self):
|
||||
- """
|
||||
- L{_keys_pynacl.Ed25519PrivateKey.private_bytes} and
|
||||
- L{_keys_pynacl.Ed25519PrivateKey.from_private_bytes} round-trip.
|
||||
- """
|
||||
- from cryptography.hazmat.primitives import serialization
|
||||
-
|
||||
- key = _keys_pynacl.Ed25519PrivateKey.generate()
|
||||
- key_bytes = key.private_bytes(
|
||||
- serialization.Encoding.Raw,
|
||||
- serialization.PrivateFormat.Raw,
|
||||
- serialization.NoEncryption(),
|
||||
- )
|
||||
- self.assertIsInstance(key_bytes, bytes)
|
||||
- self.assertEqual(
|
||||
- key, _keys_pynacl.Ed25519PrivateKey.from_private_bytes(key_bytes)
|
||||
- )
|
||||
-
|
||||
- def test_naclPrivateBytesInvalidParameters(self):
|
||||
- """
|
||||
- L{_keys_pynacl.Ed25519PrivateKey.private_bytes} only accepts certain parameters.
|
||||
- """
|
||||
- from cryptography.hazmat.primitives import serialization
|
||||
-
|
||||
- key = _keys_pynacl.Ed25519PrivateKey.generate()
|
||||
- self.assertRaises(
|
||||
- ValueError,
|
||||
- key.private_bytes,
|
||||
- serialization.Encoding.PEM,
|
||||
- serialization.PrivateFormat.Raw,
|
||||
- serialization.NoEncryption(),
|
||||
- )
|
||||
- self.assertRaises(
|
||||
- ValueError,
|
||||
- key.private_bytes,
|
||||
- serialization.Encoding.Raw,
|
||||
- serialization.PrivateFormat.PKCS8,
|
||||
- serialization.NoEncryption(),
|
||||
- )
|
||||
- self.assertRaises(
|
||||
- ValueError,
|
||||
- key.private_bytes,
|
||||
- serialization.Encoding.Raw,
|
||||
- serialization.PrivateFormat.Raw,
|
||||
- serialization.BestAvailableEncryption(b"password"),
|
||||
- )
|
||||
-
|
||||
- def test_naclPrivateHash(self):
|
||||
- """
|
||||
- L{_keys_pynacl.Ed25519PrivateKey.__hash__} allows instances to be hashed.
|
||||
- """
|
||||
- key = _keys_pynacl.Ed25519PrivateKey.generate()
|
||||
- d = {key: True}
|
||||
- self.assertTrue(d[key])
|
||||
-
|
||||
- def test_naclPrivateEquality(self):
|
||||
- """
|
||||
- L{_keys_pynacl.Ed25519PrivateKey} implements equality test methods.
|
||||
- """
|
||||
- key1 = _keys_pynacl.Ed25519PrivateKey.generate()
|
||||
- key2 = _keys_pynacl.Ed25519PrivateKey.generate()
|
||||
- self.assertEqual(key1, key1)
|
||||
- self.assertNotEqual(key1, key2)
|
||||
- self.assertNotEqual(key1, bytes(key1))
|
||||
-
|
||||
- def test_naclPublicBytes(self):
|
||||
- """
|
||||
- L{_keys_pynacl.Ed25519PublicKey.public_bytes} and
|
||||
- L{_keys_pynacl.Ed25519PublicKey.from_public_bytes} round-trip.
|
||||
- """
|
||||
- from cryptography.hazmat.primitives import serialization
|
||||
-
|
||||
- key = _keys_pynacl.Ed25519PrivateKey.generate().public_key()
|
||||
- key_bytes = key.public_bytes(
|
||||
- serialization.Encoding.Raw, serialization.PublicFormat.Raw
|
||||
- )
|
||||
- self.assertIsInstance(key_bytes, bytes)
|
||||
- self.assertEqual(
|
||||
- key, _keys_pynacl.Ed25519PublicKey.from_public_bytes(key_bytes)
|
||||
- )
|
||||
-
|
||||
- def test_naclPublicBytesInvalidParameters(self):
|
||||
- """
|
||||
- L{_keys_pynacl.Ed25519PublicKey.public_bytes} only accepts certain parameters.
|
||||
- """
|
||||
- from cryptography.hazmat.primitives import serialization
|
||||
-
|
||||
- key = _keys_pynacl.Ed25519PrivateKey.generate().public_key()
|
||||
- self.assertRaises(
|
||||
- ValueError,
|
||||
- key.public_bytes,
|
||||
- serialization.Encoding.PEM,
|
||||
- serialization.PublicFormat.Raw,
|
||||
- )
|
||||
- self.assertRaises(
|
||||
- ValueError,
|
||||
- key.public_bytes,
|
||||
- serialization.Encoding.Raw,
|
||||
- serialization.PublicFormat.PKCS1,
|
||||
- )
|
||||
-
|
||||
- def test_naclPublicHash(self):
|
||||
- """
|
||||
- L{_keys_pynacl.Ed25519PublicKey.__hash__} allows instances to be hashed.
|
||||
- """
|
||||
- key = _keys_pynacl.Ed25519PrivateKey.generate().public_key()
|
||||
- d = {key: True}
|
||||
- self.assertTrue(d[key])
|
||||
-
|
||||
- def test_naclPublicEquality(self):
|
||||
- """
|
||||
- L{_keys_pynacl.Ed25519PublicKey} implements equality test methods.
|
||||
- """
|
||||
- key1 = _keys_pynacl.Ed25519PrivateKey.generate().public_key()
|
||||
- key2 = _keys_pynacl.Ed25519PrivateKey.generate().public_key()
|
||||
- self.assertEqual(key1, key1)
|
||||
- self.assertNotEqual(key1, key2)
|
||||
- self.assertNotEqual(key1, bytes(key1))
|
||||
-
|
||||
- def test_naclVerify(self):
|
||||
- """
|
||||
- L{_keys_pynacl.Ed25519PublicKey.verify} raises appropriate exceptions.
|
||||
- """
|
||||
- key = _keys_pynacl.Ed25519PrivateKey.generate()
|
||||
- self.assertIsInstance(key, keys.Ed25519PrivateKey)
|
||||
- signature = key.sign(b"test data")
|
||||
- self.assertIsNone(key.public_key().verify(signature, b"test data"))
|
||||
- self.assertRaises(
|
||||
- InvalidSignature, key.public_key().verify, signature, b"wrong data"
|
||||
- )
|
||||
- self.assertRaises(
|
||||
- InvalidSignature, key.public_key().verify, b"0" * 64, b"test data"
|
||||
- )
|
||||
-
|
||||
-
|
||||
class PersistentRSAKeyTests(unittest.TestCase):
|
||||
"""
|
||||
Tests for L{keys._getPersistentRSAKey}.
|
@ -2,10 +2,10 @@
|
||||
src/twisted/test/test_udp.py | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
Index: Twisted-22.10.0/src/twisted/test/test_udp.py
|
||||
Index: twisted-24.3.0/src/twisted/test/test_udp.py
|
||||
===================================================================
|
||||
--- Twisted-22.10.0.orig/src/twisted/test/test_udp.py
|
||||
+++ Twisted-22.10.0/src/twisted/test/test_udp.py
|
||||
--- twisted-24.3.0.orig/src/twisted/test/test_udp.py
|
||||
+++ twisted-24.3.0/src/twisted/test/test_udp.py
|
||||
@@ -8,7 +8,7 @@ Tests for implementations of L{IReactorU
|
||||
|
||||
|
||||
@ -15,7 +15,7 @@ Index: Twisted-22.10.0/src/twisted/test/test_udp.py
|
||||
|
||||
from twisted.internet import defer, error, interfaces, protocol, reactor, udp
|
||||
from twisted.internet.defer import Deferred, gatherResults, maybeDeferred
|
||||
@@ -581,6 +581,7 @@ class MulticastTests(TestCase):
|
||||
@@ -578,6 +578,7 @@ class MulticastTests(TestCase):
|
||||
skip = "This reactor does not support multicast"
|
||||
|
||||
def setUp(self):
|
||||
|
@ -1,116 +0,0 @@
|
||||
From da3bf3dc29f067e7019b2a1c205834ab64b2139a Mon Sep 17 00:00:00 2001
|
||||
From: Paul Eggert <eggert@cs.ucla.edu>
|
||||
Date: Fri, 9 Dec 2022 10:16:42 -0800
|
||||
Subject: [PATCH] #11786 fix misuse of mktime in tests
|
||||
|
||||
---
|
||||
src/twisted/logger/test/test_format.py | 27 +++++++++++++-------------
|
||||
1 file changed, 14 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/src/twisted/logger/test/test_format.py b/src/twisted/logger/test/test_format.py
|
||||
index dbfbe1af1ae..0671b6662c8 100644
|
||||
--- a/src/twisted/logger/test/test_format.py
|
||||
+++ b/src/twisted/logger/test/test_format.py
|
||||
@@ -166,16 +166,17 @@ def test_formatTimeWithDefaultFormat(self) -> None:
|
||||
def testForTimeZone(name: str, expectedDST: str, expectedSTD: str) -> None:
|
||||
setTZ(name)
|
||||
|
||||
- localDST = mktime((2006, 6, 30, 0, 0, 0, 4, 181, 1))
|
||||
localSTD = mktime((2007, 1, 31, 0, 0, 0, 2, 31, 0))
|
||||
-
|
||||
- self.assertEqual(formatTime(localDST), expectedDST)
|
||||
self.assertEqual(formatTime(localSTD), expectedSTD)
|
||||
|
||||
+ if expectedDST:
|
||||
+ localDST = mktime((2006, 6, 30, 0, 0, 0, 4, 181, 1))
|
||||
+ self.assertEqual(formatTime(localDST), expectedDST)
|
||||
+
|
||||
# UTC
|
||||
testForTimeZone(
|
||||
"UTC+00",
|
||||
- "2006-06-30T00:00:00+0000",
|
||||
+ None,
|
||||
"2007-01-31T00:00:00+0000",
|
||||
)
|
||||
|
||||
@@ -196,7 +197,7 @@ def testForTimeZone(name: str, expectedDST: str, expectedSTD: str) -> None:
|
||||
# No DST
|
||||
testForTimeZone(
|
||||
"CST+06",
|
||||
- "2006-06-30T00:00:00-0600",
|
||||
+ None,
|
||||
"2007-01-31T00:00:00-0600",
|
||||
)
|
||||
|
||||
@@ -211,7 +212,7 @@ def test_formatTimeWithNoFormat(self) -> None:
|
||||
"""
|
||||
If C{timeFormat} argument is L{None}, we get the default output.
|
||||
"""
|
||||
- t = mktime((2013, 9, 24, 11, 40, 47, 1, 267, 1))
|
||||
+ t = mktime((2013, 9, 24, 11, 40, 47, 1, 267, -1))
|
||||
self.assertEqual(formatTime(t, timeFormat=None), "-")
|
||||
self.assertEqual(formatTime(t, timeFormat=None, default="!"), "!")
|
||||
|
||||
@@ -219,7 +220,7 @@ def test_formatTimeWithAlternateTimeFormat(self) -> None:
|
||||
"""
|
||||
Alternate time format in output.
|
||||
"""
|
||||
- t = mktime((2013, 9, 24, 11, 40, 47, 1, 267, 1))
|
||||
+ t = mktime((2013, 9, 24, 11, 40, 47, 1, 267, -1))
|
||||
self.assertEqual(formatTime(t, timeFormat="%Y/%W"), "2013/38")
|
||||
|
||||
def test_formatTimePercentF(self) -> None:
|
||||
@@ -246,7 +247,7 @@ def test_formatTimeDefault(self) -> None:
|
||||
addTZCleanup(self)
|
||||
setTZ("UTC+00")
|
||||
|
||||
- t = mktime((2013, 9, 24, 11, 40, 47, 1, 267, 1))
|
||||
+ t = mktime((2013, 9, 24, 11, 40, 47, 1, 267, -1))
|
||||
event = dict(log_format="XYZZY", log_time=t)
|
||||
self.assertEqual(
|
||||
formatEventAsClassicLogText(event),
|
||||
@@ -539,7 +540,7 @@ def test_eventAsTextSystemOnly(self) -> None:
|
||||
except CapturedError:
|
||||
f = Failure()
|
||||
|
||||
- t = mktime((2013, 9, 24, 11, 40, 47, 1, 267, 1))
|
||||
+ t = mktime((2013, 9, 24, 11, 40, 47, 1, 267, -1))
|
||||
event: LogEvent = {
|
||||
"log_format": "ABCD",
|
||||
"log_system": "fake_system",
|
||||
@@ -573,7 +574,7 @@ def test_eventAsTextTimestampOnly(self) -> None:
|
||||
except CapturedError:
|
||||
f = Failure()
|
||||
|
||||
- t = mktime((2013, 9, 24, 11, 40, 47, 1, 267, 1))
|
||||
+ t = mktime((2013, 9, 24, 11, 40, 47, 1, 267, -1))
|
||||
event: LogEvent = {
|
||||
"log_format": "ABCD",
|
||||
"log_system": "fake_system",
|
||||
@@ -601,7 +602,7 @@ def test_eventAsTextSystemMissing(self) -> None:
|
||||
except CapturedError:
|
||||
f = Failure()
|
||||
|
||||
- t = mktime((2013, 9, 24, 11, 40, 47, 1, 267, 1))
|
||||
+ t = mktime((2013, 9, 24, 11, 40, 47, 1, 267, -1))
|
||||
event: LogEvent = {
|
||||
"log_format": "ABCD",
|
||||
"log_time": t,
|
||||
@@ -628,7 +629,7 @@ def test_eventAsTextSystemMissingNamespaceAndLevel(self) -> None:
|
||||
except CapturedError:
|
||||
f = Failure()
|
||||
|
||||
- t = mktime((2013, 9, 24, 11, 40, 47, 1, 267, 1))
|
||||
+ t = mktime((2013, 9, 24, 11, 40, 47, 1, 267, -1))
|
||||
event: LogEvent = {
|
||||
"log_format": "ABCD",
|
||||
"log_time": t,
|
||||
@@ -657,7 +658,7 @@ def test_eventAsTextSystemMissingLevelOnly(self) -> None:
|
||||
except CapturedError:
|
||||
f = Failure()
|
||||
|
||||
- t = mktime((2013, 9, 24, 11, 40, 47, 1, 267, 1))
|
||||
+ t = mktime((2013, 9, 24, 11, 40, 47, 1, 267, -1))
|
||||
event: LogEvent = {
|
||||
"log_format": "ABCD",
|
||||
"log_time": t,
|
BIN
twisted-24.3.0.tar.gz
(Stored with Git LFS)
Normal file
BIN
twisted-24.3.0.tar.gz
(Stored with Git LFS)
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user