예제 #1
0
def test_unpack_krb_ap_rep():
    data = get_data('initial_context_token_krb_ap_rep')

    actual = sp.unpack_token(data)
    assert actual == data

    actual = sp.unpack_token(data, unwrap=True)

    assert isinstance(actual, sp.InitialContextToken)
    assert actual.this_mech == GSSMech.kerberos.value

    actual = actual.token

    assert isinstance(actual, kerb.KrbApRep)
    assert actual.PVNO == 5
    assert actual.MESSAGE_TYPE == kerb.KerberosMessageType.ap_rep
    assert isinstance(actual.enc_part.cipher, bytes)
    assert actual.enc_part.etype == kerb.KerberosEncryptionType.aes256_cts_hmac_sha1_96
    assert actual.enc_part.kvno is None

    # Test pyspnego-parse dict.
    actual = kerb.parse_kerberos_token(actual)
    assert actual['pvno'] == 5
    assert actual['msg-type'] == 'AP-REP (15)'
    assert actual['enc-part']['etype'] == 'AES256_CTS_HMAC_SHA1_96 (18)'
    assert actual['enc-part']['kvno'] is None
    assert isinstance(actual['enc-part']['cipher'], text_type)
예제 #2
0
def test_unpack_ntlm():
    data = get_data('ntlm_challenge')
    actual = sp.unpack_token(data)

    assert actual == data

    actual = sp.unpack_token(data, unwrap=True)
    assert isinstance(actual, Challenge)
    assert actual.MESSAGE_TYPE == MessageType.challenge
예제 #3
0
def test_unpack_krb_ap_rep():
    data = get_data('initial_context_token_krb_ap_rep')
    actual = sp.unpack_token(data)

    assert actual == data

    actual = sp.unpack_token(data, unwrap=True)
    assert isinstance(actual, sp.InitialContextToken)
    assert actual.this_mech == GSSMech.kerberos.value
    assert isinstance(actual.token, KrbApRep)
예제 #4
0
def test_unpack_neg_token_resp():
    data = get_data('neg_token_resp')
    actual = sp.unpack_token(data)

    assert isinstance(actual, sp.NegTokenResp)
    assert actual.mech_list_mic is None
    assert actual.neg_state == sp.NegState.accept_complete
    assert isinstance(actual.response_token, bytes)
    assert actual.supported_mech == GSSMech.kerberos.value

    actual = sp.unpack_token(data, unwrap=True)
    assert isinstance(actual, sp.NegTokenResp)
예제 #5
0
def test_unpack_krb_tgs_rep():
    data = get_data('krb_tgs_rep')

    actual = sp.unpack_token(data)
    assert actual == data

    actual = sp.unpack_token(data, unwrap=True)

    assert isinstance(actual, kerb.KrbTgsRep)
    assert actual.PVNO == 5
    assert actual.MESSAGE_TYPE == kerb.KerberosMessageType.tgs_rep
    assert actual.cname == kerb.PrincipalName(
        kerb.KerberosPrincipalNameType.principal, [b'vagrant-domain'])
    assert actual.crealm == b'DOMAIN.LOCAL'

    assert isinstance(actual.enc_part.cipher, bytes)
    assert actual.enc_part.etype == kerb.KerberosEncryptionType.aes256_cts_hmac_sha1_96
    assert actual.enc_part.kvno is None

    assert actual.padata is None

    assert isinstance(actual.ticket.enc_part.cipher, bytes)
    assert actual.ticket.enc_part.etype == kerb.KerberosEncryptionType.aes256_cts_hmac_sha1_96
    assert actual.ticket.enc_part.kvno == 6
    assert actual.ticket.realm == b'DOMAIN.LOCAL'
    assert actual.ticket.sname == kerb.PrincipalName(
        kerb.KerberosPrincipalNameType.srv_hst,
        [b'HTTP', b'server2019.domain.local'])
    assert actual.ticket.tkt_vno == 5

    # Test pyspnego-parse dict.
    actual = kerb.parse_kerberos_token(actual)
    assert actual['pvno'] == 5
    assert actual['msg-type'] == 'TGS-REP (13)'
    assert actual['padata'] is None
    assert actual['crealm'] == 'DOMAIN.LOCAL'
    assert actual['cname']['name-type'] == 'NT-PRINCIPAL (1)'
    assert actual['cname']['name-string'] == ['vagrant-domain']
    assert actual['ticket']['tkt-vno'] == 5
    assert actual['ticket']['realm'] == 'DOMAIN.LOCAL'
    assert actual['ticket']['sname']['name-type'] == 'NT-SRV-HST (3)'
    assert actual['ticket']['sname']['name-string'] == [
        'HTTP', 'server2019.domain.local'
    ]
    assert actual['ticket']['enc-part'][
        'etype'] == 'AES256_CTS_HMAC_SHA1_96 (18)'
    assert actual['ticket']['enc-part']['kvno'] == 6
    assert isinstance(actual['ticket']['enc-part']['cipher'], text_type)
    assert actual['enc-part']['etype'] == 'AES256_CTS_HMAC_SHA1_96 (18)'
    assert actual['enc-part']['kvno'] is None
    assert isinstance(actual['enc-part']['cipher'], text_type)
