1919# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
2020# THE SOFTWARE.
2121
22+ import os
2223import struct
2324
24- from pyasn1 import error
25- from pyasn1 .codec .der import decoder , encoder
26-
27- import kdcproxy .asn1 as asn1
28-
29-
30- class ParsingError (Exception ):
31-
32- def __init__ (self , message ):
33- super (ParsingError , self ).__init__ (message )
34- self .message = message
25+ from kdcproxy .exceptions import ParsingError
26+
27+ ASN1MOD = os .environ .get ('KDCPROXY_ASN1MOD' )
28+
29+ if ASN1MOD is None :
30+ try :
31+ from asn1crypto .version import __version_info__ as asn1crypto_version
32+ except ImportError :
33+ asn1crypto_version = None
34+ else :
35+ if asn1crypto_version >= (0 , 22 , 0 ):
36+ ASN1MOD = 'asn1crypto'
37+ if ASN1MOD is None :
38+ try :
39+ __import__ ('pyasn1' )
40+ except ImportError :
41+ pass
42+ else :
43+ ASN1MOD = 'pyasn1'
44+
45+ if ASN1MOD == 'asn1crypto' :
46+ from kdcproxy import parse_asn1crypto as asn1mod
47+ elif ASN1MOD == 'pyasn1' :
48+ from kdcproxy import parse_pyasn1 as asn1mod
49+ else :
50+ raise ValueError ("Invalid KDCPROXY_ASN1MOD='{}'" .format (ASN1MOD ))
3551
3652
3753class ProxyRequest (object ):
@@ -40,16 +56,7 @@ class ProxyRequest(object):
4056
4157 @classmethod
4258 def parse (cls , data ):
43- (req , err ) = decoder .decode (data , asn1Spec = asn1 .ProxyMessage ())
44- if err :
45- raise ParsingError ("Invalid request." )
46-
47- request = req .getComponentByName ('message' ).asOctets ()
48- realm = req .getComponentByName ('realm' ).asOctets ()
49- try : # Python 3.x
50- realm = str (realm , "UTF8" )
51- except TypeError : # Python 2.x
52- realm = str (realm )
59+ request , realm , _ = asn1mod .decode_proxymessage (data )
5360
5461 # Check the length of the whole request message.
5562 (length , ) = struct .unpack ("!I" , request [0 :4 ])
@@ -58,42 +65,41 @@ def parse(cls, data):
5865
5966 for subcls in cls .__subclasses__ ():
6067 try :
61- (req , err ) = decoder .decode (request [subcls .OFFSET :],
62- asn1Spec = subcls .TYPE ())
63- return subcls (realm , request , err )
64- except error .PyAsn1Error :
68+ return subcls .parse_request (realm , request )
69+ except ParsingError :
6570 pass
6671
6772 raise ParsingError ("Invalid request." )
6873
69- def __init__ (self , realm , request , err ):
74+ @classmethod
75+ def parse_request (cls , realm , request ):
76+ pretty_name = asn1mod .try_decode (request [cls .OFFSET :], cls .TYPE )
77+ return cls (realm , request , pretty_name )
78+
79+ def __init__ (self , realm , request , pretty_name ):
7080 self .realm = realm
7181 self .request = request
72-
73- if len (err ) > 0 :
74- type = self .__class__ .__name__ [:0 - len (ProxyRequest .__name__ )]
75- raise ParsingError ("%s request has %d extra bytes." %
76- (type , len (err )))
82+ self .pretty_name = pretty_name
7783
7884 def __str__ (self ):
79- type = self .__class__ .__name__ [:0 - len (ProxyRequest .__name__ )]
80- return "%s %s-REQ (%d bytes)" % (self .realm , type ,
81- len (self .request ) - 4 )
85+ return "%s %s (%d bytes)" % (self .realm , self .pretty_name ,
86+ len (self .request ) - 4 )
8287
8388
8489class TGSProxyRequest (ProxyRequest ):
85- TYPE = asn1 .TGSREQ
90+ TYPE = asn1mod .TGSREQ
8691
8792
8893class ASProxyRequest (ProxyRequest ):
89- TYPE = asn1 .ASREQ
94+ TYPE = asn1mod .ASREQ
9095
9196
9297class KPASSWDProxyRequest (ProxyRequest ):
93- TYPE = asn1 .APREQ
98+ TYPE = asn1mod .APREQ
9499 OFFSET = 10
95100
96- def __init__ (self , realm , request , err ):
101+ @classmethod
102+ def parse_request (cls , realm , request ):
97103 # Check the length count in the password change request, assuming it
98104 # actually is a password change request. It should be the length of
99105 # the rest of the request, including itself.
@@ -118,13 +124,12 @@ def __init__(self, realm, request, err):
118124 # See if the tag looks like an AP request, which would look like the
119125 # start of a password change request. The rest of it should be a
120126 # KRB-PRIV message.
121- (apreq , err ) = decoder .decode (request [10 :length + 10 ],
122- asn1Spec = asn1 .APREQ ())
123- (krbpriv , err ) = decoder .decode (request [length + 10 :],
124- asn1Spec = asn1 .KRBPriv ())
127+ asn1mod .try_decode (request [10 :length + 10 ], asn1mod .APREQ )
128+ asn1mod .try_decode (request [length + 10 :], asn1mod .KRBPriv )
125129
126- super ( KPASSWDProxyRequest , self ). __init__ (realm , request , err )
130+ self = cls (realm , request , "KPASSWD-REQ" )
127131 self .version = version
132+ return self
128133
129134 def __str__ (self ):
130135 tmp = super (KPASSWDProxyRequest , self ).__str__ ()
@@ -137,6 +142,4 @@ def decode(data):
137142
138143
139144def encode (data ):
140- rep = asn1 .ProxyMessage ()
141- rep .setComponentByName ('message' , data )
142- return encoder .encode (rep )
145+ return asn1mod .encode_proxymessage (data )
0 commit comments