/usr/lib/python2.7/dist-packages/twisted/names/_rfc1982.py is in python-twisted-names 14.0.2-3.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 | # -*- test-case-name: twisted.names.test.test_rfc1982 -*-
# Copyright (c) Twisted Matrix Laboratories.
# See LICENSE for details.
"""
Utilities for handling RFC1982 Serial Number Arithmetic.
@see: U{http://tools.ietf.org/html/rfc1982}
@var RFC4034_TIME_FORMAT: RRSIG Time field presentation format. The Signature
Expiration Time and Inception Time field values MUST be represented either
as an unsigned decimal integer indicating seconds since 1 January 1970
00:00:00 UTC, or in the form YYYYMMDDHHmmSS in UTC. See U{RRSIG Presentation
Format<https://tools.ietf.org/html/rfc4034#section-3.2>}
"""
from __future__ import division, absolute_import
import calendar
from datetime import datetime, timedelta
from twisted.python.compat import nativeString
from twisted.python.util import FancyStrMixin
RFC4034_TIME_FORMAT = '%Y%m%d%H%M%S'
class SerialNumber(FancyStrMixin, object):
"""
An RFC1982 Serial Number.
This class implements RFC1982 DNS Serial Number Arithmetic.
SNA is used in DNS and specifically in DNSSEC as defined in RFC4034 in the
DNSSEC Signature Expiration and Inception Fields.
@see: U{https://tools.ietf.org/html/rfc1982}
@see: U{https://tools.ietf.org/html/rfc4034}
@ivar _serialBits: See C{serialBits} of L{__init__}.
@ivar _number: See C{number} of L{__init__}.
@ivar _modulo: The value at which wrapping will occur.
@ivar _halfRing: Half C{_modulo}. If another L{SerialNumber} value is larger
than this, it would lead to a wrapped value which is larger than the
first and comparisons are therefore ambiguous.
@ivar _maxAdd: Half C{_modulo} plus 1. If another L{SerialNumber} value is
larger than this, it would lead to a wrapped value which is larger than
the first. Comparisons with the original value would therefore be
ambiguous.
"""
showAttributes = (
('_number', 'number', '%d'),
('_serialBits', 'serialBits', '%d'),
)
def __init__(self, number, serialBits=32):
"""
Construct an L{SerialNumber} instance.
@param number: An L{int} which will be stored as the modulo
C{number % 2 ^ serialBits}
@type number: L{int}
@param serialBits: The size of the serial number space. The power of two
which results in one larger than the largest integer corresponding
to a serial number value.
@type serialBits: L{int}
"""
self._serialBits = serialBits
self._modulo = 2 ** serialBits
self._halfRing = 2 ** (serialBits - 1)
self._maxAdd = 2 ** (serialBits - 1) - 1
self._number = int(number) % self._modulo
def _convertOther(self, other):
"""
Check that a foreign object is suitable for use in the comparison or
arithmetic magic methods of this L{SerialNumber} instance. Raise
L{TypeError} if not.
@param other: The foreign L{object} to be checked.
@return: C{other} after compatibility checks and possible coercion.
@raises: L{TypeError} if C{other} is not compatible.
"""
if not isinstance(other, SerialNumber):
raise TypeError(
'cannot compare or combine %r and %r' % (self, other))
if self._serialBits != other._serialBits:
raise TypeError(
'cannot compare or combine SerialNumber instances with '
'different serialBits. %r and %r' % (self, other))
return other
def __str__(self):
"""
Return a string representation of this L{SerialNumber} instance.
@rtype: L{nativeString}
"""
return nativeString('%d' % (self._number,))
def __int__(self):
"""
@return: The integer value of this L{SerialNumber} instance.
@rtype: L{int}
"""
return self._number
def __eq__(self, other):
"""
Allow rich equality comparison with another L{SerialNumber} instance.
@type other: L{SerialNumber}
"""
other = self._convertOther(other)
return other._number == self._number
def __ne__(self, other):
"""
Allow rich equality comparison with another L{SerialNumber} instance.
@type other: L{SerialNumber}
"""
return not self.__eq__(other)
def __lt__(self, other):
"""
Allow I{less than} comparison with another L{SerialNumber} instance.
@type other: L{SerialNumber}
"""
other = self._convertOther(other)
return (
(self._number < other._number
and (other._number - self._number) < self._halfRing)
or
(self._number > other._number
and (self._number - other._number) > self._halfRing)
)
def __gt__(self, other):
"""
Allow I{greater than} comparison with another L{SerialNumber} instance.
@type other: L{SerialNumber}
@rtype: L{bool}
"""
other = self._convertOther(other)
return (
(self._number < other._number
and (other._number - self._number) > self._halfRing)
or
(self._number > other._number
and (self._number - other._number) < self._halfRing)
)
def __le__(self, other):
"""
Allow I{less than or equal} comparison with another L{SerialNumber}
instance.
@type other: L{SerialNumber}
@rtype: L{bool}
"""
other = self._convertOther(other)
return self == other or self < other
def __ge__(self, other):
"""
Allow I{greater than or equal} comparison with another L{SerialNumber}
instance.
@type other: L{SerialNumber}
@rtype: L{bool}
"""
other = self._convertOther(other)
return self == other or self > other
def __add__(self, other):
"""
Allow I{addition} with another L{SerialNumber} instance.
Serial numbers may be incremented by the addition of a positive
integer n, where n is taken from the range of integers
[0 .. (2^(SERIAL_BITS - 1) - 1)]. For a sequence number s, the
result of such an addition, s', is defined as
s' = (s + n) modulo (2 ^ SERIAL_BITS)
where the addition and modulus operations here act upon values that are
non-negative values of unbounded size in the usual ways of integer
arithmetic.
Addition of a value outside the range
[0 .. (2^(SERIAL_BITS - 1) - 1)] is undefined.
@see: U{http://tools.ietf.org/html/rfc1982#section-3.1}
@type other: L{SerialNumber}
@rtype: L{SerialNumber}
@raises: L{ArithmeticError} if C{other} is more than C{_maxAdd}
ie more than half the maximum value of this serial number.
"""
other = self._convertOther(other)
if other._number <= self._maxAdd:
return SerialNumber(
(self._number + other._number) % self._modulo,
serialBits=self._serialBits)
else:
raise ArithmeticError(
'value %r outside the range 0 .. %r' % (
other._number, self._maxAdd,))
def __hash__(self):
"""
Allow L{SerialNumber} instances to be hashed for use as L{dict} keys.
@rtype: L{int}
"""
return hash(self._number)
@classmethod
def fromRFC4034DateString(cls, utcDateString):
"""
Create an L{SerialNumber} instance from a date string in format
'YYYYMMDDHHMMSS' described in U{RFC4034
3.2<https://tools.ietf.org/html/rfc4034#section-3.2>}.
The L{SerialNumber} instance stores the date as a 32bit UNIX timestamp.
@see: U{https://tools.ietf.org/html/rfc4034#section-3.1.5}
@param utcDateString: A UTC date/time string of format I{YYMMDDhhmmss}
which will be converted to seconds since the UNIX epoch.
@type utcDateString: L{unicode}
@return: An L{SerialNumber} instance containing the supplied date as a
32bit UNIX timestamp.
"""
parsedDate = datetime.strptime(utcDateString, RFC4034_TIME_FORMAT)
secondsSinceEpoch = calendar.timegm(parsedDate.utctimetuple())
return cls(secondsSinceEpoch, serialBits=32)
def toRFC4034DateString(self):
"""
Calculate a date by treating the current L{SerialNumber} value as a UNIX
timestamp and return a date string in the format described in
U{RFC4034 3.2<https://tools.ietf.org/html/rfc4034#section-3.2>}.
@return: The date string.
"""
# Can't use datetime.utcfromtimestamp, because it seems to overflow the
# signed 32bit int used in the underlying C library. SNA is unsigned
# and capable of handling all timestamps up to 2**32.
d = datetime(1970, 1, 1) + timedelta(seconds=self._number)
return nativeString(d.strftime(RFC4034_TIME_FORMAT))
__all__ = ['SerialNumber']
|