예제 #6
0
def test_pack_neg_token_init2():
    token = sp.NegTokenInit(
        [GSSMech.kerberos.value, GSSMech.ntlm.value],
        sp.ContextFlags.anon,
        mech_token=b"\x00\x00\x00\x00",
        hint_name=b"spn",
        hint_address=b"not_defined_in_RFC4178@please_ignore",
        mech_list_mic=b"\x01\x01\x01\x01")

    actual = token.pack()

    assert actual == b"\x60\x70\x06\x06\x2B\x06\x01\x05\x05\x02\xA0\x66\x30\x64\xA0\x19" \
                     b"\x30\x17\x06\x09\x2A\x86\x48\x86\xF7\x12\x01\x02\x02\x06\x0A\x2B" \
                     b"\x06\x01\x04\x01\x82\x37\x02\x02\x0A\xA1\x04\x03\x02\x00\x04\xA2" \
                     b"\x06\x04\x04\x00\x00\x00\x00\xA3\x31\x30\x2F\xA0\x05\x1B\x03\x73" \
                     b"\x70\x6E\xA1\x26\x04\x24\x6E\x6F\x74\x5F\x64\x65\x66\x69\x6E\x65" \
                     b"\x64\x5F\x69\x6E\x5F\x52\x46\x43\x34\x31\x37\x38\x40\x70\x6C\x65" \
                     b"\x61\x73\x65\x5F\x69\x67\x6E\x6F\x72\x65\xA4\x06\x04\x04\x01\x01" \
                     b"\x01\x01"

    token = sp.unpack_token(actual)
    assert token.mech_types == [
        '1.2.840.113554.1.2.2', '1.3.6.1.4.1.311.2.2.10'
    ]
    assert token.req_flags == sp.ContextFlags.deleg
    assert token.mech_token == b"\x00\x00\x00\x00"
    assert token.hint_name == b"spn"
    assert token.hint_address == b"not_defined_in_RFC4178@please_ignore"
    assert token.mech_list_mic == b"\x01\x01\x01\x01"
예제 #7
0
def test_unpack_initial_context_token_unknown_mech():
    data = pack_asn1(
        TagClass.application, True, 0,
        pack_asn1_object_identifier('1.2.3.4.5') + b"\x00\x00\x00\x00")
    token = sp.unpack_token(data)

    assert token == data
예제 #8
0
def test_unpack_krb_ap_req():
    data = get_data('initial_context_token_krb_ap_req')

    actual = sp.unpack_token(data)
    assert actual == data

    actual = sp.unpack_token(data, unwrap=True)

    assert isinstance(actual, sp.InitialContextToken)
    assert actual.this_mech == GSSMech.kerberos.value

    actual = actual.token

    assert isinstance(actual, kerb.KrbApReq)
    assert actual.PVNO == 5
    assert actual.MESSAGE_TYPE == kerb.KerberosMessageType.ap_req
    assert actual.ap_options == kerb.KerberosAPOptions.mutual_required
    assert isinstance(actual.authenticator.cipher, bytes)
    assert actual.authenticator.etype == kerb.KerberosEncryptionType.aes256_cts_hmac_sha1_96
    assert actual.authenticator.kvno is None
    assert isinstance(actual.ticket.enc_part.cipher, bytes)
    assert actual.ticket.enc_part.etype == kerb.KerberosEncryptionType.aes256_cts_hmac_sha1_96
    assert actual.ticket.enc_part.kvno == 6
    assert actual.ticket.realm == b'DOMAIN.LOCAL'
    assert actual.ticket.sname == kerb.PrincipalName(
        kerb.KerberosPrincipalNameType.srv_hst, [b'host', b'dc01'])
    assert actual.ticket.tkt_vno == 5

    # Test pyspnego-parse dict.
    actual = kerb.parse_kerberos_token(actual)
    assert actual['pvno'] == 5
    assert actual['msg-type'] == 'AP-REQ (14)'
    assert actual['ap-options']['raw'] == 32
    assert actual['ap-options']['flags'] == ['mutual-required (32)']
    assert actual['ticket']['tkt-vno'] == 5
    assert actual['ticket']['realm'] == 'DOMAIN.LOCAL'
    assert actual['ticket']['sname']['name-type'] == 'NT-SRV-HST (3)'
    assert actual['ticket']['sname']['name-string'] == ['host', 'dc01']
    assert actual['ticket']['enc-part'][
        'etype'] == 'AES256_CTS_HMAC_SHA1_96 (18)'
    assert actual['ticket']['enc-part']['kvno'] == 6
    assert isinstance(actual['ticket']['enc-part']['cipher'], text_type)
    assert actual['authenticator']['etype'] == 'AES256_CTS_HMAC_SHA1_96 (18)'
    assert actual['authenticator']['kvno'] is None
    assert isinstance(actual['authenticator']['cipher'], text_type)
