diff options
-rw-r--r-- | Makefile.am | 4 | ||||
-rw-r--r-- | spnego.c | 90 | ||||
-rw-r--r-- | spnego.h | 3 |
3 files changed, 95 insertions, 2 deletions
diff --git a/Makefile.am b/Makefile.am index 21dd012..648758e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -3,5 +3,5 @@ root_sbin_PROGRAMS = mount.cifs mount_cifs_SOURCES = mount.cifs.c mtab.c sbin_PROGRAMS = cifs.upcall -cifs_upcall_SOURCES = cifs.upcall.c data_blob.c asn1.c -cifs_upcall_LDADD = ltalloc +cifs_upcall_SOURCES = cifs.upcall.c data_blob.c asn1.c spnego.c +cifs_upcall_LDADD = -ltalloc -lkrb5 diff --git a/spnego.c b/spnego.c new file mode 100644 index 0000000..cf9f39c --- /dev/null +++ b/spnego.c @@ -0,0 +1,90 @@ + +#include <talloc.h> +#include <stdint.h> + +#include "replace.h" +#include "data_blob.h" +#include "asn1.h" +#include "spnego.h" + +/* + generate a krb5 GSS-API wrapper packet given a ticket +*/ +DATA_BLOB spnego_gen_krb5_wrap(const DATA_BLOB ticket, const uint8_t tok_id[2]) +{ + ASN1_DATA *data; + DATA_BLOB ret; + + data = asn1_init(talloc_init("gssapi")); + if (data == NULL) { + return data_blob_null; + } + + asn1_push_tag(data, ASN1_APPLICATION(0)); + asn1_write_OID(data, OID_KERBEROS5); + + asn1_write(data, tok_id, 2); + asn1_write(data, ticket.data, ticket.length); + asn1_pop_tag(data); + +#if 0 + if (data->has_error) { + DEBUG(1,("Failed to build krb5 wrapper at offset %d\n", (int)data->ofs)); + } +#endif + + ret = data_blob(data->data, data->length); + asn1_free(data); + + return ret; +} + +/* + Generate a negTokenInit as used by the client side ... It has a mechType + (OID), and a mechToken (a security blob) ... + + Really, we need to break out the NTLMSSP stuff as well, because it could be + raw in the packets! +*/ +DATA_BLOB gen_negTokenInit(const char *OID, DATA_BLOB blob) +{ + ASN1_DATA *data; + DATA_BLOB ret; + + data = asn1_init(talloc_init("spnego")); + if (data == NULL) { + return data_blob_null; + } + + asn1_push_tag(data, ASN1_APPLICATION(0)); + asn1_write_OID(data,OID_SPNEGO); + asn1_push_tag(data, ASN1_CONTEXT(0)); + asn1_push_tag(data, ASN1_SEQUENCE(0)); + + asn1_push_tag(data, ASN1_CONTEXT(0)); + asn1_push_tag(data, ASN1_SEQUENCE(0)); + asn1_write_OID(data, OID); + asn1_pop_tag(data); + asn1_pop_tag(data); + + asn1_push_tag(data, ASN1_CONTEXT(2)); + asn1_write_OctetString(data,blob.data,blob.length); + asn1_pop_tag(data); + + asn1_pop_tag(data); + asn1_pop_tag(data); + + asn1_pop_tag(data); + +#if 0 + if (data->has_error) { + DEBUG(1,("Failed to build negTokenInit at offset %d\n", (int)data->ofs)); + } +#endif + + ret = data_blob(data->data, data->length); + asn1_free(data); + + return ret; +} + @@ -14,4 +14,7 @@ #define TOK_ID_GSS_GETMIC (unsigned char *)"\x01\x01" #define TOK_ID_GSS_WRAP (unsigned char *)"\x02\x01" +extern DATA_BLOB gen_negTokenInit(const char *OID, DATA_BLOB blob); +extern DATA_BLOB spnego_gen_krb5_wrap(const DATA_BLOB ticket, const uint8_t tok_id[2]); + #endif /* _SPNEGO_H */ |