Skip to content

Commit d4ac998

Browse files
committed
SPNEGO: big refactor
1 parent 7ea2540 commit d4ac998

File tree

19 files changed

+1088
-625
lines changed

19 files changed

+1088
-625
lines changed

scapy/layers/gssapi.py

Lines changed: 47 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
ASN1_Class_UNIVERSAL,
3535
ASN1_Codecs,
3636
)
37-
from scapy.asn1.ber import BERcodec_SEQUENCE
37+
from scapy.asn1.ber import BERcodec_SEQUENCE, BER_id_dec
3838
from scapy.asn1.mib import conf # loads conf.mib
3939
from scapy.asn1fields import (
4040
ASN1F_OID,
@@ -104,19 +104,25 @@ class GSSAPI_BLOB(ASN1_Packet):
104104
@classmethod
105105
def dispatch_hook(cls, _pkt=None, *args, **kargs):
106106
if _pkt and len(_pkt) >= 1:
107-
if ord(_pkt[:1]) & 0xA0 >= 0xA0:
107+
if _pkt[0] & 0xA0 >= 0xA0:
108108
from scapy.layers.spnego import SPNEGO_negToken
109109

110110
# XXX: sometimes the token is raw, we should look from
111111
# the session what to use here. For now: hardcode SPNEGO
112112
# (THIS IS A VERY STRONG ASSUMPTION)
113113
return SPNEGO_negToken
114-
if _pkt[:7] == b"NTLMSSP":
114+
elif _pkt[:7] == b"NTLMSSP":
115115
from scapy.layers.ntlm import NTLM_Header
116116

117117
# XXX: if no mechTypes are provided during SPNEGO exchange,
118118
# Windows falls back to a plain NTLM_Header.
119119
return NTLM_Header.dispatch_hook(_pkt=_pkt, *args, **kargs)
120+
elif BER_id_dec(_pkt)[0] & 0x7F > 0x60:
121+
from scapy.layers.kerberos import Kerberos
122+
123+
# XXX: Heuristic to detect raw Kerberos packets, when Windows
124+
# fallsback or when the parent data hasn't got any mechtype specified.
125+
return Kerberos
120126
return cls
121127

122128

@@ -454,7 +460,7 @@ class STATE(IntEnum):
454460
def GSS_Init_sec_context(
455461
self,
456462
Context: CONTEXT,
457-
token=None,
463+
input_token=None,
458464
target_name: Optional[str] = None,
459465
req_flags: Optional[GSS_C_FLAGS] = None,
460466
chan_bindings: GssChannelBindings = GSS_C_NO_CHANNEL_BINDINGS,
@@ -468,7 +474,7 @@ def GSS_Init_sec_context(
468474
def GSS_Accept_sec_context(
469475
self,
470476
Context: CONTEXT,
471-
token=None,
477+
input_token=None,
472478
req_flags: Optional[GSS_S_FLAGS] = GSS_S_FLAGS.GSS_S_ALLOW_MISSING_BINDINGS,
473479
chan_bindings: GssChannelBindings = GSS_C_NO_CHANNEL_BINDINGS,
474480
):
@@ -477,10 +483,21 @@ def GSS_Accept_sec_context(
477483
"""
478484
raise NotImplementedError
479485

486+
@abc.abstractmethod
487+
def GSS_Inquire_names_for_mech(self) -> List[str]:
488+
"""
489+
Get the available OIDs for this mech, in order of preference.
490+
"""
491+
raise NotImplementedError
492+
480493
# Passive
481494

482495
@abc.abstractmethod
483-
def GSS_Passive(self, Context: CONTEXT, token=None):
496+
def GSS_Passive(
497+
self,
498+
Context: CONTEXT,
499+
input_token=None,
500+
):
484501
"""
485502
GSS_Passive: client/server call for the SSP in passive mode
486503
"""
@@ -591,6 +608,9 @@ def GSS_GetMIC(
591608
message: bytes,
592609
qop_req: int = GSS_C_QOP_DEFAULT,
593610
):
611+
"""
612+
See GSS_GetMICEx
613+
"""
594614
return self.GSS_GetMICEx(
595615
Context,
596616
[
@@ -609,7 +629,10 @@ def GSS_VerifyMIC(
609629
Context: CONTEXT,
610630
message: bytes,
611631
signature,
612-
):
632+
) -> None:
633+
"""
634+
See GSS_VerifyMICEx
635+
"""
613636
self.GSS_VerifyMICEx(
614637
Context,
615638
[
@@ -630,6 +653,9 @@ def GSS_Wrap(
630653
conf_req_flag: bool,
631654
qop_req: int = GSS_C_QOP_DEFAULT,
632655
):
656+
"""
657+
See GSS_WrapEx
658+
"""
633659
_msgs, signature = self.GSS_WrapEx(
634660
Context,
635661
[
@@ -647,7 +673,14 @@ def GSS_Wrap(
647673

648674
# sect 2.3.4
649675

650-
def GSS_Unwrap(self, Context: CONTEXT, signature):
676+
def GSS_Unwrap(
677+
self,
678+
Context: CONTEXT,
679+
signature,
680+
):
681+
"""
682+
See GSS_UnwrapEx
683+
"""
651684
data = b""
652685
if signature.payload:
653686
# signature has a payload that is the data. Let's get that payload
@@ -679,19 +712,19 @@ def NegTokenInit2(self):
679712
"""
680713
return None, None
681714

682-
def canMechListMIC(self, Context: CONTEXT):
715+
def SupportsMechListMIC(self):
683716
"""
684-
Returns whether or not mechListMIC can be computed
717+
Returns whether mechListMIC is supported or not
685718
"""
686-
return False
719+
return True
687720

688-
def getMechListMIC(self, Context, input):
721+
def GetMechListMIC(self, Context, input):
689722
"""
690723
Compute mechListMIC
691724
"""
692-
return bytes(self.GSS_GetMIC(Context, input))
725+
return self.GSS_GetMIC(Context, input)
693726

694-
def verifyMechListMIC(self, Context, otherMIC, input):
727+
def VerifyMechListMIC(self, Context, otherMIC, input):
695728
"""
696729
Verify mechListMIC
697730
"""

scapy/layers/http.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -944,7 +944,7 @@ def request(
944944
# SPNEGO / Kerberos / NTLM
945945
self.sspcontext, token, status = self.ssp.GSS_Init_sec_context(
946946
self.sspcontext,
947-
ssp_blob,
947+
input_token=ssp_blob,
948948
target_name="http/" + host,
949949
req_flags=0,
950950
chan_bindings=self.chan_bindings,

0 commit comments

Comments
 (0)