예제 #9
0
def test_unpack_krb_error():
    data = get_data('krb_error')

    actual = sp.unpack_token(data)
    assert actual == data

    actual = sp.unpack_token(data, unwrap=True)

    assert isinstance(actual, kerb.KrbError)
    assert actual.PVNO == 5
    assert actual.MESSAGE_TYPE == kerb.KerberosMessageType.error
    assert actual.cname is None
    assert actual.crealm is None
    assert actual.ctime is None
    assert actual.cusec is None
    assert isinstance(actual.e_data, bytes)
    assert actual.e_text is None
    assert actual.error_code == kerb.KerberosErrorCode.preauth_required
    assert actual.realm == b'DOMAIN.LOCAL'
    assert actual.sname == kerb.PrincipalName(
        kerb.KerberosPrincipalNameType.srv_inst, [b'krbtgt', b'DOMAIN.LOCAL'])
    assert actual.stime == datetime.datetime(2020,
                                             6,
                                             13,
                                             21,
                                             4,
                                             23,
                                             tzinfo=UTC())
    assert actual.susec == 748591

    actual = kerb.parse_kerberos_token(actual, encoding='utf-8')
    assert actual['pvno'] == 5
    assert actual['msg-type'] == 'KRB-ERROR (30)'
    assert actual['ctime'] is None
    assert actual['cusec'] is None
    assert actual['stime'] == '2020-06-13T21:04:23+00:00'
    assert actual['susec'] == 748591
    assert actual['error-code'] == 'KDC_ERR_PREAUTH_REQUIRED (25)'
    assert actual['crealm'] is None
    assert actual['cname'] is None
    assert actual['realm'] == 'DOMAIN.LOCAL'
    assert actual['sname']['name-type'] == 'NT-SRV-INST (2)'
    assert actual['sname']['name-string'] == ['krbtgt', 'DOMAIN.LOCAL']
    assert actual['e-text'] is None
    assert isinstance(actual['e-data'], text_type)
예제 #10
0
def test_unpack_neg_token_init():
    data = get_data('initial_context_token_neg_token_init')
    actual = sp.unpack_token(data)

    assert isinstance(actual, sp.NegTokenInit)
    assert actual.hint_address is None
    assert actual.hint_name is None
    assert actual.mech_list_mic is None
    assert isinstance(actual.mech_token, bytes)
    assert actual.mech_types == [
        '1.2.840.113554.1.2.2', '1.3.6.1.4.1.311.2.2.10'
    ]
    assert actual.req_flags is None

    actual = sp.unpack_token(data, unwrap=True)
    assert isinstance(actual, sp.InitialContextToken)
    assert actual.this_mech == GSSMech.spnego.value
    assert isinstance(actual.token, sp.NegTokenInit)
예제 #11
0
def test_unpack_neg_token_init2():
    data = get_data('initial_context_token_neg_token_init2')
    actual = sp.unpack_token(data)

    assert isinstance(actual, sp.NegTokenInit)
    assert actual.hint_address is None
    assert actual.hint_name == b'not_defined_in_RFC4178@please_ignore'
    assert actual.mech_list_mic is None
    assert actual.mech_token is None
    assert actual.mech_types == [
        '1.3.6.1.4.1.311.2.2.30', '1.2.840.48018.1.2.2',
        '1.2.840.113554.1.2.2', '1.2.840.113554.1.2.2.3',
        '1.3.6.1.4.1.311.2.2.10'
    ]
    assert actual.req_flags is None

    actual = sp.unpack_token(data, unwrap=True)
    assert isinstance(actual, sp.InitialContextToken)
    assert actual.this_mech == GSSMech.spnego.value
    assert isinstance(actual.token, sp.NegTokenInit)
