-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSAPLogonTicket.py
More file actions
105 lines (88 loc) · 2.96 KB
/
SAPLogonTicket.py
File metadata and controls
105 lines (88 loc) · 2.96 KB
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
from typing import override
from scapy.all import (
Packet,
PacketField,
PacketListField,
ShortField,
StrFixedLenField,
StrLenField,
XByteField,
)
# Source: https://help.sap.com/doc/javadocs_nwce_ce711sp03/7.1.1.3/en-US/se/com.sap.se/com/sap/security/api/ticket/InfoUnit.html
ID_USER = 1
ID_CREATE_CLIENT = 2
ID_CREATE_NAME = 3
ID_CREATE_TIME = 4
ID_VALID_TIME = 5
ID_RFC = 6
ID_VALID_TIME_MIN = 7
ID_FLAGS = 8
ID_LANGUAGE = 9
ID_USER_UTF = 10
ID_CREATE_CLIENT_UTF = 11
ID_CREATE_NAME_UTF = 12
ID_CREATE_TIME_UTF = 13
ID_LANGUAGE_UTF = 14
ID_RECIPIENT_CLIENT = 15
ID_RECIPIENT_SID = 16
ID_AUTHSCHEME = 136
ID_SIGNATURE = 255
class SAPInfoUnit(Packet):
"""
Represents a single information unit within the SAP Logon Ticket data.
Corresponds to the structure created by the addField() method in the Java code
after hex decoding: ID (1 byte), Length (2 bytes), Value (variable bytes).
For more information, see:
- https://help.sap.com/doc/javadocs_nwce_ce711sp03/7.1.1.3/en-US/se/com.sap.se/com/sap/security/api/ticket/InfoUnit.html
- https://help.sap.com/doc/javadocs_nwce_ce71/7.1/en-US/se/constant-values.html
"""
name = "SAPInfoUnit"
fields_desc = [
XByteField("unit_id", 0),
ShortField("unit_length", None), # Length of unit_value in bytes
StrLenField("unit_value", b"", length_from=lambda pkt: pkt.unit_length),
]
@override
def extract_padding(self, s):
return b"", s
def _info_units_cbk(
_pkt: Packet,
_lst: list[Packet],
_cur: Packet | None,
remain: bytes,
) -> type[Packet] | None:
if remain[0] == 0xFF:
return None
else:
return SAPInfoUnit
class SAPLogonTicketDataToSign(Packet):
"""
Represents the portion of the SAP Logon Ticket that gets signed.
Corresponds to the byte array generated by buildDataToSign() and toByteArray() in Java.
Structure: Preamble | TargetSystemCodepage | InfoUnit1 | InfoUnit2 | ...
"""
target_system_codepage: str
"""For Unicode SAP systems, the system code page depends on the platform byte order: 4103 (UTF-16 LE) 4102 (UTF-16 BE)"""
name = "SAPLogonTicketDataToSign"
fields_desc = [
XByteField("preamble", 0x02),
StrFixedLenField("target_system_codepage", "4103", 4),
PacketListField("info_units", [], next_cls_cb=_info_units_cbk),
]
@override
def extract_padding(self, s):
return b"", s
class SAPLogonTicket(Packet):
"""
Represents the complete SAP Logon Ticket structure before Base64 encoding.
Structure: DataToSign | SignatureMarker (0xFF) | SignatureLength | PKCS7_Signature
"""
name = "SAPLogonTicket"
fields_desc = [
PacketField("data_to_sign", None, SAPLogonTicketDataToSign),
XByteField("signature_marker", ID_SIGNATURE),
ShortField("signature_data_len", None),
StrLenField(
"pkcs7_signature", b"", length_from=lambda pkt: pkt.signature_data_len
),
]