diff options
Diffstat (limited to 'source3/libsmb')
-rw-r--r-- | source3/libsmb/cliconnect.c | 7 | ||||
-rw-r--r-- | source3/libsmb/clikrb5.c | 122 | ||||
-rw-r--r-- | source3/libsmb/clispnego.c | 124 |
3 files changed, 185 insertions, 68 deletions
diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 389b7a1733..b758af41c4 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -465,8 +465,7 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, const char *user, neg_flags = NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_NEGOTIATE_128 | - NTLMSSP_NEGOTIATE_NTLM | - NTLMSSP_REQUEST_TARGET; + NTLMSSP_NEGOTIATE_NTLM; memset(sess_key, 0, 16); @@ -477,8 +476,8 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, const char *user, "NTLMSSP", NTLMSSP_NEGOTIATE, neg_flags, - workgroup, - cli->calling.name); + workgroup, strlen(workgroup), + cli->calling.name, strlen(cli->calling.name) + 1); DEBUG(10, ("neg_flags: %0X, workgroup: %s, calling name %s\n", neg_flags, workgroup, cli->calling.name)); /* and wrap it in a SPNEGO wrapper */ diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 2047efd704..203d9d874b 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -70,6 +70,128 @@ __ERROR__XX__UNKNOWN_ADDRTYPE #endif +#if defined(HAVE_KRB5_PRINCIPAL2SALT) && defined(HAVE_KRB5_USE_ENCTYPE) && defined(HAVE_KRB5_STRING_TO_KEY) + int create_kerberos_key_from_string(krb5_context context, + krb5_principal host_princ, + krb5_data *password, + krb5_keyblock *key) +{ + int ret; + krb5_data salt; + krb5_encrypt_block eblock; + + ret = krb5_principal2salt(context, host_princ, &salt); + if (ret) { + DEBUG(1,("krb5_principal2salt failed (%s)\n", error_message(ret))); + return ret; + } + krb5_use_enctype(context, &eblock, ENCTYPE_DES_CBC_MD5); + return krb5_string_to_key(context, &eblock, key, password, &salt); +} +#elif defined(HAVE_KRB5_GET_PW_SALT) && defined(HAVE_KRB5_STRING_TO_KEY_SALT) + int create_kerberos_key_from_string(krb5_context context, + krb5_principal host_princ, + krb5_data *password, + krb5_keyblock *key) +{ + int ret; + krb5_salt salt; + + ret = krb5_get_pw_salt(context, host_princ, &salt); + if (ret) { + DEBUG(1,("krb5_get_pw_salt failed (%s)\n", error_message(ret))); + return ret; + } + return krb5_string_to_key_salt(context, ENCTYPE_DES_CBC_MD5, password->data, + salt, key); +} +#else + __ERROR_XX_UNKNOWN_CREATE_KEY_FUNCTIONS +#endif + +#if defined(HAVE_KRB5_AUTH_CON_SETKEY) && !defined(HAVE_KRB5_AUTH_CON_SETUSERUSERKEY) + krb5_error_code krb5_auth_con_setuseruserkey(krb5_context context, + krb5_auth_context auth_context, + krb5_keyblock *keyblock) +{ + return krb5_auth_con_setkey(context, auth_context, keyblock); +} +#endif + + void get_auth_data_from_tkt(DATA_BLOB *auth_data, krb5_ticket *tkt) +{ +#if defined(HAVE_KRB5_TKT_ENC_PART2) + if (tkt->enc_part2) + *auth_data = data_blob(tkt->enc_part2->authorization_data[0]->contents, + tkt->enc_part2->authorization_data[0]->length); +#else + if (tkt->ticket.authorization_data && tkt->ticket.authorization_data->len) + *auth_data = data_blob(tkt->ticket.authorization_data->val->ad_data.data, + tkt->ticket.authorization_data->val->ad_data.length); +#endif +} + + krb5_const_principal get_principal_from_tkt(krb5_ticket *tkt) +{ +#if defined(HAVE_KRB5_TKT_ENC_PART2) + return tkt->enc_part2->client; +#else + return tkt->client; +#endif +} + +#if !defined(HAVE_KRB5_LOCATE_KDC) + krb5_error_code krb5_locate_kdc(krb5_context ctx, const krb5_data *realm, struct sockaddr **addr_pp, int *naddrs, int get_masters) +{ + krb5_krbhst_handle hnd; + krb5_krbhst_info *hinfo; + krb5_error_code rc; + int num_kdcs, i; + struct sockaddr *sa; + + *addr_pp = NULL; + *naddrs = 0; + + rc = krb5_krbhst_init(ctx, realm->data, KRB5_KRBHST_KDC, &hnd); + if (rc) { + DEBUG(0, ("krb5_locate_kdc: krb5_krbhst_init failed (%s)\n", error_message(rc))); + return rc; + } + + for ( num_kdcs = 0; (rc = krb5_krbhst_next(ctx, hnd, &hinfo) == 0); num_kdcs++) + ; + + krb5_krbhst_reset(ctx, hnd); + + if (!num_kdcs) { + DEBUG(0, ("krb5_locate_kdc: zero kdcs found !\n")); + krb5_krbhst_free(ctx, hnd); + return -1; + } + + sa = malloc( sizeof(struct sockaddr) * num_kdcs ); + if (!sa) { + DEBUG(0, ("krb5_locate_kdc: malloc failed\n")); + krb5_krbhst_free(ctx, hnd); + naddrs = 0; + return -1; + } + + memset(*addr_pp, '\0', sizeof(struct sockaddr) * num_kdcs ); + + for (i = 0; i < num_kdcs && (rc = krb5_krbhst_next(ctx, hnd, &hinfo) == 0); i++) { + if (hinfo->ai->ai_family == AF_INET) + memcpy(&sa[i], hinfo->ai->ai_addr, sizeof(struct sockaddr)); + } + + krb5_krbhst_free(ctx, hnd); + + *naddrs = num_kdcs; + *addr_pp = sa; + return 0; +} +#endif + /* we can't use krb5_mk_req because w2k wants the service to be in a particular format */ 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) { |