예제 #12
0
def test_pack_neg_token_resp():
    token = sp.NegTokenResp(sp.NegState.request_mic, GSSMech.ntlm.value,
                            b"\x00\x00\x00\x00", b"\x01\x01\x01\x01")

    actual = token.pack()
    assert actual == b"\xA1\x25\x30\x23\xA0\x03\x0A\x01\x03\xA1\x0C\x06\x0A\x2B\x06\x01" \
                     b"\x04\x01\x82\x37\x02\x02\x0A\xA2\x06\x04\x04\x00\x00\x00\x00\xA3" \
                     b"\x06\x04\x04\x01\x01\x01\x01"

    token = sp.unpack_token(actual)
    assert token.neg_state == sp.NegState.request_mic
    assert token.supported_mech == GSSMech.ntlm.value
    assert token.response_token == b"\x00\x00\x00\x00"
    assert token.mech_list_mic == b"\x01\x01\x01\x01"
예제 #13
0
def test_unpack_unknown_krb():
    sequence = pack_asn1_sequence([
        pack_asn1(TagClass.context_specific, True, 0, pack_asn1_integer(5)),
        pack_asn1(TagClass.context_specific, True, 1, pack_asn1_integer(0)),
    ])
    actual = sp.unpack_token(sequence, unwrap=True)

    assert isinstance(actual, kerb.KerberosV5Msg)
    assert actual.PVNO == 5
    assert isinstance(actual.sequence, dict)

    assert actual.sequence[0].tag_class == TagClass.universal
    assert not actual.sequence[0].constructed
    assert actual.sequence[0].tag_number == TypeTagNumber.integer
    assert actual.sequence[0].b_data == b'\x05'

    assert actual.sequence[1].tag_class == TagClass.universal
    assert not actual.sequence[1].constructed
    assert actual.sequence[1].tag_number == TypeTagNumber.integer
    assert actual.sequence[1].b_data == b'\x00'
예제 #14
0
def test_pack_neg_token_init():
    token = sp.NegTokenInit([GSSMech.kerberos.value, GSSMech.ntlm.value],
                            sp.ContextFlags.anon,
                            b"\x00\x00\x00\x00",
                            mech_list_mic=b"\x01\x01\x01\x01")

    actual = token.pack()
    assert actual == b"\x60\x3D\x06\x06\x2B\x06\x01\x05\x05\x02\xA0\x33\x30\x31\xA0\x19" \
                     b"\x30\x17\x06\x09\x2A\x86\x48\x86\xF7\x12\x01\x02\x02\x06\x0A\x2B" \
                     b"\x06\x01\x04\x01\x82\x37\x02\x02\x0A\xA1\x04\x03\x02\x00\x04\xA2" \
                     b"\x06\x04\x04\x00\x00\x00\x00\xA3\x06\x04\x04\x01\x01\x01\x01"

    token = sp.unpack_token(actual)
    assert token.mech_types == [
        '1.2.840.113554.1.2.2', '1.3.6.1.4.1.311.2.2.10'
    ]
    assert token.req_flags == sp.ContextFlags.deleg
    assert token.mech_token == b"\x00\x00\x00\x00"
    assert token.hint_name is None
    assert token.hint_address is None
    assert token.mech_list_mic == b"\x01\x01\x01\x01"
