diff options
Diffstat (limited to 'source3/libsmb/clispnego.c')
-rw-r--r-- | source3/libsmb/clispnego.c | 124 |
1 files changed, 60 insertions, 64 deletions
diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index 3e28baa417..55f49c5987 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -387,6 +387,51 @@ BOOL spnego_parse_challenge(DATA_BLOB blob, /* + generate a spnego NTLMSSP challenge packet given two security blobs + The second challenge is optional +*/ +BOOL spnego_gen_challenge(DATA_BLOB *blob, + DATA_BLOB *chal1, DATA_BLOB *chal2) +{ + ASN1_DATA data; + + ZERO_STRUCT(data); + + asn1_push_tag(&data,ASN1_CONTEXT(1)); + asn1_push_tag(&data,ASN1_SEQUENCE(0)); + + asn1_push_tag(&data,ASN1_CONTEXT(0)); + asn1_write_enumerated(&data,1); + asn1_pop_tag(&data); + + asn1_push_tag(&data,ASN1_CONTEXT(1)); + asn1_write_OID(&data, OID_NTLMSSP); + asn1_pop_tag(&data); + + asn1_push_tag(&data,ASN1_CONTEXT(2)); + asn1_write_OctetString(&data, chal1->data, chal1->length); + asn1_pop_tag(&data); + + /* the second challenge is optional (XP doesn't send it) */ + if (chal2) { + asn1_push_tag(&data,ASN1_CONTEXT(3)); + asn1_write_OctetString(&data, chal2->data, chal2->length); + asn1_pop_tag(&data); + } + + asn1_pop_tag(&data); + asn1_pop_tag(&data); + + if (data.has_error) { + return False; + } + + *blob = data_blob(data.data, data.length); + asn1_free(&data); + return True; +} + +/* generate a SPNEGO NTLMSSP auth packet. This will contain the encrypted passwords */ DATA_BLOB spnego_gen_auth(DATA_BLOB blob) @@ -440,37 +485,18 @@ BOOL spnego_parse_auth(DATA_BLOB blob, DATA_BLOB *auth) /* generate a minimal SPNEGO NTLMSSP response packet. Doesn't contain much. */ -DATA_BLOB spnego_gen_auth_response(DATA_BLOB *ntlmssp_reply, NTSTATUS nt_status) +DATA_BLOB spnego_gen_auth_response(void) { ASN1_DATA data; DATA_BLOB ret; - uint8 negResult; - - if (NT_STATUS_IS_OK(nt_status)) { - negResult = SPNGEO_NEG_RESULT_ACCEPT; - } else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - negResult = SPNGEO_NEG_RESULT_INCOMPLETE; - } else { - negResult = SPNGEO_NEG_RESULT_REJECT; - } - ZERO_STRUCT(data); + memset(&data, 0, sizeof(data)); asn1_push_tag(&data, ASN1_CONTEXT(1)); asn1_push_tag(&data, ASN1_SEQUENCE(0)); asn1_push_tag(&data, ASN1_CONTEXT(0)); - asn1_write_enumerated(&data, negResult); + asn1_write_enumerated(&data, 0); asn1_pop_tag(&data); - if (negResult == SPNGEO_NEG_RESULT_INCOMPLETE) { - asn1_push_tag(&data,ASN1_CONTEXT(1)); - asn1_write_OID(&data, OID_NTLMSSP); - asn1_pop_tag(&data); - - asn1_push_tag(&data,ASN1_CONTEXT(2)); - asn1_write_OctetString(&data, ntlmssp_reply->data, ntlmssp_reply->length); - asn1_pop_tag(&data); - } - asn1_pop_tag(&data); asn1_pop_tag(&data); @@ -488,9 +514,8 @@ DATA_BLOB spnego_gen_auth_response(DATA_BLOB *ntlmssp_reply, NTSTATUS nt_status) format specifiers are: U = unicode string (input is unix string) - a = address (input is BOOL unicode, char *unix_string) - (1 byte type, 1 byte length, unicode/ASCII string, all inline) - A = ASCII string (input is unix string) + a = address (1 byte type, 1 byte length, unicode string, all inline) + A = ASCII string (pointer + length) Actually same as B B = data blob (pointer + length) b = data blob in header (pointer + length) D @@ -506,7 +531,6 @@ BOOL msrpc_gen(DATA_BLOB *blob, uint8 *b; int head_size=0, data_size=0; int head_ofs, data_ofs; - BOOL unicode; /* first scan the format to work out the header and body size */ va_start(ap, format); @@ -517,21 +541,12 @@ BOOL msrpc_gen(DATA_BLOB *blob, head_size += 8; data_size += str_charnum(s) * 2; break; - case 'A': - s = va_arg(ap, char *); - head_size += 8; - data_size += str_ascii_charnum(s); - break; case 'a': - unicode = va_arg(ap, BOOL); n = va_arg(ap, int); s = va_arg(ap, char *); - if (unicode) { - data_size += (str_charnum(s) * 2) + 4; - } else { - data_size += (str_ascii_charnum(s)) + 4; - } + data_size += (str_charnum(s) * 2) + 4; break; + case 'A': case 'B': b = va_arg(ap, uint8 *); head_size += 8; @@ -571,39 +586,20 @@ BOOL msrpc_gen(DATA_BLOB *blob, push_string(NULL, blob->data+data_ofs, s, n*2, STR_UNICODE|STR_NOALIGN); data_ofs += n*2; break; - case 'A': - s = va_arg(ap, char *); - n = str_ascii_charnum(s); - SSVAL(blob->data, head_ofs, n); head_ofs += 2; - SSVAL(blob->data, head_ofs, n); head_ofs += 2; - SIVAL(blob->data, head_ofs, data_ofs); head_ofs += 4; - push_string(NULL, blob->data+data_ofs, s, n, STR_ASCII|STR_NOALIGN); - data_ofs += n; - break; case 'a': - unicode = va_arg(ap, BOOL); n = va_arg(ap, int); SSVAL(blob->data, data_ofs, n); data_ofs += 2; s = va_arg(ap, char *); - if (unicode) { - n = str_charnum(s); - SSVAL(blob->data, data_ofs, n*2); data_ofs += 2; - if (0 < n) { - push_string(NULL, blob->data+data_ofs, s, n*2, - STR_UNICODE|STR_NOALIGN); - } - data_ofs += n*2; - } else { - n = str_ascii_charnum(s); - SSVAL(blob->data, data_ofs, n); data_ofs += 2; - if (0 < n) { - push_string(NULL, blob->data+data_ofs, s, n, - STR_ASCII|STR_NOALIGN); - } - data_ofs += n; + n = str_charnum(s); + SSVAL(blob->data, data_ofs, n*2); data_ofs += 2; + if (0 < n) { + push_string(NULL, blob->data+data_ofs, s, n*2, + STR_UNICODE|STR_NOALIGN); } + data_ofs += n*2; break; + case 'A': case 'B': b = va_arg(ap, uint8 *); n = va_arg(ap, int); @@ -718,7 +714,7 @@ BOOL msrpc_parse(DATA_BLOB *blob, break; case 'C': s = va_arg(ap, char *); - head_ofs += pull_string(NULL, p, blob->data+head_ofs, sizeof(p), + head_ofs += pull_string(NULL, p, blob->data+head_ofs, -1, blob->length - head_ofs, STR_ASCII|STR_TERMINATE); if (strcmp(s, p) != 0) { |