int decode_negTokenInit(unsigned char *security_blob, int length, enum securityEnum *secType) { struct asn1_ctx ctx; unsigned char *end; unsigned char *sequence_end; unsigned long *oid = NULL; unsigned int cls, con, tag, oidlen, rc; bool use_ntlmssp = false; bool use_kerberos = false; bool use_mskerberos = false; *secType = NTLM; /* BB eventually make Kerberos or NLTMSSP the default*/ /* cifs_dump_mem(" Received SecBlob ", security_blob, length); */ asn1_open(&ctx, security_blob, length); /* GSSAPI header */ if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { cFYI(1, ("Error decoding negTokenInit header")); return 0; } else if ((cls != ASN1_APL) || (con != ASN1_CON) || (tag != ASN1_EOC)) { cFYI(1, ("cls = %d con = %d tag = %d", cls, con, tag)); return 0; } /* Check for SPNEGO OID -- remember to free obj->oid */ rc = asn1_header_decode(&ctx, &end, &cls, &con, &tag); if (rc) { if ((tag == ASN1_OJI) && (con == ASN1_PRI) && (cls == ASN1_UNI)) { rc = asn1_oid_decode(&ctx, end, &oid, &oidlen); if (rc) { rc = compare_oid(oid, oidlen, SPNEGO_OID, SPNEGO_OID_LEN); kfree(oid); } } else rc = 0; } /* SPNEGO OID not present or garbled -- bail out */ if (!rc) { cFYI(1, ("Error decoding negTokenInit header")); return 0; } if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { cFYI(1, ("Error decoding negTokenInit")); return 0; } else if ((cls != ASN1_CTX) || (con != ASN1_CON) || (tag != ASN1_EOC)) { cFYI(1, ("cls = %d con = %d tag = %d end = %p (%d) exit 0", cls, con, tag, end, *end)); return 0; } if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { cFYI(1, ("Error decoding negTokenInit")); return 0; } else if ((cls != ASN1_UNI) || (con != ASN1_CON) || (tag != ASN1_SEQ)) { cFYI(1, ("cls = %d con = %d tag = %d end = %p (%d) exit 1", cls, con, tag, end, *end)); return 0; } if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { cFYI(1, ("Error decoding 2nd part of negTokenInit")); return 0; } else if ((cls != ASN1_CTX) || (con != ASN1_CON) || (tag != ASN1_EOC)) { cFYI(1, ("cls = %d con = %d tag = %d end = %p (%d) exit 0", cls, con, tag, end, *end)); return 0; } if (asn1_header_decode (&ctx, &sequence_end, &cls, &con, &tag) == 0) { cFYI(1, ("Error decoding 2nd part of negTokenInit")); return 0; } else if ((cls != ASN1_UNI) || (con != ASN1_CON) || (tag != ASN1_SEQ)) { cFYI(1, ("cls = %d con = %d tag = %d end = %p (%d) exit 1", cls, con, tag, end, *end)); return 0; } while (!asn1_eoc_decode(&ctx, sequence_end)) { rc = asn1_header_decode(&ctx, &end, &cls, &con, &tag); if (!rc) { cFYI(1, ("Error decoding negTokenInit hdr exit2")); return 0; } if ((tag == ASN1_OJI) && (con == ASN1_PRI)) { if (asn1_oid_decode(&ctx, end, &oid, &oidlen)) { cFYI(1, ("OID len = %d oid = 0x%lx 0x%lx " "0x%lx 0x%lx", oidlen, *oid, *(oid + 1), *(oid + 2), *(oid + 3))); if (compare_oid(oid, oidlen, MSKRB5_OID, MSKRB5_OID_LEN) && !use_kerberos) use_mskerberos = true; else if (compare_oid(oid, oidlen, KRB5_OID, KRB5_OID_LEN) && !use_mskerberos) use_kerberos = true; else if (compare_oid(oid, oidlen, NTLMSSP_OID, NTLMSSP_OID_LEN)) use_ntlmssp = true; kfree(oid); } } else { cFYI(1, ("Should be an oid what is going on?")); } } if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { cFYI(1, ("Error decoding last part negTokenInit exit3")); return 0; } else if ((cls != ASN1_CTX) || (con != ASN1_CON)) { /* tag = 3 indicating mechListMIC */ cFYI(1, ("Exit 4 cls = %d con = %d tag = %d end = %p (%d)", cls, con, tag, end, *end)); return 0; } if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { cFYI(1, ("Error decoding last part negTokenInit exit5")); return 0; } else if ((cls != ASN1_UNI) || (con != ASN1_CON) || (tag != ASN1_SEQ)) { cFYI(1, ("cls = %d con = %d tag = %d end = %p (%d)", cls, con, tag, end, *end)); } if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { cFYI(1, ("Error decoding last part negTokenInit exit 7")); return 0; } else if ((cls != ASN1_CTX) || (con != ASN1_CON)) { cFYI(1, ("Exit 8 cls = %d con = %d tag = %d end = %p (%d)", cls, con, tag, end, *end)); return 0; } if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { cFYI(1, ("Error decoding last part negTokenInit exit9")); return 0; } else if ((cls != ASN1_UNI) || (con != ASN1_PRI) || (tag != ASN1_GENSTR)) { cFYI(1, ("Exit10 cls = %d con = %d tag = %d end = %p (%d)", cls, con, tag, end, *end)); return 0; } cFYI(1, ("Need to call asn1_octets_decode() function for %s", ctx.pointer)); /* is this UTF-8 or ASCII? */ if (use_kerberos) *secType = Kerberos; else if (use_mskerberos) *secType = MSKerberos; else if (use_ntlmssp) *secType = NTLMSSP; return 1; }
int decode_negTokenInit(unsigned char *security_blob, int length, struct TCP_Server_Info *server) { struct asn1_ctx ctx; unsigned char *end; unsigned char *sequence_end; unsigned long *oid = NULL; unsigned int cls, con, tag, oidlen, rc; /* cifs_dump_mem(" Received SecBlob ", security_blob, length); */ asn1_open(&ctx, security_blob, length); /* GSSAPI header */ if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { cFYI(1, "Error decoding negTokenInit header"); return 0; } else if ((cls != ASN1_APL) || (con != ASN1_CON) || (tag != ASN1_EOC)) { cFYI(1, "cls = %d con = %d tag = %d", cls, con, tag); return 0; } /* Check for SPNEGO OID -- remember to free obj->oid */ rc = asn1_header_decode(&ctx, &end, &cls, &con, &tag); if (rc) { if ((tag == ASN1_OJI) && (con == ASN1_PRI) && (cls == ASN1_UNI)) { rc = asn1_oid_decode(&ctx, end, &oid, &oidlen); if (rc) { rc = compare_oid(oid, oidlen, SPNEGO_OID, SPNEGO_OID_LEN); kfree(oid); } } else rc = 0; } /* SPNEGO OID not present or garbled -- bail out */ if (!rc) { cFYI(1, "Error decoding negTokenInit header"); return 0; } /* SPNEGO */ if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { cFYI(1, "Error decoding negTokenInit"); return 0; } else if ((cls != ASN1_CTX) || (con != ASN1_CON) || (tag != ASN1_EOC)) { cFYI(1, "cls = %d con = %d tag = %d end = %p (%d) exit 0", cls, con, tag, end, *end); return 0; } /* negTokenInit */ if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { cFYI(1, "Error decoding negTokenInit"); return 0; } else if ((cls != ASN1_UNI) || (con != ASN1_CON) || (tag != ASN1_SEQ)) { cFYI(1, "cls = %d con = %d tag = %d end = %p (%d) exit 1", cls, con, tag, end, *end); return 0; } /* sequence */ if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { cFYI(1, "Error decoding 2nd part of negTokenInit"); return 0; } else if ((cls != ASN1_CTX) || (con != ASN1_CON) || (tag != ASN1_EOC)) { cFYI(1, "cls = %d con = %d tag = %d end = %p (%d) exit 0", cls, con, tag, end, *end); return 0; } /* sequence of */ if (asn1_header_decode (&ctx, &sequence_end, &cls, &con, &tag) == 0) { cFYI(1, "Error decoding 2nd part of negTokenInit"); return 0; } else if ((cls != ASN1_UNI) || (con != ASN1_CON) || (tag != ASN1_SEQ)) { cFYI(1, "cls = %d con = %d tag = %d end = %p (%d) exit 1", cls, con, tag, end, *end); return 0; } /* list of security mechanisms */ while (!asn1_eoc_decode(&ctx, sequence_end)) { rc = asn1_header_decode(&ctx, &end, &cls, &con, &tag); if (!rc) { cFYI(1, "Error decoding negTokenInit hdr exit2"); return 0; } if ((tag == ASN1_OJI) && (con == ASN1_PRI)) { if (asn1_oid_decode(&ctx, end, &oid, &oidlen)) { cFYI(1, "OID len = %d oid = 0x%lx 0x%lx " "0x%lx 0x%lx", oidlen, *oid, *(oid + 1), *(oid + 2), *(oid + 3)); if (compare_oid(oid, oidlen, MSKRB5_OID, MSKRB5_OID_LEN)) server->sec_mskerberos = true; else if (compare_oid(oid, oidlen, KRB5U2U_OID, KRB5U2U_OID_LEN)) server->sec_kerberosu2u = true; else if (compare_oid(oid, oidlen, KRB5_OID, KRB5_OID_LEN)) server->sec_kerberos = true; else if (compare_oid(oid, oidlen, NTLMSSP_OID, NTLMSSP_OID_LEN)) server->sec_ntlmssp = true; kfree(oid); } } else { cFYI(1, "Should be an oid what is going on?"); } } <<<<<<< HEAD
int decode_negTokenInit(unsigned char *security_blob, int length, struct TCP_Server_Info *server) { struct asn1_ctx ctx; unsigned char *end; unsigned char *sequence_end; unsigned long *oid = NULL; unsigned int cls, con, tag, oidlen, rc; /* */ asn1_open(&ctx, security_blob, length); /* */ if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { cFYI(1, "Error decoding negTokenInit header"); return 0; } else if ((cls != ASN1_APL) || (con != ASN1_CON) || (tag != ASN1_EOC)) { cFYI(1, "cls = %d con = %d tag = %d", cls, con, tag); return 0; } /* */ rc = asn1_header_decode(&ctx, &end, &cls, &con, &tag); if (rc) { if ((tag == ASN1_OJI) && (con == ASN1_PRI) && (cls == ASN1_UNI)) { rc = asn1_oid_decode(&ctx, end, &oid, &oidlen); if (rc) { rc = compare_oid(oid, oidlen, SPNEGO_OID, SPNEGO_OID_LEN); kfree(oid); } } else rc = 0; } /* */ if (!rc) { cFYI(1, "Error decoding negTokenInit header"); return 0; } /* */ if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { cFYI(1, "Error decoding negTokenInit"); return 0; } else if ((cls != ASN1_CTX) || (con != ASN1_CON) || (tag != ASN1_EOC)) { cFYI(1, "cls = %d con = %d tag = %d end = %p (%d) exit 0", cls, con, tag, end, *end); return 0; } /* */ if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { cFYI(1, "Error decoding negTokenInit"); return 0; } else if ((cls != ASN1_UNI) || (con != ASN1_CON) || (tag != ASN1_SEQ)) { cFYI(1, "cls = %d con = %d tag = %d end = %p (%d) exit 1", cls, con, tag, end, *end); return 0; } /* */ if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { cFYI(1, "Error decoding 2nd part of negTokenInit"); return 0; } else if ((cls != ASN1_CTX) || (con != ASN1_CON) || (tag != ASN1_EOC)) { cFYI(1, "cls = %d con = %d tag = %d end = %p (%d) exit 0", cls, con, tag, end, *end); return 0; } /* */ if (asn1_header_decode (&ctx, &sequence_end, &cls, &con, &tag) == 0) { cFYI(1, "Error decoding 2nd part of negTokenInit"); return 0; } else if ((cls != ASN1_UNI) || (con != ASN1_CON) || (tag != ASN1_SEQ)) { cFYI(1, "cls = %d con = %d tag = %d end = %p (%d) exit 1", cls, con, tag, end, *end); return 0; } /* */ while (!asn1_eoc_decode(&ctx, sequence_end)) { rc = asn1_header_decode(&ctx, &end, &cls, &con, &tag); if (!rc) { cFYI(1, "Error decoding negTokenInit hdr exit2"); return 0; } if ((tag == ASN1_OJI) && (con == ASN1_PRI)) { if (asn1_oid_decode(&ctx, end, &oid, &oidlen)) { cFYI(1, "OID len = %d oid = 0x%lx 0x%lx " "0x%lx 0x%lx", oidlen, *oid, *(oid + 1), *(oid + 2), *(oid + 3)); if (compare_oid(oid, oidlen, MSKRB5_OID, MSKRB5_OID_LEN)) server->sec_mskerberos = true; else if (compare_oid(oid, oidlen, KRB5U2U_OID, KRB5U2U_OID_LEN)) server->sec_kerberosu2u = true; else if (compare_oid(oid, oidlen, KRB5_OID, KRB5_OID_LEN)) server->sec_kerberos = true; else if (compare_oid(oid, oidlen, NTLMSSP_OID, NTLMSSP_OID_LEN)) server->sec_ntlmssp = true; kfree(oid); } } else { cFYI(1, "Should be an oid what is going on?"); } } /* */ if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { /* */ if (ctx.error == ASN1_ERR_DEC_EMPTY) goto decode_negtoken_exit; cFYI(1, "Error decoding last part negTokenInit exit3"); return 0; } else if ((cls != ASN1_CTX) || (con != ASN1_CON)) { /* */ cFYI(1, "Exit 4 cls = %d con = %d tag = %d end = %p (%d)", cls, con, tag, end, *end); return 0; } /* */ if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { cFYI(1, "Error decoding last part negTokenInit exit5"); return 0; } else if ((cls != ASN1_UNI) || (con != ASN1_CON) || (tag != ASN1_SEQ)) { cFYI(1, "cls = %d con = %d tag = %d end = %p (%d)", cls, con, tag, end, *end); } /* */ if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { cFYI(1, "Error decoding last part negTokenInit exit 7"); return 0; } else if ((cls != ASN1_CTX) || (con != ASN1_CON)) { cFYI(1, "Exit 8 cls = %d con = %d tag = %d end = %p (%d)", cls, con, tag, end, *end); return 0; } /* */ if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { cFYI(1, "Error decoding last part negTokenInit exit9"); return 0; } else if ((cls != ASN1_UNI) || (con != ASN1_PRI) || (tag != ASN1_GENSTR)) { cFYI(1, "Exit10 cls = %d con = %d tag = %d end = %p (%d)", cls, con, tag, end, *end); return 0; } cFYI(1, "Need to call asn1_octets_decode() function for %s", ctx.pointer); /* */ decode_negtoken_exit: return 1; }