예제 #15
0
def test_unpack_krb_as_rep():
    data = get_data('krb_as_rep')

    actual = sp.unpack_token(data)
    assert actual == data

    actual = sp.unpack_token(data, unwrap=True)

    assert isinstance(actual, kerb.KrbAsRep)
    assert actual.PVNO == 5
    assert actual.MESSAGE_TYPE == kerb.KerberosMessageType.as_rep
    assert actual.cname == kerb.PrincipalName(
        kerb.KerberosPrincipalNameType.principal, [b'vagrant-domain'])
    assert actual.crealm == b'DOMAIN.LOCAL'

    assert isinstance(actual.enc_part.cipher, bytes)
    assert actual.enc_part.etype == kerb.KerberosEncryptionType.aes256_cts_hmac_sha1_96
    assert actual.enc_part.kvno == 11

    assert isinstance(actual.padata, list)
    assert len(actual.padata) == 1
    assert actual.padata[0].data_type == kerb.KerberosPADataType.etype_info2
    assert actual.padata[0].b_value == b"\x30\x25\x30\x23\xA0\x03\x02\x01\x12\xA1\x1C\x1B\x1A\x44\x4F\x4D" \
                                       b"\x41\x49\x4E\x2E\x4C\x4F\x43\x41\x4C\x76\x61\x67\x72\x61\x6E\x74" \
                                       b"\x2D\x64\x6F\x6D\x61\x69\x6E"
    pa1_val = actual.padata[0].value
    assert isinstance(pa1_val, list)
    assert len(pa1_val) == 1
    assert pa1_val[
        0].etype == kerb.KerberosEncryptionType.aes256_cts_hmac_sha1_96
    assert pa1_val[0].salt == b"DOMAIN.LOCALvagrant-domain"
    assert pa1_val[0].s2kparams is None

    assert isinstance(actual.ticket.enc_part.cipher, bytes)
    assert actual.ticket.enc_part.etype == kerb.KerberosEncryptionType.aes256_cts_hmac_sha1_96
    assert actual.ticket.enc_part.kvno == 2
    assert actual.ticket.realm == b'DOMAIN.LOCAL'
    assert actual.ticket.sname == kerb.PrincipalName(
        kerb.KerberosPrincipalNameType.srv_inst, [b'krbtgt', b'DOMAIN.LOCAL'])
    assert actual.ticket.tkt_vno == 5

    # Test pyspnego-parse dict.
    actual = kerb.parse_kerberos_token(actual)
    assert actual['pvno'] == 5
    assert actual['msg-type'] == 'AS-REP (11)'
    assert isinstance(actual['padata'], list)
    assert len(actual['padata']) == 1
    assert actual['padata'][0]['padata-type'] == 'PA-ETYPE-INFO2 (19)'
    assert isinstance(actual['padata'][0]['padata-value'], list)
    assert len(actual['padata'][0]['padata-value']) == 1
    assert actual['padata'][0]['padata-value'][0][
        'etype'] == 'AES256_CTS_HMAC_SHA1_96 (18)'
    assert actual['padata'][0]['padata-value'][0][
        'salt'] == '444F4D41494E2E4C4F43414C76616772616E742D646F6D61696E'
    assert actual['padata'][0]['padata-value'][0]['s2kparams'] is None
    assert actual['crealm'] == 'DOMAIN.LOCAL'
    assert actual['cname']['name-type'] == 'NT-PRINCIPAL (1)'
    assert actual['cname']['name-string'] == ['vagrant-domain']
    assert actual['ticket']['tkt-vno'] == 5
    assert actual['ticket']['realm'] == 'DOMAIN.LOCAL'
    assert actual['ticket']['sname']['name-type'] == 'NT-SRV-INST (2)'
    assert actual['ticket']['sname']['name-string'] == [
        'krbtgt', 'DOMAIN.LOCAL'
    ]
    assert actual['ticket']['enc-part'][
        'etype'] == 'AES256_CTS_HMAC_SHA1_96 (18)'
    assert actual['ticket']['enc-part']['kvno'] == 2
    assert isinstance(actual['ticket']['enc-part']['cipher'], text_type)
    assert actual['enc-part']['etype'] == 'AES256_CTS_HMAC_SHA1_96 (18)'
    assert actual['enc-part']['kvno'] == 11
    assert isinstance(actual['enc-part']['cipher'], text_type)
예제 #16
0
def test_unpack_krb_tgs_req():
    data = get_data('krb_tgs_req')

    actual = sp.unpack_token(data)
    assert actual == data

    actual = sp.unpack_token(data, unwrap=True)

    assert isinstance(actual, kerb.KrbTgsReq)
    assert actual.PVNO == 5
    assert actual.MESSAGE_TYPE == kerb.KerberosMessageType.tgs_req
    assert isinstance(actual.padata, list)
    assert len(actual.padata) == 1
    assert actual.padata[0].data_type == kerb.KerberosPADataType.tgs_req
    assert isinstance(actual.padata[0].b_value, bytes)

    pa1_val = actual.padata[0].value
    assert pa1_val.PVNO == 5
    assert pa1_val.MESSAGE_TYPE == kerb.KerberosMessageType.ap_req
    assert pa1_val.ap_options == 0
    assert isinstance(pa1_val.authenticator.cipher, bytes)
    assert pa1_val.authenticator.etype == kerb.KerberosEncryptionType.aes256_cts_hmac_sha1_96
    assert pa1_val.authenticator.kvno is None
    assert isinstance(pa1_val.ticket.enc_part.cipher, bytes)
    assert pa1_val.ticket.enc_part.etype == kerb.KerberosEncryptionType.aes256_cts_hmac_sha1_96
    assert pa1_val.ticket.enc_part.kvno == 2
    assert pa1_val.ticket.realm == b'DOMAIN.LOCAL'
    assert pa1_val.ticket.sname == kerb.PrincipalName(
        kerb.KerberosPrincipalNameType.srv_inst, [b'krbtgt', b'DOMAIN.LOCAL'])
    assert pa1_val.ticket.tkt_vno == 5

    assert actual.req_body.additional_tickets is None
    assert actual.req_body.addresses is None
    assert actual.req_body.cname is None
    assert actual.req_body.enc_authorization_data is None
    assert actual.req_body.etype == [
        kerb.KerberosEncryptionType.aes256_cts_hmac_sha1_96,
        kerb.KerberosEncryptionType.aes128_cts_hmac_sha1_96,
        kerb.KerberosEncryptionType.des3_cbc_sha1,
        kerb.KerberosEncryptionType.rc4_hmac
    ]
    assert actual.req_body.kdc_options == 1073807360
    assert actual.req_body.nonce == 333512069
    assert actual.req_body.postdated_from is None
    assert actual.req_body.postdated_till == datetime.datetime(1970,
                                                               1,
                                                               1,
                                                               0,
                                                               0,
                                                               0,
                                                               tzinfo=UTC())
    assert actual.req_body.realm == b'DOMAIN.LOCAL'
    assert actual.req_body.rtime is None
    assert actual.req_body.sname == kerb.PrincipalName(
        kerb.KerberosPrincipalNameType.srv_hst,
        [b'HTTP', b'server2019.domain.local'])

    # Test pyspnego-parse dict.
    actual = kerb.parse_kerberos_token(actual)
    assert actual['pvno'] == 5
    assert actual['msg-type'] == 'TGS-REQ (12)'
    assert isinstance(actual['padata'], list)
    assert len(actual['padata']) == 1
    assert actual['padata'][0]['padata-type'] == 'PA-TGS-REQ (1)'
    assert actual['padata'][0]['padata-value']['pvno'] == 5
    assert actual['padata'][0]['padata-value']['msg-type'] == 'AP-REQ (14)'
    assert actual['padata'][0]['padata-value']['ap-options']['raw'] == 0
    assert actual['padata'][0]['padata-value']['ap-options']['flags'] == []
    assert actual['padata'][0]['padata-value']['ticket']['tkt-vno'] == 5
    assert actual['padata'][0]['padata-value']['ticket'][
        'realm'] == 'DOMAIN.LOCAL'
    assert actual['padata'][0]['padata-value']['ticket']['sname'][
        'name-type'] == 'NT-SRV-INST (2)'
    assert actual['padata'][0]['padata-value']['ticket']['sname'][
        'name-string'] == ['krbtgt', 'DOMAIN.LOCAL']
    assert actual['padata'][0]['padata-value']['ticket']['enc-part'][
        'etype'] == 'AES256_CTS_HMAC_SHA1_96 (18)'
    assert actual['padata'][0]['padata-value']['ticket']['enc-part'][
        'kvno'] == 2
    assert isinstance(
        actual['padata'][0]['padata-value']['ticket']['enc-part']['cipher'],
        text_type)
    assert actual['padata'][0]['padata-value']['authenticator'][
        'etype'] == 'AES256_CTS_HMAC_SHA1_96 (18)'
    assert actual['padata'][0]['padata-value']['authenticator']['kvno'] is None
    assert isinstance(
        actual['padata'][0]['padata-value']['authenticator']['cipher'],
        text_type)
    assert actual['req-body']['kdc-options']['raw'] == 1073807360
    assert actual['req-body']['kdc-options']['flags'] == [
        'forwardable (1073741824)', 'canonicalize (65536)'
    ]
    assert actual['req-body']['cname'] is None
    assert actual['req-body']['realm'] == 'DOMAIN.LOCAL'
    assert actual['req-body']['sname']['name-type'] == 'NT-SRV-HST (3)'
    assert actual['req-body']['sname']['name-string'] == [
        'HTTP', 'server2019.domain.local'
    ]
    assert actual['req-body']['from'] is None
    assert actual['req-body']['till'] == '1970-01-01T00:00:00+00:00'
    assert actual['req-body']['rtime'] is None
    assert actual['req-body']['etype'] == [
        'AES256_CTS_HMAC_SHA1_96 (18)', 'AES128_CTS_HMAC_SHA1_96 (17)',
        'DES3_CBC_SHA1 (16)', 'RC4_HMAC (23)'
    ]
    assert actual['req-body']['addresses'] is None
    assert actual['req-body']['enc-authorization-data'] is None
    assert actual['req-body']['additional-tickets'] is None
예제 #17
0
def test_unpack_krb_as_req():
    data = get_data('krb_as_req')

    actual = sp.unpack_token(data)
    assert actual == data

    actual = sp.unpack_token(data, unwrap=True)

    assert isinstance(actual, kerb.KrbAsReq)
    assert actual.PVNO == 5
    assert actual.MESSAGE_TYPE == kerb.KerberosMessageType.as_req
    assert isinstance(actual.padata, list)
    assert len(actual.padata) == 2

    assert actual.padata[0].data_type == kerb.KerberosPADataType.enc_timestamp
    assert actual.padata[0].b_value == b"\x30\x41\xA0\x03\x02\x01\x12\xA2\x3A\x04\x38\x07\x40\x46\x03\xA8" \
                                       b"\x69\xC9\x31\x76\xE2\x8E\xDA\xD1\x34\xCE\x7F\xC4\xC8\x73\x58\x0D" \
                                       b"\xF4\x61\x1C\x85\x5F\x43\xF6\xAA\x9E\x48\xE2\xF0\x8C\xC2\x88\x70" \
                                       b"\xAA\xBC\xF0\xF7\xF2\xD4\xA2\xC2\xE3\x53\xDE\x81\xF7\x30\x2F\xAF" \
                                       b"\x7C\x85\x12"
    pa1_val = actual.padata[0].value
    assert isinstance(pa1_val, kerb.EncryptedData)
    assert pa1_val.etype == kerb.KerberosEncryptionType.aes256_cts_hmac_sha1_96
    assert pa1_val.kvno is None
    assert pa1_val.cipher == b"\x07\x40\x46\x03\xA8\x69\xC9\x31\x76\xE2\x8E\xDA\xD1\x34\xCE\x7F" \
                             b"\xC4\xC8\x73\x58\x0D\xF4\x61\x1C\x85\x5F\x43\xF6\xAA\x9E\x48\xE2" \
                             b"\xF0\x8C\xC2\x88\x70\xAA\xBC\xF0\xF7\xF2\xD4\xA2\xC2\xE3\x53\xDE" \
                             b"\x81\xF7\x30\x2F\xAF\x7C\x85\x12"

    assert actual.padata[1].data_type == 149
    assert actual.padata[1].b_value == b""
    assert actual.padata[1].value == b""

    assert isinstance(actual.req_body, kerb.KdcReqBody)
    assert actual.req_body.additional_tickets is None
    assert actual.req_body.addresses is None
    assert actual.req_body.cname == kerb.PrincipalName(
        kerb.KerberosPrincipalNameType.principal, [b'vagrant-domain'])
    assert actual.req_body.enc_authorization_data is None
    assert actual.req_body.etype == [
        kerb.KerberosEncryptionType.aes256_cts_hmac_sha1_96,
        kerb.KerberosEncryptionType.aes128_cts_hmac_sha1_96,
        kerb.KerberosEncryptionType.des3_cbc_sha1,
        kerb.KerberosEncryptionType.rc4_hmac
    ]
    assert actual.req_body.kdc_options == 1073741824
    assert actual.req_body.nonce == 734266074
    assert actual.req_body.postdated_from is None
    assert actual.req_body.postdated_till == datetime.datetime(2020,
                                                               6,
                                                               14,
                                                               7,
                                                               4,
                                                               20,
                                                               tzinfo=UTC())
    assert actual.req_body.realm == b'DOMAIN.LOCAL'
    assert actual.req_body.rtime is None
    assert actual.req_body.sname == kerb.PrincipalName(
        kerb.KerberosPrincipalNameType.srv_inst, [b'krbtgt', b'DOMAIN.LOCAL'])

    # Test pyspnego-parse dict.
    actual = kerb.parse_kerberos_token(actual)
    assert isinstance(actual, dict)
    assert actual['pvno'] == 5
    assert actual['msg-type'] == 'AS-REQ (10)'
    assert isinstance(actual['padata'], list)
    assert len(actual['padata']) == 2
    assert actual['padata'][0]['padata-type'] == 'PA-ENC-TIMESTAMP (2)'
    assert actual['padata'][0]['padata-value'][
        'etype'] == 'AES256_CTS_HMAC_SHA1_96 (18)'
    assert actual['padata'][0]['padata-value']['kvno'] is None
    assert actual['padata'][0]['padata-value']['cipher'] == '07404603A869C93176E28EDAD134CE7F' \
                                                            'C4C873580DF4611C855F43F6AA9E48E2' \
                                                            'F08CC28870AABCF0F7F2D4A2C2E353DE' \
                                                            '81F7302FAF7C8512'
    assert actual['padata'][1]['padata-type'] == 'PA-REQ-ENC-PA-REP (149)'
    assert actual['padata'][1]['padata-value'] == ''
    assert actual['req-body']['kdc-options']['raw'] == 1073741824
    assert actual['req-body']['kdc-options']['flags'] == [
        'forwardable (1073741824)'
    ]
    assert actual['req-body']['cname']['name-type'] == 'NT-PRINCIPAL (1)'
    assert actual['req-body']['cname']['name-string'] == ['vagrant-domain']
    assert actual['req-body']['realm'] == 'DOMAIN.LOCAL'
    assert actual['req-body']['sname']['name-type'] == 'NT-SRV-INST (2)'
    assert actual['req-body']['sname']['name-string'] == [
        'krbtgt', 'DOMAIN.LOCAL'
    ]
    assert actual['req-body']['from'] is None
    assert actual['req-body']['till'] == '2020-06-14T07:04:20+00:00'
    assert actual['req-body']['rtime'] is None
    assert actual['req-body']['nonce'] == 734266074
    assert actual['req-body']['etype'] == [
        'AES256_CTS_HMAC_SHA1_96 (18)', 'AES128_CTS_HMAC_SHA1_96 (17)',
        'DES3_CBC_SHA1 (16)', 'RC4_HMAC (23)'
    ]
    assert actual['req-body']['addresses'] is None
    assert actual['req-body']['enc-authorization-data'] is None
    assert actual['req-body']['additional-tickets'] is None
예제 #18
0
def test_unpack_initial_context_token_invalid_context_specific_tag():
    data = pack_asn1(TagClass.context_specific, True, 2, b"\x00\x00\x00\x00")

    expected = "Unknown NegotiationToken CHOICE 2, only expecting 0 or 1"
    with pytest.raises(ValueError, match=expected):
        sp.unpack_token(data)
예제 #19
0
def test_unpack_initial_context_token_invalid_application_tag():
    data = pack_asn1(TagClass.application, True, 1, b"\x00\x00\x00\x00")

    expected = "Expecting a tag number of 0 not 1 for InitialContextToken"
    with pytest.raises(ValueError, match=expected):
        sp.unpack_token(data)
예제 #20
0
    def _step_spnego_input(self, in_token=None):
        mech_list_mic = None
        token = None
        is_spnego = True

        if in_token:
            in_token = unpack_token(in_token)

            if isinstance(in_token, NegTokenInit):
                mech_list_mic = in_token.mech_list_mic
                token = in_token.mech_token

                # This is the first token of the exchange, we should build our context list based on the mechs the
                # opposite end supports.
                mech_list = self._rebuild_context_list(
                    mech_types=in_token.mech_types)

                if self.usage == 'initiate':
                    # If initiate processes a NegTokenInit2 token that's just used as a hint, use the actually
                    # supported mechs as the true mech list.
                    self._mech_list = mech_list

                else:
                    # If accept processes a NegTokenInit token we treat that as an actual init is sent so it does not
                    # send it's own and uses the initiate mech list as the true mech list.
                    self._init_sent = True
                    self._mech_list = in_token.mech_types

            elif isinstance(in_token, NegTokenResp):
                mech_list_mic = in_token.mech_list_mic
                token = in_token.response_token

                # If we have received the supported_mech then we don't need to send our own.
                if in_token.supported_mech:
                    if in_token.supported_mech != self._chosen_mech.value:
                        self._mic_required = True

                    self.__chosen_mech = GSSMech.from_oid(
                        in_token.supported_mech)
                    self._mech_sent = True

                # Raise exception if we are rejected and have no error info (mechToken) that will give us more info.
                if in_token.neg_state == NegState.reject and not token:
                    raise InvalidTokenError(
                        context_msg=
                        "Received SPNEGO rejection with no token error message"
                    )

                if in_token.neg_state == NegState.request_mic:
                    self._mic_required = True
                elif in_token.neg_state == NegState.accept_complete:
                    self._complete = True

            else:
                # This usually indicates the token is a raw NTLM or Kerberos token, return as is.
                is_spnego = False
                token = in_token

                self.__chosen_mech = GSSMech.ntlm if token.startswith(
                    b"NTLMSSP\x00") else GSSMech.kerberos

                if not self._context_list:
                    self._rebuild_context_list(
                        mech_types=[self.__chosen_mech.value])

        else:
            self._mech_list = self._rebuild_context_list()

        return token, mech_list_mic, is_spnego